@vpxa/aikit 0.1.379 → 0.1.381

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.
Files changed (74) hide show
  1. package/package.json +1 -1
  2. package/packages/claude-desktop/dist/manifest.json +1 -1
  3. package/packages/cli/dist/index.js +3 -3
  4. package/packages/cli/dist/{init-BTsNYC02.js → init-Be3nyugf.js} +1 -1
  5. package/packages/cli/dist/{templates-CRs_gkfS.js → templates-CK9mSHyJ.js} +24 -24
  6. package/packages/core/dist/index.d.ts +23 -3
  7. package/packages/server/dist/bin.js +2 -2
  8. package/packages/server/dist/config-Bz8Uyzuq.js +2 -0
  9. package/packages/server/dist/config-CTYSUkDf.js +1 -0
  10. package/packages/server/dist/{curated-manager-CBKTmAjM.js → curated-manager-D4MOFQ-t.js} +1 -1
  11. package/packages/server/dist/dashboard-static-BbHMHkQ3.js +1 -0
  12. package/packages/server/dist/dashboard-static-gAOiHHqI.js +2 -0
  13. package/packages/server/dist/index.d.ts +1 -1
  14. package/packages/server/dist/index.js +2 -2
  15. package/packages/server/dist/{observations-CfglxBMB.js → observations-BhMmh4uj.js} +1 -1
  16. package/packages/server/dist/{observations-CrQU_HVm.js → observations-Cri43dvk.js} +1 -1
  17. package/packages/server/dist/register-tools-0E-d3SIk.js +3043 -0
  18. package/packages/server/dist/register-tools-fdniAqWz.js +3044 -0
  19. package/packages/server/dist/server-C4qsakCZ.js +27 -0
  20. package/packages/server/dist/server-DHdcyAmX.js +26 -0
  21. package/packages/server/dist/server-http-CC39yGVF.js +1 -0
  22. package/packages/server/dist/server-http-DlTdz6ch.js +2 -0
  23. package/packages/server/dist/server-stdio-CTbBp6wO.js +1 -0
  24. package/packages/server/dist/server-stdio-Colzu8Wb.js +2 -0
  25. package/packages/server/dist/settings-static-DV2hXZgq.js +1 -0
  26. package/packages/server/dist/settings-static-PjpMR9Q7.js +2 -0
  27. package/packages/server/dist/startup-maintenance-BnTozHs1.js +21 -0
  28. package/packages/server/dist/startup-maintenance-CxAICs-n.js +20 -0
  29. package/packages/tools/dist/index.d.ts +40 -3
  30. package/packages/tools/dist/index.js +121 -104
  31. package/scaffold/dist/adapters/_shared.mjs +1 -1
  32. package/scaffold/dist/adapters/hermes.mjs +1 -1
  33. package/scaffold/dist/definitions/agents.mjs +1 -1
  34. package/scaffold/dist/definitions/exec-hooks.mjs +1 -1
  35. package/scaffold/dist/definitions/hooks.mjs +1 -1
  36. package/scaffold/dist/definitions/protocols.mjs +20 -20
  37. package/scaffold/dist/definitions/skills/aikit.mjs +10 -4
  38. package/scaffold/dist/definitions/skills/browser-use.mjs +1 -1
  39. package/scaffold/dist/definitions/skills/orchestrator.mjs +45 -8
  40. package/scaffold/dist/definitions/skills/present.mjs +8 -5
  41. package/scaffold/general/hooks/scripts/__tests__/bash-guard.test.mjs +214 -0
  42. package/scaffold/general/hooks/scripts/__tests__/read-size-guard.test.mjs +183 -0
  43. package/scaffold/general/hooks/scripts/bash-guard.mjs +6 -0
  44. package/packages/server/dist/config-BJiacqlj.js +0 -2
  45. package/packages/server/dist/config-DyLck_1C.js +0 -1
  46. package/packages/server/dist/dashboard-static-Dw7Nsq4f.js +0 -1
  47. package/packages/server/dist/dashboard-static-dPnij4uF.js +0 -2
  48. package/packages/server/dist/evolution-BX_zTSdj.js +0 -2
  49. package/packages/server/dist/evolution-DWaEE6XW.js +0 -3
  50. package/packages/server/dist/prelude-BbNJxiBp.js +0 -1
  51. package/packages/server/dist/prelude-CZ1LShfj.js +0 -2
  52. package/packages/server/dist/promotion-DRnRfteq.js +0 -3
  53. package/packages/server/dist/promotion-DzVLWVtx.js +0 -2
  54. package/packages/server/dist/repair-json-B6Q_HRoP.js +0 -3
  55. package/packages/server/dist/repair-json-D4mft_HA.js +0 -4
  56. package/packages/server/dist/resolve-sibling-BmZ7AxaA.js +0 -1
  57. package/packages/server/dist/resolve-sibling-DrGKPpb0.js +0 -2
  58. package/packages/server/dist/rolldown-runtime-yuFVEuWy.js +0 -2
  59. package/packages/server/dist/sampling-CzGQqIbt.js +0 -1
  60. package/packages/server/dist/sampling-MSeOiAqz.js +0 -2
  61. package/packages/server/dist/server-CMpnBSAC.js +0 -3068
  62. package/packages/server/dist/server-Cq5wP6Hk.js +0 -3067
  63. package/packages/server/dist/server-http-UNbq9MsP.js +0 -1
  64. package/packages/server/dist/server-http-dyzC379J.js +0 -2
  65. package/packages/server/dist/server-stdio-COZ6ut6S.js +0 -1
  66. package/packages/server/dist/server-stdio-yz2eyGS4.js +0 -2
  67. package/packages/server/dist/settings-static-BpQgaMRs.js +0 -1
  68. package/packages/server/dist/settings-static-MepJZjer.js +0 -2
  69. package/packages/server/dist/startup-maintenance-BPrX5-1U.js +0 -2
  70. package/packages/server/dist/startup-maintenance-CT6Z3734.js +0 -1
  71. package/packages/server/dist/supersession-CWEne3av.js +0 -2
  72. package/packages/server/dist/supersession-DO_ZROFl.js +0 -3
  73. package/packages/server/dist/version-check-C7xqQr9o.js +0 -1
  74. package/packages/server/dist/version-check-CH5SIhnq.js +0 -2
@@ -1,3068 +0,0 @@
1
- #!/usr/bin/env node
2
- import{n as e,t}from"./bin.js";import{a as n,c as r,d as i,f as a,h as o,i as s,l as c,m as l,n as u,o as d,p as f,r as p,s as m,u as h}from"./supersession-DO_ZROFl.js";import{a as g,i as _,n as v,o as y,r as b,reconfigureForWorkspace as x,t as S}from"./config-BJiacqlj.js";import{n as C,r as w}from"./resolve-sibling-DrGKPpb0.js";import{n as T,r as E}from"./evolution-DWaEE6XW.js";import{a as D,i as O,n as k,r as ee,s as te,t as ne}from"./promotion-DRnRfteq.js";import{t as re}from"./repair-json-D4mft_HA.js";import{autoUpgradeScaffold as ie,cleanupOldVersions as ae,getCurrentVersion as oe,getUpgradeState as se}from"./version-check-CH5SIhnq.js";import{createRequire as ce}from"node:module";import{fileURLToPath as le}from"node:url";import{promisify as ue}from"node:util";import{AIKIT_PATHS as de,AIKIT_RUNTIME_PATHS as fe,CONTENT_TYPES as pe,CircuitBreaker as me,DISPLAY_SERVER_NAME as he,EMBEDDING_DEFAULTS as ge,HealthBus as _e,KNOWLEDGE_ORIGINS as ve,MODEL_REGISTRY as ye,SOURCE_TYPES as A,TOKEN_BUDGETS as j,addLogListener as be,computePartitionKey as xe,createLogger as M,getGlobalDataDir as Se,getPartitionDir as Ce,hashPath as we,isUserInstalled as Te,listWorkspaces as Ee,safeCwd as De,safeCwdOrHome as Oe,serializeError as N}from"../../core/dist/index.js";import{copyFileSync as ke,existsSync as P,mkdirSync as Ae,readFileSync as F,readdirSync as je,renameSync as Me,rmSync as Ne,statSync as Pe,unlinkSync as Fe,writeFileSync as Ie}from"node:fs";import{basename as Le,dirname as Re,isAbsolute as ze,join as I,relative as Be,resolve as L,sep as Ve}from"node:path";import{mkdir as He,readFile as Ue,readdir as We,rm as Ge,stat as Ke,unlink as qe,writeFile as Je}from"node:fs/promises";import{createHash as Ye,randomBytes as Xe,randomUUID as Ze,timingSafeEqual as Qe}from"node:crypto";import{FileCache as $e,WORKSPACE_SKILL_FILENAME as et,acquireLease as tt,addToWorkset as nt,audit as rt,bookendReorder as it,buildNodeNameMap as at,changelog as ot,check as st,checkpointDiff as ct,checkpointGC as lt,checkpointHistory as ut,checkpointLatest as dt,checkpointList as ft,checkpointLoad as pt,checkpointSave as mt,codemod as ht,compressTerminalOutput as gt,computeSourceHash as _t,createRestorePoint as vt,createSearchSuccessResponse as yt,delegate as bt,delegateListModels as xt,deleteWorkset as St,diffParse as Ct,digest as wt,envInfo as Tt,evaluate as Et,evidenceMap as Dt,fileSummaryTool as Ot,find as kt,findExamples as At,forgeGround as jt,generateFlowBriefing as Mt,generateWorkspaceSkill as Nt,getRefTelemetry as Pt,getWorkset as Ft,gitContext as It,graphAugmentSearch as Lt,graphQuery as Rt,isSkillStale as zt,laneCreate as Bt,laneDiff as Vt,laneDiscard as Ht,laneList as Ut,laneMerge as Wt,laneStatus as Gt,listActiveLeases as Kt,listRestorePoints as qt,listWorksets as Jt,measure as Yt,onboard as Xt,parseOutput as Zt,processList as Qt,processLogs as $t,processStart as en,processStatus as tn,processStop as nn,queueClear as rn,queueCreate as an,queueDag as on,queueDelete as sn,queueDone as cn,queueFail as ln,queueGet as un,queueList as dn,queueNext as fn,queuePush as pn,releaseLease as mn,removeFromWorkset as hn,rename as gn,replayClear as _n,replayList as vn,replayTrim as yn,resolveNodeName as bn,resolveSkillDir as xn,resolveWorkspaceDir as Sn,restoreFromPoint as Cn,saveWorkset as wn,schemaValidate as Tn,scopeMap as En,scoreCompliance as Dn,sessionDigest as On,sessionDigestSampling as kn,stashClear as An,stashDelete as jn,stashGet as Mn,stashList as Nn,stashSet as Pn,storeReversibleContext as Fn,summarizeCheckResult as In,symbol as Ln,testRun as Rn,trace as zn,truncateToTokenBudget as Bn,watchList as Vn,webFetch as Hn,webSearch as Un}from"../../tools/dist/index.js";import{homedir as Wn,tmpdir as Gn}from"node:os";import{McpServer as Kn,ResourceTemplate as qn}from"@modelcontextprotocol/sdk/server/mcp.js";import{RootsListChangedNotificationSchema as Jn}from"@modelcontextprotocol/sdk/types.js";import{buildFormSchema as Yn,field as Xn,normalizeResponse as Zn}from"../../elicitation/dist/index.js";import{completable as Qn}from"@modelcontextprotocol/sdk/server/completable.js";import{z as R}from"zod";import{getEngine as $n,registerBrowserTools as er}from"../../browser/dist/index.js";import{DependencyAnalyzer as tr,DiagramGenerator as nr,EntryPointAnalyzer as rr,KnowledgeProducer as ir,PatternAnalyzer as ar,StructureAnalyzer as or,SymbolAnalyzer as sr}from"../../analyzers/dist/index.js";import{WasmDiagnostics as cr,WasmRuntime as lr,initializeWasm as ur}from"../../chunker/dist/index.js";import{ERCache as dr,ERClient as fr,EvolutionCollector as pr,PolicyStore as mr,PushAdapter as hr,mergeResults as gr}from"../../enterprise-bridge/dist/index.js";import{RESOURCE_MIME_TYPE as _r,getUiCapability as vr,registerAppResource as yr,registerAppTool as br}from"@modelcontextprotocol/ext-apps/server";import{SqliteGraphStore as xr,allMigrations as Sr,createSqliteAdapter as Cr,createStateStore as wr,createStore as Tr,runMigrations as Er}from"../../store/dist/index.js";import{exec as Dr,execFile as Or,execSync as kr}from"node:child_process";import{buildSnapshot as Ar,createOwnerCapability as jr,rotateOwnerCapability as Mr,validateToken as Nr}from"../../flows/dist/index.js";import{TemplateRegistry as Pr,buildShell as Fr,dashboardTemplateDefinition as Ir,defaultRegistry as Lr,flameGraphTemplateDefinition as Rr,isError as zr,isResult as Br,kanbanTemplateDefinition as Vr,listSortTemplateDefinition as Hr,renderSurface as Ur}from"../../blocks-core/dist/index.mjs";import{createServer as Wr}from"node:http";import"../../tool-routing/dist/index.mjs";import{EmbedderProxy as Gr}from"../../embeddings/dist/index.js";import{FileHashCache as Kr,IncrementalIndexer as qr}from"../../indexer/dist/index.js";import{AsyncLocalStorage as Jr}from"node:async_hooks";const Yr=M(`sampling`);function Xr(e){if(!e.modelPreferences)return;let t={...e.modelPreferences.costPriority===void 0?{}:{costPriority:e.modelPreferences.costPriority},...e.modelPreferences.speedPriority===void 0?{}:{speedPriority:e.modelPreferences.speedPriority},...e.modelPreferences.intelligencePriority===void 0?{}:{intelligencePriority:e.modelPreferences.intelligencePriority}};return Object.keys(t).length>0?t:void 0}function Zr(e){if(Array.isArray(e))return e.map(e=>Zr(e)).filter(e=>e.length>0).join(`
3
- `);if(e&&typeof e==`object`&&`type`in e){let t=e;if(t.type===`text`&&typeof t.text==`string`)return t.text}return JSON.stringify(e)}function Qr(e){let t=e.server,n=typeof t?.createMessage==`function`;return{get available(){return n},async createMessage(e){if(!n)throw Error(`Sampling not available: client does not support createMessage`);let r=e.context?`${e.context}\n\n---\n\n${e.prompt}`:e.prompt;try{let n=t.createMessage({messages:[{role:`user`,content:{type:`text`,text:r}}],systemPrompt:e.systemPrompt,modelPreferences:Xr(e),maxTokens:e.maxTokens??4e3}),i;if(e.timeoutMs&&e.timeoutMs>0){let t=new Promise((t,n)=>setTimeout(()=>n(Error(`Sampling createMessage timed out after ${e.timeoutMs}ms`)),e.timeoutMs));i=await Promise.race([n,t])}else i=await n;return{text:Zr(i.content),model:i.model,stopReason:i.stopReason}}catch(e){throw Yr.warn(`Sampling createMessage failed`,{error:String(e)}),e}}}}function $r(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 Zn(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,Yn({confirmed:Xn.confirm(e)}));return t?.action===`accept`&&t.content?.confirmed===!0},async selectOne(e,t){let r=await n(e,Yn({selection:Xn.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,Yn({selections:Xn.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,Yn({text:Xn.text(e,{description:t})}));if(r?.action!==`accept`)return null;let i=r.content?.text;return typeof i==`string`?i:null}}}const ei={debug:`debug`,info:`info`,warn:`warning`,error:`error`};function ti(e){return be(({level:t,component:n,message:r,data:i})=>{try{Promise.resolve(e.sendLoggingMessage({level:ei[t],logger:n,data:i?{message:r,...i}:r})).catch(()=>{})}catch{}})}const ni=3e4,ri=new Map;function ii(e,t,n){let r=ri.get(e);if(r&&Date.now()<r.expires)return Promise.resolve(r.data);let i=n();return Promise.resolve(i).then(n=>(ri.set(e,{data:n,expires:Date.now()+t}),n))}function ai(){ri.clear()}function oi(e,t){return ii(`curated-paths`,ni,async()=>e.listPaths({limit:5e3})).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function si(e,t){return ii(`file-paths`,ni,()=>e.listSourcePaths()).then(e=>e.filter(e=>e.toLowerCase().includes(t.toLowerCase())).slice(0,20))}function ci(e,t){return ii(`symbol-names`,ni,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 li(e,t){return t?Nn(t).map(e=>e.key).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function ui(e){return Jt().map(e=>e.name).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20)}function di(e,t){return t?ft(t).map(e=>e.label).filter(t=>t.toLowerCase().includes(e.toLowerCase())).slice(0,20):[]}function fi(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(`
4
- `)}}]})),e.registerPrompt(`onboard`,{title:`Onboard Codebase`,description:`Analyze the codebase for first-time onboarding — runs all analyzers and produces a knowledge summary`,argsSchema:{path:R.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(`
5
- `)}}]})),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(`
6
- `)}}]})),e.registerPrompt(`sessionEnd`,{title:`End AI Kit Session`,description:`Persist decisions and create a session checkpoint before ending`,argsSchema:{summary:R.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(`
7
- `)}}]})),e.registerPrompt(`search`,{title:`Search AI Kit`,description:`Search AI Kit with hybrid semantic + keyword search`,argsSchema:{query:R.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:R.string().describe(`Title of the knowledge entry`),content:R.string().describe(`Content to remember`),category:R.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:R.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` then `compact` for detail","4. `blast_radius` on planned changes to assess impact"].join(`
8
- `)}}]})),e.registerPrompt(`investigate`,{title:`Investigate Bug`,description:`Bug investigation workflow — parse error, find symbols, trace data flow, assess impact`,argsSchema:{error:R.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({ changed_files: [<affected files>] })` — assess fix impact"].join(`
9
- `)}}]})),!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:Qn(R.string().describe(`Path of the curated entry (e.g. conventions/naming.md)`),async e=>oi(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:Qn(R.string().describe(`Path of the curated entry to update`),async e=>oi(r,e)),content:R.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:Qn(R.string().describe(`Path of the curated entry to delete`),async e=>oi(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:Qn(R.string().describe(`Source file path`),async e=>si(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:Qn(R.string().describe(`Symbol name`),async e=>ci(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:Qn(R.string().describe(`Stash key`),e=>li(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:Qn(R.string().describe(`Workset name`),e=>ui(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:Qn(R.string().describe(`Checkpoint name`),e=>di(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(`
10
- `)}}]})),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({ changed_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(`
11
- `)}}]})),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(`
12
- `)}}]})),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({ changed_files })` — Assess impact of fix",`5. Implement fix`,"6. `check({})` + `test_run({})` — Verify fix works",``,`Describe the issue:`].join(`
13
- `)}}]})),e.registerPrompt(`context_workflow`,{title:`Build Context`,description:`Progressive context building: file_summary → compact → 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. `compact({ path, query })` or `compact({ ref, query? })` — 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(`
14
- `)}}]})),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(`
15
- `)}}]}))}const pi={enabled:!0,batchSize:10,debounceMs:5e3,maxFactsPerSession:50,minQuality:.3};function mi(e){return(e.content??[]).filter(e=>e.type===`text`&&typeof e.text==`string`).map(e=>e.text??``).join(`
16
- `)}function z(e){return Ye(`sha256`).update(e).digest(`hex`).slice(0,16)}function hi(e){let t=0;return e.length>=50&&(t+=.2),e.length>=150&&(t+=.1),/[a-zA-Z]\w+\.\w+/.test(e)&&(t+=.15),/[:=]|^[-*]|\n[-*]|```/.test(e)&&(t+=.15),/\b(use|should|must|always|never|prefer|avoid|requires?|detected|confirmed|verified)\b/i.test(e)&&(t+=.2),/^(Error|TypeError|ReferenceError):/m.test(e)&&e.length<100&&(t-=.2),Math.max(0,Math.min(1,t))}const gi={enabled:!0,batchThreshold:20,cooldownMs:3e5,maxCandidatesPerSession:5,initialConfidence:40,excludeTools:[`knowledge`,`replay`,`stash`,`checkpoint`,`session_digest`,`reindex`,`status`,`flow`,`evidence_map`,`present`]},_i=new Set([`search`,`find`,`symbol`,`grep_search`,`semantic_search`]),vi=new Set([`replace_string_in_file`,`editfiles`,`create_file`,`apply_patch`]),yi=new Set([`check`,`test_run`]),bi=new Set(`action.and.args.auto.buffer.category.content.create.cwd.false.file.files.find.grep.json.knowledge.list.path.query.read.replace.search.semantic.subaction.symbol.test.tool.true.update`.split(`.`));function xi(e){let t=e.toLowerCase().match(/[a-z0-9]{2,}/g)??[];return new Set(t)}function Si(e,t){let n=xi(e),r=xi(t);if(n.size===0&&r.size===0)return 1;if(n.size===0||r.size===0)return 0;let i=new Set([...n].filter(e=>r.has(e))),a=new Set([...n,...r]);return i.size/a.size}function Ci(e,t){return e.length<=t?e:`${e.slice(0,Math.max(0,t-1))}...`}function wi(e){try{return JSON.stringify(e)}catch{return`[unserializable args]`}}function Ti(e){return e.replace(/^mcp_[^_]+_/,``).toLowerCase()}function Ei(e){return[...new Set(e.filter(e=>e.length>0))]}function Di(e,t){return{...t,confidence:gi.initialConfidence,tags:[`auto-observed`,`detector:${e}`],detector:e}}function Oi(e,t){let n=new Map;for(let t of e)for(let e of xi(t))bi.has(e)||n.set(e,(n.get(e)??0)+1);let r=[...n.entries()].filter(([,e])=>e>=t).sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0])).map(([e])=>e);return r.length>0?r.slice(0,4):[...n.entries()].sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0])).slice(0,4).map(([e])=>e)}function ki(e){return e.length>0?e.join(`, `):`similar tasks`}function Ai(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.ts==`number`&&Number.isFinite(t.ts)&&typeof t.tool==`string`&&typeof t.input==`string`&&(t.output===void 0||typeof t.output==`string`)&&Array.isArray(t.files)&&t.files.every(e=>typeof e==`string`)}function ji(e){let t=[];for(let n of e)t.some(e=>Si(e.title,n.title)>.8)||t.push(n);return t}function Mi(e){return typeof e==`string`?[e]:Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function Ni(e){return typeof e==`string`?[...e.matchAll(/^\*\*\* (?:Add|Delete|Update) File: (.+)$/gm)].map(e=>e[1]?.trim()??``).filter(Boolean):[]}function Pi(e){let t=[],n=e=>{if(!(typeof e!=`object`||!e)){if(Array.isArray(e)){for(let t of e)n(t);return}for(let[r,i]of Object.entries(e))(r===`path`||r===`filePath`||r===`files`)&&t.push(...Mi(i)),n(i)}};return n(e),t.push(...Ni(e.input)),Ei(t)}function Fi(e){return{tool:e.toolName,input:Ci(wi(e.args),200),output:Ci(mi(e.result),500),files:Pi(e.args),ts:Date.now()}}function Ii(e){return{title:e.title,content:`${e.context}\n\n${e.insight}\n\nEvidence:\n${e.evidence}`,category:`conventions`,tags:Ei([`auto-observed`,`detector:${e.detector}`,...e.tags]),hash:Ye(`sha256`).update(`${e.detector}:${e.title}`).digest(`hex`).slice(0,16),quality:Math.max(0,Math.min(1,e.confidence/100)),source:`behavioral:${e.detector}`}}function Li(e){let t=new Map;for(let n of e){let e=Ti(n.tool),r=t.get(e)??[];r.push(n),t.set(e,r)}return[...t.entries()].filter(([,e])=>e.length>=5).map(([e,t])=>{let n=ki(Oi(t.map(e=>e.input),Math.max(2,Math.ceil(t.length/2))));return Di(`tool-preference`,{title:`Preferred tool: ${e} for ${n}`,context:`Observed ${t.length} ${e} calls with recurring inputs around ${n}.`,insight:`Use ${e} when working with ${n}.`,evidence:t.slice(0,5).map(e=>`${e.tool}: ${e.input}`).join(`
17
- `)})})}function Ri(e){let t=new Map;for(let n=0;n<e.length;n+=1){let r=e[n];if(_i.has(Ti(r.tool)))for(let i=n+1;i<e.length&&i<=n+5;i+=1){let n=e[i];if(!(!vi.has(Ti(n.tool))||n.files.length===0))for(let e of Ei(n.files)){let i=t.get(e)??{count:0,queries:[],evidence:[]};i.count+=1,i.queries.push(r.input),i.evidence.push(`${r.tool}: ${r.input} -> ${n.tool}: ${e}`),t.set(e,i)}}}return[...t.entries()].filter(([,e])=>e.count>=3).map(([e,t])=>{let n=ki(Oi(t.queries,Math.max(2,Math.ceil(t.count/2))));return Di(`search-action`,{title:`Check ${e} when searching for ${n}`,context:`Searches related to ${n} were followed by edits to ${e} ${t.count} times within five tool calls.`,insight:`When working on ${n}, check ${e} early because searches repeatedly led there.`,evidence:t.evidence.slice(0,5).join(`
18
- `)})})}function zi(e){let t=new Map;for(let n=0;n<e.length-2;n+=1){let r=e[n];if(!yi.has(Ti(r.tool)))continue;let i=new Set,a=!1;for(let o=n+1;o<e.length;o+=1){let n=e[o],s=Ti(n.tool);if(vi.has(s)){a=!0;for(let e of n.files)i.add(e);continue}if(yi.has(s)){if(!a||i.size===0)break;let e=[...i].sort(),o=e.join(`|`),s=t.get(o)??{count:0,evidence:[]};s.count+=1,s.evidence.push(`${r.tool} -> edit(${e.join(`, `)}) -> ${n.tool}`),t.set(o,s);break}if(!a)break}}return[...t.entries()].filter(([,e])=>e.count>=2).map(([e,t])=>{let n=e.split(`|`);return Di(`error-fix-cycle`,{title:`Repeated validation-edit loop in ${n.length===1?n[0]:`${n[0]} and related files`}`,context:`Observed ${t.count} validation cycles touching ${n.join(`, `)}.`,insight:`Common fix pattern in ${n.join(`, `)}: check -> edit -> recheck.`,evidence:t.evidence.slice(0,5).join(`
19
- `)})})}function Bi(e,t=gi){if(!t.enabled||e.length===0)return[];let n=new Set(t.excludeTools.map(e=>e.toLowerCase())),r=e.filter(e=>!n.has(Ti(e.tool)));return ji([...Li(r),...Ri(r),...zi(r)].map(e=>({...e,confidence:t.initialConfidence,tags:Ei([`auto-observed`,`detector:${e.detector}`,...e.tags])}))).slice(0,t.maxCandidatesPerSession)}function Vi(e){return e.split(`
20
- `).filter(Boolean).map(e=>{try{return JSON.parse(e)}catch{return null}}).filter(Ai).map(e=>({...e,output:e.output??``}))}var Hi=class{name=`behavioral`;tools=[];buffer=[];eventCounter=0;lastDetectionTs=0;extract(e){if(this.push(Fi(e)),this.eventCounter+=1,this.eventCounter%50!=0)return[];let t=Date.now();if(t-this.lastDetectionTs<3e5)return[];let n=Bi(this.buffer).map(Ii);return this.eventCounter=0,this.lastDetectionTs=t,n}push(e){this.buffer.push(e),this.buffer.length>100&&this.buffer.splice(0,this.buffer.length-100)}};function Ui(){return new Hi}Ui();const Wi={name:`build-commands`,tools:[`check`,`test_run`],extract(e){if(e.isError)return[];let t=mi(e.result);if(!t)return[];let n=[];if(e.toolName===`check`){let r=[];if(/typecheck.*(?:pass|success|0 error)/i.test(t)&&r.push(`typecheck`),/lint.*(?:pass|success|no (?:warning|error))/i.test(t)&&r.push(`lint`),/biome.*(?:checked|no fixes)/i.test(t)&&r.push(`biome`),r.length>0){let t=[...r].sort();n.push({title:`Verified checks: ${t.join(`, `)}`,content:`The following checks passed successfully: ${t.join(`, `)}.\nRun with the \`check\` tool to verify code quality.`,category:`conventions`,tags:[`build`,`verified`,...t],hash:z(`build-checks-${t.join(`,`)}`),quality:.8,source:e.toolName})}}if(e.toolName===`test_run`){let r=t.match(/(\d+)\s*(?:tests?\s+)?pass/i),i=t.match(/(\d+)\s*(?:total|tests)/i),a=t.match(/(\d+)\s*(?:test\s+)?files?/i);if(r){let t=r[1],o=i?.[1]??t,s=a?.[1]??`unknown`;n.push({title:`Test suite summary`,content:`Test results: ${t}/${o} tests passed across ${s} test files.\nUse \`test_run\` tool to execute the test suite.`,category:`context`,tags:[`testing`,`verified`,`test-summary`],hash:z(`test-summary-${t}-${o}`),quality:.7,source:e.toolName,ttlMs:72e5})}let o=t.match(/(?:running|command|exec):\s*(.+?)$/im);if(o?.[1]){let t=o[1].trim();n.push({title:`Test command: ${t.slice(0,60)}`,content:`Verified test command: \`${t}\`\nThis command successfully ran the project's test suite.`,category:`conventions`,tags:[`testing`,`build-command`,`verified`],hash:z(`test-cmd-${t}`),quality:.9,source:e.toolName})}}return n}},Gi={name:`codebase-insights`,tools:[`analyze`,`scope_map`,`blast_radius`,`onboard`],extract(e){let t=mi(e.result);if(!t||t.length<50||e.isError)return[];let n=[];if(e.toolName===`analyze`&&e.args.aspect===`structure`){let r=typeof e.args.path==`string`?e.args.path:`.`,i=t.slice(0,600);n.push({title:`Structure: ${r}`,content:`Project structure analysis for ${r}:\n${i}`,category:`context`,tags:[`architecture`,`structure`,`analysis`],hash:z(`structure-${r}`),identityKey:`analyze:structure:${r}`,quality:Math.min(.9,hi(i)+.2),source:e.toolName})}if(e.toolName===`analyze`&&e.args.aspect===`dependencies`){let r=typeof e.args.path==`string`?e.args.path:`.`,i=t.split(/\r?\n/).filter(e=>/(?:depends on|imports?|requires?|from)\s/i.test(e)).slice(0,10);if(i.length>0){let t=`Dependency analysis for ${r}:\n${i.join(`
21
- `)}`;n.push({title:`Dependencies: ${r}`,content:t,category:`context`,tags:[`architecture`,`dependencies`,`analysis`],hash:z(`deps-${r}`),identityKey:`analyze:dependencies:${r}`,quality:.7,source:e.toolName})}}if(e.toolName===`blast_radius`){let r=e.args.changed_files,i=Array.isArray(r)?r.map(String).join(`, `):String(r??``);if(i&&t.length>50){let r=t.slice(0,400);n.push({title:`Blast radius: ${i.slice(0,60)}`,content:`Impact analysis for changes to ${i}:\n${r}`,category:`context`,tags:[`architecture`,`blast-radius`,`impact`],hash:z(`blast-${i}`),identityKey:`blast-radius:${i}`,quality:.6,source:e.toolName,ttlMs:36e5})}}if(e.toolName===`analyze`&&e.args.aspect===`entry_points`){let r=t.split(/\r?\n/).filter(e=>/(?:entry|export|main|bin)\b/i.test(e)).slice(0,10);r.length>0&&n.push({title:`Project entry points`,content:`Detected entry points:\n${r.join(`
22
- `)}`,category:`context`,tags:[`architecture`,`entry-points`],hash:z(`entry-points`),identityKey:`analyze:entry-points`,quality:.7,source:e.toolName})}if(e.toolName===`scope_map`){let r=typeof e.args.task==`string`?e.args.task:``;r&&t.length>100&&n.push({title:`Scope map: ${r.slice(0,60)}`,content:`Scope analysis for "${r}":\n${t.slice(0,500)}`,category:`context`,tags:[`planning`,`scope-map`],hash:z(`scope-${r}`),identityKey:`scope-map:${r}`,quality:.6,source:e.toolName,ttlMs:72e5})}return e.toolName===`onboard`&&t.length>200&&n.push({title:`Onboard analysis summary`,content:`Codebase onboarding analysis:\n${t.slice(0,800)}`,category:`context`,tags:[`onboarding`,`analysis`,`structure`],hash:z(`onboard-summary`),identityKey:`onboard:summary`,quality:.9,source:e.toolName}),n}};function Ki(e,t,n,r,i,a,o,s){return{title:e,content:t,category:`context`,tags:s,hash:z(n),identityKey:r,quality:i,ttlMs:a,source:o}}const qi={name:`context-reads`,tools:[`file_summary`,`digest`,`lookup`,`compact`,`stratum_card`],extract(e){if(e.isError)return[];let t=mi(e.result);if(!t)return[];if(e.toolName===`compact`){let n=typeof e.args.path==`string`?e.args.path:void 0,r=typeof e.args.query==`string`?e.args.query:void 0;return!n||!r||t.length<100?[]:[Ki(`Context: ${n} (${r.slice(0,40)})`,t.slice(0,800),`compact-${n}-${r}`,`compact:${n}:${r}`,.7,72e5,e.toolName,[`context`,`compact`,`file-read`])]}if(e.toolName===`file_summary`){let n=Array.isArray(e.args.files)?e.args.files:[],r=typeof e.args.path==`string`?e.args.path:n[0],i=typeof e.args.query==`string`?e.args.query:void 0,a=typeof e.args.tier==`string`?e.args.tier:void 0;return r?a===`T2`||i&&n.length>0?!i||t.length<100?[]:[Ki(`Context: ${r} (${i.slice(0,40)})`,t.slice(0,800),`file-summary-${r}-${i}`,`file-summary:${r}:${i}`,.7,72e5,e.toolName,[`context`,`file_summary`,`file-read`])]:t.length<50?[]:[Ki(`Structure: ${r}`,t,`file-summary-${r}`,`file-summary:${r}`,.65,144e5,e.toolName,[`context`,`file-summary`,`structure`])]:[]}if(e.toolName===`digest`){let n=typeof e.args.query==`string`?e.args.query:void 0;if(!n||t.length<150)return[];let r=Array.isArray(e.args.sources)?e.args.sources.map(e=>{if(!e||typeof e!=`object`)return``;let t=e.id;return typeof t==`string`?t:``}).join(`,`):``;return[Ki(`Digest: ${n.slice(0,60)}`,t.slice(0,1e3),`digest-${n}-${r}`,`digest:${n}:${r}`,.75,72e5,e.toolName,[`context`,`digest`,`compression`])]}if(e.toolName===`lookup`){let n=typeof e.args.path==`string`?e.args.path:void 0;return!n||t.length<100?[]:[Ki(`Indexed: ${n}`,t.slice(0,600),`lookup-${n}`,`lookup:${n}`,.5,72e5,e.toolName,[`context`,`lookup`,`file-content`])]}if(e.toolName===`stratum_card`){let n=Array.isArray(e.args.files)?e.args.files.filter(e=>typeof e==`string`):[],r=typeof e.args.query==`string`?e.args.query:``,i=typeof e.args.tier==`string`?e.args.tier:void 0;if(n.length===0||!i||t.length<50)return[];let a=n.join(`,`),o=i===`T2`?`stratum-${a}-${i}-${r}`:`stratum-${a}-${i}`;return[Ki(`Card [${i}]: ${n[0]} (+${n.length-1})`,t.slice(0,600),o,`stratum:${i}:${a}:${r}`,i===`T2`?.7:.55,72e5,e.toolName,[`context`,`stratum-card`,i])]}return[]}};function Ji(e,t){let n=[],r=e.toLowerCase();r.includes(`biome`)?n.push({title:`Linter: Biome`,content:`This project uses Biome for linting and formatting.`,category:`conventions`,tags:[`tooling`,`linter`,`biome`],hash:z(`convention-linter-biome`),quality:.8,source:t}):r.includes(`eslint`)&&n.push({title:`Linter: ESLint`,content:`This project uses ESLint for linting.`,category:`conventions`,tags:[`tooling`,`linter`,`eslint`],hash:z(`convention-linter-eslint`),quality:.8,source:t}),r.includes(`prettier`)&&n.push({title:`Formatter: Prettier`,content:`This project uses Prettier for code formatting.`,category:`conventions`,tags:[`tooling`,`formatter`,`prettier`],hash:z(`convention-formatter-prettier`),quality:.8,source:t}),(/strict\s*(?:mode)?.*(?:enabled|true)/i.test(e)||/"strict"\s*:\s*true/.test(e))&&n.push({title:`TypeScript strict mode enabled`,content:`This project has TypeScript strict mode enabled. Ensure all types are explicit.`,category:`conventions`,tags:[`typescript`,`strict`,`config`],hash:z(`convention-ts-strict`),quality:.8,source:t});for(let e of[`pnpm`,`yarn`,`npm`,`bun`])if(r.includes(e)&&(r.includes(`lockfile`)||r.includes(`workspace`)||r.includes(`${e} run`))){n.push({title:`Package manager: ${e}`,content:`This project uses ${e} as its package manager.`,category:`conventions`,tags:[`tooling`,`package-manager`,e],hash:z(`convention-pm-${e}`),quality:.7,source:t});break}return(r.includes(`monorepo`)||r.includes(`workspaces`)||/packages\/\w+/.test(e))&&n.push({title:`Monorepo structure detected`,content:`This project uses a monorepo structure with multiple packages.`,category:`conventions`,tags:[`architecture`,`monorepo`],hash:z(`convention-monorepo`),quality:.7,source:t}),n}function Yi(e,t){let n=[],r=e.matchAll(/(?:pattern|convention):\s*(.+?)(?:\n|$)/gi);for(let e of r){let r=e[1]?.trim();r&&r.length>20&&r.length<200&&n.push({title:`Pattern: ${r.slice(0,80)}`,content:r,category:`patterns`,tags:[`detected-pattern`],hash:z(`pattern-${r}`),quality:.6,source:t})}return n}const Xi={name:`convention-detection`,tools:[`check`,`analyze`,`onboard`],extract(e){let t=mi(e.result);if(!t||e.isError)return[];let n=[];return n.push(...Ji(t,e.toolName)),e.toolName===`analyze`&&e.args.aspect===`patterns`&&n.push(...Yi(t,e.toolName)),n}};function Zi(e){let t=e&&typeof e==`object`&&`content`in e&&Array.isArray(e.content)?e.content.filter(e=>e?.text).map(e=>e.text).join(`
23
- `):``;if(!t)return null;try{return JSON.parse(t)}catch{return null}}function Qi(e,t,n,r,i,a,o,s,c){let l=[`decision-outcomes`,`flow`];return s&&l.push(`flow:${s}`),o&&l.push(...o),{title:e,content:t,category:`flow-context`,tags:l,hash:z(n),identityKey:r,quality:i,ttlMs:288e5,source:a,workspaceId:c}}function $i(e){return e.replace(/[^a-zA-Z0-9_-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`flow`}function ea(e){let t=.5;return e.length>=80&&(t+=.1),e.length>=160&&(t+=.05),/step[s]?[:/]\s*\w+/i.test(e)&&(t+=.1),/\d+\/\d+/.test(e)&&(t+=.05),/\b(completed|skipped|outcome|success)\b/i.test(e)&&(t+=.05),/\b(decision|decided|chose|selected|because|rationale)\b/i.test(e)&&(t+=.1),/\b(artifact|produced|created|generated|file:|\.md)\b/i.test(e)&&(t+=.05),Math.min(1,Math.max(0,t))}function ta(e){return typeof e.slug==`string`&&e.slug.length>0?e.slug:null}function na(e){let t=Array.isArray(e.completedSteps)?e.completedSteps.filter(e=>typeof e==`string`):[],n=Array.isArray(e.skippedSteps)?e.skippedSteps.filter(e=>typeof e==`string`):[],r=typeof e.totalSteps==`number`?e.totalSteps:t.length+n.length;return{stepId:typeof e.currentStep==`string`?e.currentStep:null,phase:typeof e.phase==`string`?e.phase:null,completedSteps:t,skippedSteps:n,totalSteps:r}}const ra={name:`decision-outcomes`,tools:[`flow`,`knowledge:remember`,`knowledge:forget`],maxFactsPerEvent:5,extract(e){if(e.isError)return[];let t=[],n=typeof e.args.action==`string`?e.args.action:``,r=Zi(e.result),i=r?ta(r):null,a=i?$i(i):null;if(n===`start`){let n=typeof e.args.name==`string`?e.args.name:`unknown`,i=typeof e.args.topic==`string`?e.args.topic:void 0,o=r?na(r):null,s=o?.stepId??`unknown`,c=o?.totalSteps??0,l=[`Flow started: "${n}".`,i?`Topic: "${i}".`:``,`First step: ${s}.`,c>0?`Total steps: ${c}.`:``,a?`Slug: ${a}.`:``].filter(Boolean).join(` `);t.push(Qi(`Flow started: ${n}${i?` — ${i}`:``}`,l,`flow-start-${a??n}`,`flow:start:${a??n}`,ea(l),e.toolName,[`flow:start`],a??void 0,e.workspaceId))}if(n===`step`){let n=typeof e.args.advance==`string`?e.args.advance:``,i=r?na(r):null,o=i?.stepId??`unknown`,s=i?.completedSteps??[],c=i?.skippedSteps??[],l=i?.totalSteps??0,u=s.length+c.length,d=n===`next`?`completed`:n===`skip`?`skipped`:n===`redo`?`redone`:`transitioned`,f=n===`next`?s[s.length-1]:n===`skip`?c[c.length-1]:null,p=[`Step ${d}: ${f??(n===`redo`?o:`initial`)}.`,`Current step: ${o}.`,`Progress: ${u}/${l} steps.`,a?`Slug: ${a}.`:``].filter(Boolean);if(t.push(Qi(`Step ${d}: ${f??o} (${u}/${l})`,p.join(` `),`flow-step-${a??``}-${o}-${n}`,`flow:step:${a??``}:${o}:${n}`,ea(p.join(` `)),e.toolName,[`flow:step`,`step:${n}`],a??void 0,e.workspaceId)),l>0&&t.push(Qi(`Flow progress: ${u}/${l} (${o})`,`Progress: ${u}/${l} steps completed. Completed: ${s.join(`, `)||`none`}. Skipped: ${c.join(`, `)||`none`}. Current: ${o}.`+(a?` Slug: ${a}.`:``),`flow-progress-${a??``}-${u}`,`flow:progress:${a??``}`,.75,e.toolName,[`flow:progress`],a??void 0,e.workspaceId)),r&&r.status===`completed`){let n=[`Flow completed successfully.`,`Steps: ${u}/${l}.`,`Completed: ${s.join(`, `)||`none`}.`,`Skipped: ${c.join(`, `)||`none`}.`,`Duration: ${e.durationMs}ms.`,a?`Slug: ${a}.`:``].filter(Boolean);t.push(Qi(`Flow completed: ${s.length+c.length}/${l} steps done`,n.join(` `),`flow-complete-${a??``}`,`flow:complete:${a??``}`,.8,e.toolName,[`flow:complete`],a??void 0,e.workspaceId))}}if(n===`reset`){let n=r?na(r):null,i=[`Flow abandoned or reset.`,`Completed: ${n?.completedSteps.length??0} steps.`,`Skipped: ${n?.skippedSteps.length??0} steps.`,a?`Slug: ${a}.`:``].filter(Boolean);t.push(Qi(`Flow abandoned: ${a??`unknown`}`,i.join(` `),`flow-abandon-${a??``}`,`flow:abandon:${a??``}`,.5,e.toolName,[`flow:abandon`],a??void 0,e.workspaceId))}if(e.toolName===`knowledge:remember`){let n=typeof e.args.title==`string`?e.args.title:void 0;if(!n)return t;t.push(Qi(`Memory recorded: ${n.slice(0,60)}`,`Explicit memory write for "${n}". Source: ${typeof e.args.source==`string`?e.args.source:`user`}.`,`memory-remember-${n}`,`memory:remember:${z(n).slice(0,12)}`,.9,e.toolName))}if(e.toolName===`knowledge:forget`){let n=typeof e.args.title==`string`?e.args.title:void 0;if(!n)return t;t.push(Qi(`Memory removed: ${n.slice(0,60)}`,`Explicit memory removal for "${n}".`,`memory-forget-${n}`,`memory:forget:${z(n).slice(0,12)}`,.7,e.toolName))}return t}};function ia(e,t){return e.match(t)?.[1]?.trim()||null}function aa(e,t,n,r,i,a){return{title:e,content:t,category:`context`,tags:n,hash:z(r),quality:i,source:a}}const oa={name:`environment-facts`,tools:[`env`,`config`,`status`],extract(e){let t=mi(e.result);if(!t)return[];let n=[],r=ia(t,/node(?:\.js)?\s*[:=]\s*([^\r\n]+)/i);r&&n.push(aa(`Node.js version`,`Detected Node.js version: ${r}`,[`environment`,`node`],`node-version-${r}`,.4,e.toolName));let i=ia(t,/(?:^|\n)os\s*[:=]\s*([^\r\n]+)/i);i&&n.push(aa(`Operating system`,`Detected OS: ${i}`,[`environment`,`os`],`os-${i}`,.4,e.toolName));let a=ia(t,/workspace(?: path)?\s*[:=]\s*([^\r\n]+)/i);a&&n.push(aa(`Workspace path`,`Primary workspace path: ${a}`,[`environment`,`workspace`],`workspace-${a}`,.4,e.toolName));let o=ia(t,/store(?: backend)?\s*[:=]\s*([^\r\n]+)/i);o&&n.push(aa(`Store backend`,`Configured store backend: ${o}`,[`environment`,`storage`],`store-${o}`,.6,e.toolName));let s=ia(t,/embedding(?: model)?\s*[:=]\s*([^\r\n]+)/i);return s&&n.push(aa(`Embedding model`,`Configured embedding model: ${s}`,[`environment`,`embedding`],`embedding-${s}`,.6,e.toolName)),n}},sa={"search-result":800,"file-card":2e3,analysis:1500,"step-summary":3e3},ca=[`search`,`file_summary`,`stratum_card`,`compact`,`blast_radius`,`scope_map`,`flow`],la={search:`search-result`,file_summary:`file-card`,stratum_card:`file-card`,compact:`analysis`,blast_radius:`analysis`,scope_map:`step-summary`,flow:`step-summary`},ua={"search-result":72e5,"file-card":144e5,analysis:144e5,"step-summary":288e5};function da(e){return e.replace(/\s+/g,` `).trim()}function fa(e){return Math.max(.6,Math.min(.8,hi(e)))}function B(e,t=500){let n=da(e);return n.length<=t?n:`${n.slice(0,Math.max(0,t-3)).trimEnd()}...`}function pa(e){return typeof e==`object`&&!!e}function ma(e){try{return JSON.parse(e)}catch{return null}}function V(e){return typeof e==`string`?da(e):typeof e==`number`||typeof e==`boolean`?String(e):``}function ha(e,t=5){if(!Array.isArray(e))return[];let n=[];for(let r of e){if(n.length>=t)break;if(typeof r==`string`){let e=da(r);e&&n.push(e);continue}if(pa(r)){let e=V(r.path)||V(r.sourcePath)||V(r.title)||V(r.name)||V(r.label);e&&n.push(e)}}return n}function H(e,...t){for(let n of t){let t=V(e[n]);if(t)return t}return``}function ga(e){let t=[e.file,e.path,e.files,e.changed_files,e.changedFiles].flatMap(e=>typeof e==`string`?[da(e)]:ha(e,6));return[...new Set(t.filter(Boolean))].slice(0,6)}function _a(e,t=6){let n=e.match(/(?:[A-Za-z]:[\\/]|\.\/?|\.\.[\\/]|[A-Za-z0-9_.-]+\/)[^\s,:;]+\.[A-Za-z0-9]+/g)??[];return[...new Set(n.map(e=>da(e)))].slice(0,t)}function va(e,t){return e.length===0?``:`${t}: ${e.join(`, `)}`}function ya(e,t=3){return e.split(/\r?\n/).map(e=>da(e)).filter(e=>e.length>=12).slice(0,t)}function ba(e){if(!pa(e))return``;let t=V(e.title)||V(e.path)||V(e.sourcePath)||V(e.file),n=V(e.snippet)||V(e.preview)||V(e.content)||V(e.summary);return da([t,n&&`- ${n}`].filter(Boolean).join(` `))}function xa(e,t){let n=H(e,`query`),r=ma(t);if(pa(r)&&Array.isArray(r.results)){let e=r.results.map(e=>ba(e)).filter(Boolean).slice(0,3);if(e.length>0)return B(`Query: ${n||`unknown`}. Top hits: ${e.join(` | `)}`,sa[`search-result`])}let i=ya(t,3);return B(`Query: ${n||`unknown`}. Top hits: ${i.join(` | `)}`,sa[`search-result`])}function Sa(e,t){let n=H(e,`path`,`file`),r=ma(t);if(pa(r)){let e=V(r.path)||n||`unknown file`,t=ha(r.imports,4),i=ha(r.exports,5),a=ha(r.functions,4),o=[`File: ${e}`,va(i,`Exports`),va(t,`Imports`),va(a,`Functions`)].filter(Boolean);if(o.length>1)return B(o.join(`. `),sa[`file-card`])}let i=ya(t,4);return B(`File: ${n||`unknown file`}. Structure: ${i.join(` | `)}`,sa[`file-card`])}function Ca(e,t){let n=ga(e),r=H(e,`tier`)||`T1`,i=ma(t);if(pa(i)){let e=(Array.isArray(i.cards)?i.cards:[]).map(e=>ba(e)).filter(Boolean).slice(0,3);if(e.length>0)return B(`Tier: ${r}. Files: ${n.join(`, `)||`unknown`}. Cards: ${e.join(` | `)}`,sa[`file-card`])}let a=ya(t,3);return B(`Tier: ${r}. Files: ${n.join(`, `)||`unknown`}. Highlights: ${a.join(` | `)}`,sa[`file-card`])}function wa(e,t){let n=H(e,`path`,`file`),r=H(e,`query`);return B(`Path: ${n||`unknown`}. Focus: ${r||`general`}. Summary: ${t}`,sa.analysis)}function Ta(e,t){let n=ga(e),r=ma(t),i=pa(r)?[...ha(r.affectedFiles,8),...ha(r.tests,4),...ha(r.importers,4)]:[],a=[...new Set([...i,..._a(t,8)])].slice(0,8),o=[`Changed: ${n.join(`, `)||`unknown`}`,va(a,`Affected`)].filter(Boolean);return o.length>1?B(o.join(`. `),sa.analysis):B(`Changed: ${n.join(`, `)||`unknown`}. Summary: ${t}`,sa.analysis)}function Ea(e,t){let n=H(e,`task`),r=ma(t);if(pa(r)){let e=ha(r.files,6),t=typeof r.totalFiles==`number`?r.totalFiles:e.length;if(e.length>0)return B(`Task: ${n||`unknown`}. Reading plan (${t} files): ${e.join(`, `)}`,sa[`step-summary`])}let i=_a(t,6);return B(`Task: ${n||`unknown`}. Reading plan: ${i.join(`, `)||ya(t,3).join(` | `)}`,sa[`step-summary`])}function Da(e,t){let n=H(e,`action`),r=H(e,`advance`);try{let e=JSON.parse(t),i=typeof e.slug==`string`?e.slug:``,a=typeof e.currentStep==`string`?e.currentStep:``,o=Array.isArray(e.completedSteps)?e.completedSteps.join(`, `):``,s=Array.isArray(e.skippedSteps)?e.skippedSteps.join(`, `):``;typeof e.totalSteps==`number`&&e.totalSteps;let c=typeof e.progress==`string`?e.progress:``,l=typeof e.phase==`string`?e.phase:``;return B([`Action: ${n}${r?`/${r}`:``}.`,i?`Slug: ${i}.`:``,a?`Current: ${a}.`:``,c?`Progress: ${c}.`:``,o?`Completed: ${o}.`:``,s?`Skipped: ${s}.`:``,l?`Phase: ${l}.`:``].filter(Boolean).join(` `),sa[`step-summary`])}catch{let e=ya(t,3);return B(`Flow action: ${n||`unknown`}. ${e.join(` | `)}`,sa[`step-summary`])}}function Oa(e){let t=H(e,`action`),n=H(e,`name`),r=H(e,`advance`);return B(t===`start`&&n?`Flow started: ${n}`:t===`step`&&r?`Flow step: ${r}`:t===`status`?`Flow status`:t===`reset`?`Flow abandoned`:`Flow: ${t||`unknown action`}`,120)}function ka(e){let t=H(e,`action`),n=H(e,`name`),r=H(e,`advance`);return t===`start`?`flow:start:${n||`unknown`}`:t===`step`?`flow:step:${r||`unknown`}`:t===`status`?`flow:status`:t===`reset`?`flow:reset`:`flow:${t||`unknown`}`}function Aa(e,t){switch(e.toolName){case`search`:return xa(e.args,t);case`file_summary`:return Sa(e.args,t);case`stratum_card`:return Ca(e.args,t);case`compact`:return wa(e.args,t);case`blast_radius`:return Ta(e.args,t);case`scope_map`:return Ea(e.args,t);case`flow`:return Da(e.args,t);default:return``}}function ja(e){switch(e.toolName){case`search`:return B(`Search: ${H(e.args,`query`)||`unknown query`}`,120);case`file_summary`:return B(`File summary: ${H(e.args,`path`,`file`)||`unknown file`}`,120);case`stratum_card`:return B(`Stratum card: ${ga(e.args).join(`, `)||`unknown files`}${H(e.args,`tier`)?` (${H(e.args,`tier`)})`:``}`,120);case`compact`:return B(`Compact: ${H(e.args,`path`,`file`)||`unknown path`}${H(e.args,`query`)?` - ${H(e.args,`query`)}`:``}`,120);case`blast_radius`:return B(`Blast radius: ${ga(e.args).join(`, `)||`unknown changes`}`,120);case`scope_map`:return B(`Scope map: ${H(e.args,`task`)||`unknown task`}`,120);case`flow`:return Oa(e.args);default:return B(`Flow context: ${e.toolName}`,120)}}function Ma(e){switch(e.toolName){case`search`:return`search:${H(e.args,`query`)||`unknown-query`}`;case`file_summary`:return`file-summary:${H(e.args,`path`,`file`)||`unknown-file`}`;case`stratum_card`:{let t=ga(e.args).join(`,`),n=H(e.args,`tier`)||`unknown-tier`,r=H(e.args,`query`);return`stratum:${n}:${t}${r?`:${r}`:``}`}case`compact`:{let t=H(e.args,`path`,`file`)||`unknown-path`,n=H(e.args,`query`);return`compact:${t}${n?`:${n}`:``}`}case`blast_radius`:return`blast-radius:${ga(e.args).join(`,`)||`unknown-changes`}`;case`scope_map`:return`scope-map:${H(e.args,`task`)||`unknown-task`}`;case`flow`:return ka(e.args);default:return`${e.toolName}:generic`}}function Na(e){return{name:`flow-context`,tools:[...ca],extract(t){if(t.isError)return[];let n=e();if(!n?.active||!n.slug||!(t.toolName in la))return[];let r=mi(t.result).trim();if(r.length<50)return[];let i=la[t.toolName],a=Aa(t,r);if(a.length<50)return[];let o=ja(t);return[{title:o,content:a,category:`flow-context`,tags:[`flow-context`,`flow:${n.slug.replace(/[^a-zA-Z0-9_-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`flow`}`,i,`tool:${t.toolName}`],hash:z(`${n.slug}|${t.toolName}|${o}|${a}`),identityKey:Ma(t),quality:fa(a),ttlMs:ua[i],source:t.toolName}]}}}const Pa={name:`research-results`,tools:[`web_search`,`web_fetch`,`search`,`find`],extract(e){let t=mi(e.result);if(!t||t.length<100||e.isError)return[];let n=[];if(e.toolName===`web_search`){let r=typeof e.args.query==`string`?e.args.query:``;if(r&&t.length>200){let i=t.slice(0,800);n.push({title:`Web research: ${r.slice(0,80)}`,content:`Research query: "${r}"\n\nKey findings:\n${i}`,category:`context`,tags:[`research`,`web-search`],hash:z(`web-search-${r}`),quality:Math.min(.8,hi(i)+.2),source:e.toolName,ttlMs:864e5})}}if(e.toolName===`web_fetch`){let r=e.args.urls,i=Array.isArray(r)?String(r[0]??``):typeof e.args.url==`string`?e.args.url:``;if(i&&t.length>200){let r=t.split(/\r?\n/).find(e=>e.trim().length>10)?.trim()??i,a=t.slice(0,600);n.push({title:`Fetched: ${r.slice(0,80)}`,content:`Source: ${i}\n\n${a}`,category:`context`,tags:[`research`,`web-fetch`],hash:z(`web-fetch-${i}`),quality:hi(a),source:e.toolName,ttlMs:864e5})}}if(e.toolName===`search`){let r=typeof e.args.query==`string`?e.args.query:``,i=typeof e.args.origin==`string`?e.args.origin:``,a=typeof e.args.search_mode==`string`?e.args.search_mode:`hybrid`;i===`curated`&&r&&t.length>100&&n.push({title:`Curated search: ${r.slice(0,80)}`,content:`Searched curated knowledge for: "${r}"\n\nResults:\n${t.slice(0,500)}`,category:`context`,tags:[`research`,`curated-search`],hash:z(`curated-search-${r}`),quality:.5,source:e.toolName,ttlMs:36e5}),i!==`curated`&&r&&t.length>150&&n.push({title:`Search: ${r.slice(0,80)}`,content:t.slice(0,500),category:`context`,tags:[`research`,`search`,i||`hybrid`,a],hash:z(`search-${r}-${i||`hybrid`}-${a}`),quality:.5,source:e.toolName,ttlMs:36e5})}if(e.toolName===`find`){let r=typeof e.args.query==`string`?e.args.query:``,i=typeof e.args.pattern==`string`?e.args.pattern:``,a=typeof e.args.glob==`string`?e.args.glob:``,o=typeof e.args.mode==`string`?e.args.mode:``,s=r||i||a||``;s&&t.length>100&&n.push({title:o?`Find (${o}): ${s.slice(0,60)}`:`Find: ${s.slice(0,60)}`,content:t.slice(0,600),category:`context`,tags:[`research`,`find`,o||`search`],hash:z(`find-${r}-${i}-${a}-${o}`),quality:.55,source:e.toolName,ttlMs:36e5})}return n}};function Fa(e,t,n,r,i,a){return{title:e,content:t,category:`conventions`,tags:[`scaffold-behavior`,`tool-patterns`],hash:z(n),identityKey:r,quality:i,ttlMs:144e5,source:a}}const Ia={name:`scaffold-behavior`,tools:[`init`,`status`],maxFactsPerEvent:3,extract(e){if(e.isError)return[];let t=mi(e.result);if(!t||t.length<20)return[];let n=[];if(e.toolName===`init`&&n.push(Fa(`Scaffold initialized`,`Workspace scaffold initialized. Result: ${t.slice(0,200)}.`,`scaffold-init-${e.timestamp}`,`scaffold:init:${z(t).slice(0,12)}`,.6,e.toolName)),e.toolName===`status`){let r=t.includes(`Extractor`)||t.includes(`extractor`),i=t.includes(`hook`)||t.includes(`Hook`),a=t.includes(`knowledge`)||t.includes(`curated`),o=`runtime status`;r&&i&&a?o=`full capability stack`:(r||i)&&(o=`partial capability`),n.push(Fa(`Scaffold capability: ${o}`,`Runtime status detected: extractors=${r}, hooks=${i}, knowledge=${a}. Result length: ${t.length} chars.`,`scaffold-status-${e.timestamp}`,`scaffold:status:${z(t).slice(0,12)}`,Math.min(.7,.3+t.length/2e3),e.toolName))}return n}};function La(e,t,n,r,i,a,o){return{title:e,content:t,category:`workflow`,tags:[`search-strategy`,`tool-patterns`],hash:z(n),identityKey:r,quality:i,ttlMs:a,source:o}}const Ra={name:`search-strategy`,tools:[`search`,`find`,`web_search`,`web_fetch`],maxFactsPerEvent:3,extract(e){if(e.isError)return[];let t=typeof e.args.query==`string`?e.args.query:typeof e.args.pattern==`string`?e.args.pattern:``;if(!t||t.length<5)return[];let n=mi(e.result);if(!n||n.length<50)return[];let r=typeof e.args.limit==`number`?e.args.limit:n.split(`
24
- `).filter(e=>e.includes(`http`)||e.startsWith(`-`)).length,i=Math.min(.9,.3+r*.05+Math.min(t.length/100,.3));return[La(`Search strategy: ${t.slice(0,60)}`,`Effective query "${t}" returned ${r} results across ${n.length} chars. Quality ${i.toFixed(2)} — ${i>.6?`repeatable strategy`:`exploratory query`}.`,`search-strategy-${t}-${e.toolName}`,`search:${z(t).slice(0,12)}:${e.toolName}`,Math.round(i*100)/100,144e5,e.toolName)]}},za=new Set([`neighbors`,`traverse`,`find_nodes`,`symbol360`]),Ba=144e5;function Va(e,t){return e.slice(0,t).trim()}function Ha(e,t){let n=Va(t,800);return n.length<80?[]:[{title:`Symbol: ${e}`,content:n,category:`patterns`,tags:[`architecture`,`symbol`,`definition`],hash:z(`symbol-${e}`),quality:.7,ttlMs:Ba,source:`symbol`}]}function Ua(e,t,n){let r=Va(n,800);return r.length<100?[]:[{title:`Trace ${t}: ${e}`,content:r,category:`patterns`,tags:[`architecture`,`trace`,`data-flow`,t],hash:z(`trace-${e}-${t}`),quality:.75,ttlMs:Ba,source:`trace`}]}function Wa(e,t){return e===`find_nodes`?`Graph nodes: ${t}`:e===`neighbors`?`Graph neighbors: ${t}`:e===`traverse`?`Graph traverse: ${t}`:`Symbol360: ${t}`}function Ga(e,t,n,r,i){let a=Va(i,600);return a.length<50?[]:[{title:Wa(e,t),content:a,category:`patterns`,tags:[`architecture`,`graph`,e],hash:z(`graph-${e}-${t}-${n}-${r}`),quality:.6,ttlMs:Ba,source:`graph`}]}const Ka={name:`symbol-analysis`,tools:[`symbol`,`trace`,`graph`],extract(e){let t=mi(e.result);if(!t||e.isError)return[];if(e.toolName===`symbol`){let n=typeof e.args.name==`string`?e.args.name:``;return n?Ha(n,t):[]}if(e.toolName===`trace`){let n=typeof e.args.start==`string`?e.args.start:``,r=typeof e.args.direction==`string`?e.args.direction:``;return!n||!r?[]:Ua(n,r,t)}if(e.toolName===`graph`){let n=typeof e.args.action==`string`?e.args.action:``;if(!za.has(n))return[];let r=typeof e.args.node_id==`string`?e.args.node_id:``,i=typeof e.args.name_pattern==`string`?e.args.name_pattern:``;if(n===`find_nodes`&&!i||(n===`neighbors`||n===`traverse`||n===`symbol360`)&&!r)return[];let a=typeof e.args.direction==`string`?e.args.direction:`both`,o=typeof e.args.max_depth==`number`?String(e.args.max_depth):``;return Ga(n,n===`find_nodes`?i:r,a,o,t)}return[]}};function qa(e){let t=e.toLowerCase();return t.includes(`vitest`)?`vitest`:t.includes(`jest`)?`jest`:t.includes(`mocha`)?`mocha`:t.includes(`playwright`)?`playwright`:t.includes(`cypress`)?`cypress`:null}function Ja(e){let t=[/(\S+\.test\.\w+)/,/(\S+\.spec\.\w+)/,/(\S+_test\.\w+)/,/__tests__\/\S+/],n=new Set;for(let r of t){let t=e.matchAll(new RegExp(r.source,`g`));for(let e of t){let t=e[0].match(/\.(test|spec)\.\w+$/);t&&n.add(t[0])}}return n.size>0?[...n].join(`, `):null}const Ya={name:`test-results`,tools:[`check`,`test_run`],extract(e){let t=mi(e.result);if(!t)return[];let n=[],r=qa(t);r&&n.push({title:`Test framework: ${r}`,content:`This project uses ${r} for testing. Detected from ${e.toolName} output.`,category:`context`,tags:[`testing`,`environment`,r],hash:z(`test-framework-${r}`),quality:.7,source:e.toolName});let i=Ja(t);return i&&n.push({title:`Test file pattern: ${i}`,content:`Test files use the naming pattern: ${i}. Follow this convention when creating new tests.`,category:`conventions`,tags:[`testing`,`naming-convention`],hash:z(`test-pattern-${i}`),quality:.7,source:e.toolName}),n}};function Xa(e,t,n,r,i,a){return{title:e,content:t,category:`workflow`,tags:[`token-efficiency`,`optimization`],hash:z(n),identityKey:r,quality:i,ttlMs:144e5,source:a}}const Za={name:`token-efficiency`,tools:[`compact`,`file_summary`],maxFactsPerEvent:3,extract(e){if(e.isError)return[];let t=mi(e.result);if(!t||t.length<20)return[];let n=[];if(e.toolName===`compact`){let r=typeof e.args.path==`string`?e.args.path:void 0,i=typeof e.args.query==`string`?e.args.query:``;if(!r)return[];let a=Math.max(0,1-t.length/Math.max(1,e.args.originalSize??t.length)),o=Math.min(.85,.3+a*.5);n.push(Xa(`Compact savings: ${r.slice(0,50)}`,`Ref reuse for "${i}" on ${r} saved ~${Math.round(a*100)}% tokens (${t.length} chars vs original). Quality: ${(o*100).toFixed(0)}%.`,`token-efficiency-compact-${r}-${i}`,`compact:savings:${z(r).slice(0,12)}`,Math.round(o*100)/100,e.toolName))}if(e.toolName===`file_summary`){let r=Array.isArray(e.args.files)?e.args.files:[],i=typeof e.args.query==`string`?e.args.query:void 0,a=typeof e.args.tier==`string`?e.args.tier:void 0;if(a!==`T1`&&!i)return[];let o=r.length,s=Math.min(.7,.2+o*.05);n.push(Xa(`File summary reuse: ${o} files`,`Used file_summary on ${o} files${i?` for "${i}"`:``} (tier: ${a??`auto`}). Result: ${t.length} chars.`,`token-efficiency-file-summary-${o}-${i??`none`}`,`file-summary:reuse:${z(r.join(`,`)).slice(0,12)}`,Math.round(s*100)/100,e.toolName))}return n}};function Qa(e){let t=e.toLowerCase();return/enoent|no such file|not found/i.test(e)?{type:`missing-file`,actionable:!1}:/econnreset|econnrefused|etimedout|fetch failed/i.test(e)?{type:`network`,actionable:!1}:/permission denied|eacces/i.test(e)?{type:`permission`,actionable:!0}:/type\s*error|cannot.*property|is not a function/i.test(e)?{type:`type-error`,actionable:!0}:/syntax\s*error|unexpected token|parsing error/i.test(e)?{type:`syntax`,actionable:!0}:/out of memory|heap|allocation/i.test(e)?{type:`memory`,actionable:!0}:/timeout|timed out/i.test(e)?{type:`timeout`,actionable:t.includes(`increase`)||t.includes(`config`)}:/import|require|module not found|cannot find module/i.test(e)?{type:`module-resolution`,actionable:!0}:{type:`unknown`,actionable:e.length>100}}const $a={name:`tool-failure-patterns`,tools:[],extract(e){if(!e.isError)return[];let t=mi(e.result);if(!t||t.length<30)return[];let{type:n,actionable:r}=Qa(t);if(!r)return[];let i=t.slice(0,500),a=hi(i);return a<.2?[]:[{title:`${n} error in ${e.toolName}`,content:`Tool \`${e.toolName}\` failed with a ${n} error.\n\nArgs: ${JSON.stringify(e.args,null,2).slice(0,200)}\n\nError:\n${i}`,category:`context`,tags:[`errors`,n,e.toolName],hash:z(`smart-error-${n}-${e.toolName}-${t.slice(0,80)}`),quality:Math.min(.7,a+.1),source:e.toolName,ttlMs:72e5}]}},eo=M(`extractor-registry`),to={defaultMaxFactsPerEvent:20,globalMaxFactsPerEvent:200};var no=class{extractors=[];config;constructor(e={}){this.config={...to,...e}}register(e){this.extractors.push(e)}getExtractors(e){return this.extractors.filter(t=>t.tools.length===0?!0:t.tools.some(t=>{if(t===e||t===`*`||t===`*:*`)return!0;if(t.endsWith(`:*`)){let n=t.slice(0,-2);return e===n||e.startsWith(`${n}_`)||e.startsWith(`${n}-`)}return!1}))}extractAll(e){let t=this.getExtractors(e.toolName),n=[];for(let r of t){let i=r.maxFactsPerEvent??this.config.defaultMaxFactsPerEvent,a=r.extract(e);if(a.length>i?(eo.warn(`Extractor "${r.name}" produced ${a.length} facts (cap: ${i}). Excess of ${a.length-i} facts discarded.`,{extractor:r.name,factsProduced:a.length,cap:i}),n.push(...a.slice(0,i))):n.push(...a),n.length>=this.config.globalMaxFactsPerEvent){let i=t.slice(t.indexOf(r)+1).map(e=>e.name);eo.warn(`Global max facts per event reached`,{toolName:e.toolName,extractor:r.name,globalCap:this.config.globalMaxFactsPerEvent,skippedExtractors:i.length>0?i.join(`, `):void 0}),n.length=this.config.globalMaxFactsPerEvent;break}}return n}getStats(){let e={};for(let t of this.extractors)e[t.name]={tools:t.tools.length,maxFactsPerEvent:t.maxFactsPerEvent};return{count:this.extractors.length,byName:e}}reset(){this.extractors.length=0}};const ro=new Set([`lifecycleOwnerToken`,`_ownerToken`,`ownerTokenSalt`,`ownerTokenHash`,`currentToken`]),io=M(`auto-knowledge`),ao=2e3;var oo=class e{registry;curated;flowContextAdapter;promotionEngine;eventBus;queue=[];timer=null;seenHashes=new Map;failedBuffer=[];maxBufferSize=50;storedCount=0;droppedCount=0;dedupedCount=0;bufferDropCount=0;collisionCount=0;promotedCount=0;recoveryListenerRegistered=!1;config;existingCuratedEntries=null;recoveryListener=null;constructor(e,t,n={},r,i,a){this.registry=e,this.curated=t,this.flowContextAdapter=r,this.promotionEngine=i,this.eventBus=a,this.config={...pi,...n}}push(e){if(!(!this.config.enabled||!this.curated&&!this.flowContextAdapter)&&!(this.storedCount>=this.config.maxFactsPerSession)){if(this.queue.push(e),this.queue.length>=this.config.batchSize){this.flush().catch(e=>{io.warn(`Auto-knowledge flush error`,{error:String(e)})});return}this.scheduleBatch()}}async flush(){this.timer&&=(clearTimeout(this.timer),null);let e=this.queue.splice(0);if(e.length===0||!this.curated&&!this.flowContextAdapter)return;this.existingCuratedEntries===null&&(this.existingCuratedEntries=await this.loadExistingCuratedEntries());let t=new Map;for(let n of e)for(let e of this.registry.extractAll(n)){n.workspaceId!=null&&(e.workspaceId=n.workspaceId),e.evidenceRefs||=[];let r={sourceTool:n.toolName,requestId:n.requestId??n.toolName,timestamp:new Date(n.timestamp).getTime()};if(e.evidenceRefs.push(r),e.evidenceRefs.length>5&&(e.evidenceRefs=e.evidenceRefs.slice(e.evidenceRefs.length-5)),e.quality<this.config.minQuality){this.droppedCount++;continue}if(this.isSeenRecently(e)){this.dedupedCount++;continue}let i=this.buildFactIdentity(e),a=t.get(i);if(a){t.set(i,this.choosePreferredFact(a,e)),this.dedupedCount++;continue}t.set(i,e),this.promotionEngine&&this.promotionEngine.recordObservation(e,i)}for(let e of t.values()){if(this.storedCount>=this.config.maxFactsPerSession)break;if(_e.instance().isDegraded(`embedder`)){io.debug?.(`Auto-knowledge embedder degraded — buffering fact`),this.bufferFact(e);continue}try{await this.storeFact(e)}catch(t){io.warn(`Auto-knowledge store failed — buffered for retry`,{title:e.title,error:String(t)}),this.bufferFact(e)}}}reset(){this.queue=[],this.seenHashes.clear(),this.failedBuffer.length=0,this.storedCount=0,this.droppedCount=0,this.dedupedCount=0,this.bufferDropCount=0,this.collisionCount=0,this.promotedCount=0,this.existingCuratedEntries=null,this.removeRecoveryListener(),this.timer&&=(clearTimeout(this.timer),null)}getStats(){return{queued:this.queue.length,stored:this.storedCount,seen:this.seenHashes.size,dropped:this.droppedCount,deduped:this.dedupedCount,bufferSize:this.failedBuffer.length,bufferDropped:this.bufferDropCount,collisions:this.collisionCount,promoted:this.promotedCount}}bufferFact(e){this.failedBuffer.length>=this.maxBufferSize&&(this.failedBuffer.shift(),this.bufferDropCount++),this.failedBuffer.push(e),this.ensureRecoveryListener()}ensureRecoveryListener(){if(this.recoveryListenerRegistered)return;let e=_e.instance(),t=n=>{n.subsystem===`embedder`&&(e.removeListener(`healthy`,t),this.recoveryListener=null,this.recoveryListenerRegistered=!1,this.flushBuffer().catch(e=>{io.warn(`Buffer flush failed`,{error:String(e)})}))};this.recoveryListener=t,this.recoveryListenerRegistered=!0,e.on(`healthy`,t)}removeRecoveryListener(){if(!this.recoveryListener){this.recoveryListenerRegistered=!1;return}_e.instance().removeListener(`healthy`,this.recoveryListener),this.recoveryListener=null,this.recoveryListenerRegistered=!1}async flushBuffer(){if(this.failedBuffer.length===0||!this.curated&&!this.flowContextAdapter)return;this.existingCuratedEntries===null&&(this.existingCuratedEntries=await this.loadExistingCuratedEntries()),io.info(`Flushing ${this.failedBuffer.length} buffered auto-knowledge facts`);let e=this.failedBuffer.splice(0);for(let t=0;t<e.length;t++){let n=e[t];if(n){if(this.storedCount>=this.config.maxFactsPerSession){this.failedBuffer.unshift(...e.slice(t));break}if(_e.instance().isDegraded(`embedder`)){this.failedBuffer.unshift(...e.slice(t)),this.ensureRecoveryListener();break}try{let e=await this.storeFact(n);(e===`created`||e===`updated`)&&io.info(`Buffered fact stored on recovery`,{title:n.title,status:e})}catch(r){io.warn(`Auto-knowledge store failed — buffered for retry`,{title:n.title,error:String(r)}),this.failedBuffer.unshift(n,...e.slice(t+1)),this.ensureRecoveryListener();break}}}}isSeenRecently(e){let t=this.seenHashes.get(e.hash);return t==null?!1:e.ttlMs==null?!0:Date.now()-t<e.ttlMs}normalizeTitle(e){return e.toLowerCase().trim()}buildFactIdentity(e){let t=e.identityKey?`key:${e.identityKey}`:`hash:${e.hash||this.normalizeTitle(e.title)}`;return`${e.workspaceId?`ws:${e.workspaceId}`:`ws:global`}:${e.category}:${t}`}choosePreferredFact(e,t){return t.quality===e.quality?e:t.quality>e.quality?t:e}slugify(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``).slice(0,80)||`untitled`}resolveCuratedRelativePath(e){let t=`${e.category}/auto-${this.slugify(e.identityKey??e.title)}.md`,n=this.existingCuratedEntries??[],r=n.find(e=>e.path===t);if(r)return r.path;let i=this.normalizeTitle(e.title),a=n.filter(t=>t.category===e.category&&this.normalizeTitle(t.title)===i);return a.length===0?t:(a.sort((t,n)=>{let r=this.tagOverlapScore(n.tags,e.tags),i=this.tagOverlapScore(t.tags,e.tags);return r===i?t.path.localeCompare(n.path):r-i}),a[0]?.path??t)}resolveFlowContextRelativePath(e){return`${e.tags.find(e=>!e.startsWith(`flow:`)&&!e.startsWith(`tool:`)&&e!==`flow-context`)||`analysis`}/${this.slugify(e.identityKey??e.title)}.md`}tagOverlapScore(e,t){let n=new Set(e),r=0;for(let e of t)n.has(e)&&(r+=1);return r}markFactSeen(e){this.seenHashes.set(e.hash,Date.now())}rememberExistingCuratedFact(e,t){let n=this.existingCuratedEntries;if(!n)return;let r=n.find(t=>t.path===e);if(r){r.title=t.title,r.category=t.category,r.tags=[...t.tags];return}n.push({path:e,title:t.title,category:t.category,tags:[...t.tags]})}static OWNER_TOKEN_PATTERN=/\b[a-f0-9]{64}\b/g;applyContentBudget(e){return e.content.length<=2e3?e.content:(io.warn(`Fact "${e.title}" content truncated from ${e.content.length} to ${ao} chars`,{title:e.title,originalLength:e.content.length,maxChars:ao}),e.content.slice(0,ao-50)+`\n\n[... truncated from ${e.content.length} chars to fit budget ...]`)}async storeFact(t){let n=this.applyContentBudget(t).replace(e.OWNER_TOKEN_PATTERN,`[REDACTED]`),r={...t,content:n},i=r.title.toLowerCase();for(let e of ro)if(i.includes(e.toLowerCase()))return this.dedupedCount++,`unchanged`;if(r.tags.includes(`flow-context`)&&this.flowContextAdapter){let e=this.resolveFlowContextRelativePath(r),t=`# ${r.title}\n\n${r.content}`,n=await this.flowContextAdapter.read(e);if(n===t)return this.markFactSeen(r),this.dedupedCount++,`unchanged`;await this.flowContextAdapter.write(e,t);let i=n==null?`created`:`updated`;return this.markFactSeen(r),this.storedCount++,io.info(i===`created`?`Auto-knowledge stored`:`Auto-knowledge refreshed`,{title:r.title,category:r.category,quality:r.quality,source:r.source,status:i}),i}else if(this.curated){let e=this.resolveCuratedRelativePath(r),t=`Auto-knowledge refresh from ${r.source}`;if(this.promotionEngine){let e=r.identityKey??`${r.source}:${r.hash}`,t=await this.promotionEngine.evaluate(r,e);if(t.status!==`promoted`)return this.droppedCount++,io.debug(`Fact not promoted`,{title:r.title,status:t.status,reason:t.reason}),`skipped`;this.promotedCount++}let n=await this.curated.upsertAutoKnowledge(e,r.title,r.content,r.category,r.tags,t);return this.markFactSeen(r),this.rememberExistingCuratedFact(n.path,r),this.eventBus&&this.eventBus.emit({type:`knowledge:promoted`,timestamp:Date.now(),eventId:`kp-${r.identityKey??r.hash}-${Date.now()}`,workspaceId:r.workspaceId??`ws:global`,source:`auto-knowledge-worker`,identityKey:r.identityKey??`${r.source}:${r.hash}`,toolName:r.source,result:n.status,confidence:r.quality}),n.status===`updated`&&this.collisionCount++,n.status===`unchanged`?(this.dedupedCount++,`unchanged`):(this.storedCount++,io.info(n.status===`created`?`Auto-knowledge stored`:`Auto-knowledge refreshed`,{title:r.title,category:r.category,quality:r.quality,source:r.source,status:n.status}),n.status)}throw Error(`AutoKnowledgeWorker: curated manager must implement upsertAutoKnowledge. The remember() fallback was removed per architecture invariant #4 (identity-keyed upserts required).`)}async loadExistingCuratedEntries(){let e=this.curated;if(!e)return[];try{return(await e.list()).map(e=>({path:e.path,title:e.title,category:e.category,tags:[...e.tags]}))}catch{io.warn(`Failed to load existing curated entries for dedup`,{})}return[]}scheduleBatch(){this.timer||=setTimeout(()=>{this.timer=null,this.flush().catch(e=>{io.warn(`Auto-knowledge flush error`,{error:String(e)})})},this.config.debounceMs)}};const so=/```/,co=/^\s*(?:import|export|function|class|interface|type|const|let|var|return|if|for|while|switch|try|catch|throw|await|async)\b/,lo=/=>|;\s*$|{\s*$|}\s*$|:\s*(?:string|number|boolean|unknown|void|any|Record|Array|Set|Map|Promise|ReadonlyArray)\b/;function uo(e){let t=e.trimStart();if(t.length===0)return!1;let n=t.charAt(0);return n!==`{`&&n!==`[`?!1:n===`{`?!(!t.includes(`"`)||!t.includes(`:`)):t.length>2}function fo(e){if(uo(e)||e.includes("```")||so.test(e))return!0;let t=e.split(/\r?\n/u).filter(e=>e.trim().length>0);if(t.length<3)return!1;let n=0;for(let e of t)(co.test(e)||lo.test(e))&&(n+=1);return n/t.length>=.25}function po(e){let t=e.meta?.compression?.preserve??`balanced`;if(t===`exact`||fo(e.text))return{profile:`exact`,shouldCompress:!1,mode:`structural`,threshold:e.threshold,tokenBudget:e.tokenBudget,reason:t===`exact`?`tool-specific preservation profile`:`code-like output preserved verbatim`};if(t===`dense`){let t=Math.max(1,Math.floor(e.threshold*.65)),n=Math.max(1,Math.floor(e.tokenBudget*.6));return{profile:`dense`,shouldCompress:e.text.length>=t,mode:`aggressive`,threshold:t,tokenBudget:n,reason:`dense tool profile`}}return{profile:`balanced`,shouldCompress:e.text.length>=e.threshold,mode:`structural`,threshold:e.threshold,tokenBudget:e.tokenBudget,reason:`balanced tool profile`}}const mo={search:{title:`Hybrid Search`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`search`],compression:{preserve:`dense`}},find:{title:`Federated Find`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`search`],compression:{preserve:`dense`}},symbol:{title:`Symbol Resolver — Cross-Module Definitions & References`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`search`],compression:{preserve:`exact`}},trace:{title:`Data Flow Tracer — Cross-Module Call & Import Chains`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`search`],compression:{preserve:`exact`}},scope_map:{title:`Task Scope Map`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`search`],compression:{preserve:`exact`},capabilities:{indexIndependent:!0}},file_summary:{title:`File Summary`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`search`,`compression`],compression:{preserve:`balanced`},capabilities:{indexIndependent:!0}},analyze:{title:`Analyze`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`analysis`],compression:{preserve:`exact`}},knowledge:{title:`Knowledge`,annotations:{readOnlyHint:!1},category:[`knowledge`],compression:{preserve:`balanced`},capabilities:{indexIndependent:!0}},produce_knowledge:{title:`Produce Knowledge`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`knowledge`],compression:{preserve:`exact`},capabilities:{zeroDep:!0,indexIndependent:!0}},digest:{title:`Multi-Source Digest`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`compression`],compression:{preserve:`balanced`},capabilities:{indexIndependent:!0}},forge_ground:{title:`FORGE Ground`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`forge`],compression:{preserve:`exact`}},evidence_map:{title:`Evidence Map`,annotations:{readOnlyHint:!1},category:[`forge`],compression:{preserve:`exact`},capabilities:{zeroDep:!0,indexIndependent:!0}},present:{title:`Rich Content Presenter`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`presentation`],compression:{preserve:`balanced`},capabilities:{zeroDep:!0,indexIndependent:!0}},check:{title:`Typecheck & Lint`,annotations:{readOnlyHint:!0,openWorldHint:!0},category:[`execution`],compression:{preserve:`dense`,selfManaged:!0},capabilities:{zeroDep:!0,indexIndependent:!0}},test_run:{title:`Run Tests`,annotations:{readOnlyHint:!0,openWorldHint:!0},category:[`execution`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},eval:{title:`Evaluate Code`,annotations:{readOnlyHint:!1,openWorldHint:!0},category:[`execution`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},audit:{title:`Project Audit`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`execution`],compression:{preserve:`dense`,selfManaged:!0}},browser:{title:`Browser Automation`,annotations:{readOnlyHint:!1,openWorldHint:!0},category:[`web`],compression:{preserve:`balanced`},capabilities:{zeroDep:!0,indexIndependent:!0}},rename:{title:`Rename Symbol`,annotations:{readOnlyHint:!1,destructiveHint:!0},category:[`manipulation`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},restore:{title:`Restore`,annotations:{readOnlyHint:!1},category:[`manipulation`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},codemod:{title:`Codemod`,annotations:{readOnlyHint:!1,destructiveHint:!0},category:[`manipulation`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},session:{title:`Session Manager`,annotations:{readOnlyHint:!1},category:[`session`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},git:{title:`Git — Context, Diff Parse, Changelog`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`git`],compression:{preserve:`exact`},capabilities:{zeroDep:!0,indexIndependent:!0}},parse_output:{title:`Parse Build Output`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`git`],compression:{preserve:`exact`},capabilities:{zeroDep:!0,indexIndependent:!0}},process:{title:`Process Manager`,annotations:{readOnlyHint:!1,openWorldHint:!0},category:[`process`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},delegate:{title:`Delegate Task`,annotations:{readOnlyHint:!1,openWorldHint:!0},category:[`process`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},config:{title:`Configuration Manager`,annotations:{readOnlyHint:!1},category:[`system`],compression:{preserve:`exact`},capabilities:{indexIndependent:!0}},status:{title:`AI Kit Status`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`system`],compression:{preserve:`balanced`},capabilities:{zeroDep:!0,indexIndependent:!0}},reindex:{title:`Reindex`,annotations:{readOnlyHint:!1},category:[`system`],compression:{preserve:`dense`},capabilities:{indexIndependent:!0}},onboard:{title:`Onboard Codebase`,annotations:{readOnlyHint:!1},category:[`system`],compression:{preserve:`dense`},capabilities:{indexIndependent:!0}},graph:{title:`Code Knowledge Graph — Module & Symbol Relationships`,annotations:{readOnlyHint:!1},category:[`system`],compression:{preserve:`balanced`},capabilities:{indexIndependent:!0}},replay:{title:`Replay History`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`system`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},measure:{title:`Code Metrics`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`utilities`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},env:{title:`Environment Info`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`utilities`],compression:{preserve:`exact`},capabilities:{zeroDep:!0,indexIndependent:!0}},web_fetch:{title:`Web Fetch`,annotations:{readOnlyHint:!0,openWorldHint:!0},category:[`web`],compression:{preserve:`balanced`},capabilities:{zeroDep:!0,indexIndependent:!0}},web_search:{title:`Web Search`,annotations:{readOnlyHint:!0,openWorldHint:!0},category:[`web`],compression:{preserve:`balanced`},capabilities:{zeroDep:!0,indexIndependent:!0}},queue:{title:`Operation Queue`,annotations:{readOnlyHint:!1},category:[`queue`],compression:{preserve:`dense`},capabilities:{zeroDep:!0,indexIndependent:!0}},bridge_push:{title:`Bridge Push`,annotations:{readOnlyHint:!1},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},bridge_pull:{title:`Bridge Pull`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},bridge_sync:{title:`Bridge Sync Status`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},er_push:{title:`Enterprise Push`,annotations:{readOnlyHint:!1},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},er_pull:{title:`Enterprise Pull`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},er_sync_status:{title:`Enterprise Sync Status`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},er_update_policy:{title:`Enterprise Update Policy`,annotations:{readOnlyHint:!1},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},er_evolve_review:{title:`Enterprise Evolution Review`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},evolution_state:{title:`Evolution State`,annotations:{readOnlyHint:!1},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},policy_check:{title:`Policy Check`,annotations:{readOnlyHint:!0,idempotentHint:!0},category:[`system`],compression:{preserve:`balanced`},capabilities:{conditional:!0}},flow:{title:`Flow`,annotations:{readOnlyHint:!1},category:[`flow`],compression:{preserve:`balanced`},capabilities:{zeroDep:!0}}},ho=Object.keys(mo).filter(e=>!mo[e]?.capabilities?.conditional),go=new Set(Object.entries(mo).filter(([e,t])=>t.capabilities?.zeroDep).map(([e])=>e)),_o=new Set(Object.entries(mo).filter(([e,t])=>t.capabilities?.indexIndependent).map(([e])=>e));function U(e){return mo[e]??{title:e,annotations:{readOnlyHint:!1},category:[]}}function vo(e){switch(e){case`efficient`:return{threshold:2e3,tokenBudget:1e3};case`full`:return{threshold:1/0};default:return{threshold:4e3,tokenBudget:2e3}}}function yo(e){let t=e?.threshold??4e3,n=e?.tokenBudget??2e3;return async(e,r)=>{if(U(e.toolName).compression?.selfManaged)return r();let i=await r();if(!Array.isArray(i.content))return i;let a={profile:`balanced`,applied:!1,reason:`below threshold`,mode:`structural`,threshold:t,tokenBudget:n,originalChars:0,compressedChars:0,savedChars:0,compressedItems:0,preservedItems:0},o=i.content.map(r=>{if(r.type!==`text`||typeof r.text!=`string`)return r;a.originalChars+=r.text.length;let i=po({meta:e.meta,text:r.text,threshold:t,tokenBudget:n});if(a.profile=i.profile,a.mode=i.mode,a.threshold=i.threshold,a.tokenBudget=i.tokenBudget,a.reason=i.reason,!i.shouldCompress||r.text.length<i.threshold)return a.preservedItems+=1,a.compressedChars+=r.text.length,r;let o=gt({text:r.text,tool:e.toolName,tokenBudget:i.tokenBudget,mode:i.mode});return a.applied=!0,a.compressedItems+=1,a.compressedChars+=o.text.length,o.text===r.text?r:{...r,text:o.text}});return a.originalChars===0?i:(a.savedChars=a.originalChars-a.compressedChars,{...i,content:o,_meta:{...i._meta??{},compression:a}})}}var bo=class{baseDir;getActiveSlug;constructor(e,t){this.baseDir=e,this.getActiveSlug=t}async initialize(){await He(this.baseDir,{recursive:!0})}async read(e){let t=this.resolveScopedPath(e);if(t==null)return null;try{return await Ue(t,`utf-8`)}catch(e){if(this.isMissingError(e))return null;throw e}}async write(e,t,n){let r=this.resolveScopedPath(e);r!=null&&(await He(Re(r),{recursive:!0}),await Je(r,t,{encoding:`utf-8`,flag:n?.exclusive?`wx`:`w`}))}async delete(e){let t=this.resolveScopedPath(e);if(t==null)return!1;try{return await qe(t),!0}catch(e){if(this.isMissingError(e))return!1;throw e}}async list(e){let t=this.getActiveSlugDir();if(t==null)return[];let n=e?this.resolveScopedPath(e):t;return n==null?[]:this.collectFiles(n,e??``)}async exists(e){let t=this.resolveScopedPath(e);if(t==null)return!1;try{return await Ke(t),!0}catch(e){if(this.isMissingError(e))return!1;throw e}}async listDirectories(){let e=this.getActiveSlugDir();if(e==null)return[];try{return(await We(e,{withFileTypes:!0})).filter(e=>e.isDirectory()&&/^[a-z][a-z0-9-]*$/.test(e.name)).map(e=>e.name).sort()}catch(e){if(this.isMissingError(e))return[];throw e}}async flushAll(){let e=this.getActiveSlugDir();if(e==null)return 0;let t=await this.countFiles(e);return t===0?0:(await Ge(e,{recursive:!0,force:!0}),t)}async close(){}getActiveSlugDir(){let e=this.getActiveSlug();return e?I(this.baseDir,e):null}resolveScopedPath(e){let t=this.getActiveSlugDir();if(t==null)return null;let n=L(t),r=L(n,e),i=Be(n,r);if(i===``||i===`..`||i.startsWith(`..${Ve}`)||ze(i))throw Error(`Path escapes active flow context scope: ${e}`);return r}async collectFiles(e,t){let n;try{n=await We(e,{withFileTypes:!0})}catch(e){if(this.isMissingError(e))return[];throw e}let r=[];for(let i of n){let n=t?`${t}/${i.name}`:i.name,a=I(e,i.name);if(i.isDirectory()){r.push(...await this.collectFiles(a,n));continue}if(!(!i.isFile()||!i.name.endsWith(`.md`)))try{let e=await Ke(a);r.push({path:n,size:e.size,mtimeMs:e.mtimeMs})}catch(e){if(!this.isMissingError(e))throw e}}return r.sort((e,t)=>e.path.localeCompare(t.path))}async countFiles(e){let t;try{t=await We(e,{withFileTypes:!0})}catch(e){if(this.isMissingError(e))return 0;throw e}let n=0;for(let r of t){let t=I(e,r.name);if(r.isDirectory()){n+=await this.countFiles(t);continue}r.isFile()&&(n+=1)}return n}isMissingError(e){return typeof e==`object`&&!!e&&`code`in e&&(e.code===`ENOENT`||e.code===`ENOTDIR`)}};M(`procedural-memory`);const xo={minSequenceLength:3,minRepetitions:3,maxSequenceLength:10,confidenceIncrement:10,confidenceDecrement:20},So=new Set([`status`,`guide`,`health`,`onboard`,`reindex`,`replay`,`session_digest`,`process`,`watch`,`produce_knowledge`,`list_tools`,`describe_tool`,`search_tools`]);function Co(e){return e.join(`→`)}function wo(e){return{...e,steps:[...e.steps]}}function To(e){return e.every(e=>e.success)}var Eo=class{config;history=[];sequences=new Map;procedures=new Map;pendingProcedures=new Map;constructor(e=xo){this.config=e}record(e,t){let n=new Date().toISOString();this.history.push({toolName:e,timestamp:n,success:t}),this.history.length>100&&(this.history=this.history.slice(-100));let r=this.detectSequences(n);this.updateMatchedProcedures(n,r)}getExtractableSequences(){return[...this.sequences.entries()].filter(([,e])=>e.count>=this.config.minRepetitions).map(([e,t])=>({steps:e.split(`→`),count:t.count,lastSeen:t.lastSeen})).sort((e,t)=>t.count===e.count?t.steps.length-e.steps.length:t.count-e.count)}listProcedures(){return[...this.procedures.values()].map(e=>wo(e)).sort((e,t)=>t.occurrences===e.occurrences?t.steps.length-e.steps.length:t.occurrences-e.occurrences)}drainNewProcedures(){let e=[...this.pendingProcedures.values()].map(e=>wo(e));return this.pendingProcedures.clear(),e}requeueProcedures(e){for(let t of e)this.pendingProcedures.set(Co(t.steps),wo(t))}extractProcedure(e,t){return{id:Ze(),steps:[...e],occurrences:t,confidence:Math.min(50+(t-this.config.minRepetitions)*this.config.confidenceIncrement,100),lastSeen:new Date().toISOString(),conditions:`Use when these user-facing tools are run in this order within a single session.`}}adjustConfidence(e,t){return e.confidence=t?Math.min(100,e.confidence+this.config.confidenceIncrement):Math.max(0,e.confidence-this.config.confidenceDecrement),e.confidence}getHistoryLength(){return this.history.length}clear(){this.history=[],this.sequences.clear(),this.procedures.clear(),this.pendingProcedures.clear()}detectSequences(e){let t=this.history.map(e=>e.toolName),n=Math.min(this.config.maxSequenceLength,t.length),r=new Set,i=Math.max(1,Math.min(2,this.config.minRepetitions));for(let a=this.config.minSequenceLength;a<=n;a+=1){let n=t.slice(-a),o=Co(n),s=0;for(let e=0;e<=t.length-a;e+=1)Co(t.slice(e,e+a))===o&&(s+=1);if(!(s<i)&&(this.sequences.set(o,{count:s,lastSeen:e}),s>=this.config.minRepetitions&&!this.procedures.has(o))){let t=this.extractProcedure(n,s);t.lastSeen=e,this.procedures.set(o,t),this.pendingProcedures.set(o,wo(t)),r.add(o)}}return r}updateMatchedProcedures(e,t){for(let[n,r]of this.procedures.entries()){if(t.has(n))continue;let i=n.split(`→`);if(this.history.length<i.length)continue;let a=this.history.slice(-i.length);Co(a.map(e=>e.toolName))===n&&(r.occurrences+=1,r.lastSeen=e,this.adjustConfidence(r,To(a)))}}};const Do={recurrenceWeight:.3,confidenceWeight:.3,sourceDiversityWeight:.2,freshnessWeight:.1,actionabilityWeight:.1};function Oo(e){let t=0;return/\b(use|should|must|always|never|prefer|avoid|requires?)\b/i.test(e)&&(t+=.3),/```|```[\w]*\n|`\w+`|(?:^|\n)[*-] /m.test(e)&&(t+=.3),/\b\d+%|\d+\.\d+|\d+tps?\b/i.test(e)&&(t+=.2),/\b(next|todo|fixme|hack|bug|workaround)\b/i.test(e)&&(t+=.2),Math.min(t,1)}const ko=M(`promotion-engine`);var Ao=class{running=!1;records=[];config;observationCache=new Map;constructor(e){this.config={...Do,...e}}async evaluate(e,t){this.running&&ko.warn(`Promotion cycle already running — queueing evaluation`),this.running=!0;try{return this.evaluateInner(e,t)}finally{this.running=!1}}recordObservation(e,t){let n=Date.now(),r=this.observationCache.get(t);r?(r.observationCount++,r.lastObservedAt=n,r.sourceDiversity.includes(e.source)||r.sourceDiversity.push(e.source)):this.observationCache.set(t,{observationCount:1,firstObservedAt:n,lastObservedAt:n,sourceDiversity:e.source?[e.source]:[],userCorrectionCount:0})}getObservationMetadata(e){return this.observationCache.get(e)??{observationCount:0,firstObservedAt:0,lastObservedAt:0,sourceDiversity:[],userCorrectionCount:0}}recordDecision(e,t){this.records.push({decision:e,factTitle:t.title,factCategory:t.category,identityKey:t.identityKey??`unknown`}),this.records.length>1e4&&this.records.splice(0,this.records.length-1e4)}isSuperseded(e){return this.records.some(t=>t.decision.status===`promoted`&&t.decision.supersededBy===e)}getStats(){let e={promoted:0,held:0,rejected:0,superseded:0,decayed:0};for(let t of this.records)e[t.decision.status]!==void 0&&e[t.decision.status]++;return{totalEvaluated:this.records.length,...e,observedFacts:this.observationCache.size,recentDecisions:this.records.slice(-10)}}reset(){this.records=[],this.observationCache.clear(),this.running=!1}evaluateInner(e,t){let n=this.getObservationMetadata(t),r=Date.now(),i={status:`rejected`,reason:`Default: not evaluated`,timestamp:r,evidenceRefs:this.collectEvidenceRefs(e)};if(this.isSuperseded(t))return i.status=`superseded`,i.reason=`Fact superseded: identityKey "${t}" has been superseded by a newer version`,this.recordDecision(i,e),i;if(n.observationCount>0&&this.hasExceededHoldTTL(n.firstObservedAt))return i.status=`decayed`,i.reason=`Held fact exceeded max hold TTL of 30 days without reaching promotion threshold`,this.recordDecision(i,e),i;if(this.isFastPathQualified(e,n))return i.status=`promoted`,i.tier=`fast-path`,i.reason=`Fast-path: quality=${e.quality.toFixed(2)}≥${.9.toFixed(2)}, observations=${n.observationCount}≥3, sources=${n.sourceDiversity.length}≥2`,this.recordDecision(i,e),i;let a=this.computeScore(e,n);return i.score=a,a.totalScore>=70?(i.status=`promoted`,i.tier=a.totalScore>=85?`standard`:`borderline`,n.observationCount<5||n.sourceDiversity.length<2?i.reason=`Promoted (score=${a.totalScore.toFixed(1)}). Auto-inject deferred: need 5 observations (have ${n.observationCount}) and 2 sources (have ${n.sourceDiversity.length}).`:(i.tier=`standard`,i.reason=`Promoted (score=${a.totalScore.toFixed(1)}). Recurrence=${a.components.recurrence.toFixed(1)}, confidence=${a.components.confidence.toFixed(1)}, sources=${a.components.sourceDiversity.toFixed(1)}, freshness=${a.components.freshness.toFixed(1)}, actionability=${a.components.actionability.toFixed(1)}`)):a.totalScore>=45?(i.status=`held`,i.heldUntil=r+720*60*60*1e3,i.reason=`Held (score=${a.totalScore.toFixed(1)}). Below promote threshold (70) but above decay (45). Will expire ${new Date(i.heldUntil).toISOString()}.`):(i.status=`rejected`,i.reason=`Rejected (score=${a.totalScore.toFixed(1)}). Below decay threshold (45). Consider improving fact quality or recurrence.`),this.recordDecision(i,e),i}computeScore(e,t){let{recurrenceWeight:n,confidenceWeight:r,sourceDiversityWeight:i,freshnessWeight:a,actionabilityWeight:o}=this.config,s=Math.min(t.observationCount/20,1)*100,c=e.quality*100,l=Math.min(t.sourceDiversity.length/5,1)*100,u=Date.now()-t.lastObservedAt,d=Math.max(0,1-u/(10080*60*1e3))*100,f=Oo(e.content)*100,p=s*n+c*r+l*i+d*a+f*o;return{totalScore:Math.round(p*10)/10,components:{recurrence:Math.round(s*10)/10,confidence:Math.round(c*10)/10,sourceDiversity:Math.round(l*10)/10,freshness:Math.round(d*10)/10,actionability:Math.round(f*10)/10}}}isFastPathQualified(e,t){return e.quality>=.9&&t.observationCount>=3&&t.sourceDiversity.length>=2}hasExceededHoldTTL(e){return Date.now()-e>720*60*60*1e3}collectEvidenceRefs(e){let t=[];if(e.evidenceRefs)for(let n of e.evidenceRefs)t.push(`${n.sourceTool}:${n.requestId}@${n.timestamp}`);return t.length===0&&t.push(`auto:${e.source}@${Date.now()}`),t}};const W=M(`skill-compiler`),jo={debounceMs:5e3,stalenessFallbackMs:864e5,backgroundQueue:!0};var Mo=class{skillDir;curated;getFlowState;config;debounceTimer=null;pendingRegeneration=!1;isCompiling=!1;totalCompiles=0;failedCompiles=0;skippedCompiles=0;lastCompiledAt=null;currentVersion=1;flowBriefingManager;constructor(e,t={},n,r,i){this.skillDir=e,this.curated=r,this.getFlowState=i,this.config={...jo,...t},this.curated=r??null,this.flowBriefingManager=new No(this.skillDir,this.config,this.curated,this.getFlowState),this.ensureDir(),this.loadVersion()}ensureDir(){P(this.skillDir)||Ae(this.skillDir,{recursive:!0});let e=I(this.skillDir,`references`);P(e)||Ae(e,{recursive:!0})}loadVersion(){let e=I(this.skillDir,`.aikit-skill.json`);try{if(P(e)){let t=JSON.parse(F(e,`utf-8`));this.currentVersion=t.version??1}}catch{this.currentVersion=1}}saveVersion(){let e=I(this.skillDir,`.aikit-skill.json`);try{Ie(e,JSON.stringify({version:this.currentVersion,updated:new Date().toISOString()},null,2),`utf-8`)}catch(e){W.warn(`Failed to save skill manifest`,{error:String(e)})}}getStats(){let e=I(this.skillDir,et),t=P(e);return{lastCompiledAt:this.lastCompiledAt,isStale:t?this.isStaleFromCacheOrCheck(e):!0,isCompiling:this.isCompiling,totalCompiles:this.totalCompiles,failedCompiles:this.failedCompiles,skippedCompiles:this.skippedCompiles,skillExists:t,skillPath:t?e:null,skillSize:t?Pe(e).size:0,skillVersion:this.currentVersion,pendingRegeneration:this.pendingRegeneration}}getWarnings(e){let t=[];return this.failedCompiles>0&&t.push(`Skill compiler: ${this.failedCompiles} failed compile(s) out of ${this.totalCompiles} total. Check logs.`),!this.getFlowState&&e&&t.push(`Skill compiler: getFlowState callback not configured — flow briefings not compiled automatically.`),this.pendingRegeneration&&t.push(`Skill compiler: regeneration is pending.`),t}readCurrentSkill(){let e=I(this.skillDir,et);try{return P(e)?F(e,`utf-8`):null}catch(e){return W.warn(`Failed to read current skill file`,{error:String(e)}),null}}scheduleRegeneration(e){this.debounceTimer&&clearTimeout(this.debounceTimer),W.debug(`Skill compile scheduled (trigger: ${e}, debounce: ${this.config.debounceMs}ms)`),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.executeCompile(e)},this.config.debounceMs)}scheduleImmediateRegeneration(e){this.debounceTimer&&=(clearTimeout(this.debounceTimer),null),W.debug(`Skill compile scheduled immediate (trigger: ${e})`),setImmediate(()=>{this.executeCompile(e)})}async compileNow(e=`manual`){this.debounceTimer&&=(clearTimeout(this.debounceTimer),null),await this.executeCompile(e)}scheduleFlowBriefingRegeneration(e,t){this.flowBriefingManager.scheduleFlowBriefingRegeneration(e,t)}async deleteFlowBriefing(e){await this.flowBriefingManager.deleteFlowBriefing(e)}readFlowBriefing(e){return this.flowBriefingManager.readFlowBriefing(e)}async loadFlowDecisions(e){return this.flowBriefingManager.loadFlowDecisions(e)}resolveActiveFlowSlug(){return this.flowBriefingManager.resolveActiveFlowSlug()}subscribeToEventBus(e){let t=[];return t.push(e.subscribe({eventType:`flow:step:eventbus`,policy:`async`,name:`skill-compiler-flow-step`,handler:async e=>{let t=typeof e.flowSlug==`string`?e.flowSlug:void 0;t&&this.scheduleFlowBriefingRegeneration(t,`flow:step:eventbus`)}})),t.push(e.subscribe({eventType:`flow:complete:eventbus`,policy:`async`,name:`skill-compiler-flow-complete`,handler:async e=>{let t=typeof e.flowSlug==`string`?e.flowSlug:void 0;t&&this.scheduleFlowBriefingRegeneration(t,`flow:complete:eventbus`)}})),t.push(e.subscribe({eventType:`flow:abandon`,policy:`async`,name:`skill-compiler-flow-abandon`,handler:async e=>{let t=typeof e.flowSlug==`string`?e.flowSlug:void 0;t&&await this.deleteFlowBriefing(t)}})),t.push(e.subscribe({eventType:`reindex:done`,policy:`async`,name:`skill-compiler-reindex`,handler:async()=>{this.scheduleRegeneration(`reindex:done`)}})),t.push(e.subscribe({eventType:`knowledge:promoted`,policy:`async`,name:`skill-compiler-knowledge`,handler:async()=>{this.scheduleRegeneration(`knowledge:promoted`)}})),()=>{for(let e of t)e()}}async executeCompile(e){if(this.isCompiling){this.pendingRegeneration=!0,W.debug(`Skill compile already in progress — pending flag set`);return}this.isCompiling=!0,this.pendingRegeneration=!1;try{do{let t=await this.loadSkillInput(),n=_t(t),r=this.readCurrentSkill();if(r&&!zt(r,n)){W.debug(`Skill up to date — skipping compile`,{sourceHash:n}),this.skippedCompiles++;continue}W.info(`Skill compile starting`,{trigger:e,sourceHash:n});let i=Date.now(),a=Nt(t,this.currentVersion);await this.writeSkillAtomically(a,n),this.lastCompiledAt=Date.now(),this.currentVersion++,this.saveVersion(),this.totalCompiles++,W.info(`Skill compile complete`,{durationMs:Date.now()-i,size:a.length}),this.pendingRegeneration&&(this.pendingRegeneration=!1,W.debug(`Pending regeneration detected — recompiling`))}while(this.pendingRegeneration)}catch(t){this.failedCompiles++,W.error(`Skill compile failed`,{error:String(t),trigger:e})}finally{this.isCompiling=!1}}async loadSkillInput(){let e=[],t={workspaceName:this.skillDir,promotedKnowledge:e,pitfalls:[],adrSummaries:[],validationCommands:[]};if(this.curated)try{let[n,r,i]=await Promise.all([this.curated.list({category:`lessons`,limit:20,orderBy:`updated`,order:`desc`}),this.curated.list({category:`conventions`,limit:10,orderBy:`updated`,order:`desc`}),this.curated.list({category:`retrieval`,limit:10,orderBy:`updated`,order:`desc`})]);for(let t of n)t.contentPreview&&e.push({title:t.title,insight:t.contentPreview.slice(0,200),confidence:t.tags.includes(`high-confidence`)?80:60,category:`lessons`});for(let t of r)t.contentPreview&&e.push({title:t.title,insight:t.contentPreview.slice(0,200),confidence:70,category:`conventions`});for(let t of i)t.contentPreview&&e.push({title:t.title,insight:t.contentPreview.slice(0,200),confidence:75,category:`retrieval`});for(let e of r.slice(0,5))e.contentPreview&&e.contentPreview.length>5&&t.pitfalls?.push(`${e.title}: ${e.contentPreview.slice(0,150)}`)}catch(e){W.warn(`Failed to load promoted knowledge for skill`,{error:String(e)})}return t}async writeSkillAtomically(e,t){let n=I(this.skillDir,et),r=I(this.skillDir,`.SKILL.tmp`),i=I(this.skillDir,`.SKILL.backup.md`);if(P(n))try{ke(n,i)}catch{}if(Ie(r,e,`utf-8`),Me(r,n),P(i))try{Date.now()-Pe(i).mtimeMs>10080*60*1e3&&Fe(i)}catch{}}isStaleFromCacheOrCheck(e){try{let t=F(e,`utf-8`);if(!t.match(/^---\n[\s\S]*?\n---\n/))return!0;let n=t.match(/^updated:\s(.+)$/m);if(n){let e=new Date(n[1]).getTime();if(!Number.isNaN(e)&&Date.now()-e>this.config.stalenessFallbackMs)return!0}return!1}catch{return!0}}},No=class{skillDir;config;curated;getFlowState;debounceTimers=new Map;compilingSlugs=new Set;constructor(e,t,n,r){this.skillDir=e,this.config=t,this.curated=n,this.getFlowState=r}scheduleFlowBriefingRegeneration(e,t){let n=this.debounceTimers.get(e);n&&clearTimeout(n),W.debug(`Flow briefing regeneration scheduled for slug ${e} (trigger: ${t})`);let r=setTimeout(()=>{this.debounceTimers.delete(e),this.executeFlowBriefingCompile(e,t)},this.config.debounceMs);this.debounceTimers.set(e,r)}async deleteFlowBriefing(e){let t=e.replace(/[^a-zA-Z0-9_-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`unknown`,n=I(this.skillDir,`references`,`flow-${t}.md`);try{P(n)&&(Fe(n),W.debug(`Flow briefing deleted for slug ${e}`))}catch(t){W.warn(`Failed to delete flow briefing`,{slug:e,error:String(t)})}}readFlowBriefing(e){let t=e.replace(/[^a-zA-Z0-9_-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`unknown`,n=I(this.skillDir,`references`,`flow-${t}.md`);try{if(!P(n))return null;let e=F(n,`utf-8`);return e.length>0?e:null}catch{return null}}async executeFlowBriefingCompile(e,t){if(!this.getFlowState){W.warn(`getFlowState not configured — skipping flow briefing compile`,{slug:e});return}let n=e.replace(/[^a-zA-Z0-9_-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`unknown`;if(this.compilingSlugs.has(n)){W.debug(`Flow briefing already compiling for ${n} — skipping`);return}this.compilingSlugs.add(n);try{let r=await this.getFlowState(e);if(!r?.flow){W.debug(`No active flow state — skipping flow briefing compile`,{slug:e});return}let i=await this.loadFlowDecisions(e),a=(r.completedSteps??[]).map(e=>({id:e,outcome:`completed`,summary:void 0,producedArtifacts:[]})),o=(r.skippedSteps??[]).map(e=>({id:e,outcome:`skipped`,summary:void 0,producedArtifacts:[]})),s=r.stepSequence??[],c=Mt({flowName:r.flow,slug:e,topic:r.topic??``,objective:r.objective,currentStep:r.currentStep,completedSteps:[...a,...o],totalSteps:s.length||a.length||1,decisions:i.map(e=>({title:e.title,summary:e.summary})),phase:r.phase??`flow`,stepSequence:s,acceptanceCriteria:r.acceptanceCriteria,scope:r.scope,exclusions:r.exclusions}),l=I(this.skillDir,`references`);P(l)||Ae(l,{recursive:!0});let u=I(l,`flow-${n}.md`),d=I(l,`.flow-${n}.tmp`);Ie(d,c,`utf-8`),Me(d,u),W.info(`Flow briefing compiled`,{slug:e,trigger:t,size:c.length})}catch(t){W.error(`Flow briefing compile failed`,{slug:e,error:String(t)})}finally{this.compilingSlugs.delete(n)}}async loadFlowDecisions(e){if(!this.curated)return[];try{let t=await this.curated.list({category:`flow-context`,limit:20,orderBy:`updated`,order:`desc`}),n=e.replace(/[^a-zA-Z0-9_-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`flow`;return t.filter(e=>e.tags?.includes(`flow:${n}`)&&e.contentPreview&&e.contentPreview.length>10).map(e=>({title:e.title,summary:e.contentPreview.slice(0,200)}))}catch{return[]}}resolveActiveFlowSlug(){let e=I(this.skillDir,`references`);try{if(!P(e))return null;let t=je(e).filter(e=>e.startsWith(`flow-`)&&e.endsWith(`.md`)).map(t=>({slug:t.replace(/^flow-/,``).replace(/\.md$/,``),mtime:Pe(I(e,t)).mtimeMs})).sort((e,t)=>t.mtime-e.mtime);return t.length>0?t[0].slug:null}catch{return null}}};const Po=M(`event-bus`);function Fo(e,t){if(typeof e!=`object`||!e)return e;t??=new WeakSet;let n=e;if(t.has(n))return e;t.add(n);let r=Object.getOwnPropertyNames(n);for(let n of r){let r=e[n];r&&typeof r==`object`&&Fo(r,t)}return Object.freeze(e)}const Io=[`compression`,`hookDebug`,`origin`,`workspace`];var Lo=class{subscribers=new Map;subById=new Map;subCounter=0;failureCounts=new Map;consecutiveFailures=new Map;lastErrors=new Map;autoDisabled=new Map;subscribe(e){let t=e.id||`sub_${++this.subCounter}`,n={...e,id:t},r=this.subscribers.get(e.eventType);return r?r.push(n):this.subscribers.set(e.eventType,[n]),this.subById.set(t,e.eventType),Po.debug(`Subscriber registered`,{id:n.id,eventType:e.eventType}),()=>this.unsubscribe(t)}unsubscribe(e){let t=this.subById.get(e);if(!t)return;this.subById.delete(e);let n=this.subscribers.get(t);if(!n)return;let r=n.findIndex(t=>t.id===e);r!==-1&&(n.splice(r,1),n.length===0&&this.subscribers.delete(t)),Po.debug(`Subscriber unregistered`,{id:e,eventType:t})}emit(e){let t=this.subscribers.get(e.type);if(!(!t||t.length===0)){this.validateMeta(e.meta),Fo(e);for(let n=0;n<t.length;n+=10){let r=t.slice(n,n+10);queueMicrotask(()=>{for(let t of r)this.executeSubscriber(t,e)})}}}executeSubscriber(e,t){e.id&&this.autoDisabled.has(e.id)||Promise.resolve().then(()=>e.handler(t)).then(()=>{e.id&&this.consecutiveFailures.delete(e.id)}).catch(n=>{let r=n instanceof Error?n.message:String(n),i=e.id??`unknown`,a=(this.failureCounts.get(i)??0)+1;this.failureCounts.set(i,a);let o=(this.consecutiveFailures.get(i)??0)+1;if(this.consecutiveFailures.set(i,o),o>=10&&e.id){this.autoDisabled.set(e.id,{name:e.name,reason:`Auto-disabled after ${o} consecutive failures. Last error: ${r}`,disabledAt:Date.now()}),this.unsubscribe(e.id),this.failureCounts.delete(i),this.consecutiveFailures.delete(i),this.lastErrors.delete(i),Po.error(`Subscriber auto-disabled after consecutive failures`,{subscriber:e.name,id:e.id,eventType:t.type,consecutiveFailures:o});return}let s=this.lastErrors.get(i)??[];s.push({timestamp:Date.now(),error:r}),s.length>10&&s.splice(0,s.length-10),this.lastErrors.set(i,s),Po.error(`EventBus subscriber failed`,{subscriber:e.name,id:e.id,eventType:t.type,error:r,consecutiveFailures:o})})}validateMeta(e){if(e==null)return;if(typeof e!=`object`||Array.isArray(e)){Po.warn(`EventBus meta must be a known meta shape or null`,{type:typeof e});return}let t=Object.keys(e);if(t.length===0){Po.warn(`EventBus meta has no top-level keys`);return}for(let e of t)Io.includes(e)||Po.warn(`EventBus meta key not recognized`,{key:e,allowed:Io})}resetFailures(e){this.failureCounts.delete(e),this.consecutiveFailures.delete(e),this.lastErrors.delete(e),this.autoDisabled.delete(e)}getStats(){let e={},t=[];for(let[n,r]of this.subscribers)if(r.length!==0){e[n]=r.length;for(let e of r)t.push({id:e.id??`auto`,name:e.name,eventType:e.eventType,policy:e.policy})}let n=[];for(let[e,t]of this.lastErrors)for(let r of t)n.push({subscriberId:e,timestamp:r.timestamp,error:r.error});let r={};for(let[e,t]of this.failureCounts)r[e]=t;let i=[];for(let[e,t]of this.autoDisabled)i.push({id:e,name:t.name,reason:t.reason});return{totalSubscribers:t.length,byEvent:e,subscriptions:t,failureCounts:r,lastErrors:n,autoDisabled:i}}};const Ro=M(`observation-store`),zo=1e3;var Bo=class{entries=new Map;artifacts=new Map;maxEntries;entryTtlMs;maxArtifacts;artifactInsertionOrder=[];storeCounter=0;constructor(e,t,n){this.maxEntries=e??zo,this.entryTtlMs=t??18e5,this.maxArtifacts=n??Math.floor((e??zo)/2)}store(e){let t={data:e,storedAt:Date.now()};for(this.entries.set(e.requestId,t);this.entries.size>this.maxEntries;){let e=this.entries.keys().next().value;e&&this.entries.delete(e)}this.storeCounter++,this.storeCounter%100==0&&this.sweepStale()}get(e){let t=this.entries.get(e);if(t){if(Date.now()-t.storedAt>this.entryTtlMs){this.entries.delete(e);return}return t.data}}createArtifact(e,t,n,r){let i=r.length>256e3,a=i?r.slice(0,256e3):r;for(this.artifacts.set(e,{content:a,storedAt:Date.now(),contentType:n}),this.artifactInsertionOrder.push(e);this.artifactInsertionOrder.length>this.maxArtifacts;){let e=this.artifactInsertionOrder.shift();e&&this.artifacts.delete(e)}return Ro.debug(`Observation artifact stored`,{requestId:e,length:a.length,truncated:i}),{requestId:e,eventId:t,contentType:n,sizeChars:a.length,truncated:i}}getArtifact(e){let t=this.artifacts.get(e);if(t){if(Date.now()-t.storedAt>this.entryTtlMs){this.artifacts.delete(e);return}return{content:t.content,contentType:t.contentType}}}size(){return this.sweepStale(),this.entries.size}clear(){this.entries.clear(),this.artifacts.clear(),this.artifactInsertionOrder=[],this.storeCounter=0}sweepStale(){let e=Date.now(),t=[];for(let[n,r]of this.entries)e-r.storedAt>this.entryTtlMs&&t.push(n);for(let e of t)this.entries.delete(e);for(let[t,n]of this.artifacts)e-n.storedAt>this.entryTtlMs&&this.artifacts.delete(t);t.length>0&&Ro.debug(`Swept stale observation entries`,{count:t.length})}};const Vo={search:5e4,check:1e5,test_run:1e5,onboard:5e5},Ho={argsMaxChars:500,resultMaxChars:8e3,payloadMaxChars:16e3,artifactMaxChars:256e3};function Uo(e,t){if(e.length<=t)return e;let n=e.slice(0,t),r=Math.floor(t*.3),i=n.lastIndexOf(`.`,t);if(i>r)return n.slice(0,i+1);let a=n.lastIndexOf(`
25
- `,t);if(a>r)return n.slice(0,a);let o=n.lastIndexOf(`,`,t);return o>r?n.slice(0,o):`${n.slice(0,t-3)}...`}function Wo(e,t,n=Ho){let r=e.text.length+t.text.length+200;if(r<=n.payloadMaxChars)return{args:e,result:t};let i=r-n.payloadMaxChars,a=Math.max(t.text.length-i-10,Math.min(t.text.length,100)),o=Uo(t.text,a),s=e.text.length+o.length+200;if(s<=n.payloadMaxChars)return{args:e,result:{...t,text:o,truncated:!0}};let c=s-n.payloadMaxChars,l=Math.max(e.text.length-c-10,Math.min(e.text.length,50));return{args:{...e,text:Uo(e.text,l),truncated:!0},result:{...t,text:o,truncated:!0}}}function Go(e){try{return JSON.stringify(e)}catch{return`[Non-serializable args]`}}function Ko(e){if(e==null)return``;if(typeof e==`string`)return e;if(typeof e==`object`){let t=e;if(Array.isArray(t.content))return t.content.filter(e=>typeof e.text==`string`).map(e=>e.text).join(`
26
- `);try{return JSON.stringify(e)}catch{return String(e)}}return String(e)}const qo=M(`observation-compressor`);function Jo(){return{total:0,byTool:new Map,byOrigin:new Map,errors:0,successes:0,artifacts:0,truncations:0}}var Yo=class{store;counters=Jo();budget;constructor(e,t){this.store=e??new Bo,this.budget={...Ho,...t}}getStore(){return this.store}buildObservation(e,t,n,r,i,a,o,s){this.counters.total++,this.counters.byTool.set(e,(this.counters.byTool.get(e)??0)+1),this.counters.byOrigin.set(a,(this.counters.byOrigin.get(a)??0)+1),i?this.counters.errors++:this.counters.successes++;let c=Go(t),l={text:Uo(c,this.budget.argsMaxChars),truncated:c.length>this.budget.argsMaxChars,originalLength:c.length};l.truncated&&this.counters.truncations++;let u=Ko(n),d,f;u.length>this.budget.artifactMaxChars?(qo.warn(`Tool result exceeds artifact max chars — data omitted from observation`,{toolName:e,resultLength:u.length,maxChars:this.budget.artifactMaxChars}),f={requestId:o,eventId:o,contentType:`text/plain`,sizeChars:u.length,truncated:!0},this.counters.truncations++,this.counters.artifacts++,d={text:`[Result too large: ${u.length} chars — truncated at ${this.budget.artifactMaxChars} limit]`,truncated:!0,originalLength:u.length,artifactRef:f}):u.length>this.budget.resultMaxChars?(f=this.store.createArtifact(o,o,`text/plain`,u),this.counters.artifacts++,d={text:Uo(u,this.budget.resultMaxChars),truncated:!0,originalLength:u.length,artifactRef:f}):d={text:u,truncated:!1,originalLength:u.length};let p={...this.budget,payloadMaxChars:Vo[e]??this.budget.payloadMaxChars},m=Wo(l,d,p);return this.store.store({requestId:o,eventId:o,toolName:e,args:t,result:n,durationMs:r,isError:i,timestamp:Date.now(),workspaceId:s}),{toolName:e,args:m.args,result:m.result,durationMs:r,isError:i,origin:a,requestId:o,workspaceId:s}}fromToolAfter(e){return this.buildObservation(e.toolName,e.args,e.result,e.durationMs,e.isError,e.origin,e.requestId,e.workspaceId)}getStats(){let e={};for(let[t,n]of this.counters.byTool)e[t]=n;let t={};for(let[e,n]of this.counters.byOrigin)t[e]=n;return{totalObservations:this.counters.total,byTool:e,byOrigin:t,byError:{success:this.counters.successes,error:this.counters.errors},artifactCount:this.counters.artifacts,truncationCount:this.counters.truncations,storeSize:this.store.size()}}reset(){this.counters=Jo(),this.store.clear()}};function Xo(e,t,n){let r={...t},i=new Map;for(let t of n)for(let[n,a]of Object.entries(t.args)){let o=i.get(n);if(o!==void 0&&r[n]!==a)throw Error(`MutateArgs conflict for arg "${n}" between hooks "${o}" and "${t.hookId}" on tool "${e}"`);r[n]=a,i.set(n,t.hookId)}return r}var Zo=class{hooks=[];failureCounts=new Map;register(e){if(!e.id||!e.scope||e.timeoutMs==null)throw Error(`DecisionHook "${e.id}" missing required fields`);if(e.timeoutMs<1||e.timeoutMs>3e4)throw Error(`DecisionHook "${e.id}" timeoutMs must be 1-30000ms`);if(!e.decisionTypes||e.decisionTypes.length===0)throw Error(`DecisionHook "${e.id}" must declare at least one decision type`);if(this.hooks.some(t=>t.id===e.id))throw Error(`DecisionHook "${e.id}" is already registered`);let t=e=>typeof e==`string`&&e.length>0,n=Array.isArray(e.scope)?e.scope:[e.scope];if(n.length===0||!n.every(t))throw Error(`DecisionHook "${e.id}" has invalid scope`);this.hooks.push(e)}getHooksForTool(e){return this.hooks.filter(t=>(Array.isArray(t.scope)?t.scope:[t.scope]).some(t=>e.startsWith(t)||t===`*`||t===e)).sort((e,t)=>e.order-t.order)}async executeHooks(e,t){let n=this.getHooksForTool(e),r=[],i=[];for(let a of n)try{let n=await Qo(n=>a.fn(e,t,n),a);`timeout`in n&&n.timeout?(r.push(n.fallback),i.push({hookId:a.id,error:`Hook timed out, applied ${a.failurePolicy}`})):`result`in n&&r.push(n.result)}catch(e){if(this.failureCounts.set(a.id,(this.failureCounts.get(a.id)??0)+1),i.push({hookId:a.id,error:e instanceof Error?e.message:String(e)}),a.failurePolicy===`fail-closed`)throw Error(`Decision hook "${a.id}" fail-closed: ${e instanceof Error?e.message:String(e)}`)}return{results:r,errors:i}}getStats(){return{count:this.hooks.length,hooks:this.hooks.map(e=>({id:e.id,order:e.order,scope:e.scope,decisionTypes:e.decisionTypes,failurePolicy:e.failurePolicy})),failureCounts:Object.fromEntries(this.failureCounts)}}unregister(e){let t=this.hooks.findIndex(t=>t.id===e);return t===-1?!1:(this.hooks.splice(t,1),this.failureCounts.delete(e),!0)}get size(){return this.hooks.length}};async function Qo(e,t){let n=new AbortController,{signal:r}=n,i=setTimeout(()=>{n.abort()},t.timeoutMs),a=!1;try{let n=e(r);if(n instanceof Promise)throw clearTimeout(i),Error(`DecisionHook "${t.id}" returned a Promise. Async hooks are not supported in Phase 01 — all hooks must return synchronously.`);return a=!1,{result:n}}catch(e){if(a=e instanceof Error&&e.message.includes(`timed out`),t.failurePolicy===`fail-open`)return{fallback:{type:`decision`,hookId:t.id,decision:`allow`,reason:a?`Hook timed out after ${t.timeoutMs}ms — fail-open applied.`:`Hook failed: ${e instanceof Error?e.message:String(e)} — fail-open applied.`},timeout:a};if(t.failurePolicy===`degrade-with-warning`)return{fallback:{type:`decision`,hookId:t.id,decision:`allow`,reason:a?`Hook degraded after ${t.timeoutMs}ms — degrade-with-warning applied.`:`Hook degraded: ${e instanceof Error?e.message:String(e)}`},timeout:a};throw e}finally{clearTimeout(i)}}const $o=M(`tool-pipeline`);function es(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ts(e,t){return e.tools?(Array.isArray(e.tools)?e.tools:[e.tools]).includes(t):!0}function ns(e){return e.middleware.critical===!0}var rs=class{entries=[];middlewareCache=new Map;decisionHookRegistry=new Zo;observationCompressor;constructor(e){this.observationCompressor=e??new Yo}getObservationCompressor(){return this.observationCompressor}getObservationCompressorStats(){return this.observationCompressor.getStats()}use(e,t){this.entries.push({middleware:e,order:t?.order??100,tools:t?.tools,name:t?.name??e.name??`anonymous`}),this.middlewareCache.clear()}useFor(e,t,n){this.use(t,{order:n?.order,tools:e,name:n?.name})}getMiddleware(e){let t=this.middlewareCache.get(e);return t||(t=this.entries.filter(t=>ts(t,e)).sort((e,t)=>e.order-t.order),this.middlewareCache.set(e,t)),t}emitToolAfterEvent(e,t){e.emit({type:`tool:after`,toolName:t.toolName,args:t.args,result:t.result,durationMs:t.durationMs,isError:t.isError,origin:t.origin,requestId:t.requestId,timestamp:Date.now(),eventId:t.requestId,workspaceId:t.workspaceId,source:`tool-pipeline`,observation:t.observation,...t.meta?{meta:t.meta}:{}})}addDecisionHook(e){this.decisionHookRegistry.register(e)}wrap(e,t,n,r,i,a,o){let s=this.getMiddleware(e);return async(c,l)=>{let u;try{u=typeof a==`function`?a():a}catch{$o.warn(`workspaceId resolution failed — using empty string`,{toolName:e}),u=``}let d={toolName:e,args:es(c)?c:{},requestId:Ze(),meta:r,extra:l,toolConfig:n,eventBus:i,workspaceId:u,origin:o??`llm`},f=Date.now(),p,m;try{m=await this.decisionHookRegistry.executeHooks(e,d.args)}catch(e){p=e instanceof Error?e:Error(String(e))}m&&m.errors.length>0&&$o.warn(`Decision hook errors`,{toolName:e,errors:m.errors});let h=m?.results.find(e=>e.decision===`deny`);if(h||p){let t=Date.now()-f,n=h?{isError:!0,content:[{type:`error`,text:`Decision hook denied: ${h.reason}`}],structuredContent:{hookDenial:{hookId:h.hookId,reason:h.reason}}}:{isError:!0,content:[{type:`text`,text:`Decision hook fail-closed: ${p?.message??`Unknown error`}`}]},r=this.observationCompressor.buildObservation(e,d.args,n,t,!0,`hook`,d.requestId,d.workspaceId??``);if(i){let a=h?.hookId??(p?p.message.match(/^Decision hook "([^"]+)" fail-closed:/)?.[1]??`unknown`:`unknown`);this.emitToolAfterEvent(i,{toolName:e,args:d.args,result:n,durationMs:t,isError:!0,origin:`hook`,requestId:d.requestId,workspaceId:d.workspaceId??``,observation:r,meta:{hookDebug:{hookId:a,decision:h?`deny`:`fail-closed`,durationMs:t}}})}if(p)throw p;return n}let g=(m?.results??[]).filter(e=>e.decision===`mutateArgs`&&e.args!=null).map(e=>({hookId:e.hookId,args:e.args}));if(g.length>0)try{d.args=Xo(e,d.args??{},g)}catch(t){let n=Date.now()-f,r=t instanceof Error?t.message:String(t),a={isError:!0,content:[{type:`error`,text:`Arg mutation conflict: ${r}`}],structuredContent:{isError:!0,mutationConflict:r}},o=this.observationCompressor.buildObservation(e,d.args,a,n,!0,`hook`,d.requestId,d.workspaceId??``);return i&&this.emitToolAfterEvent(i,{toolName:e,args:d.args,result:a,durationMs:n,isError:!0,origin:`hook`,requestId:d.requestId,workspaceId:d.workspaceId??``,observation:o,meta:{hookDebug:{hookId:`conflict`,decision:`conflict`,conflict:r,durationMs:n}}}),a}let _=async n=>{let r=s[n];if(!r)return await t(d.args,l);let i=!1,a=!1,o,c=async()=>{i=!0;let e=await _(n+1);return a=!0,o=e,e};try{return await r.middleware(d,c)}catch(t){if(ns(r))throw t;if($o.warn(`Middleware failed for tool`,{middleware:r.name,tool:e,error:String(t)}),i){if(a&&o)return o;throw t}return _(n+1)}};try{let t=await _(0),n=Date.now()-f,r=t?.isError===!0||t?.structuredContent?.isError===!0,a=d.origin??o??`llm`,s=this.observationCompressor.buildObservation(e,d.args,t,n,r,a,d.requestId,d.workspaceId??``);return i&&this.emitToolAfterEvent(i,{toolName:e,args:d.args,result:t,durationMs:n,isError:r,origin:a,requestId:d.requestId,workspaceId:d.workspaceId??``,observation:s}),t}catch(t){let n=Date.now()-f,r=d.origin??o??`llm`,a={isError:!0,content:[{type:`text`,text:String(t)}]},s=this.observationCompressor.buildObservation(e,d.args,a,n,!0,r,d.requestId,d.workspaceId??``);throw i&&this.emitToolAfterEvent(i,{toolName:e,args:d.args,result:a,durationMs:n,isError:!0,origin:r,requestId:d.requestId,workspaceId:d.workspaceId??``,observation:s}),t}}}getMiddlewareNames(){return this.entries.map(e=>e.name)}};const is=M(`metrics-collector`),as={maxL0Chars:4500,maxL0StaleMs:36e5,maxDuplicateRate:.05,maxEventPayloadKB:48,maxEventErrorRate:.01,maxReportEntries:50,maxReportBytes:20480};var os=class{counters=new Map;gauges=new Map;thresholds;MAX_LABEL_COMBOS=50;constructor(e){this.thresholds={...as,...e}}getThresholds(){return{...this.thresholds}}enforceCounterHardCap(){if(this.counters.size<=this.MAX_LABEL_COMBOS*2)return;let e=this.counters.size-this.MAX_LABEL_COMBOS;for(let t=0;t<e;t++){let e=this.counters.keys().next().value;e&&this.counters.delete(e)}is.warn(`Metrics: counter hard cap enforced, evicted oldest entries`,{evicted:e,remaining:this.counters.size})}incrementCounter(e,t){let n=this.buildKey(e,t);this.counters.set(n,(this.counters.get(n)??0)+1),this.counters.size>=this.MAX_LABEL_COMBOS&&(is.warn(`Metrics: label combination count exceeded ${this.MAX_LABEL_COMBOS}`,{counterKeys:this.counters.size}),this.enforceCounterHardCap())}addToCounter(e,t,n){let r=this.buildKey(e,n);this.counters.set(r,(this.counters.get(r)??0)+t),this.counters.size>=this.MAX_LABEL_COMBOS&&(is.warn(`Metrics: label combination count exceeded ${this.MAX_LABEL_COMBOS}`,{counterKeys:this.counters.size}),this.enforceCounterHardCap())}setGauge(e,t,n){let r=this.buildKey(e,n);this.gauges.set(r,t)}getCounter(e,t){return this.counters.get(this.buildKey(e,t))??0}getGauge(e,t){return this.gauges.get(this.buildKey(e,t))??0}buildKey(e,t){if(!t)return e;let n=Object.keys(t).sort().reduce((e,n)=>(e[n]=t[n],e),{});return`${e}:${JSON.stringify(n)}`}getReport(){let e=Object.fromEntries(this.counters),t=Object.fromEntries(this.gauges);if(Object.keys(e).length>this.thresholds.maxReportEntries){let t=Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).slice(0,this.thresholds.maxReportEntries);e=Object.fromEntries(t)}if(Object.keys(t).length>this.thresholds.maxReportEntries){let e=Object.entries(t).sort(([e],[t])=>e.localeCompare(t)).slice(0,this.thresholds.maxReportEntries);t=Object.fromEntries(e)}let n=Object.entries(e),r=Object.entries(t);for(;n.length>0||r.length>0;){let e={counters:Object.fromEntries(n),gauges:Object.fromEntries(r)};if(JSON.stringify(e).length<=this.thresholds.maxReportBytes)return e;n.length>=r.length?n.pop():r.pop()}return is.warn(`Metrics report exceeds ${this.thresholds.maxReportBytes} bytes — all entries dropped`),{counters:{},gauges:{}}}checkThresholds(){let e=[],t=this.getReport(),n=t.gauges[`l0.size`];n!=null&&n>this.thresholds.maxL0Chars&&e.push(`L0 size ${n} chars > ${this.thresholds.maxL0Chars} threshold`);let r=t.gauges[`l0.age_ms`];r!=null&&r>this.thresholds.maxL0StaleMs&&e.push(`L0 age ${Math.round(r/1e3/60)}m > ${Math.round(this.thresholds.maxL0StaleMs/1e3/60)}m threshold`);let i=(t.counters[`fact.duplicate`]??0)/(t.counters[`fact.total`]??1);return i>this.thresholds.maxDuplicateRate&&e.push(`Duplicate fact rate ${(i*100).toFixed(1)}% > ${(this.thresholds.maxDuplicateRate*100).toFixed(1)}% threshold`),e}reset(){this.counters.clear(),this.gauges.clear()}};function ss(e,t){e.registerResource(`aikit-curated-index`,`aikit://curated`,{description:`Index of all curated knowledge entries`,mimeType:`text/markdown`},async()=>{let e=await t.listPage({limit:200,orderBy:`updated`,order:`desc`}),n=e.entries,r=n.map(e=>`- [${e.title}](aikit://curated/${e.path}) — ${e.category}`),i=e.hasMore?`\n\n_Showing ${n.length} of ${e.totalCount} entries. Use knowledge list for pagination._`:``;return{contents:[{uri:`aikit://curated`,text:`# Curated Knowledge Index\n\n${r.length>0?r.join(`
27
- `):`_No curated entries yet._`}${i}`,mimeType:`text/markdown`}]}});let n=new qn(`aikit://curated/{+path}`,{list:async()=>({resources:(await t.listPage({limit:200,orderBy:`updated`,order:`desc`})).entries.map(e=>({uri:`aikit://curated/${e.path}`,name:e.title,description:`[${e.category}] ${e.contentPreview?.slice(0,80)??``}`,mimeType:`text/markdown`}))})});e.registerResource(`aikit-curated-entry`,n,{description:`A curated knowledge entry`,mimeType:`text/markdown`},async(e,n)=>{let r=n.path;if(!r)throw Error(`Missing path variable in curated resource URI`);let i=await t.read(r);return{contents:[{uri:e.toString(),text:`---\ntitle: ${i.title}\ncategory: ${i.category}\ntags: ${i.tags?.join(`, `)??``}\nversion: ${i.version??1}\n---\n\n${i.content??i.contentPreview??``}`,mimeType:`text/markdown`}]}})}const cs=M(`resources`);function ls(e,t,n){if(!t){cs.debug(`No EventBus available — hooks resource skipped`);return}e.registerResource(`aikit-hooks-config`,`aikit://hooks/config`,{description:`Active EventBus hook subscribers and decision hooks — lists all registered subscriptions, their event types, execution policies, and decision hook diagnostics. Read this to discover what automated behaviors (auto-knowledge, replay, observations, decision hooks) are currently active.`,mimeType:`application/json`},async()=>{let e=t.getStats(),r=n?.getStats();return{contents:[{uri:`aikit://hooks/config`,text:JSON.stringify({totalSubscribers:e.totalSubscribers,byEvent:e.byEvent,subscriptions:e.subscriptions.map(e=>({id:e.id,name:e.name,eventType:e.eventType,policy:e.policy})),diagnostics:{failureCounts:e.failureCounts,lastErrors:e.lastErrors,autoDisabled:e.autoDisabled},decisionHooks:r?{count:r.count,hooks:r.hooks}:null},null,2),mimeType:`application/json`}]}}),cs.debug(`Hooks config resource registered`,{subscriberCount:t.getStats().totalSubscribers,decisionHookCount:n?.getStats().count??0})}const us=M(`resources`),ds=`aikit://schemas/channel-surface`,fs=new URL(`../../../blocks-core/schemas/channel-surface.schema.json`,import.meta.url);let ps;function ms(){return ps??=Ue(fs,`utf8`),ps}const hs=[{type:`markdown`,valueShape:`string`,example:`**bold**`},{type:`table`,valueShape:`{headers: string[], rows: string[][]}`,example:`{headers:["Name"], rows:[["Alice"]]}`},{type:`metrics`,valueShape:`{label:string, value:string|number}[]`,example:`[{label:"Pass", value:42}]`},{type:`checklist`,valueShape:`{label:string, checked:boolean}[]`,example:`[{label:"Done", checked:true}]`},{type:`chart`,valueShape:`{chartType, data, xKey, yKeys}`,example:`{chartType:"line", data:[{x:1}], xKey:"x", yKeys:["y"]}`},{type:`code`,valueShape:`string`,example:`const x = 1;`},{type:`heading`,valueShape:`string`,example:`## Section`},{type:`mermaid`,valueShape:`string`,example:`graph TD; A-->B;`},{type:`timeline`,valueShape:`{title, timestamp?, status?}[]`,example:`[{title:"Release", status:"done"}]`},{type:`cards`,valueShape:`{title, body?, status?}[]`,example:`[{title:"Card", body:"Content"}]`},{type:`comparison`,valueShape:`{title, items}[]`,example:`[{title:"Option A", items:["Fast"]}]`},{type:`kv`,valueShape:`Record<string, string>`,example:`{key: "value"}`},{type:`tree`,valueShape:`{name, children?}`,example:`{name:"root", children:[{name:"leaf"}]}`},{type:`status-board`,valueShape:`{category, items}[]`,example:`[{category:"Services", items:[{label:"API", status:"healthy"}]}]`},{type:`progress`,valueShape:`{label, value, max?}`,example:`{label:"Progress", value:75}`},{type:`separator`,valueShape:`none`,example:`separator`}];function gs(e){let t={schema:JSON.parse(e),blockCatalog:hs,presetCatalog:`aikit://present/presets`,templateCatalog:`aikit://present/templates`};return JSON.stringify(t,null,2)}function _s(e,t,n,r,i,a,o){ls(e,i,a),e.registerResource(`aikit-status`,`aikit://status`,{description:`Current AI Kit status and statistics`,mimeType:`text/plain`},async()=>{let e=await t.getStats();return{contents:[{uri:`aikit://status`,text:`AI Kit: ${e.totalRecords} records from ${e.totalFiles} files. Last indexed: ${e.lastIndexedAt??`Never`}`,mimeType:`text/plain`}]}}),e.registerResource(`aikit-file-tree`,`aikit://file-tree`,{description:`List of all indexed source files`,mimeType:`text/plain`},async()=>({contents:[{uri:`aikit://file-tree`,text:(await t.listSourcePaths()).sort().join(`
28
- `),mimeType:`text/plain`}]})),e.registerResource(`aikit-channel-surface-schema`,ds,{description:`Composite catalog: ChannelSurface JSON Schema, block types, and resource URIs`,mimeType:`application/json`},async()=>({contents:[{uri:ds,text:gs(await ms()),mimeType:`application/json`}]})),ss(e,n),r?(e.registerResource(`aikit-skill-index`,`aikit://skill`,{description:`Index of available workspace skill files for the current workspace`,mimeType:`text/markdown`},async()=>({contents:[{uri:`aikit://skill`,text:`# Workspace Skill\n\n${[`- [SKILL.md](aikit://skill/SKILL.md) — Workspace conventions, known issues, and workflow tips`].join(`
29
- `)}`,mimeType:`text/markdown`}]})),e.registerResource(`aikit-skill-file`,`aikit://skill/SKILL.md`,{description:`Workspace skill in SKILL.md format — conventions, known issues, workflow tips`,mimeType:`text/markdown`},async()=>{let e=I(r,`SKILL.md`),t,n=``;if(o){let e=o.getStats();e.isStale&&e.skillExists&&(n=`
30
-
31
- > ⚠ *This skill may be stale. Trigger regeneration via onboard, reindex, or flow completion.*
32
- `)}try{t=P(e)?F(e,`utf-8`)+n:`# Workspace Skill: not generated
33
-
34
- Run \`onboard({ path: "." })\` to generate this skill.`+n}catch{t=`# Workspace Skill: error
35
-
36
- Failed to read skill file.`}return{contents:[{uri:`aikit://skill/SKILL.md`,text:t,mimeType:`text/markdown`}]}}),us.debug(`Workspace skill resources registered`,{skillDir:r})):us.debug(`skillDir not configured — skill resources skipped`)}const vs=[`er_push`,`er_pull`,`er_sync_status`],ys=[...vs,`er_update_policy`,`er_evolve_review`],bs=new Set(ys);function xs(e){return e.toolProfiles}const Ss=5e3,Cs=M(`structured-content-guard`);function ws(){let e=(async(e,t)=>{let n;try{n=await t()}catch(e){n={content:[{type:`text`,text:`[ERROR:INTERNAL] ${e instanceof Error?e.message:String(e)}`}],isError:!0}}let r=(e.toolConfig??{}).outputSchema;if(r==null)return n;let i=null;if(n.structuredContent==null){let t=Ts(r);n.structuredContent=t,i=`synthesize`,n.structuredContent??(n.structuredContent={},i=`synthesize-null-fallback`,Cs.error(`synthesizeStructuredContent returned null/undefined — using empty fallback`,{tool:e.toolName}))}let a=Es(r,n.structuredContent);if(a.action!=null&&(n.structuredContent=a.structuredContent,i=a.action),Os(n.structuredContent)||(n.isError=!0,n.structuredContent={},i=`fallback-error`),Ds(r,n.structuredContent)===!1){let e=Ts(r);n.structuredContent=e??{},Ds(r,n.structuredContent)===!1?(n.structuredContent=Os(n.structuredContent)?n.structuredContent:{},i=`final-validation-failed`):i??=`final-heal`}return n});return e.critical=!0,e}function Ts(e){try{return ks(e)??{}}catch{return{}}}function Es(e,t){if(Ds(e,t)!==!1)return{structuredContent:t,action:null};try{let n=Ts(e);if(Os(n)&&Os(t)){let r={...n,...t};if(Ds(e,r)!==!1)return{structuredContent:r,action:`heal`}}return{structuredContent:n,action:`fallback-zero-value`}}catch{return{structuredContent:t,action:null}}}function Ds(e,t){let n=e.safeParse;if(typeof n==`function`)try{return n(t).success}catch{return}}function Os(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ks(e){if(!e)return{};if(e.anyOf){let t=e.anyOf.find(e=>e.type!==`null`);return t?ks(t):null}let t=e._def?.typeName;if(t&&!e.type)switch(t){case`ZodObject`:{let t={},n=null;try{n=e.shape??(typeof e._def?.shape==`function`?e._def.shape():e._def?.shape)}catch{n=null}if(n)for(let[e,r]of Object.entries(n))try{t[e]=ks(r)}catch{t[e]=null}return t}case`ZodArray`:return[];case`ZodString`:return``;case`ZodNumber`:return 0;case`ZodBoolean`:return!1;case`ZodNullable`:return null;case`ZodOptional`:return;case`ZodRecord`:return{};case`ZodEnum`:return e._def?.values?.[0]??``;default:return{}}switch(e.type){case`object`:{let t={},n=e.properties??e.shape;if(n)for(let[e,r]of Object.entries(n))t[e]=ks(r);return t}case`array`:return[];case`string`:return``;case`number`:case`integer`:return 0;case`boolean`:return!1;case`nullable`:return null;case`optional`:return;case`record`:return{};case`enum`:return e.options?.[0]??Object.values(e.enum??e._def?.entries??{})[0]??``;default:return{}}}function As(e){if(!e)return{};try{let t=ks(e);return Os(t)?t:{}}catch{return{}}}const js=Symbol(`toolPipelineState`);function Ms(e){return e[js]}function Ns(e,t){e[js]=t}function Ps(e,t){return t?async(...n)=>{let r=await e(...n);if(!r||typeof r!=`object`)return r;let i=r;return!(`content`in i)||i.structuredContent!=null&&typeof i.structuredContent==`object`?r:(i.structuredContent=As(t),i.structuredContent??={},r)}:e}function Fs(e,t,n=``,r,i){let a=Ms(e);if(a){a.pipeline=t,a.prefix=n,r!==void 0&&(a.eventBus=r),i!==void 0&&(a.workspaceId=i);return}let o={originalRegisterTool:e.registerTool.bind(e),pipeline:t,prefix:n,eventBus:r,workspaceId:i};Ns(e,o),e.registerTool=(n,r,i)=>{let a=Ms(e),s=a?.prefix?`${a.prefix}${n}`:n;if(!i)return a?.originalRegisterTool(s,r);let c=r?.outputSchema;if((a?.pipeline??t).getMiddlewareNames().length===0){let e=Ps(i,c);return a?.originalRegisterTool(s,r,e)}let l=U(n),u=a??o,d=Ps(u.pipeline.wrap(n,i,r,l,u.eventBus,u.workspaceId),c);return a?.originalRegisterTool(s,r,d)}}const Is={analyze:1,audit:1,check:2,codemod:2,config:0,delegate:3,digest:1,env:0,eval:2,evidence_map:2,file_summary:1,find:1,flow:3,forge_ground:2,git:1,graph:1,measure:1,onboard:3,parse_output:1,present:1,process:3,produce_knowledge:3,queue:3,reindex:3,rename:2,replay:1,restore:2,scope_map:1,search:1,session:2,status:0,symbol:1,test_run:2,trace:1,web_fetch:1,web_search:1};function Ls(e,t){return e.filter(e=>(Is[e]??0)<=t)}const Rs=new Set([`status`,`config`]),zs={full:{description:`All tools enabled (default)`,includeCategories:[]},safe:{description:`Read-only tools — no file/state modifications`,includeCategories:[`search`,`analysis`,`compression`,`utilities`,`system`,`git`,`flow`],excludeTools:[`reindex`,`onboard`]},research:{description:`Search, analysis, knowledge, and web access`,includeCategories:[`search`,`analysis`,`knowledge`,`compression`,`web`,`system`,`flow`]},minimal:{description:`Essential tools only — search, status, basic operations`,includeCategories:[`search`,`system`],includeTools:[`file_summary`,`check`,`test_run`]},discovery:{description:`Full toolset plus discovery-oriented meta-tools for guided tool exploration`,includeCategories:[],includeTools:[`list_tools`,`describe_tool`,`search_tools`]}};function Bs(e,t){let n=zs[e];if(n)return n;let r=t?.[e];if(r)return r;throw Error(`Unknown tool profile: ${e}`)}function Vs(e,t,n){return t.includes(`*`)?!0:(n[e]?.category??[]).some(e=>t.includes(e))}function Hs(e,t,n,r){if(t.includes(`*`)){for(let t of n)e.add(t);return}for(let i of n)Vs(i,t,r)&&e.add(i)}function Us(e,t,n){if(t.includes(`*`)){e.clear();return}for(let r of[...e])Vs(r,t,n)&&e.delete(r)}function Ws(e,t,n){if(!e||e.length===0||e.includes(`*`))return new Set(t);let r=new Set;return Hs(r,e,t,n),r}function Gs(e,t){return e===void 0?t:t===void 0?e:Math.min(e,t)}function Ks(e,t){for(let n of[...e])t[n]?.annotations?.readOnlyHint===!1&&e.delete(n)}function qs(e,t,n=0,r=[]){if(n>10)throw Error(`Tool profile inheritance exceeded max depth 10: ${[...r,e].join(` -> `)}`);if(r.includes(e))throw Error(`Tool profile inheritance cycle detected: ${[...r,e].join(` -> `)}`);let i=Bs(e,t);return Gs(i.extends?qs(i.extends,t,n+1,[...r,e]):void 0,i.maxTier)}function Js(e,t,n,r){let i=(e,a,o)=>{if(a>10)throw Error(`Tool profile inheritance exceeded max depth 10: ${[...o,e].join(` -> `)}`);if(o.includes(e))throw Error(`Tool profile inheritance cycle detected: ${[...o,e].join(` -> `)}`);let s=Bs(e,r),c=[...o,e],l=s.extends?i(s.extends,a+1,c):Ws(s.includeCategories,t,n);s.extends&&s.includeCategories?.length&&Hs(l,s.includeCategories,t,n),s.excludeCategories?.length&&Us(l,s.excludeCategories,n);for(let e of s.includeTools??[])l.add(e);for(let e of s.excludeTools??[])l.delete(e);return l},a=i(e,0,[]),o=qs(e,r);if(o!==void 0){let e=Ls([...a],o);a.clear();for(let t of e)a.add(t)}for(let e of Rs)a.add(e);return e===`safe`&&Ks(a,n),a}const Ys=new Set([`search`,`analysis`,`knowledge`,`compression`,`forge`,`presentation`,`execution`,`manipulation`,`session`,`git`,`process`,`system`,`meta`,`utilities`,`web`,`queue`,`flow`]);function Xs(e,t,n,r){let i=process.env.AIKIT_TOOLSET||e.toolProfile||`full`,a=Js(i,t,n,r);if(e.features&&e.features.length>0){let i=e.features.filter(e=>!Ys.has(e));if(i.length>0)throw Error(`Unknown feature group(s): ${i.join(`, `)}. Valid categories: ${[...Ys].join(`, `)}`);let o={description:`Synthetic profile from features config`,includeCategories:e.features},s=Js(`_features`,t,n,{...r,_features:o});for(let e of a)!s.has(e)&&!Rs.has(e)&&a.delete(e)}if(e.readOnly)for(let e of[...a])n[e]?.annotations?.readOnlyHint===!1&&!Rs.has(e)&&a.delete(e);for(let e of Rs)a.add(e);return i===`safe`&&Ks(a,n),a}const Zs=R.object({mode:R.enum([`wasm`,`regex`,`unknown`]),reason:R.string(),pathsChecked:R.array(R.object({path:R.string(),exists:R.boolean()})),os:R.string(),arch:R.string(),nodeVersion:R.string(),webTreeSitterImportable:R.boolean(),healAttempted:R.boolean(),healSuccess:R.boolean(),healError:R.string().nullable(),initError:R.string().nullable(),wasmDir:R.string().nullable(),grammarCount:R.number()}),Qs=R.object({kind:R.enum([`onboard`,`reindex`,`handoff`,`proceed`]),reason:R.string()}),$s=R.object({title:R.string(),insight:R.string(),confidence:R.number()}),ec=R.object({lessons:R.array($s),conventions:R.array(R.object({title:R.string(),preview:R.string()})),checkpoint:R.string().nullable()});R.object({totalRecords:R.number(),totalFiles:R.number(),lastIndexedAt:R.string().nullable(),onboarded:R.boolean(),onboardDir:R.string(),contentTypes:R.record(R.string(),R.number()),wasmAvailable:R.boolean(),wasmDiagnostics:Zs,graphStats:R.object({nodes:R.number(),edges:R.number()}).nullable(),curatedCount:R.number(),serverVersion:R.string(),scaffoldVersion:R.string().nullable(),workspaceScaffoldVersion:R.string().nullable(),upgradeAvailable:R.boolean(),sessionTokens:R.object({callCount:R.number(),totalInputChars:R.number(),totalOutputChars:R.number(),estInputTokens:R.number(),estTotalTokens:R.number(),startTime:R.string()}).optional(),storeBackend:R.string().optional(),storeDiagnostics:R.object({adapterType:R.string(),vectorSearchEnabled:R.boolean(),ftsEnabled:R.boolean(),degradedMode:R.boolean(),dbPath:R.string(),dbSizeBytes:R.number().nullable(),embeddingDim:R.number(),vectorDtype:R.string()}).nullable().optional(),contextPressure:R.number().min(0).max(100).describe(`0–100 score indicating AI Kit saturation`),nextAction:Qs,prelude:ec.nullable().optional()}).catchall(R.any()),R.object({ok:R.boolean(),checks:R.array(R.object({name:R.string(),ok:R.boolean(),message:R.string().optional()}))});const tc=R.object({summary:R.object({totalFiles:R.number(),totalLines:R.number(),totalCodeLines:R.number(),totalFunctions:R.number(),avgComplexity:R.number(),maxComplexity:R.object({value:R.number(),file:R.string()})}),files:R.array(R.object({path:R.string(),lines:R.number(),code:R.number(),complexity:R.number(),functions:R.number()}))}),nc=R.object({platform:R.string(),arch:R.string(),nodeVersion:R.string(),cwd:R.string(),cpus:R.number(),memoryFreeGb:R.number(),memoryTotalGb:R.number()});R.object({iso:R.string(),unix:R.number(),timezone:R.string(),formatted:R.string()});const rc=R.object({passed:R.boolean(),errorCount:R.number(),warningCount:R.number(),topErrors:R.array(R.string())}),ic=R.object({passed:R.boolean(),tsc:rc,biome:rc}),ac=R.object({name:R.string(),path:R.string(),depth:R.number()}),oc=R.object({name:R.string(),definedIn:R.object({path:R.string(),line:R.number(),kind:R.string(),signature:R.string().optional()}).nullable(),importedBy:R.array(R.object({path:R.string(),line:R.number(),importStatement:R.string()})),referencedIn:R.array(R.object({path:R.string(),line:R.number(),context:R.string(),scope:R.string().optional()})),graphContext:R.object({definingModule:R.string().optional(),importedByModules:R.array(R.string()),siblingSymbols:R.array(R.string())}).nullable(),trace:R.object({callers:R.array(ac),callees:R.array(ac)}).nullable(),confidence:R.number().nullable(),method:R.string().nullable(),rationale:R.string().nullable(),error:R.string().optional()}),sc=R.object({symbols:R.array(oc)}),cc=R.object({sourcePath:R.string(),contentType:R.string(),score:R.number(),headingPath:R.string().optional(),startLine:R.number().optional(),endLine:R.number().optional(),origin:R.string().optional(),category:R.string().optional(),tags:R.array(R.string()).optional()}),lc=R.object({results:R.array(cc),totalResults:R.number(),searchMode:R.string(),query:R.string(),ref:R.string().optional().describe(`Reusable cache reference for later compact(ref, query)`)}),uc=R.object({path:R.string(),line:R.number().optional(),matchType:R.string(),preview:R.string()}),dc=R.object({matches:R.array(uc),totalMatches:R.number(),pattern:R.string(),truncated:R.boolean(),ref:R.string().optional().describe(`Reusable cache reference for later compact(ref, query)`)}),fc=R.object({path:R.string(),relevance:R.number(),estimatedTokens:R.number(),focusLines:R.array(R.string()).optional()}),pc=R.object({files:R.array(fc),totalFiles:R.number(),totalEstimatedTokens:R.number(),task:R.string()}),mc=R.object({path:R.string(),impact:R.string(),reason:R.string()});R.object({changedFiles:R.array(R.string()),affectedFiles:R.array(mc),totalAffected:R.number(),riskLevel:R.string()});const hc=R.object({name:R.string(),passed:R.boolean(),message:R.string().optional(),severity:R.string().optional()}),gc=R.object({passed:R.boolean(),score:R.number(),checks:R.array(hc),summary:R.string()}),_c=R.object({id:R.string(),name:R.string(),type:R.string(),sourcePath:R.string().optional()}),vc=R.object({fromId:R.string(),toId:R.string(),fromName:R.string(),toName:R.string(),type:R.string()}),yc=R.object({id:R.string(),name:R.string(),type:R.string()}),bc=R.object({id:R.string(),nodeCount:R.number(),types:R.record(R.string(),R.number()),samples:R.array(yc)}),xc=R.object({nodes:R.array(_c),edges:R.array(vc),communities:R.array(bc).optional(),totalNodes:R.number(),totalEdges:R.number(),query:R.string()});R.object({symbols:R.array(R.object({name:R.string(),path:R.string(),line:R.number().optional(),kind:R.string()})),totalDead:R.number()});const Sc=R.object({gitRoot:R.string(),branch:R.string(),commitCount:R.number(),hasUncommitted:R.boolean(),recentCommits:R.array(R.object({hash:R.string(),message:R.string(),author:R.string(),date:R.string()}))}),Cc=R.object({sourceId:R.string(),value:R.string()}),wc=R.object({id:R.string(),originalChars:R.number(),keptChars:R.number(),segmentsKept:R.number(),segmentsTotal:R.number()}),Tc=R.object({text:R.string().describe(`The compressed digest text output`),ref:R.string().optional().describe(`Reusable cache reference`),fields:R.record(R.string(),R.array(Cc)),sourceStats:R.array(wc),totalOriginalChars:R.number(),totalCompressedChars:R.number(),ratio:R.number()}),Ec=R.object({passed:R.boolean(),totalTests:R.number(),passedTests:R.number(),failedTests:R.number(),skippedTests:R.number(),duration:R.number().describe(`Duration in milliseconds`),failures:R.array(R.object({name:R.string(),message:R.string(),file:R.string().optional()}))}),Dc=M(`utils:enrich`);async function G(e,t){let n={curated:[],graph:[]},r=t.limit??3,[i,a]=await Promise.allSettled([Oc(e,t.query,r),kc(e,t.filePath)]);return i.status===`fulfilled`?n.curated=i.value:Dc.debug(`Curated enrichment failed`,{error:i.reason}),a.status===`fulfilled`?n.graph=a.value:Dc.debug(`Graph enrichment failed`,{error:a.reason}),n}async function Oc(e,t,n){if(!e.store||!t)return[];try{let r=await e.store.ftsSearch(t,{origin:`curated`,limit:n});if(r.length>0)return r.map(e=>jc(e.record));if(e.embedder){let r=await e.embedder.embedQuery(t);return(await e.store.search(r,{origin:`curated`,limit:n,minScore:.3})).map(e=>jc(e.record))}return[]}catch(e){return Dc.debug(`Curated enrichment failed`,{error:e}),[]}}async function kc(e,t){if(!e.graphStore||!t)return[];try{let n=await e.graphStore.findNodes({sourcePath:t,limit:1});if(n.length===0){let r=t.split(/[/\\]/).pop()?.replace(/\.\w+$/,``)||``;if(!r)return[];let i=await e.graphStore.findNodes({namePattern:r,type:`module`,limit:1});if(i.length===0)return[];n.push(i[0])}let r=n[0],i=await e.graphStore.getNeighbors(r.id,{direction:`both`,limit:10}),a=[];for(let e of i.edges){let t=e.fromId===r.id?e.toId:e.fromId,n=i.nodes.find(e=>e.id===t);if(!n)continue;let o=e.fromId===r.id?`->`:`<-`;a.push(`${o} ${e.type}: ${n.name} (${n.type})`)}return a}catch(e){return Dc.debug(`Graph enrichment failed`,{error:e}),[]}}function Ac(e){let t=[];if(e.curated.length>0){t.push(`**Curated Knowledge:**`);for(let n of e.curated)t.push(`- ${n}`)}if(e.graph.length>0){t.push(`**Graph Context:**`);for(let n of e.graph)t.push(`- ${n}`)}return t.length===0?``:`\n\n---\n### Enrichment\n${t.join(`
37
- `)}`}function jc(e){let t=Mc(e.metadata,`title`)||e.sourcePath||`Untitled`;return`[${Mc(e.metadata,`category`)}] ${t}: ${e.content.slice(0,200)}`}function Mc(e,t){let n=e?.[t];return typeof n==`string`?n:``}function K(e,t,n){return{content:[{type:`text`,text:`[ERROR:${e}] ${t}`}],isError:!0,...n==null?{}:{structuredContent:n}}}function q(e,t){return async(n,r)=>{let i=Date.now(),a=await t(n,r),o=Date.now()-i;return a._meta={...a._meta??{},durationMs:o,toolName:e},a}}const Nc=M(`tools`),Pc=R.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`);function Fc(e,t){return t?Bn(e,t):e}function Ic(){let e=[];return lr.get()||e.push(`Tree-sitter unavailable — using regex fallback, symbol/pattern confidence reduced`),e.length===0?``:`\n\n> **⚠ Caveats:** ${e.join(`; `)}`}async function Lc(e,t,n,r,i){try{let a=`produced/analysis/${n}/${we(r,12)}.md`,o=Ye(`sha256`).update(i).digest(`hex`).slice(0,16),s=new Date().toISOString(),c=i.length>2e3?i.split(/(?=^## )/m).filter(e=>e.trim().length>0):[i],l=c.map((e,t)=>({id:Ye(`sha256`).update(`${a}::${t}`).digest(`hex`).slice(0,16),content:e.trim(),sourcePath:a,contentType:`produced-knowledge`,chunkIndex:t,totalChunks:c.length,startLine:0,endLine:0,fileHash:o,indexedAt:s,origin:`produced`,tags:[`analysis`,n],category:`analysis`,version:1})),u=await t.embedBatch(l.map(e=>e.content));await e.upsert(l,u),Nc.info(`Auto-persisted analysis`,{analyzerName:n,chunkCount:l.length})}catch(e){Nc.warn(`Auto-persist analysis failed`,{analyzerName:n,...N(e)})}}const Rc=R.enum([`structure`,`dependencies`,`symbols`,`patterns`,`entry_points`,`diagram`]),zc=R.string().describe(`Root path to analyze`),Bc=R.boolean().default(!1).describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens. Default false — set true when you need stored decisions, conventions, or relationship context.`),Vc=R.object({path:zc,max_depth:R.number().min(1).max(10).default(6).describe(`Maximum directory depth`),format:R.enum([`json`,`markdown`]).default(`markdown`).describe(`Output format`),max_tokens:Pc,enrich:Bc}),Hc=R.object({path:zc,format:R.enum([`json`,`markdown`,`mermaid`]).default(`markdown`).describe(`Output format`),max_tokens:Pc,enrich:Bc}),Uc=R.object({path:zc,filter:R.string().optional().describe(`Filter symbols by name substring`),format:R.enum([`json`,`markdown`]).default(`markdown`).describe(`Output format`),enrich:Bc}),Wc=R.object({path:zc,enrich:Bc}),Gc=R.object({path:zc,enrich:Bc}),Kc=R.object({path:zc,diagram_type:R.enum([`architecture`,`dependencies`]).default(`architecture`).describe(`Type of diagram`),enrich:Bc}),qc=R.object({path:zc,aspect:Rc.describe(`Analysis aspect to execute`),max_depth:R.number().min(1).max(10).optional(),format:R.enum([`json`,`markdown`,`mermaid`]).optional(),filter:R.string().optional().describe(`Filter symbols by name substring`),diagram_type:R.enum([`architecture`,`dependencies`]).optional().describe(`Type of diagram when aspect="diagram"`)}),Jc=R.object({items:R.array(qc).min(1).describe(`Array of analysis requests to run in batch.`),max_tokens:Pc,enrich:Bc});async function Yc(e,t,n,r){return!n||!r?e:e+Ac(await G(r,{query:t,filePath:t}))}async function Xc(e,{store:t,embedder:n,enrichDeps:r}){let i=new or,{path:a,max_depth:o,format:s,max_tokens:c,enrich:l}=Vc.parse(e),u=await i.analyze(a,{format:s,maxDepth:o,maxTokens:c});Lc(t,n,`structure`,a,u.output);let d=u.data;return{content:[{type:`text`,text:Fc(await Yc(u.output+'\n\n---\n_Analysis auto-saved to AI Kit memory. Next: Use `analyze({ aspect: "dependencies", ... })` for import graphs, or `analyze({ aspect: "patterns", ... })` to detect architecture patterns._',a,l,r),c)}],structuredContent:{files:d.fileCount??u.meta.fileCount,packages:d.packageCount??0,languages:d.languages??{},tree:u.output.slice(0,2e3)}}}async function Zc(e,{store:t,embedder:n,enrichDeps:r}){let i=new tr,{path:a,format:o,max_tokens:s,enrich:c}=Hc.parse(e),l=await i.analyze(a,{format:o});return Lc(t,n,`dependencies`,a,l.output),{content:[{type:`text`,text:Fc(await Yc(l.output+'\n\n---\n_Analysis auto-saved to AI Kit memory. Next: Use `analyze({ aspect: "symbols", ... })` to explore exported symbols, or `analyze({ aspect: "diagram", ... })` for visual representation._',a,c,r),s)}]}}async function Qc(e,{store:t,embedder:n,enrichDeps:r}){let i=new sr,{path:a,filter:o,format:s,enrich:c}=Uc.parse(e),l=await i.analyze(a,{format:s,filter:o});return Lc(t,n,`symbols`,a,l.output),{content:[{type:`text`,text:await Yc(l.output+Ic()+'\n\n---\n_Analysis auto-saved to AI Kit memory. Next: Use `analyze({ aspect: "dependencies", ... })` to see import relationships, or `search` to find usage patterns._',a,c,r)}]}}async function $c(e,{store:t,embedder:n,enrichDeps:r}){let i=new ar,{path:a,enrich:o}=Wc.parse(e),s=await i.analyze(a);return Lc(t,n,`patterns`,a,s.output),{content:[{type:`text`,text:await Yc(s.output+Ic()+'\n\n---\n_Analysis auto-saved to AI Kit memory. Next: Use `analyze({ aspect: "entry_points", ... })` to find Lambda handlers and main exports, or `produce_knowledge` for full analysis._',a,o,r)}]}}async function el(e,{store:t,embedder:n,enrichDeps:r}){let i=new rr,{path:a,enrich:o}=Gc.parse(e),s=await i.analyze(a);return Lc(t,n,`entry-points`,a,s.output),{content:[{type:`text`,text:await Yc(s.output+Ic()+'\n\n---\n_Analysis auto-saved to AI Kit memory. Next: Use `analyze({ aspect: "dependencies", ... })` to see what each entry point imports, or `produce_knowledge` for comprehensive analysis._',a,o,r)}]}}async function tl(e,{store:t,embedder:n,enrichDeps:r}){let i=new nr,{path:a,diagram_type:o,enrich:s}=Kc.parse(e),c=await i.analyze(a,{diagramType:o});return Lc(t,n,`diagram`,a,c.output),{content:[{type:`text`,text:await Yc(c.output+'\n\n---\n_Analysis auto-saved to AI Kit memory. Next: Use `analyze({ aspect: "structure", ... })` for detailed file tree, or `produce_knowledge` for comprehensive analysis._',a,s,r)}]}}async function nl(e,t,n){switch(e){case`structure`:return Xc(t,n);case`dependencies`:return Zc(t,n);case`symbols`:return Qc(t,n);case`patterns`:return $c(t,n);case`entry_points`:return el(t,n);case`diagram`:return tl(t,n)}}function rl(e,t,n,r){let i=U(`analyze`);e.registerTool(`analyze`,{title:i.title,description:"Analyze a codebase using one of the supported aspects. Set `aspect` to structure, dependencies, symbols, patterns, entry_points, or diagram.",inputSchema:Jc.shape,annotations:i.annotations},q(`analyze`,async e=>{try{let i=Jc.parse(e);if(!i.items||i.items.length===0)return K(`VALIDATION`,`"items[]" is required.`);let a=await Promise.allSettled(i.items.map(async e=>{let a={...e,enrich:i.enrich,max_tokens:i.max_tokens};return nl(e.aspect,a,{store:t,embedder:n,enrichDeps:r})})),o=[],s=[];for(let e=0;e<a.length;e++){let t=a[e],n=i.items[e],r=`${n.aspect}:${n.path}`;if(t.status===`fulfilled`){let i=t.value.content[0]?.text??``;o.push(`## ${e+1}. ${r}\n${i}`),s.push({aspect:n.aspect,path:n.path,...`structuredContent`in t.value?t.value.structuredContent:{}})}else{let i=t.reason instanceof Error?t.reason.message:String(t.reason);o.push(`## ${e+1}. ${r}\nERROR: ${i}`),s.push({aspect:n.aspect,path:n.path,error:i})}}return{content:[{type:`text`,text:o.join(`
38
-
39
- `)}],structuredContent:{items:s}}}catch(e){return Nc.error(`Analysis failed`,N(e)),K(`INTERNAL`,`Analysis failed: ${e instanceof Error?e.message:String(e)}`)}}))}const il=M(`task-manager`);let al=0;function ol(e){let t=typeof e?.sendNotification==`function`;return{createTask(n,r){let i=`aikit-task-${++al}`,a=(n,r,a)=>{t&&e.sendNotification?.({method:`notifications/progress`,params:{progressToken:i,progress:n,total:r,...a?{message:a}:{}}}).catch(e=>{il.debug(`Progress notification failed`,{token:i,error:String(e)})})};return t&&il.debug(`Task created`,{token:i,title:n,totalSteps:r}),{progress(e,t){a(e,r,t??`${n}: step ${e+1}/${r}`)},complete(e){a(r,r,e??`${n}: complete`)},fail(e){a(r,r,e??`${n}: failed`)}}}}}const sl=M(`tools`);function cl(e,t,n,r){let i=U(`audit`);e.registerTool(`audit`,{title:i.title,description:`Run a unified audit: structure, dependencies, patterns, health, dead_symbols, check, entry_points. Returns synthesized report with score, recommendations, and next steps. 6 round-trips → 1.`,outputSchema:gc,inputSchema:{path:R.string().default(`.`).describe(`Root path to audit`),checks:R.array(R.enum([`structure`,`dependencies`,`patterns`,`health`,`dead_symbols`,`check`,`entry_points`])).optional().describe(`Which checks to run (default: all)`),detail:R.enum(j).optional().describe(`'efficient' for overview (~500 tokens), 'full' includes pattern table`)},annotations:i.annotations},async({path:e,checks:i,detail:a},o)=>{try{let s=await rt(t,n,{path:e,checks:i,detail:a??r??`efficient`});return ol(o).createTask(`Audit`,1).complete(`Audit complete: ${s.data?.recommendations?.length??0} recommendations`),{content:[{type:`text`,text:s.ok?`${s.summary}\n\n---\n_Audit score: ${s.data?.score}/100 | ${s.meta.durationMs}ms${s.next&&s.next.length>0?` | Next: ${s.next.map(e=>`\`${e.tool}\` (${e.reason})`).join(`, `)}`:``}_`:s.error?.message??`Audit failed`}],isError:!s.ok,...s.ok&&s.data?{structuredContent:{passed:s.ok,score:s.data.score??0,checks:(s.data.recommendations??[]).map(e=>({name:e.area,passed:e.priority!==`high`,message:e.message,severity:e.priority})),summary:s.summary??``}}:{}}}catch(e){return sl.error(`Audit failed`,N(e)),K(`INTERNAL`,`Audit failed: ${e instanceof Error?e.message:String(e)}`)}})}const ll=M(`tools`);function ul(e){if(!e?.enabled)return;let t=process.env.AIKIT_ER_API_KEY;if(!t){ll.warn(`ER bridge enabled but AIKIT_ER_API_KEY not set; disabling`);return}return{enabled:!0,baseUrl:e.baseUrl,apiKey:t,timeoutMs:e.timeoutMs??5e3,cacheTtlMs:e.cacheTtlMs??360*60*1e3,cacheMaxEntries:e.cacheMaxEntries??100,fallbackThreshold:e.fallbackThreshold??.45}}function dl(e){let t=ul(e);if(t)try{let e=new fr(t),n=new dr({maxEntries:t.cacheMaxEntries,defaultTtl:t.cacheTtlMs}),r=new hr(e);try{let e=new URL(t.baseUrl).hostname;ll.info(`ER bridge initialized`,{host:e})}catch{ll.info(`ER bridge initialized`)}return{client:e,cache:n,pushAdapter:r,config:t}}catch(e){ll.warn(`ER bridge initialization failed`,N(e));return}}function fl(e,t,n){let r=U(`er_push`);e.registerTool(`er_push`,{title:r.title,description:`Push a curated knowledge entry to Enterprise RAG. The entry is stored via ER's curated_remember tool and becomes immediately searchable in the enterprise AI Kit.`,inputSchema:{title:R.string().min(3).max(120).describe(`Title for the knowledge entry`),content:R.string().min(10).max(1e5).describe(`Markdown content to push (max 100KB)`),category:R.string().regex(/^[a-z][a-z0-9-]*$/).default(`conventions`).describe(`Category slug (e.g., "decisions", "patterns", "conventions")`),tags:R.array(R.string()).default([]).describe(`Optional tags`),rule_id:R.string().optional().describe(`ID of the classification rule that motivated this push (from remember classification signals). Improves rule effectiveness tracking.`)},annotations:r.annotations},q(`er_push`,async({title:e,content:r,category:i,tags:a,rule_id:o})=>{try{let s=`${i}/${e.toLowerCase().replace(/[^a-z0-9]+/g,`-`)}`,c=await t.pushAdapter.push(s,{title:e,content:r,category:i,tags:a});return c.pushed?(n&&n.recordPush(s,c.pushed,o),{content:[{type:`text`,text:`Pushed to ER: **${e}**\n\nRemote path: \`${c.remotePath??`unknown`}\`\nTimestamp: ${c.timestamp}\n\n---\n_Next: Use \`er_pull\` to verify the entry is searchable in ER, or \`er_sync_status\` to see push history._`}]}):(n&&n.recordPush(s,!1,o),K(`INTERNAL`,`ER push failed: ${c.error??`Unknown error`}\n\n_The local AI Kit is unaffected. You can retry or check ER health with \`er_sync_status\`._`))}catch(t){if(ll.error(`ER push failed`,N(t)),n){let t=`${i}/${e.toLowerCase().replace(/[^a-z0-9]+/g,`-`)}`;n.recordPush(t,!1,o)}return K(`INTERNAL`,`ER push failed: operation unsuccessful
40
-
41
- _The local AI Kit is unaffected. You can retry or check ER health with \`er_sync_status\`._`)}}))}function pl(e,t){let n=U(`er_pull`);e.registerTool(`er_pull`,{title:n.title,description:`Explicitly search the Enterprise RAG AI Kit. Returns results from the enterprise system only (not local AI Kit). Uses a cache with 6-hour TTL to reduce API calls.`,inputSchema:{query:R.string().min(1).max(2e3).describe(`Search query for Enterprise RAG AI Kit (max 2000 chars)`),max_results:R.number().min(1).max(20).default(5).describe(`Maximum results to return`),bypass_cache:R.boolean().default(!0).describe(`Skip cache and fetch fresh results from ER (default: true per DR-001)`)},annotations:n.annotations},q(`er_pull`,async({query:e,max_results:n,bypass_cache:r})=>{try{if(!r){let r=t.cache.get(e);if(r)return{content:[{type:`text`,text:`${r.slice(0,n).map((e,t)=>`### Result ${t+1} (score: ${e.score.toFixed(3)}, source: ER cached)\n- **Source**: ${e.sourcePath}\n\n${e.content}`).join(`
42
-
43
- ---
44
-
45
- `)}\n\n---\n_Source: ER cache (${r.length} cached results) | Use \`bypass_cache: true\` for fresh results_`}]}}let i=await t.client.pull(e,n);return i.length>0&&t.cache.set(e,i),i.length===0?{content:[{type:`text`,text:`No results found in Enterprise RAG for the given query.`}]}:{content:[{type:`text`,text:`${i.map((e,t)=>`### Result ${t+1} (score: ${e.score.toFixed(3)}, source: ER)\n- **Source**: ${e.sourcePath}\n\n${e.content}`).join(`
46
-
47
- ---
48
-
49
- `)}\n\n---\n_Source: Enterprise RAG (${i.length} results) | Results cached for ${Math.floor(t.config.cacheTtlMs/36e5)}h_`}]}}catch(e){return ll.error(`ER pull failed`,N(e)),K(`INTERNAL`,`ER pull failed: search request unsuccessful
50
-
51
- _Enterprise RAG may be unavailable. Local AI Kit search is unaffected._`)}}))}function ml(e,t){let n=U(`er_sync_status`);e.registerTool(`er_sync_status`,{title:n.title,description:`Show the status of the Enterprise RAG bridge: health, cache stats, and push history.`,inputSchema:{check_health:R.boolean().default(!0).describe(`Whether to ping ER health endpoint (adds latency)`)},annotations:n.annotations},q(`er_sync_status`,async({check_health:e})=>{try{let n=t.cache.stats(),r=t.pushAdapter.getStatus(),i=new URL(t.config.baseUrl),a=`${i.protocol}//${i.hostname}${i.port?`:${i.port}`:``}`,o=`_Health check skipped_`;if(e){let e=await t.client.health();o=e.healthy?`✅ Healthy (HTTP ${e.status})`:`❌ Unhealthy${e.status?` (HTTP ${e.status})`:``}`}let s=[`## ER Bridge Status
52
- `,`**Endpoint**: \`${a}\``,`**Health**: ${o}`,`**Threshold**: ${t.config.fallbackThreshold} (vector similarity for auto-fallback)`,``,`### Cache`,`- Entries: ${n.size} / ${n.maxEntries}`,`- TTL: ${Math.floor(n.defaultTtlMs/36e5)}h`,``,`### Push History`,`- Total pushed: ${r.totalPushed}`,`- Successful: ${r.successCount}`,`- Failed: ${r.failCount}`];return r.lastPush&&s.push(`- Last push: "${r.lastPush.title}" at ${r.lastPush.pushedAt} (${r.lastPush.status})`),s.push("\n---\n_Next: Use `er_push` to send knowledge to ER, or `er_pull` to search ER._"),{content:[{type:`text`,text:s.join(`
53
- `)}]}}catch(e){return ll.error(`ER sync status failed`,N(e)),K(`INTERNAL`,`ER sync status failed: ${e instanceof Error?e.message:String(e)}`)}}))}function J(e){return String(e??``).replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}const hl=R.object({action:R.enum([`view`,`update`]).default(`view`).describe(`Action to perform: view current configuration or update it`),updates:R.record(R.string(),R.unknown()).optional().describe(`Partial configuration to merge when action is "update". Supports nested paths like { "indexing": { "chunkSize": 2000 } }`)}),gl=M(`config-tool`),_l=`ui://aikit/config.html`,vl=[`serverName`,`toolPrefix`,`autoIndex`,`sources`,`indexing`,`tokenBudget`];function yl(){let e=process.env.AIKIT_CONFIG_PATH;if(e&&P(e))return e;let t=De();if(t){let e=L(t,`aikit.config.json`);if(P(e))return e}return``}function bl(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function xl(e,t){let n={...e};for(let[e,r]of Object.entries(t)){let t=n[e];if(bl(t)&&bl(r)){n[e]=xl(t,r);continue}n[e]=r}return n}function Sl(e){return e===void 0?`undefined`:JSON.stringify(e)}function Cl(e,t,n,r=``){let i=[];for(let[a,o]of Object.entries(n)){let n=r?`${r}.${a}`:a,s=e[a],c=t[a];if(bl(o)&&bl(s)&&bl(c)){i.push(...Cl(s,c,o,n));continue}Sl(s)!==Sl(c)&&i.push(`- ${n}: ${Sl(s)} -> ${Sl(c)}`)}return i}function wl(e){let t=[];for(let[n,r]of Object.entries(e)){if(n===`store`||n===`embedding`||n===`er`){t.push(`Field "${n}" cannot be updated through this tool because it requires a restart.`);continue}if(n===`onboardDir`||n===`stateDir`||n===`curated`){t.push(`Field "${n}" cannot be updated through this tool because it requires a restart.`);continue}if(n===`autoIndex`){typeof r!=`boolean`&&t.push(`autoIndex must be a boolean.`);continue}if(n===`serverName`||n===`toolPrefix`){typeof r!=`string`&&t.push(`${n} must be a string.`);continue}if(n===`sources`){(!Array.isArray(r)||r.length===0)&&t.push(`sources must be a non-empty array.`);continue}if(n===`indexing`){if(!bl(r)){t.push(`indexing must be an object.`);continue}for(let[e,n]of Object.entries(r)){if(e!==`chunkSize`&&e!==`chunkOverlap`&&e!==`minChunkSize`&&e!==`concurrency`){t.push(`indexing.${e} is not updatable through this tool.`);continue}(typeof n!=`number`||!Number.isFinite(n)||n<=0)&&t.push(`indexing.${e} must be a positive number.`)}continue}if(n===`tokenBudget`){(typeof r!=`string`||!j.includes(r))&&t.push(`tokenBudget must be one of: ${j.join(`, `)}.`);continue}t.push(`Field "${n}" is not updatable through this tool.`)}return t}function Tl(e){let t=[];if(`autoIndex`in e&&typeof e.autoIndex!=`boolean`&&t.push(`autoIndex must be a boolean.`),`serverName`in e&&e.serverName!==void 0&&typeof e.serverName!=`string`&&t.push(`serverName must be a string.`),`toolPrefix`in e&&e.toolPrefix!==void 0&&typeof e.toolPrefix!=`string`&&t.push(`toolPrefix must be a string.`),(!Array.isArray(e.sources)||e.sources.length===0)&&t.push(`sources must be a non-empty array.`),!bl(e.indexing))return t.push(`indexing must be an object.`),t;for(let n of[`chunkSize`,`chunkOverlap`,`minChunkSize`,`concurrency`]){let r=e.indexing[n];r!==void 0&&(typeof r!=`number`||!Number.isFinite(r)||r<=0)&&t.push(`indexing.${n} must be a positive number.`)}return t}function El(e){let t=JSON.parse(F(e,`utf-8`));if(!bl(t))throw Error(`Config file must contain a JSON object.`);return t}function Dl(e,t){return[`AI Kit Configuration`,`Config file: ${t}`,``,JSON.stringify(e,null,2)].join(`
54
- `)}function Ol(e){return e===void 0?``:bl(e)||Array.isArray(e)?JSON.stringify(e,null,2):String(e)}function kl(e){let t=e.metrics??[],n={success:`#22c55e`,warning:`#f59e0b`,error:`#ef4444`,info:`#38bdf8`},r={up:`↑`,down:`↓`,neutral:`→`};return`
55
- <style>
56
- .db-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px}
57
- .db-card{padding:14px;border:1px solid var(--aikit-border,#3c3c3c);border-left-width:4px;border-radius:8px;background:var(--aikit-surface,#252526)}
58
- .db-label{color:var(--aikit-muted,#9ca3af);font:600 11px var(--aikit-font-sans,system-ui,sans-serif);text-transform:uppercase;letter-spacing:.06em}
59
- .db-value{color:var(--aikit-text,#e5e7eb);font:700 24px var(--aikit-font-sans,system-ui,sans-serif);margin-top:6px}
60
- .db-trend{font:600 12px var(--aikit-font-sans,system-ui,sans-serif);margin-left:8px}
61
- .db-trend.up{color:#22c55e}.db-trend.down{color:#ef4444}.db-trend.neutral{color:#9ca3af}
62
- .db-progress{height:6px;background:var(--aikit-surface2,#2d2d30);border-radius:3px;margin-top:8px;overflow:hidden}
63
- .db-progress-bar{height:100%;border-radius:3px;transition:width .3s}
64
- .db-list{margin-top:8px;display:grid;gap:4px}
65
- .db-list-row{display:flex;justify-content:space-between;padding:4px 0;color:var(--aikit-muted,#9ca3af);font:400 12px var(--aikit-font-sans,system-ui,sans-serif);border-bottom:1px solid var(--aikit-border,#3c3c3c)}
66
- </style>
67
- <div class="db-grid">${t.map(e=>{let t=n[e.status??`info`]??n.info,i=e.trend?`<span class="db-trend ${e.trend.direction}">${r[e.trend.direction]??``} ${J(e.trend.value)}</span>`:``,a=`<div class="db-value">${J(String(e.value))}</div>${i}`;return e.type===`progress`&&e.progress!=null&&(a+=`<div class="db-progress"><div class="db-progress-bar" style="width:${Math.min(100,Math.max(0,e.progress))}%;background:${t}"></div></div>`),e.type===`list`&&e.items?.length&&(a+=`<div class="db-list">${e.items.map(e=>`<div class="db-list-row"><span>${J(e.label)}</span><span>${J(e.value)}</span></div>`).join(``)}</div>`),`
68
- <div class="db-card" style="border-left-color:${t}">
69
- <div class="db-label">${J(e.label)}</div>
70
- ${a}
71
- </div>`}).join(``)}</div>`}function Al(e){let t=e.fields??[];return`
72
- <style>
73
- .fm-container{display:grid;grid-template-columns:1fr 280px;gap:24px}
74
- @media(max-width:640px){.fm-container{grid-template-columns:1fr}}
75
- .fm-fields{display:flex;flex-direction:column;gap:16px}
76
- .fm-group{display:flex;flex-direction:column;gap:5px}
77
- .fm-label{font-size:11px;color:var(--aikit-muted);font-weight:600;text-transform:uppercase;letter-spacing:.5px}
78
- .fm-input{padding:9px 14px;background:var(--aikit-surface);border:1px solid var(--aikit-border);
79
- border-radius:8px;color:var(--aikit-text);font-size:13px;outline:none;font-family:inherit;width:100%;box-sizing:border-box}
80
- .fm-input:focus{border-color:var(--aikit-accent)}
81
- .fm-textarea{resize:vertical;min-height:80px}
82
- .fm-multi{display:flex;flex-wrap:wrap;gap:10px;padding:4px 0}
83
- .fm-check-label{display:flex;align-items:center;gap:4px;font-size:13px;color:var(--aikit-text);cursor:pointer}
84
- .fm-check-label input{accent-color:var(--aikit-accent)}
85
- .fm-submit{margin-top:8px;width:100%;padding:10px;background:var(--aikit-accent);color:#fff;
86
- border:none;border-radius:8px;cursor:pointer;font-size:14px;font-weight:600}
87
- .fm-submit:hover{filter:brightness(1.1)}
88
- .fm-preview{background:var(--aikit-surface);border:1px solid var(--aikit-border);border-radius:10px;
89
- padding:16px;height:fit-content;position:sticky;top:20px}
90
- .fm-preview-title{font-size:11px;color:var(--aikit-muted);text-transform:uppercase;
91
- letter-spacing:.5px;margin-bottom:10px}
92
- .fm-preview-json{font-size:12px;color:var(--aikit-text);margin:0;white-space:pre-wrap;
93
- word-break:break-all;font-family:'SF Mono',Consolas,monospace;line-height:1.5}
94
- </style>
95
- <div class="fm-container">
96
- <div class="fm-fields" id="fmFields">
97
- ${t.map(e=>{let t=e.type??`text`,n;if(t===`select`&&e.options){let t=e.options.map(t=>`<option value="${J(t)}"${t===e.value?` selected`:``}>${J(t)}</option>`).join(``);n=`<select class="fm-input" data-field="${J(e.name)}">${t}</select>`}else n=t===`textarea`?`<textarea class="fm-input fm-textarea" data-field="${J(e.name)}" rows="4">${J(e.value??``)}</textarea>`:t===`multi-select`&&e.options?`<div class="fm-multi">${e.options.map(t=>`<label class="fm-check-label"><input type="checkbox" data-field="${J(e.name)}" value="${J(t)}"${e.value?.includes(t)?` checked`:``}> ${J(t)}</label>`).join(``)}</div>`:`<input class="fm-input" type="${J(t)}" data-field="${J(e.name)}" value="${J(e.value??``)}">`;return`<div class="fm-group"><label class="fm-label">${J(e.label)}</label>${n}</div>`}).join(``)}
98
- <button class="fm-submit" id="fmSubmit">Submit</button>
99
- </div>
100
- <div class="fm-preview">
101
- <div class="fm-preview-title">Live Preview</div>
102
- <pre class="fm-preview-json" id="fmPreview">{}</pre>
103
- </div>
104
- </div>
105
- <script>
106
- (function(){
107
- const fields = document.getElementById('fmFields');
108
- const preview = document.getElementById('fmPreview');
109
- const fieldDefs = ${JSON.stringify(t.map(e=>({name:e.name,type:e.type??`text`})))};
110
-
111
- function getValues() {
112
- const vals = {};
113
- fieldDefs.forEach(f => {
114
- if(f.type === 'multi-select') {
115
- vals[f.name] = [...fields.querySelectorAll('input[data-field="'+f.name+'"]:checked')].map(cb => cb.value).join(', ');
116
- } else {
117
- const el = fields.querySelector('[data-field="'+f.name+'"]');
118
- if(el) vals[f.name] = el.value;
119
- }
120
- });
121
- return vals;
122
- }
123
-
124
- function updatePreview() { preview.textContent = JSON.stringify(getValues(), null, 2); }
125
- fields.addEventListener('input', updatePreview);
126
- fields.addEventListener('change', updatePreview);
127
- updatePreview();
128
-
129
- document.getElementById('fmSubmit').addEventListener('click', () => {
130
- if(window.__aikitCallback) {
131
- fetch(window.__aikitCallback, {method:'POST',headers:{'Content-Type':'application/json'},
132
- body:JSON.stringify({actionId:'submit',value:JSON.stringify(getValues())})}).catch(()=>{});
133
- }
134
- });
135
- })();
136
- <\/script>`}function jl(e){return kl({metrics:Object.entries(e).map(([e,t])=>({label:e,value:bl(t)||Array.isArray(t)?JSON.stringify(t,null,2):String(t),status:`info`}))})}function Ml(e){return Al({fields:vl.map(t=>{let n=e[t];return typeof n==`boolean`?{name:t,label:t,type:`select`,options:[`true`,`false`],value:String(n)}:{name:t,label:t,type:bl(n)||Array.isArray(n)?`textarea`:`text`,value:Ol(n)}})})}function Nl(e,t){return`<!DOCTYPE html><html><head><meta charset="utf-8"><title>${e}</title><style>:root{--aikit-bg:#1e1e1e;--aikit-surface:#252526;--aikit-surface2:#2d2d30;--aikit-border:#3c3c3c;--aikit-text:#e5e7eb;--aikit-muted:#9ca3af;--aikit-accent:#60a5fa;--aikit-success:#22c55e;font-family:system-ui,sans-serif}body{margin:0;padding:20px;background:var(--aikit-bg);color:var(--aikit-text);font-family:system-ui,sans-serif}h2{margin:0 0 16px}</style></head><body><h2>${e}</h2>${t}</body></html>`}function Pl(e){let t=``,n=``,r=!1;return function(i,a){t=i,n=a,!r&&(r=!0,yr(e,`AI Kit Config App`,_l,{description:`View and update AI Kit configuration`},async()=>({contents:[{uri:_l,mimeType:_r,text:Nl(t,n)}]})))}}function Fl(e,t){let n=U(`config`),r=Pl(e);br(e,`config`,{title:n.title,description:`View and update AI Kit server configuration. Use action "view" to see current settings, or "update" to modify configuration values. Changes are written to aikit.config.json and take effect on next server restart. Some settings (store, embedding) require a full restart.`,inputSchema:hl,annotations:n.annotations,_meta:{ui:{resourceUri:_l}}},q(`config`,async e=>{let{action:n,updates:i}=e;if(t.readOnly&&n!==`view`)return K(`PERMISSION`,`Configuration updates are disabled in read-only mode`);if(n===`view`){let e=yl(),n=e||`(runtime config only; no aikit.config.json found)`;try{let i=e?El(e):t,a=Dl(i,n);return r(`Configuration`,jl(i)),{content:[{type:`text`,text:a}],ui:{type:`resource`,uri:_l}}}catch(t){return gl.error(`Failed to read config for view`,{configPath:e,error:t instanceof Error?t.message:String(t)}),{content:[{type:`text`,text:`Failed to read configuration from ${n}: ${t instanceof Error?t.message:String(t)}`}]}}}if(!i)return r(`Configuration Form`,Ml(t)),{content:[{type:`text`,text:`No updates provided. Pass an updates object when action is "update".`}],ui:{type:`resource`,uri:_l}};let a=yl();if(!a)return r(`Configuration Form`,Ml(t)),{content:[{type:`text`,text:`No config file found to update.`}],ui:{type:`resource`,uri:_l}};let o=wl(i);if(o.length>0)return r(`Configuration Form`,Ml(El(a))),{content:[{type:`text`,text:`Configuration update rejected:\n${o.map(e=>`- ${e}`).join(`
137
- `)}`}],ui:{type:`resource`,uri:_l}};try{let e=El(a),t=xl(e,i),n=Tl(t);if(n.length>0)return r(`Configuration Form`,Ml(e)),{content:[{type:`text`,text:`Configuration update rejected:\n${n.map(e=>`- ${e}`).join(`
138
- `)}`}],ui:{type:`resource`,uri:_l}};Ie(a,JSON.stringify(t,null,2),`utf-8`);let o=Cl(e,t,i),s=`Configuration updated successfully.
139
-
140
- Config file: ${a}
141
-
142
- Changed values:
143
- ${o.length>0?o.join(`
144
- `):`- No effective changes; requested values already matched the file.`}
145
-
146
- These changes take effect on the next server restart.`;return r(`Configuration`,jl(t)),{content:[{type:`text`,text:s}],ui:{type:`resource`,uri:_l}}}catch(e){return gl.error(`Failed to update config`,{configPath:a,error:e instanceof Error?e.message:String(e)}),{content:[{type:`text`,text:`Failed to update configuration in ${a}: ${e instanceof Error?e.message:String(e)}`}]}}})),r(`Configuration`,jl(t))}const Il=M(`cross-workspace`);function Ll(e,t){if(!Te())return[];let n=Ee();if(n.length===0)return[];if(e.includes(`*`))return t?n.filter(e=>e.partition!==t):n;let r=[];for(let i of e){let e=n.find(e=>e.partition===i);if(e){e.partition!==t&&r.push(e);continue}let a=n.filter(e=>e.partition!==t&&e.partition.replace(/-[a-f0-9]{8}$/,``)===i.toLowerCase());r.push(...a)}let i=new Set;return r.filter(e=>i.has(e.partition)?!1:(i.add(e.partition),!0))}async function Rl(e){let t=new Map;for(let n of e){let e=Ce(n.partition),r=I(e,`aikit.db`);try{let e=await Tr({backend:`sqlite-vec`,path:r});await e.initialize(),t.set(n.partition,e)}catch(t){Il.warn(`Failed to open workspace store`,{partition:n.partition,partitionDir:e,storePath:r,error:N(t)})}}return{stores:t,closeAll:async()=>{for(let[,e]of t)try{await e.close()}catch{}}}}async function zl(e,t,n){let r=[...e.entries()].map(async([e,r])=>{try{return(await r.search(t,n)).map(t=>({...t,workspace:e}))}catch(t){return Il.warn(`Cross-workspace search failed for partition`,{partition:e,err:t}),[]}});return(await Promise.all(r)).flat().sort((e,t)=>t.score-e.score).slice(0,n.limit)}async function Bl(e,t,n){let r=[...e.entries()].map(async([e,r])=>{try{return(await r.ftsSearch(t,n)).map(t=>({...t,workspace:e}))}catch(t){return Il.warn(`Cross-workspace FTS search failed for partition`,{partition:e,err:t}),[]}});return(await Promise.all(r)).flat().sort((e,t)=>t.score-e.score).slice(0,n.limit)}function Vl(e){if(e.length!==0)return Fn({kind:`compact`,text:e,originalChars:e.length,compressedChars:e.length})?.ref??void 0}function Hl(e,t){return t?`${e}\n\nRef: ${t}`:e}const Ul=M(`tools:context`);function Wl(e){return e instanceof Error?(`code`in e?e.code:void 0)===`ENOENT`||e.message.startsWith(`File not found:`)||e.message.startsWith(`Path not found:`):!1}function Gl(e,t){return Wl(t)?(Ul.warn(`${e} failed`,{error:`File not found`}),K(`NOT_FOUND`,`File not found`)):(Ul.error(`${e} failed`,N(t)),K(`INTERNAL`,`${e} failed: ${t instanceof Error?t.message:String(t)}`))}function Kl(e,t,n,r){let i=U(`scope_map`);e.registerTool(`scope_map`,{title:i.title,description:`Generate a task-scoped reading plan. Given a task description, identifies which files and sections are relevant, with estimated token counts and suggested reading order.`,outputSchema:pc,inputSchema:{task:R.string().describe(`Description of the task to scope`),max_files:R.number().min(1).max(50).default(15).describe(`Maximum files to include`),content_type:R.enum(pe).optional().describe(`Filter by content type`),max_tokens:R.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),enrich:R.boolean().default(!0).describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens. Default true for planning tools — set false to save tokens when enrichment is not needed.`)},annotations:i.annotations},q(`scope_map`,async({task:e,max_files:i,content_type:a,max_tokens:o,enrich:s})=>{try{let c=await En(t,n,{task:e,maxFiles:i,contentType:a}),l=[`## Scope Map: ${e}`,`Total estimated tokens: ~${c.totalEstimatedTokens}`,``,`### Files (by relevance)`,...c.files.map((e,t)=>`${t+1}. **${e.path}** (~${e.estimatedTokens} tokens, ${(e.relevance*100).toFixed(0)}% relevant)\n ${e.reason}\n Focus: ${e.focusRanges.map(e=>`L${e.start}-${e.end}`).join(`, `)}`),``,`### Suggested Reading Order`,...c.readingOrder.map((e,t)=>`${t+1}. ${e}`),``,`### Suggested Compact Calls`,`_Estimated compressed total: ~${Math.ceil(c.totalEstimatedTokens/5)} tokens_`,...c.compactCommands.map((e,t)=>`${t+1}. ${e}`)].join(`
147
- `)+"\n\n---\n_Next: Use `search` to dive into specific files, or `compact` to compress file contents for context._";if(s&&r){let t=await G(r,{query:e});l+=Ac(t)}return{content:[{type:`text`,text:o?Bn(l,o):l}],structuredContent:{files:c.files.map(e=>({path:e.path,relevance:e.relevance,estimatedTokens:e.estimatedTokens,...e.focusRanges.length>0?{focusLines:e.focusRanges.map(e=>`L${e.start}-${e.end}`)}:{}})),totalFiles:c.files.length,totalEstimatedTokens:c.totalEstimatedTokens,task:e}}}catch(e){return Gl(`Scope map`,e)}}))}function ql(e,t,n,r,i,a){let o=U(`find`);e.registerTool(`find`,{title:o.title,description:`Multi-strategy search combining vector, FTS, glob, and regex. Use for precise queries needing multiple strategies. mode=examples finds real usage of a symbol. For general discovery use search instead.`,outputSchema:dc,inputSchema:{query:R.string().optional().describe(`Semantic/keyword search query (required for mode "examples")`),glob:R.string().optional().describe(`File glob pattern (search mode only)`),pattern:R.string().optional().describe(`Regex pattern to match in content (search mode only)`),limit:R.number().min(1).max(50).default(10).describe(`Max results`),content_type:R.enum(pe).optional().describe(`Filter by content type`),mode:R.enum([`search`,`examples`,`explore`]).default(`search`).describe(`Mode: "search" (default) for federated search, "examples" to find usage examples of a symbol/pattern, "explore" for enriched context with graph neighbors and related symbols`),explore:R.boolean().optional().describe(`Enable explore mode: enriches find results with related context (neighboring symbols, file summaries, dependency info) from the knowledge graph. Can be used alongside mode="search" or standalone.`),max_tokens:R.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),workspaces:R.array(R.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all. User-level mode only.`),enrich:R.boolean().default(!1).describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens. Default false — set true when you need stored decisions, conventions, or relationship context for the file/query.`)},annotations:o.annotations},q(`find`,async({query:e,glob:o,pattern:s,limit:c,content_type:l,mode:u,max_tokens:d,workspaces:f,enrich:p,explore:m})=>{try{if(u===`examples`){if(!e)return K(`VALIDATION`,`"query" is required for mode "examples".`);let r=await At(t,n,{query:e,limit:c,contentType:l}),a=Vl(JSON.stringify(r)),o=JSON.stringify(a?{ref:a,...r}:r);if(p&&i){let t=await G(i,{query:e});o+=Ac(t)}return{content:[{type:`text`,text:d?Bn(o,d):o}]}}if(u===`explore`||m){if(!e)return K(`VALIDATION`,`"query" is required for mode "explore".`);let a=await kt(t,n,{query:e,glob:o,pattern:s,limit:c,contentType:l,cwd:r,explore:!0}),u=[...new Set(a.results.map(e=>e.path))].slice(0,5),f=i?.graphStore?await Promise.allSettled(u.map(async e=>{let t=await G(i,{filePath:e,limit:3});return{filePath:e,graph:t.graph,curated:t.curated}})):[],m=new Map;for(let e of f)e.status===`fulfilled`&&e.value&&m.set(e.value.filePath,{graph:e.value.graph,curated:e.value.curated});let h=`## Explore: ${e}\n\nFound ${a.totalFound} results across ${a.results.length} files.\n\n`;for(let e of a.results.slice(0,c)){let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``;h+=`### ${e.path}${t}\n`,h+=`- **Source:** ${e.source} | **Score:** ${e.score.toFixed(3)}\n`,e.preview&&(h+=`- **Preview:** ${e.preview.slice(0,200).replace(/\n/g,` `)}\n`);let n=m.get(e.path);n?.graph&&n.graph.length>0&&(h+=`- **Related symbols:** ${n.graph.slice(0,4).join(`; `)}\n`),n?.curated&&n.curated.length>0&&(h+=`- **Related knowledge:** ${n.curated.slice(0,2).join(`; `)}\n`),h+=`
148
- `}if(p&&i){let t=await G(i,{query:e});h+=Ac(t)}return h+=`
149
- ---
150
- _Explore mode: results enriched with graph neighbors, related symbols, and curated knowledge._`,{content:[{type:`text`,text:d?Bn(h,d):h}]}}let h=await kt(t,n,{query:e,glob:o,pattern:s,limit:c,contentType:l,cwd:r}),g=``;if(f&&f.length>0&&e){let n=Ll(f,a);if(n.length>0){let{stores:r,closeAll:i}=await Rl(n);try{let i=await zl(r,await t.embedQuery(e),{limit:c,contentType:l});for(let e of i)h.results.push({path:`[${e.workspace}] ${e.record.sourcePath}`,score:e.score,source:`cross-workspace`,lineRange:e.record.startLine?{start:e.record.startLine,end:e.record.endLine}:void 0,preview:e.record.content.slice(0,200)});h.results.sort((e,t)=>t.score-e.score),h.results=h.results.slice(0,c),h.totalFound=h.results.length,g=` + ${n.length} workspace(s)`}finally{await i()}}}if(h.results.length===0){let t=`No results found.${h.failedStrategies?.length?`\nStrategies attempted: ${h.strategies.join(`, `)}\nFailed: ${h.failedStrategies.map(e=>`${e.strategy} (${e.reason})`).join(`, `)}`:h.strategies.length===0?`
151
- No search strategies were activated. Provide at least one of: query, glob, or pattern.`:``}`;if(p&&i){let n=await G(i,{query:e});t+=Ac(n)}let n=d?Bn(t,d):t,r=Vl(n);return{content:[{type:`text`,text:Hl(n,r)}],structuredContent:{matches:[],totalMatches:0,pattern:e??o??s??``,truncated:!1,ref:r}}}let _=[`Found ${h.totalFound} results via ${h.strategies.join(` + `)}${g}`,``,...h.results.map(e=>{let t=e.lineRange?`:${e.lineRange.start}-${e.lineRange.end}`:``,n=e.preview?`\n ${e.preview.slice(0,100)}...`:``;return`- [${e.source}] ${e.path}${t} (${(e.score*100).toFixed(0)}%)${n}`})].join(`
152
- `);if(p&&i){let t=await G(i,{query:e,filePath:h.results[0]?.path});_+=Ac(t)}let v=d?Bn(_,d):_,y=Vl(v);return{content:[{type:`text`,text:Hl(v,y)}],structuredContent:{matches:h.results.map(e=>({path:e.path,...e.lineRange?{line:e.lineRange.start}:{},matchType:e.source,preview:e.preview?.slice(0,200)??``})),totalMatches:h.totalFound,pattern:e??o??s??``,truncated:h.results.length<h.totalFound,ref:y}}}catch(e){return Gl(`Find`,e)}}))}function Jl(e,t,n,r,i){let a=U(`symbol`);e.registerTool(`symbol`,{title:a.title,description:`Find definition, imports, and references of a named symbol (function, class, type). For tracing data flow across call sites use trace instead. Supports transitive trace with direction and maxDepth parameters when a graph store is available.`,inputSchema:{items:R.array(R.object({name:R.string().describe(`Symbol name to look up`),limit:R.number().min(1).max(50).default(20).optional().describe(`Max results per category`),direction:R.enum([`callers`,`callees`,`both`]).optional().describe(`Transitive trace direction: callers (who calls this), callees (what this calls), or both`),maxDepth:R.number().min(1).max(10).default(2).optional().describe(`Max traversal depth for transitive trace`),edgeKinds:R.array(R.string()).optional().describe(`Filter trace by edge types (e.g., ["imports", "calls"])`),use_llm:R.boolean().default(!1).optional().describe(`Enable Tier 3 LLM disambiguation for ambiguous symbols (uses local Ollama)`)})).nonempty().describe(`Array of symbol names to look up in batch.`),max_tokens:R.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),enrich:R.boolean().default(!1).optional().describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens.`)},outputSchema:sc,annotations:a.annotations},q(`symbol`,async({items:e,max_tokens:a,enrich:o})=>{try{if(!e||e.length===0)return K(`VALIDATION`,`"items[]" is required.`);let s=await Promise.allSettled(e.map(e=>Ln(t,n,{name:e.name,limit:e.limit,graphStore:r,direction:e.direction,maxDepth:e.maxDepth,edgeKinds:e.edgeKinds,useLLM:e.use_llm??!1}))),c=[],l=[];for(let t=0;t<s.length;t++){let n=s[t],r=e[t].name;if(n.status===`fulfilled`)c.push(`## ${t+1}. ${r}\n${Xl(n.value)}`),l.push({name:n.value.name,definedIn:n.value.definedIn??null,importedBy:n.value.importedBy??[],referencedIn:n.value.referencedIn??[],graphContext:n.value.graphContext??null,trace:n.value.trace??null,confidence:n.value.confidence??null,method:n.value.method??null,rationale:n.value.rationale??null});else{let e=n.reason instanceof Error?n.reason.message:String(n.reason);c.push(`## ${t+1}. ${r}\nERROR: ${e}`),l.push({name:r,definedIn:null,importedBy:[],referencedIn:[],graphContext:null,trace:null,confidence:null,method:null,rationale:null,error:e})}}let u=c.join(`
153
-
154
- `);if(o&&i){let t=await G(i,{query:`symbols: ${e.map(e=>e.name).join(`, `)}`});u+=Ac(t)}return{content:[{type:`text`,text:a?Bn(u,a):u}],structuredContent:{symbols:l}}}catch(e){return Gl(`Symbol lookup`,e)}}))}function Yl(e,t,n,r,i){let a=U(`trace`);function o(e){let t=[`## Trace: ${e.start}`,`Direction: ${e.direction} | Depth: ${e.depth}`,``];if(e.graphContext&&(t.push(`### Graph Context`),e.graphContext.definingModule&&t.push(`- Module: ${e.graphContext.definingModule}`),e.graphContext.community&&t.push(`- Community: ${e.graphContext.community}`),e.graphContext.importedByModules.length>0&&t.push(`- Imported by modules: ${e.graphContext.importedByModules.join(`, `)}`),e.graphContext.siblingSymbols.length>0&&t.push(`- Sibling symbols: ${e.graphContext.siblingSymbols.join(`, `)}`),t.push(``)),e.nodes.length===0)t.push(`No connections found.`);else{let n=e.nodes.filter(e=>e.relationship===`calls`),r=e.nodes.filter(e=>e.relationship===`called-by`),i=e.nodes.filter(e=>e.relationship===`imports`),a=e.nodes.filter(e=>e.relationship===`imported-by`),o=e.nodes.filter(e=>e.relationship===`references`);if(n.length>0){t.push(`### Calls (${n.length})`);for(let e of n){let n=e.scope?` (from ${e.scope}())`:``;t.push(`- ${e.symbol}() — ${e.path}:${e.line}${n}`)}t.push(``)}if(r.length>0){t.push(`### Called by (${r.length})`);for(let e of r){let n=e.scope?` in ${e.scope}()`:``;t.push(`- ${e.symbol}()${n} — ${e.path}:${e.line}`)}t.push(``)}if(i.length>0){t.push(`### Imports (${i.length})`);for(let e of i)t.push(`- ${e.symbol} — ${e.path}:${e.line}`);t.push(``)}if(a.length>0){t.push(`### Imported by (${a.length})`);for(let e of a)t.push(`- ${e.path}:${e.line}`);t.push(``)}if(o.length>0){t.push(`### References (${o.length})`);for(let e of o)t.push(`- ${e.path}:${e.line}`);t.push(``)}}return{lines:t,structured:{start:e.start,direction:e.direction,depth:e.depth,nodes:e.nodes,graphContext:e.graphContext??null}}}e.registerTool(`trace`,{title:a.title,description:`Follow data flow forward/backward across imports and call sites from a starting symbol or file:line. For finding a single symbol definition use symbol instead.`,inputSchema:{items:R.array(R.object({start:R.string().describe(`Starting point — symbol name or file:line reference`),direction:R.enum([`forward`,`backward`,`both`]).describe(`Which direction to trace relationships`),max_depth:R.number().min(1).max(10).default(3).optional().describe(`Maximum trace depth`),edge_kinds:R.array(R.string()).optional().describe(`Filter edges by type (e.g., ["calls", "imports"]). Default: all edge types`)})).min(1).describe(`Array of trace queries to run in batch.`),max_tokens:R.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),enrich:R.boolean().default(!1).optional().describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens.`)},annotations:a.annotations},q(`trace`,async({items:e,max_tokens:a,enrich:s})=>{try{if(!e||e.length===0)return K(`VALIDATION`,`"items[]" is required.`);let c=await Promise.allSettled(e.map(e=>zn(t,n,{start:e.start,direction:e.direction??`both`,maxDepth:e.max_depth,graphStore:r,edgeKinds:e.edge_kinds}))),l=[],u=[];for(let t=0;t<c.length;t++){let n=c[t],r=e[t].start;if(n.status===`fulfilled`){let e=o(n.value);l.push(`## ${t+1}. ${r}\n${e.lines.join(`
155
- `)}`),u.push(e.structured)}else{let e=n.reason instanceof Error?n.reason.message:String(n.reason);l.push(`## ${t+1}. ${r}\nERROR: ${e}`),u.push({start:r,error:e})}}let d=l.join(`
156
-
157
- `)+"\n\n---\n_Next: `symbol` for definition details | `compact` to read a referenced file_";if(s&&i){let t=await G(i,{query:`traces: ${e.map(e=>e.start).join(`, `)}`});d+=Ac(t)}return{content:[{type:`text`,text:a?Bn(d,a):d}],structuredContent:{traces:u}}}catch(e){return Gl(`Trace`,e)}}))}function Xl(e){let t=[`Symbol: ${e.name}`];if(e.confidence!==void 0){let n=(e.confidence*100).toFixed(0);t.push(`Confidence: ${n}% (${e.method??`unknown`})`)}if(e.definedIn){let n=`Defined in: ${e.definedIn.path}:${e.definedIn.line} (${e.definedIn.kind})`;e.definedIn.signature&&(n+=`\nSignature: ${e.definedIn.signature}`),e.rationale&&(n+=`\nRationale: ${e.rationale}`),t.push(n)}else t.push(`Defined in: not found`);if(t.push(``,`Imported by:`),e.importedBy.length===0)t.push(` none`);else for(let n of e.importedBy)t.push(` - ${n.path}:${n.line} ${n.importStatement}`);if(t.push(``,`Referenced in:`),e.referencedIn.length===0)t.push(` none`);else for(let n of e.referencedIn){let e=`scope`in n&&n.scope?` in ${n.scope}()`:``;t.push(` - ${n.path}:${n.line}${e} ${n.context}`)}if(e.graphContext){let n=e.graphContext;t.push(``,`Graph context:`),n.definingModule&&t.push(` Module: ${n.definingModule}`),n.importedByModules.length>0&&t.push(` Imported by modules: ${n.importedByModules.join(`, `)}`),n.siblingSymbols.length>0&&t.push(` Sibling symbols: ${n.siblingSymbols.join(`, `)}`)}if(e.trace){if(e.trace.callers.length>0){t.push(``,`Transitive callers:`);for(let n of e.trace.callers)t.push(` - ${n.name} (${n.path}) [depth: ${n.depth}]`)}if(e.trace.callees.length>0){t.push(``,`Transitive callees:`);for(let n of e.trace.callees)t.push(` - ${n.name} (${n.path}) [depth: ${n.depth}]`)}}return t.join(`
158
- `)}const Zl=M(`tools`);function Ql(e,t){let n=U(`er_evolve_review`);e.registerTool(`er_evolve_review`,{title:n.title,description:`Review evolution metrics for the AI Kit ↔ ER bridge. Shows local miss rates, push acceptance, rule effectiveness, and top missed queries. Use this to reason about improving classification rules and knowledge flow.`,inputSchema:{include_details:R.boolean().default(!0).describe(`Include detailed breakdowns (top missed queries, rule stats)`),reset_after:R.boolean().default(!1).describe(`Reset collected metrics after review`)},annotations:n.annotations},async({include_details:e,reset_after:n})=>{try{let r=t.getMetrics(),i=[`## ER Evolution Review
159
- `,`**Period**: ${r.period.startedAt} → ${r.period.queriedAt}`,`**Total events**: ${r.period.totalEvents}\n`,`### Search`,`- Total searches: ${r.search.totalSearches}`,`- ER fallback triggered: ${r.search.erFallbackCount} (${(r.search.erFallbackRate*100).toFixed(1)}%)`,`- ER cache hits: ${r.search.erCacheHitCount} (${(r.search.erCacheHitRate*100).toFixed(1)}% of fallbacks)`];if(e&&r.search.topMissedQueries.length>0){i.push(`
160
- **Top missed queries** (triggered ER fallback):`);for(let e of r.search.topMissedQueries.slice(0,10)){let t=e.query.length>60?`${e.query.slice(0,57)}...`:e.query;i.push(` - "${t}" (${e.count}x)`)}}if(i.push(``,`### Push`,`- Total pushes: ${r.push.totalPushes} (${r.push.successCount} ok, ${r.push.failCount} failed)`,`- Classification match rate: ${(r.push.classificationMatchRate*100).toFixed(1)}%`,`- Push acceptance rate: ${(r.push.pushAcceptanceRate*100).toFixed(1)}%`),i.push(``,`### Rule Effectiveness`),Object.keys(r.rules.matchCounts).length>0)for(let[e,t]of Object.entries(r.rules.matchCounts)){let n=r.rules.pushCounts[e]??0,a=t>0?(n/t*100).toFixed(0):`0`;i.push(`- **${e}**: ${t} matches → ${n} pushes (${a}% conversion)`)}else i.push(`- _No rule activity recorded yet_`);if(e&&r.rules.lowConversionRules.length>0){i.push(``,`### ⚠️ Low Conversion Rules (potential false positives)`);for(let e of r.rules.lowConversionRules)i.push(`- **${e.ruleId}**: ${e.matchCount} matches, ${e.pushCount} pushes (${(e.conversionRate*100).toFixed(0)}% conversion) — consider tightening patterns`)}return i.push(``,`---`,"_Next: Use `er_update_policy` to refine rules based on these metrics, or `er_push` to share high-value knowledge._"),n&&(Zl.info(`Evolution metrics reset requested`,{requestedAt:new Date().toISOString(),clearedEvents:r.period.totalEvents}),t.reset(),i.push(`
161
- _Metrics have been reset._`)),{content:[{type:`text`,text:i.join(`
162
- `)}]}}catch(e){return Zl.error(`Evolution review failed`,N(e)),K(`INTERNAL`,`Evolution review failed: unable to compute metrics`)}})}const $l=M(`tools:execution`);function eu(e,t,n){let r=U(`check`);e.registerTool(`check`,{title:r.title,description:`Run incremental typecheck (tsc) and lint (biome) on the project or specific files. Returns structured error and warning lists. Default detail level is "efficient" (~300 tokens).`,inputSchema:{files:R.array(R.string()).optional().describe(`Specific files to check (if omitted, checks all)`),cwd:R.string().optional().describe(`Working directory`),skip_types:R.boolean().default(!1).describe(`Skip TypeScript typecheck`),skip_lint:R.boolean().default(!1).describe(`Skip Biome lint`),detail:R.enum(j).optional().describe(`Output detail level: efficient (default, ~300 tokens — pass/fail + counts + top errors), normal (parsed error objects), full (includes raw terminal output)`),enrich:R.boolean().default(!1).describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens. Default false — set true when you need stored decisions, conventions, or relationship context.`)},outputSchema:ic,annotations:r.annotations},q(`check`,async({files:e,cwd:r,skip_types:i,skip_lint:a,detail:o,enrich:s},c)=>{try{let l=o??n??`efficient`,u=await st({files:e,cwd:r,skipTypes:i,skipLint:a,detail:l===`efficient`?`normal`:l}),d=ol(c).createTask(`Check`,2);if(d.progress(0,`tsc: ${u.tsc.errors.length} errors`),d.progress(1,`biome: ${u.biome.errors.length} errors`),d.complete(`Check ${u.passed?`passed`:`failed`}`),l===`efficient`){let e=In(u),n=[];if(u.passed)n.push({tool:`test_run`,reason:`Types and lint clean — run tests next`});else{let t=u.tsc.errors[0]?.file??u.biome.errors[0]?.file,r=e.tsc.topErrors[0]??e.biome.topErrors[0]??`reported errors`;t&&n.push({tool:`compact`,reason:`Inspect failing code with compact({ path: ${JSON.stringify(t)}, query: ${JSON.stringify(r)} })`,suggested_args:{path:t,query:r}}),n.push({tool:`check`,reason:`Re-check after fixing errors`,suggested_args:{detail:`normal`}})}let r=[`## Check ${e.passed?`✅ PASS`:`❌ FAIL`}`,``,`**tsc**: ${e.tsc.passed?`✅`:`❌`} ${e.tsc.errorCount} errors, ${e.tsc.warningCount} warnings`];if(e.tsc.topErrors.length>0)for(let t of e.tsc.topErrors)r.push(` - ${t}`);if(r.push(`**biome**: ${e.biome.passed?`✅`:`❌`} ${e.biome.errorCount} errors, ${e.biome.warningCount} warnings`),e.biome.topErrors.length>0)for(let t of e.biome.topErrors)r.push(` - ${t}`);if(n.length>0){r.push(``,`**Next steps:**`);for(let e of n)r.push(`- \`${e.tool}\`: ${e.reason}`)}let i=r.join(`
163
- `);if(s&&t){let e=await G(t,{query:`known issues failures`});i+=Ac(e)}return{content:[{type:`text`,text:i}],structuredContent:{...e}}}let f=JSON.stringify(u);if(s&&t){let e=await G(t,{query:`known issues failures`});f+=Ac(e)}return{content:[{type:`text`,text:f}]}}catch(e){return $l.error(`Check failed`,N(e)),K(`INTERNAL`,`Check failed: ${e instanceof Error?e.message:String(e)}`)}}))}function tu(e){let t=U(`eval`);e.registerTool(`eval`,{title:t.title,description:`Execute a JavaScript or TypeScript snippet in a constrained VM sandbox with a timeout. Captures console output and returned values.`,inputSchema:{code:R.string().max(1e5).describe(`Code snippet to execute`),lang:R.enum([`js`,`ts`]).default(`js`).optional().describe(`Language mode: js executes directly, ts strips common type syntax first`),timeout:R.number().min(1).max(6e4).default(5e3).optional().describe(`Execution timeout in milliseconds`)},annotations:t.annotations},q(`eval`,async({code:e,lang:t,timeout:n})=>{try{let r=await Et({code:e,lang:t,timeout:n});return r.success?{content:[{type:`text`,text:`Eval succeeded in ${r.durationMs}ms\n\n${r.output}`}]}:K(`INTERNAL`,`Eval failed in ${r.durationMs}ms: ${r.error??`Unknown error`}`)}catch(e){return $l.error(`Eval failed`,N(e)),K(`INTERNAL`,`Eval failed: ${e instanceof Error?e.message:String(e)}`)}}))}function nu(e,t){let n=U(`test_run`);e.registerTool(`test_run`,{title:n.title,description:`Run Vitest for the current project or a subset of files, then return a structured summary of passing and failing tests.`,inputSchema:{files:R.array(R.string()).optional().describe(`Specific test files or patterns to run`),grep:R.string().optional().describe(`Only run tests whose names match this pattern`),cwd:R.string().optional().describe(`Working directory for the test run`),enrich:R.boolean().default(!1).describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens. Default false — set true when you need stored decisions, conventions, or relationship context.`)},annotations:n.annotations,outputSchema:Ec},q(`test_run`,async({files:e,grep:n,cwd:r,enrich:i},a)=>{try{let o=await Rn({files:e,grep:n,cwd:r}),s=ol(a).createTask(`Test Run`,1),c=o.summary.passed+o.summary.failed+o.summary.skipped;s.complete(`Tests: ${o.passed?`passed`:`failed`} (${c} tests)`);let l=au(o);if(i&&t){let e=await G(t,{query:`test patterns known failures`});l+=Ac(e)}return{content:[{type:`text`,text:l}],structuredContent:{passed:o.passed,totalTests:c,passedTests:o.summary.passed,failedTests:o.summary.failed,skippedTests:o.summary.skipped,duration:o.summary.duration??0,failures:o.summary.tests.filter(e=>e.status===`fail`).map(e=>({name:e.name,message:e.error??``,...e.file?{file:e.file}:{}}))},isError:!o.passed}}catch(e){return $l.error(`Test run failed`,N(e)),K(`INTERNAL`,`Test run failed: ${e instanceof Error?e.message:String(e)}`)}}))}function ru(e){let t=U(`parse_output`);e.registerTool(`parse_output`,{title:t.title,description:`Parse structured data from build tool output. Supports tsc, vitest, biome, and git status. Auto-detects the tool or specify explicitly.`,inputSchema:{output:R.string().max(5e5).describe(`Raw output text from a build tool`),tool:R.enum([`tsc`,`vitest`,`biome`,`git-status`]).optional().describe(`Tool to parse as (auto-detects if omitted)`)},annotations:t.annotations},async({output:e,tool:t})=>{try{let n=Zt(e.replace(/\\n/g,`
164
- `).replace(/\\t/g,` `),t);return{content:[{type:`text`,text:JSON.stringify(n)}]}}catch(e){return $l.error(`Parse failed`,N(e)),K(`INTERNAL`,`Parse failed: ${e instanceof Error?e.message:String(e)}`)}})}function iu(e,t){let n=U(`delegate`);e.registerTool(`delegate`,{title:n.title,description:`Delegate a subtask to a local Ollama model. Use for summarization, classification, naming, or any task that can offload work from the host agent. Fails fast if Ollama is not running.`,inputSchema:{prompt:R.string().max(2e5).describe(`The task or question to send to the local model`),model:R.string().optional().describe(`Ollama model name (default: first available model)`),system:R.string().optional().describe(`System prompt for the model`),context:R.string().max(5e5).optional().describe(`Context text to include before the prompt (e.g. file contents)`),temperature:R.number().min(0).max(2).default(.3).optional().describe(`Sampling temperature (0=deterministic, default 0.3)`),timeout:R.number().min(1e3).max(6e5).default(12e4).optional().describe(`Timeout in milliseconds (default 120000)`),action:R.enum([`generate`,`list_models`]).default(`generate`).optional().describe(`Action: generate a response or list available models`)},annotations:n.annotations},async({prompt:e,model:n,system:r,context:i,temperature:a,timeout:o,action:s})=>{try{if(s===`list_models`){let e=await xt();return{content:[{type:`text`,text:JSON.stringify({models:e,count:e.length,_Next:`Use delegate with a model name`},null,2)}]}}if(t?.available)try{let n=await t.createMessage({prompt:e,systemPrompt:r,context:i,maxTokens:4e3,modelPreferences:{intelligencePriority:.8,speedPriority:.5,costPriority:.3}});return{content:[{type:`text`,text:JSON.stringify({model:n.model??`sampling`,response:n.text,provider:`mcp-sampling`,_Next:`Use the response in your workflow. stash to save it.`},null,2)}]}}catch{$l.debug(`Sampling failed, falling back to Ollama`)}let c=await bt({prompt:e,model:n,system:r,context:i,temperature:a,timeout:o});return c.error?K(`INTERNAL`,JSON.stringify({error:c.error,model:c.model,durationMs:c.durationMs},null,2)):{content:[{type:`text`,text:JSON.stringify({model:c.model,response:c.response,durationMs:c.durationMs,tokenCount:c.tokenCount,_Next:`Use the response in your workflow. stash to save it.`},null,2)}]}}catch(e){return $l.error(`Delegate failed`,N(e)),K(`INTERNAL`,`Delegate failed: ${e instanceof Error?e.message:String(e)}`)}})}function au(e){let t=[`Vitest run: ${e.passed?`passed`:`failed`}`,`Duration: ${e.durationMs}ms`,`Passed: ${e.summary.passed}`,`Failed: ${e.summary.failed}`,`Skipped: ${e.summary.skipped}`];e.summary.suites!==void 0&&t.push(`Suites: ${e.summary.suites}`);let n=e.summary.tests.filter(e=>e.status===`fail`);if(n.length>0){t.push(``,`Failed tests:`);for(let e of n)t.push(`- ${e.name}${e.file?` (${e.file})`:``}`),e.error&&t.push(` ${e.error}`)}return t.join(`
165
- `)}const ou=M(`tools:file-summary`);function su(e,t,n){let r=U(`file_summary`);e.registerTool(`file_summary`,{title:r.title,description:"Unified file/source summary tool. With `files`: T1=structural card (ROLE/DEPS/EXPORTS), T2=card + query-relevant content. With `text`: compress arbitrary text by relevance. With `ref`: restore cached result. Replaces file_summary + compact + stratum_card.",inputSchema:{files:R.array(R.string()).min(1).max(50).optional().describe(`File paths to summarize (card output: T1=structure, T2=structure+content)`),text:R.string().optional().describe(`Arbitrary text to compress (text output with ratio/segment stats)`),ref:R.string().optional().describe(`Cached ref to restore from compact/digest/find/knowledge output`),query:R.string().optional().describe(`Focus query — guides relevance scoring. Triggers T2 when present without explicit tier`),tier:R.enum([`T1`,`T2`]).optional().describe(`Tier: T1=structure only, T2=structure+content. Default: T1, or T2 if query present`),max_content_chars:R.number().min(100).max(5e3).default(800).describe(`For T2/text: max chars for compressed content`),segmentation:R.enum([`paragraph`,`sentence`,`line`]).default(`paragraph`).describe(`How to split content for relevance scoring`),min_score:R.number().min(0).max(1).optional().describe(`Minimum relevance score threshold (0-1)`),mode:R.enum([`full`,`delta`]).default(`full`).describe(`'full'=compress everything, 'delta'=only changes since last read`)},annotations:r.annotations},q(`file_summary`,async({files:e,text:r,ref:i,query:a,tier:o,max_content_chars:s,segmentation:c,min_score:l,mode:u})=>{try{let d=await Ot(t,{files:e,text:r,ref:i,query:a,tier:o,maxContentChars:s,segmentation:c,minScore:l,mode:u,cache:n}),f=[];if(i)f.push(`## File Summary — Ref Restored`,`Ref: ${d.ref??i}`,``,d.text??``);else if(r){let e=d.ratio==null?`?`:(d.ratio*100).toFixed(0);f.push(`## File Summary — Text Compression`,`Original: ${d.originalChars??0} chars → ${d.compressedChars??0} chars (${e}%)`,...d.ref?[`Ref: ${d.ref}`]:[],``,d.text??``)}else if(d.cards){let e=o??`T1`;f.push(`## File Summary (${e}) — ${d.cards.length} files`,`Total: ~${d.totalTokenEstimate} tokens (was ~${d.totalOriginalTokenEstimate}, ${((d.compressionRatio??1)*100).toFixed(0)}% of original)`,``,...d.cards.map(e=>e.card),``)}return f.push(`---`,'_Next: Use `file_summary` with `tier: "T2"` and a query for deeper content or `digest` for multi-file synthesis._'),{content:[{type:`text`,text:f.filter(e=>typeof e==`string`).join(`
166
- `)}]}}catch(e){return ou.error(`file_summary failed`,N(e)),K(`INTERNAL`,`file_summary failed: ${e instanceof Error?e.message:String(e)}`)}}))}const cu=[],lu=[`_docs-sync`],uu=new Map([[`_docs-sync`,`Synchronize project documentation — update docs/ folder based on changes made during the flow.`]]);function du(e){function t(t,n,r){let i=n?.installPath?Le(n.installPath):t.replaceAll(`:`,`-`),a=L(Wn(),`.copilot`,`flows`,i).replaceAll(`\\`,`/`);if(P(a))return a;let o=L(Wn(),`.claude`,`flows`,i).replaceAll(`\\`,`/`);if(P(o))return o;let s=L(r??e(),`.github`,`flows`,i).replaceAll(`\\`,`/`);return P(s)?s:n?.installPath&&P(n.installPath)?n.installPath.replaceAll(`\\`,`/`):null}function n(e,n,r){let i=t(e.name,e,r);return i?L(i,n).replaceAll(`\\`,`/`):n}function r(t,n){let r=t.replace(/^_/,``),i=n??e(),a=[I(i,`.github`,`flows`,`_epilogue`,`steps`,r,`README.md`),I(i,`.github`,`flows`,`_epilogue`,r,`README.md`)];for(let e of a)if(P(e))return e.replaceAll(`\\`,`/`);return null}function i(e){return[...cu,...e.manifest.steps.map(e=>e.id),...lu]}function a(e,t,r){let i=t?e.manifest.steps.find(e=>e.id===t)??null:null,a=t?uu.get(t)??null:null;return{currentStep:i,epilogueStep:a?{id:t,description:a}:null,instructionPath:i&&t?n(e,i.instruction,r):null,description:i?.description??a}}function o(){try{let e=I(kr(`npm root -g`,{encoding:`utf-8`}).trim(),`@fission-ai`,`openspec`);if(P(e))return{path:e,sourceType:`npm-global`,isGit:!1}}catch{}return{path:`https://github.com/Fission-AI/OpenSpec.git`,sourceType:`git`,isGit:!0}}function s(e){let t=L(e);if(P(I(t,`.claude-plugin`,`plugin.json`)))return{path:t,sourceType:`claude-plugin`};let n=Wn(),r=I(n,`.claude`,`plugins`,e);if(P(I(r,`.claude-plugin`,`plugin.json`)))return{path:r,sourceType:`claude-plugin`};let i=I(n,`.claude`,`plugins`);if(!P(i))return null;for(let t of je(i,{withFileTypes:!0})){if(!t.isDirectory())continue;let n=I(i,t.name,`.claude-plugin`,`plugin.json`);if(P(n))try{if(JSON.parse(F(n,`utf-8`)).name===e)return{path:I(i,t.name),sourceType:`claude-plugin`}}catch{}}return null}return{resolveInstallPath:t,resolveInstructionPath:n,resolveEpilogueInstructionPath:r,getStepSequence:i,resolveCurrentStepInfo:a,resolveOpenSpecSource:o,resolveClaudePluginSource:s}}function fu(e){function t(){return e.sources?.[0]?.path??Oe()}function n(){return e.allRoots?.length?e.allRoots:[t()]}function r(e){return e.map(e=>e.replaceAll(`\\`,`/`))}function i(e){let t=[];try{let n=je(e,{withFileTypes:!0});for(let r of n){if(!r.isDirectory()||r.name.startsWith(`.`))continue;let n=I(e,r.name);P(I(n,`.git`))&&t.push(n)}}catch{}return t}function a(){let e=n(),t=new Set(e);for(let n of e)for(let e of i(n))t.add(e);return[...t]}function o(e){let t=e.replaceAll(`\\`,`/`);if(r(a()).includes(t))return!0;let i=r(n());for(let n of i)if(t.startsWith(`${n}/`)&&P(I(e,`.git`)))return!0;return!1}function s(e){return I(e??t(),`.flows`)}async function c(){let e=a();for(let t of e){let e=s(t);if(P(e))for(let n of je(e,{withFileTypes:!0})){if(!n.isDirectory())continue;let r=I(e,n.name,`meta.json`);if(P(r))try{let e=JSON.parse(F(r,`utf-8`));if(e.status===`active`)return e.primaryRoot?e.primaryRoot:t}catch{}}}return null}async function l(e){return e||(await c()??t())}function u(){let e=t(),i=r(n()),o=a(),s=r(o),c=s.filter(e=>!i.includes(e));return{workspaceRoot:e,allRoots:o,normalizedAllRoots:s,discoveredRepos:c.length>0?c:void 0}}function d(e,t,n){let r=I(s(t),e,`meta.json`),i=F(r,`utf-8`),a=JSON.parse(i);a.roots=n.map(e=>e.replaceAll(`\\`,`/`)),a.primaryRoot=t.replaceAll(`\\`,`/`);let o=`${r}.tmp`;Ie(o,JSON.stringify(a,null,2),`utf-8`),Me(o,r)}function f(e,t){let n=I(s(t),e,`meta.json`);if(!P(n))return;let r=F(n,`utf-8`),i=JSON.parse(r),a=i.roots;if(!a||a.length<=1)return;let o=t.replaceAll(`\\`,`/`);for(let t of a){if(t===o)continue;let n=I(t,`.flows`,e);Ae(n,{recursive:!0});let a=I(n,`meta.json`),s=`${a}.tmp`;Ie(s,r,`utf-8`),Me(s,a),Ae(I(n,i.artifactsDir??`.spec`),{recursive:!0})}}return{getWorkspaceRoot:t,getAllRoots:a,getFlowsDir:s,isValidFlowRoot:o,resolveFlowRoot:l,resolveRoots:u,patchMetaRoots:d,syncMetaToRoots:f}}const pu={design:`researcher`,spec:`researcher`,plan:`implementer`,task:`implementer`,execute:`implementer`,verify:`reviewer`,"basic-design":`researcher`,assess:`researcher`,"basic-implement":`implementer`,"basic-verify":`reviewer`,"docs-sync":`documenter`,"lesson-learned":`documenter`,epilogue:`documenter`},mu={implementer:`implementer`,frontend:`implementer`,refactor:`implementer`,debugger:`debugger`,security:`reviewer`,documenter:`documenter`,planner:`implementer`,researcher:`researcher`,explorer:`researcher`,orchestrator:`implementer`,"code-reviewer":`reviewer`,"architect-reviewer":`reviewer`},hu=new Set([`implementer`,`documenter`,`reviewer`,`researcher`,`debugger`]);function gu(e){if(e.profile!==void 0&&e.profile!==null)return hu.has(e.profile)?e.profile:`implementer`;if(e.id){let t=pu[e.id];if(t)return t}if(e.agents&&e.agents.length>0)for(let t of e.agents){let e=mu[t.toLowerCase()];if(e)return e}return`implementer`}function _u(e){let{manifest:t}=e;if(!t?.steps)return null;let n=t.steps.find(t=>t.id===e.stepId);return n?gu(n):null}function vu(e){return{name:`flow-context`,order:40,maxTokens:120,runInBrief:!0,async execute(t){let n=_u(t),r=[`**Flow Context:** Call \`knowledge({ action: 'withdraw', scope: 'flow', profile: '${e??n??`implementer`}', budget: 4000 })\` as FIRST action for prior context.`,"Remember decisions: `knowledge({ action: 'remember', title: '...', content: '...', category: 'flow-context', scope: 'flow' })`"];t.completedSteps.length>0&&r.push(`Completed steps: ${t.completedSteps.join(`, `)}`);let i=r.join(`
167
- `);return{content:i,tokens:Math.ceil(i.length/4)}}}}function yu(e){return{name:`knowledge-recall`,order:20,maxTokens:200,runInBrief:!0,async execute(t){if(!e.store)return null;let n=[t.stepDescription,t.topic].filter(e=>typeof e==`string`&&e.trim().length>0);if(n.length===0)return null;let r=[...n,t.flowName].filter(Boolean).join(` `);if(!r.trim())return null;try{let t=await e.store.search(r,{limit:3});if(!t||t.length===0)return null;let n=t.map(e=>`• ${e.content.slice(0,200)}`).join(`
168
- `),i=Math.ceil(n.length/4);return{content:`**Recalled Knowledge:**\n${n}`,tokens:Math.min(i,200)}}catch{return null}}}}const bu=[`**Read Code:** Structure → file_summary({ files, tier: 'T1' }). Specific section → file_summary({ files, tier: 'T2', query }).`,`Multiple files → digest(). Cached ref → file_summary({ ref, query }). Repeated file ref → file_summary(). Edit lines → read_file().`,`NEVER read_file >50 lines to understand. Use search() for discovery.`].join(` `),xu={name:`token-efficiency`,order:30,maxTokens:80,runInBrief:!1,runOnce:!0,async execute(e){return{content:bu,tokens:25}}},Su=[`**Tool Routing:** search() not grep_search. file_summary() not read_file (for understanding).`,`check() not terminal tsc/lint. test_run() not terminal test. trace() for data flow.`,`read_file ONLY for exact lines before editing. symbol() for definition+refs.`].join(` `),Cu={name:`tool-routing`,order:10,maxTokens:100,runInBrief:!0,runOnce:!0,async execute(e){return{content:Su,tokens:30}}};function wu(e,t){return Promise.race([e,new Promise(e=>setTimeout(()=>e(null),t))])}var Tu=class{hooks=[];firedOnce=new Set;sealed=!1;log;constructor(e){this.log=e?.log}seal(){this.sealed=!0}register(e){if(this.sealed){this.log?.warn(`Attempted to register hook "%s" on sealed pipeline`,e.name);return}this.hooks.push(e),this.hooks.sort((e,t)=>e.order-t.order)}get hookCount(){return this.hooks.length}async enrich(e,t,n){let r=this.resolveBudget(t.mode,n),i=new Set(n?.disable??[]),a=this.hooks.filter(e=>!(i.has(e.name)||t.mode===`brief`&&!e.runInBrief||e.runOnce&&this.firedOnce.has(e.name)));if(a.length===0)return e;let o=[],s=0;for(let e of a){if(s>=r){this.log?.debug(`[step-hooks] Budget exhausted (${s}/${r}), skipping remaining hooks`);break}try{let n=await wu(e.execute(t),5e3);if(!n||n.content.length===0)continue;e.runOnce&&this.firedOnce.add(e.name);let i=n.content.replace(/<\/(step-context|step-hints)>/gi,``);if(i.length===0)continue;let a=this.truncateToTokens(i,e.maxTokens),c=Math.min(n.tokens,e.maxTokens);if(s+c<=r){o.push({content:a,tokens:c}),s+=c;continue}let l=r-s;if(l<=0)break;o.push({content:this.truncateToTokens(a,l),tokens:l}),s=r}catch(t){this.log?.warn(`[step-hooks] Hook "${e.name}" failed: ${t instanceof Error?t.message:String(t)}`)}}if(o.length===0)return e;let c=t.mode===`full`?`<step-context>`:`<step-hints>`,l=t.mode===`full`?`</step-context>`:`</step-hints>`;return`${e}\n\n${c}\n${o.map(e=>e.content).join(`
169
-
170
- `)}\n${l}`}resolveBudget(e,t){return e===`full`?t?.tokenBudget?.full??500:t?.tokenBudget?.brief??300}truncateToTokens(e,t){let n=t*4;return e.length<=n?e:`${e.slice(0,n).trimEnd()}…`}};function Eu(e={}){let t=new Tu({log:e.log});return t.register(Cu),t.register(yu({store:e.store,graphStore:e.graphStore,embedder:e.embedder})),t.register(xu),t.register(vu()),t.seal(),t}const Du=M(`flow-tools`);function Ou(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`&&e.trim().length>0):[]}function ku(e){return{content:[{type:`text`,text:e}]}}function Au(e){return e instanceof Error?e.message:String(e)}const ju={before:[],after:[{id:`_docs-sync`,description:`Synchronize project documentation — update docs/ folder based on changes made during the flow.`,position:`after`,skills:[`docs`]}]};function Mu(e,t,n,r,i,a){let o=fu(t),s=du(o.getWorkspaceRoot),c=Eu({store:n?.store,graphStore:n?.graphStore,embedder:n?.embedder,log:Du});function l(){return I(Se(),`flows`,`registry.json`)}function u(){let t=Qr(e);return async({content:e,sourceFormat:n,stepName:r,metadata:i})=>{let a=r.charAt(0).toUpperCase()+r.slice(1),o=i?JSON.stringify(i,null,2):void 0,s=`You are converting a flow step definition from "${n}" format to aikit native flow step README.md format.
171
-
172
- Convert the provided content into a well-structured README.md for a flow step named "${r}".
173
-
174
- The output must:
175
- 1. Start with a heading: # ${a}
176
- 2. Have a "## Purpose" section explaining what this step does
177
- 3. Have a "## Instructions" section with ALL technical instructions preserved from the source
178
- 4. Have a "## Artifacts" section listing what this step produces
179
- 5. Have a "## Prerequisites" section if there are dependencies on previous steps
180
- 6. Preserve ALL tool restrictions, constraints, and requirements from the source
181
- 7. Be formatted as clean Markdown
182
-
183
- Output ONLY the README.md content, nothing else.`;if(t.available)try{let i=(await t.createMessage({prompt:e,systemPrompt:s,context:o?`Step name: ${r}\nSource format: ${n}\nMetadata:\n${o}`:`Step name: ${r}\nSource format: ${n}`,maxTokens:4096,modelPreferences:{intelligencePriority:.8,speedPriority:.4,costPriority:.2}})).text.trim();if(i.length>0)return i}catch(e){Du.debug(`Flow transform sampling failed; using fallback formatting`,{error:Au(e),sourceFormat:n,stepName:r})}let c=typeof i?.description==`string`&&i.description.trim().length>0?i.description.trim():null,l=Ou(i?.produces),u=Ou(i?.requires);return[`# ${a}`,``,`## Purpose`,``,c??`${a} step.`,``,`## Instructions`,``,e.trim(),``,`## Artifacts`,``,...l.length>0?l.map(e=>`- ${e}`):[`- ${r}.md`],...u.length>0?[``,`## Prerequisites`,``,...u.map(e=>`- ${e}`)]:[],``].join(`
184
- `).trimEnd().concat(`
185
- `)}}async function d(e){let{FlowRegistryManager:n,FlowStateMachine:r,FlowLoader:i,GitInstaller:a}=await import(`../../flows/dist/index.js`),s=I(t.stateDir??``,`flows`,`installed`);return{registry:new n(l()),stateMachine:new r(o.getFlowsDir(e),ju),loader:new i,installer:new a(s)}}async function f(e){if(!r)return[];try{return(await r.list({category:`flow-context`,limit:20,orderBy:`updated`,order:`desc`})).filter(t=>t.tags?.includes(`flow:${e.replace(/[^a-zA-Z0-9_-]/g,``).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`flow`}`)&&t.contentPreview&&t.contentPreview.length>10).map(e=>({title:e.title,summary:e.contentPreview.slice(0,200)}))}catch{return[]}}return{server:e,config:t,log:Du,toTextResponse:ku,toErrorText:Au,createFlowTransform:u,getFlows:d,stepPipeline:c,stateDir:t.stateDir??``,loadFlowDecisions:f,eventBus:i??null,skillCompiler:a??null,...o,...s}}var Nu=class extends Error{code;constructor(e,t){super(t),this.code=e,this.name=`FlowError`}};function Pu(e){return e instanceof Nu}async function Fu(e){let{entry:t,stepId:n,runDir:r,slug:i,primaryRoot:a,roots:o,activeRoot:s,resolveInstructionPath:c,resolveEpilogueInstructionPath:l}=e;if(!n)return null;try{let e=t.manifest.steps.find(e=>e.id===n||e.name===n),u;if(e)u=await Ue(c(t,e.instruction,s),`utf-8`);else{let e=l(n,s);if(!e)return null;u=await Ue(e,`utf-8`)}let d=I(r,t.manifest.artifacts_dir).replaceAll(`\\`,`/`),f=r.replaceAll(`\\`,`/`);u=u.replaceAll(`{{artifacts_path}}`,d).replaceAll(`{{run_dir}}`,f).replaceAll(`{{workspace_root}}`,(a??s).replaceAll(`\\`,`/`)).replaceAll(`{{all_roots}}`,JSON.stringify(o??[s.replaceAll(`\\`,`/`)],null,2));for(let e of[`spec-driven`])u=u.replaceAll(`${e}/${i}/`,`${d}/`);return u}catch{return null}}async function Iu(e,t){let{getFlows:n,log:r,resolveEpilogueInstructionPath:i,resolveFlowRoot:a,resolveInstructionPath:o,stepPipeline:s,toErrorText:c,toTextResponse:l}=t,{step:u}=e;try{let e=await a(),{registry:t,stateMachine:r}=await n(e),c=r.getStatus();if(!c.success||!c.data)throw new Nu(`NO_ACTIVE_FLOW`,`No active flow. Use flow({ action: "start", name: "<flow>" }) to begin one, or flow({ action: "list" }) to see available flows.`);let d=c.data,f=t.get(d.flow);if(!f)throw new Nu(`FLOW_NOT_FOUND`,`Flow "${d.flow}" not found in registry.`);let p=u??d.currentStep;if(!p)throw new Nu(`STEP_OUT_OF_RANGE`,`No current step is available for the active flow.`);let m=await Fu({entry:f,stepId:p,runDir:d.runDir,slug:d.slug,primaryRoot:d.primaryRoot,roots:d.roots,activeRoot:e,resolveInstructionPath:o,resolveEpilogueInstructionPath:i});if(!m)throw new Nu(`STEP_OUT_OF_RANGE`,`Step "${p}" not found in flow "${d.flow}".`);let h=f.manifest.steps.find(e=>e.id===p||e.name===p),g=I(d.runDir,f.manifest.artifacts_dir).replaceAll(`\\`,`/`),_={stepId:p,flowName:d.flow,flowSlug:d.slug,phase:d.phase??`flow`,runDir:d.runDir,artifactsPath:g,completedSteps:d.completedSteps??[],stepDescription:h?.description,agents:h?.agents??[],mode:`full`,topic:d.topic??``,activeRoot:e};return l(await s.enrich(m,_,f.manifest.hooks))}catch(e){return Pu(e)?l(e.message):(r.error(`flow action read failed`,N(e)),e instanceof Error&&`code`in e&&e.code===`ENOENT`?l(`Could not read instruction file: ${e.message}`):l(`Error: ${c(e)}`))}}async function Lu(e,t){let{registry:n,loader:r,installer:i}=await e.getFlows(),a=e.createFlowTransform(),o=L(t.source);if(!P(o))return e.toTextResponse(`Source path no longer exists: ${o}`);let s=`${t.installPath}.updating`,c=`${t.installPath}.backup`;P(s)&&Ne(s,{recursive:!0,force:!0}),P(c)&&Ne(c,{recursive:!0,force:!0});let l=i.copyLocal(o,Le(s));if(!l.success||!l.data)return e.toTextResponse(`Failed to copy flow: ${l.error}`);let u=await r.load(s,{forceAssetSync:!0,transform:a});if(!u.success||!u.data)return i.remove(s),e.toTextResponse(`Failed to load flow manifest: ${u.error}`);let d=!1;try{Me(t.installPath,c),Me(s,t.installPath);let e=await r.load(t.installPath,{forceAssetSync:!0,transform:a});if(!e.success||!e.data)throw Error(`Failed to load flow manifest: ${e.error}`);let o=e.data.manifest,l=e.data.format,u=n.register({...t,version:o.version,format:l,installPath:t.installPath,manifest:o,updatedAt:new Date().toISOString()});if(!u.success)throw Error(`Failed to refresh flow registry entry: ${u.error}`);if(d=!0,o.install.length>0){let e=i.runInstallDeps(o.install);if(!e.success)throw Error(`Dependency install failed: ${e.error}`)}Ne(c,{recursive:!0,force:!0})}catch(r){return P(s)&&Ne(s,{recursive:!0,force:!0}),P(c)&&(P(t.installPath)&&Ne(t.installPath,{recursive:!0,force:!0}),Me(c,t.installPath)),d&&n.register(t),e.toTextResponse(e.toErrorText(r))}return e.toTextResponse(`Flow "${t.name}" updated from ${t.sourceType} source successfully.`)}async function Ru(e,t){let{registry:n,loader:r}=await e.getFlows(),i=e.createFlowTransform();try{kr(`npm update -g @fission-ai/openspec`,{encoding:`utf-8`,stdio:`pipe`})}catch(t){return e.toTextResponse(`npm update failed: ${e.toErrorText(t)}`)}let a=e.resolveOpenSpecSource(),o=await r.load(a.path,{forceAssetSync:!0,transform:i}),s=o.success&&o.data?o.data.manifest:null,c=o.success&&o.data?o.data.format:t.format;if(s){let r=n.register({...t,version:s.version,format:c,installPath:a.path,manifest:s,updatedAt:new Date().toISOString()});if(!r.success)return e.toTextResponse(`Failed to refresh flow registry entry: ${r.error}`)}return e.toTextResponse(`Flow "${t.name}" updated via npm successfully.`)}async function zu(e,t){let{registry:n,loader:r,installer:i}=await e.getFlows(),a=e.createFlowTransform(),o=i.update(t.installPath);if(!o.success)return e.toTextResponse(`Update failed: ${o.error}`);let s=await r.load(t.installPath,{forceAssetSync:!0,transform:a}),c=s.success&&s.data?s.data.manifest:null,l=s.success&&s.data?s.data.format:t.format;if(c){let r=i.getLocalCommit(t.installPath),a=n.register({...t,version:c.version,format:l,manifest:c,updatedAt:new Date().toISOString(),...r?{commitSha:r}:{}});if(!a.success)return e.toTextResponse(`Failed to refresh flow registry entry: ${a.error}`)}let u=c?.install??t.manifest.install;if(u.length>0){let t=i.runInstallDeps(u);if(!t.success)return e.toTextResponse(`Dependency install failed: ${t.error}`)}return e.toTextResponse(`Flow "${t.name}" updated successfully.`)}async function Bu(e,t){let{createFlowTransform:n,getFlows:r,log:i,resolveClaudePluginSource:a,resolveOpenSpecSource:o,toErrorText:s,toTextResponse:c}=t,{source:l,name:u,token:d}=e;try{let{registry:e,loader:t,installer:i}=await r(),s=n(),f=l===`openspec`||l.startsWith(`openspec:`),p,m=l,h;if(f){let e=o();m=e.path,p=e.sourceType}let g=f?null:a(m);g&&(m=g.path,p=g.sourceType);let _=/^https?:\/\/|^git@/.test(m),v;if(_){let e=i.clone(m,d);if(!e.success||!e.data)return c(`Failed to clone flow: ${e.error}`);v=e.data}else{let e=L(m);h=e;let t=u||Le(e)||`custom-flow`,n=i.copyLocal(e,t);if(!n.success||!n.data)return c(`Failed to copy flow: ${n.error}`);v=n.data}let y=await t.load(v,{forceAssetSync:!0,transform:s});if(!y.success||!y.data)return i.remove(v),c(`Failed to load flow manifest: ${y.error}`);let{manifest:b,format:x}=y.data,S=u||b.name,C=p??(_?`git`:`local`);if(e.has(S))return i.remove(v),c(`Flow "${S}" is already installed. Use flow({ action: "update", name: "${S}" }) to update it, or flow({ action: "remove", name: "${S}" }) then flow({ action: "add", source: "..." }) to replace.`);if(b.install.length>0){let e=i.runInstallDeps(b.install);if(!e.success)return i.remove(v),c(`Dependency install failed: ${e.error}`)}let w=new Date().toISOString(),T=_?i.getLocalCommit(v):void 0,E=e.register({name:S,version:b.version,source:C===`local`||C===`claude-plugin`?h??l:l,sourceType:C,installPath:v,format:x,registeredAt:w,updatedAt:w,manifest:b,...T?{commitSha:T}:{}});if(!E.success)return i.remove(v),c(`Failed to register flow: ${E.error}`);let D=b.steps.length;return c(`Flow "${S}" installed successfully (${D} steps). Use flow({ action: "start", name: "${S}" }) to begin.`)}catch(e){return i.error(`flow action add failed`,N(e)),c(`Error: ${s(e)}`)}}async function Vu(e,t){let{getFlows:n,log:r,toErrorText:i,toTextResponse:a}=t,{name:o}=e;try{let{registry:e,installer:t}=await n();if(!e.has(o))return a(`Flow "${o}" is not installed.`);let r=e.get(o);if(!r)return a(`Flow "${o}" is not installed.`);if(r.sourceType===`builtin`)return a(`Cannot remove builtin flow "${o}".`);let i=t.remove(r.installPath);if(!i.success)return a(`Failed to remove flow files: ${i.error}`);let s=e.unregister(o);return s.success?a(`Flow "${o}" removed successfully.`):a(`Failed to unregister flow: ${s.error}`)}catch(e){return r.error(`flow action remove failed`,N(e)),a(`Error: ${i(e)}`)}}async function Hu(e,t){let{getFlows:n,log:r,toErrorText:i,toTextResponse:a}=t,{name:o}=e,s={createFlowTransform:t.createFlowTransform,getFlows:t.getFlows,resolveOpenSpecSource:t.resolveOpenSpecSource,toErrorText:t.toErrorText,toTextResponse:t.toTextResponse};try{let{registry:e}=await n();if(!e.has(o))return a(`Flow "${o}" is not installed.`);let t=e.get(o);return!t||t.sourceType!==`git`&&t.sourceType!==`npm-global`&&t.sourceType!==`local`&&t.sourceType!==`claude-plugin`?a(`Flow "${o}" was not installed from git, npm, or a local source — cannot update. Remove and re-add instead.`):t.sourceType===`local`||t.sourceType===`claude-plugin`?Lu(s,t):t.sourceType===`npm-global`?Ru(s,t):zu(s,t)}catch(e){return r.error(`flow action update failed`,N(e)),a(`Error: ${i(e)}`)}}function Uu(e){return Ye(`sha256`).update(e,`utf-8`).digest(`hex`).slice(0,16)}const Wu=`IMPORTANT: Start/status/step only include a brief. Call flow({ action: "read" }) before executing this flow step.`,Gu=1200,Ku=/artifact|output contract|gate|completion criteria|deliverable|must|do not|forbidden/i;function qu(){return{artifactsPath:null,currentStepInstruction:null,currentStepDescription:null,currentStepContent:null,currentStepBrief:null,currentStepPins:null,stepSequence:[]}}function Ju(e){if(e.length<=Gu)return e;let t=e.slice(0,Gu-1),n=Math.max(t.lastIndexOf(`
186
- `),t.lastIndexOf(` `),t.lastIndexOf(` `));return`${(n>=Math.floor(t.length*.6)?t.slice(0,n):t).trimEnd()}…`}function Yu(e){if(!e?.trim())return{brief:null,pins:null};let t=/^##\s+/m.exec(e),n=(t?e.slice(0,t.index):e).trim(),r=null;if(n){let e=n.split(/\n\s*\n/).filter(e=>e.trim().length>0),t=(e[0]?.startsWith(`#`)&&e[1]?e.slice(0,2):e.slice(0,1)).join(`
187
-
188
- `).trim();r=t?Ju(t):null}let i=Array.from(e.matchAll(/^##\s+.*$/gm)),a=[];for(let[t,n]of i.entries()){let r=n[0];if(!Ku.test(r))continue;let o=n.index??0,s=i[t+1]?.index??e.length;a.push(e.slice(o,s).replace(/\s+$/,``))}return{brief:r,pins:a.length>0?a.join(`
189
-
190
- `):null}}function Xu(e,t){return t(e)}async function Zu(e){let{context:t,entry:n,state:r,activeRoot:i,primaryRoot:a,roots:o}=e,{instructionPath:s,description:c}=t.resolveCurrentStepInfo(n,r.currentStep,i),l=Xu(n,t.getStepSequence),u=await Fu({entry:n,stepId:r.currentStep,runDir:r.runDir,slug:r.slug,primaryRoot:a,roots:o,activeRoot:i,resolveInstructionPath:t.resolveInstructionPath,resolveEpilogueInstructionPath:t.resolveEpilogueInstructionPath}),{brief:d,pins:f}=Yu(u),p=d;if(d&&r.currentStep){let e=n.manifest.steps.find(e=>e.id===r.currentStep),a={stepId:r.currentStep,flowName:r.flow,flowSlug:r.slug,phase:`flow`,runDir:r.runDir,artifactsPath:I(r.runDir,n.manifest.artifacts_dir).replaceAll(`\\`,`/`),completedSteps:r.completedSteps??[],stepDescription:e?.description??c??void 0,agents:e?.agents??[],mode:`brief`,topic:r.topic??``,activeRoot:i};p=await t.stepPipeline.enrich(d,a,n.manifest.hooks)}return{artifactsPath:I(r.runDir,n.manifest.artifacts_dir).replaceAll(`\\`,`/`),currentStepInstruction:s,currentStepDescription:c,currentStepContent:u,currentStepBrief:p,currentStepPins:f,stepSequence:l}}function Qu(e){let{state:t,data:n,started:r,includeStatus:i,action:a,includeInstructionPath:o}=e,s={};return r&&(s.started=!0),s.flow=t.flow,t.flowOrigin&&(s.flowOrigin=t.flowOrigin),i&&(s.status=t.status),a&&(s.action=a),s.slug=t.slug,s.topic=t.topic,s.runDir=t.runDir,s.artifactsPath=n.artifactsPath,s.currentStep=t.currentStep,s.currentStepInstruction=n.currentStepInstruction,o&&(s.instructionPath=n.currentStepInstruction),s.currentStepDescription=n.currentStepDescription,s.currentStepContent=n.currentStepContent,s.currentStepContentHash=n.currentStepContent?Uu(n.currentStepContent):null,s.currentStepBrief=n.currentStepBrief,s.currentStepPins=n.currentStepPins,s.fullContentHint=`Call flow({ action: 'read' }) for the complete step instructions.`,s}function $u(e){return e.sourceType===`local`?{source:`local`,sourceType:e.sourceType,format:e.format,...e.commitSha?{commitSha:e.commitSha}:{}}:{source:e.source,sourceType:e.sourceType,format:e.format,...e.commitSha?{commitSha:e.commitSha}:{}}}async function ed(e,t){let{getAllRoots:n,getFlows:r,getWorkspaceRoot:i,isValidFlowRoot:a,log:o,patchMetaRoots:s,stateDir:c,toErrorText:l,toTextResponse:u}=t,{flow:d,topic:f,roots:p,objective:m,acceptanceCriteria:h,scope:g,exclusions:_}=e;try{if(p&&p.length>0){let e=n().map(e=>e.replaceAll(`\\`,`/`)),t=p.filter(e=>!a(e));if(t.length>0)return u(`Invalid roots — not part of the workspace or a recognized sub-repository: ${t.join(`, `)}. Available roots: ${e.join(`, `)}`)}let e=n(),o=e.map(e=>e.replaceAll(`\\`,`/`)),l=i(),v=e.length>1,y=!p&&v,b=p?.[0]??l,{registry:x,stateMachine:S}=await r(b),C=x.get(d);if(!C)throw new Nu(`UNKNOWN_FLOW`,`Flow "${d}" not found. Use flow({ action: "list" }) to see available flows.`);let w=S.start(C.name,C.manifest,f,$u(C),{objective:m,acceptanceCriteria:h,scope:g,exclusions:_});if(!w.success||!w.data){let e=w.error??`Unknown flow start error.`;return e.includes(`already active`)?u(`Cannot start: ${new Nu(`FLOW_ALREADY_ACTIVE`,e).message}`):u(`Cannot start: ${e}`)}let T=w.data;t.eventBus&&t.eventBus.emit({type:`flow:step:eventbus`,flowName:T.flow,flowSlug:T.slug,stepId:T.currentStep??``,status:`start`,action:`started`,phase:T.phase??`flow`,completedSteps:[],totalSteps:C.manifest.steps.length,timestamp:Date.now(),eventId:`flow-start-${T.slug}-${Date.now()}`,workspaceId:T.slug,source:`flow-tools`});let E;if(t.config.layeredKnowledge){let e=jr(),t=S.setOwnerCapability({ownerTokenSalt:e.salt,ownerTokenHash:e.hash,ownerTokenVersion:e.version});if(!t.success)return u(`Cannot start in layered mode: failed to persist owner capability — ${t.error??`unknown error`}`);E=e.rawToken}if(p&&p.length>1)try{s(T.slug,b,p),t.syncMetaToRoots(T.slug,b)}catch(e){return S.reset(),u(`Flow created but failed to sync to secondary roots — rolled back. Error: ${e instanceof Error?e.message:String(e)}`)}let D=I(c,`flow-context`),O=typeof We==`function`?await We(D).catch(()=>[]):[];for(let e of O)e!==T.slug&&typeof Ge==`function`&&await Ge(I(D,e),{recursive:!0,force:!0}).catch(()=>{});if(typeof He==`function`)try{await He(I(D,T.slug),{recursive:!0})}catch{}let k=await Zu({context:t,entry:C,state:T,activeRoot:b,primaryRoot:null,roots:p??null}),ee=Ar(T,C.manifest,{objective:m,acceptanceCriteria:h,scope:g,exclusions:_}),te={...Qu({state:T,data:k,started:!0}),phase:T.phase,isEpilogue:T.isEpilogue,totalSteps:k.stepSequence.length,stepSequence:k.stepSequence,artifactsDir:C.manifest.artifacts_dir,roots:p??[b.replaceAll(`\\`,`/`)],snapshot:ee,_hint:Wu,...y?{multiRootWarning:`No roots specified in multi-root workspace. Flow created at workspace root. Pass roots parameter with target repo for precise placement.`,availableRoots:o}:{},...E?{_ownerToken:E}:{}};return u(JSON.stringify(te,null,2))}catch(e){return Pu(e)?u(e.message):(o.error(`flow action start failed`,N(e)),u(`Error: ${l(e)}`))}}async function td(e,t){let{getFlows:n,log:r,resolveFlowRoot:i,syncMetaToRoots:a,toErrorText:o,toTextResponse:s}=t,{targetStep:c,lifecycleOwnerToken:l,currentToken:u}=e;try{let e=await i(),{registry:r,stateMachine:o}=await n(e),d=o.getStatus();if(!d.success||!d.data)return s(`No active flow. Use flow({ action: "start", name: "<flow>" }) first.`);let f=d.data,p=r.get(f.flow);if(!p)return s(`Flow "${f.flow}" not found in registry.`);if(t.config.layeredKnowledge){if(!l)return s(`lifecycleOwnerToken required in layered mode.`);let e=f,t=e.ownerTokenSalt,n=e.ownerTokenHash;if(!t||!n)return s(`Flow has no owner capability — cannot backtrack.`);if(!Nr(l,t,n))return s(`Invalid lifecycleOwnerToken — backtrack denied.`);if(u&&u!==f.currentToken)return s(`Invalid currentToken — flow state changed since last status.`)}let m=o.backtrack(c,p.manifest);if(!m.success||!m.data)return s(`Cannot backtrack: ${m.error}`);a(m.data.slug,e);let h=m.data,g=await Zu({context:t,entry:p,state:h,activeRoot:e,primaryRoot:h.primaryRoot,roots:h.roots}),_={...Qu({state:h,data:g,includeStatus:!0,action:`backtrack`}),_hint:h.currentStep?Wu:void 0,phase:h.phase,isEpilogue:h.isEpilogue,completedSteps:h.completedSteps,skippedSteps:h.skippedSteps,totalSteps:g.stepSequence.length};return s(JSON.stringify(_,null,2))}catch(e){return Pu(e)?s(e.message):(r.error(`flow action backtrack failed`,N(e)),s(`Error: ${o(e)}`))}}async function nd(e,t){let{getFlows:n,log:r,resolveFlowRoot:i,syncMetaToRoots:a,toErrorText:o,toTextResponse:s}=t,{currentToken:c}=e;try{let e=await i(),{stateMachine:r}=await n(e),o=r.getStatus();if(!o.success||!o.data)return s(`No active flow. Use flow({ action: "start", name: "<flow>" }) first.`);let l=o.data;if(c&&c!==l.currentToken)return s(`Invalid currentToken — claim denied.`);if(!t.config.layeredKnowledge)return s(`Claim requires layeredKnowledge mode.`);let u=t.server?(await import(`./sampling-MSeOiAqz.js`)).createSamplingClient(t.server):null;if(u?.available){if((await u.createMessage({prompt:`You have been asked to transfer flow ownership. Do you confirm?`,systemPrompt:`Respond with "yes" to confirm or anything else to decline.`,maxTokens:16,modelPreferences:{intelligencePriority:.2,speedPriority:.9,costPriority:.9}})).text.trim().toLowerCase()!==`yes`)return s(`Ownership transfer declined by user.`)}else return s(`Cannot verify ownership transfer — no elicitor available.`);let d=Mr(l.ownerTokenVersion??1),f=r.setOwnerCapability({ownerTokenSalt:d.salt,ownerTokenHash:d.hash,ownerTokenVersion:d.version});if(!f.success)return s(`Claim failed: ${f.error}`);let p=r.getStatus();if(p.success&&p.data){let t=p.data;a(t.slug,e)}let m={success:!0,_ownerToken:d.rawToken,version:d.version,message:`Ownership transferred successfully.`};return s(JSON.stringify(m,null,2))}catch(e){return Pu(e)?s(e.message):(r.error(`flow action claim failed`,N(e)),s(`Error: ${o(e)}`))}}async function rd(e){let{getFlows:t,log:n,resolveFlowRoot:r,resolveRoots:i,toErrorText:a,toTextResponse:o}=e;try{let n=await r(),{registry:a,stateMachine:s}=await t(n),c=s.getStatus();if(!c.success||!c.data)throw new Nu(`NO_ACTIVE_FLOW`,`No active flow. Use flow({ action: "start", name: "<flow>" }) to begin one, or flow({ action: "list" }) to see available flows.`);let l=c.data,u=a.get(l.flow),d=u?await Zu({context:e,entry:u,state:l,activeRoot:n,primaryRoot:l.primaryRoot,roots:l.roots}):qu(),f={...Qu({state:l,data:d,includeStatus:!0,includeInstructionPath:!0}),_hint:l.currentStep?Wu:void 0,phase:l.phase,isEpilogue:l.isEpilogue,completedSteps:l.completedSteps,skippedSteps:l.skippedSteps,artifacts:l.artifacts,startedAt:l.startedAt,updatedAt:l.updatedAt,totalSteps:d.stepSequence.length,progress:u?`${l.completedSteps.length+l.skippedSteps.length}/${d.stepSequence.length}`:`unknown`,decisions:await e.loadFlowDecisions(l.slug),briefing:{workspace_core:e.skillCompiler?.readCurrentSkill()??null,active_flow:e.skillCompiler?.readFlowBriefing(l.slug)??null},skill_warnings:e.skillCompiler?.getWarnings(l.slug)??[],workspaceRoot:n.replaceAll(`\\`,`/`),primaryRoot:(l.primaryRoot??n).replaceAll(`\\`,`/`),roots:l.roots??[n.replaceAll(`\\`,`/`)],allRoots:i().normalizedAllRoots,discoveredRepos:i().discoveredRepos};return o(JSON.stringify(f,null,2))}catch(e){return Pu(e)?o(e.message):(n.error(`flow action status failed`,N(e)),o(`Error: ${a(e)}`))}}async function id(e){let{getFlows:t,log:n,resolveFlowRoot:r,stateDir:i,syncMetaToRoots:a,toErrorText:o,toTextResponse:s}=e;try{let n=await r(),{stateMachine:o}=await t(n),c=o.getStatus();if(c.success&&c.data){if(e.eventBus){let t=c.data.slug,n=typeof c.data.startedAt==`number`?c.data.startedAt:Date.now();e.eventBus.emit({type:`flow:abandon`,flowName:c.data.flow,flowSlug:t,completedCount:c.data.completedSteps?.length??0,skippedCount:c.data.skippedSteps?.length??0,durationMs:Date.now()-n,timestamp:Date.now(),eventId:`flow-abandon-${t}-${Date.now()}`,workspaceId:t,source:`flow-tools`})}a(c.data.slug,n)}let l=o.reset();if(!l.success)return s(`Reset failed: ${l.error}`);if(c.success&&c.data?.slug)try{await Ge(I(i,`flow-context`,c.data.slug),{recursive:!0,force:!0})}catch{}return s(`Flow abandoned. Use flow({ action: "start", name: "<flow>" }) to begin a new flow.`)}catch(e){return n.error(`flow action reset failed`,N(e)),s(`Error: ${o(e)}`)}}async function ad(e,t){let{getFlows:n,log:r,resolveFlowRoot:i,syncMetaToRoots:a,toErrorText:o,toTextResponse:s}=t,{action:c,targetStep:l,lifecycleOwnerToken:u,currentToken:d}=e;if(c===`backtrack`)return l?td({targetStep:l,lifecycleOwnerToken:u,currentToken:d},t):s(`Missing required parameter: targetStep for backtrack action.`);try{let e=await i(),{registry:r,stateMachine:o}=await n(e),l=o.getStatus();if(!l.success||!l.data)throw new Nu(`NO_ACTIVE_FLOW`,`No active flow. Use flow({ action: "start", name: "<flow>" }) first.`);let u=r.get(l.data.flow);if(!u)throw new Nu(`FLOW_NOT_FOUND`,`Flow "${l.data.flow}" not found in registry.`);let d=o.step(c,u.manifest);if(!d.success||!d.data)return s(`Cannot ${c}: ${d.error}`);a(d.data.slug,e);let f=d.data;if(t.eventBus&&(t.eventBus.emit({type:`flow:step:eventbus`,flowName:f.flow,flowSlug:f.slug,stepId:f.currentStep??f.completedSteps[f.completedSteps.length-1]??``,status:{next:`complete`,skip:`complete`,redo:`start`}[c]??`complete`,action:{next:`completed`,skip:`skipped`,redo:`redo`}[c]??`completed`,phase:f.phase??`flow`,completedSteps:[...f.completedSteps,...f.skippedSteps],totalSteps:u.manifest.steps.length,timestamp:Date.now(),eventId:`flow-step-${f.slug}-${Date.now()}`,workspaceId:f.slug,source:`flow-tools`}),f.status===`completed`)){let e=typeof f.startedAt==`number`?f.startedAt:Date.now();t.eventBus.emit({type:`flow:complete:eventbus`,flowName:f.flow,flowSlug:f.slug,outcome:`success`,stepCount:u.manifest.steps.length,completedCount:f.completedSteps.length,skippedCount:f.skippedSteps.length,durationMs:Date.now()-e,timestamp:Date.now(),eventId:`flow-complete-${f.slug}-${Date.now()}`,workspaceId:f.slug,source:`flow-tools`})}let p=[];if(f.status===`completed`){let e=I(t.stateDir,`flow-context`,f.slug);for(let t of[`decision`,`pattern`]){let n=I(e,t);try{let e=await We(n);for(let r of e){if(!r.endsWith(`.md`))continue;let e=await Ue(I(n,r),`utf-8`);e.length>100&&p.push({type:t,title:r.replace(/\.md$/,``).replace(/-/g,` `),content:e.length>500?`${e.slice(0,497)}...`:e})}}catch{}}typeof Ge==`function`&&await Ge(e,{recursive:!0,force:!0}).catch(()=>{})}let m=await Zu({context:t,entry:u,state:f,activeRoot:e,primaryRoot:f.primaryRoot,roots:f.roots}),h={...Qu({state:f,data:m,includeStatus:!0,action:c}),_hint:f.currentStep?Wu:void 0,phase:f.phase,isEpilogue:f.isEpilogue,completedSteps:f.completedSteps,skippedSteps:f.skippedSteps,totalSteps:m.stepSequence.length,remaining:m.stepSequence.filter(e=>!f.completedSteps.includes(e)&&!f.skippedSteps.includes(e)&&e!==f.currentStep),...p.length>0?{promotionCandidates:p}:{}};return s(JSON.stringify(h,null,2))}catch(e){return Pu(e)?s(e.message):(r.error(`flow action step failed`,N(e)),s(`Error: ${o(e)}`))}}async function od(e){let{getFlows:t,log:n,resolveFlowRoot:r,resolveRoots:i,toErrorText:a,toTextResponse:o}=e;try{let{registry:e,stateMachine:n,installer:a}=await t(await r()),s=e.list(),c=n.getStatus(),l={flows:s.map(e=>{let t={name:e.name,version:e.version,source:e.source,sourceType:e.sourceType,format:e.format,steps:e.manifest.steps.map(e=>e.id)};if(e.sourceType===`git`&&e.commitSha){let n=a.hasUpdates(e.installPath);return{...t,commitSha:e.commitSha,updateAvailable:n.success&&n.data?n.data.hasUpdates:void 0}}return t}),activeFlow:c.success&&c.data?{flow:c.data.flow,flowOrigin:c.data.flowOrigin,status:c.data.status,currentStep:c.data.currentStep,slug:c.data.slug,topic:c.data.topic,runDir:c.data.runDir}:null,allRoots:i().normalizedAllRoots,discoveredRepos:i().discoveredRepos};return o(JSON.stringify(l,null,2))}catch(e){return n.error(`flow action list failed`,N(e)),o(`Error: ${a(e)}`)}}async function sd(e,t){let{getFlows:n,log:r,resolveInstallPath:i,resolveInstructionPath:a,toErrorText:o,toTextResponse:s}=t,{name:c}=e;try{let{registry:e,installer:t}=await n(),r=e.get(c);if(!r)throw new Nu(`UNKNOWN_FLOW`,`Flow "${c}" not found. Use flow({ action: "list" }) to see available flows.`);let o=r.commitSha??null,l;if(r.sourceType===`git`&&r.installPath){let e=t.hasUpdates(r.installPath);l=e.success&&e.data?e.data.hasUpdates:void 0}let u={name:r.name,version:r.version,description:r.manifest.description,source:r.source,sourceType:r.sourceType,format:r.format,commitSha:o,updateAvailable:l,installPath:i(r.name,r),registeredAt:r.registeredAt,updatedAt:r.updatedAt,steps:r.manifest.steps.map(e=>({id:e.id,name:e.name,instruction:a(r,e.instruction),produces:e.produces,requires:e.requires,description:e.description})),agents:r.manifest.agents,artifactsDir:r.manifest.artifacts_dir,install:r.manifest.install};return s(JSON.stringify(u,null,2))}catch(e){return Pu(e)?s(e.message):(r.error(`flow action info failed`,N(e)),s(`Error: ${o(e)}`))}}async function cd(e,t){let{getAllRoots:n,getFlows:r,log:i,toErrorText:a,toTextResponse:o}=t,{flow:s,status:c,limit:l=50}=e,u=e=>{for(let t of[`updatedAt`,`startedAt`,`createdAt`]){let n=e[t];if(typeof n==`number`&&Number.isFinite(n))return n;if(typeof n==`string`){let e=Date.parse(n);if(!Number.isNaN(e))return e}}return null};try{let e=n(),t=[];for(let n of e){let{stateMachine:e}=await r(n),i=e.listRuns({flow:s,status:c});for(let e of i)t.push({...JSON.parse(JSON.stringify(e)),root:n.replaceAll(`\\`,`/`)})}let i=new Set,a=t.filter(e=>{let t=e.id;return i.has(t)?!1:(i.add(t),!0)});if(a.length===0)return o(`No flow runs found.`);let d=a.map((e,t)=>({run:e,index:t,recency:u(e)})).sort((e,t)=>e.recency==null&&t.recency==null?e.index-t.index:e.recency==null?1:t.recency==null?-1:t.recency===e.recency?e.index-t.index:t.recency-e.recency).map(({run:e})=>e).slice(0,l);return o(JSON.stringify({total:a.length,returned:d.length,truncated:a.length>d.length,runs:d},null,2))}catch(e){return i.error(`flow action runs failed`,N(e)),o(`Error: ${a(e)}`)}}function ld(e){let t=e.content?.find(e=>e.type===`text`)?.text??``;if(!t)return null;try{let e=JSON.parse(t);if(typeof e.slug==`string`&&e.slug.length>0)return e.slug}catch{}return t.match(/[Ss]lug[:\s]*`?([^`\s,]+)`?/)?.[1]??null}function ud(e,t,n,r){let i=n&&typeof n!=`function`?n:void 0,a=typeof n==`function`?n:r,o=Mu(e,t,i,i?.curated,i?.eventBus,i?.skillCompiler),s=U(`flow`);e.registerTool(`flow`,{title:s.title,description:`Manage development flows — list available flows, start/stop runs, navigate steps, read instructions, and install/remove/update flows. Use action parameter to select operation.`,annotations:s.annotations,inputSchema:{action:R.enum([`list`,`info`,`start`,`step`,`status`,`reset`,`read`,`runs`,`add`,`remove`,`update`,`backtrack`,`claim`]).describe(`The flow operation to perform.`),name:R.string().optional().describe(`Flow name — required for info, start, remove, update. Optional override for add.`),topic:R.string().optional().describe(`Human-readable topic for the run (used by start).`),objective:R.string().optional().describe(`L1 snapshot objective — the goal of this flow run. Falls back to topic when absent.`),acceptanceCriteria:R.array(R.string()).optional().describe(`L1 snapshot acceptance criteria (used by start).`),scope:R.array(R.string()).optional().describe(`L1 snapshot scope boundaries (used by start). Falls back to roots when absent.`),exclusions:R.array(R.string()).optional().describe(`L1 snapshot exclusions — what is out of scope (used by start).`),roots:R.array(R.string()).optional().describe(`Workspace roots participating in this flow (used by start).`),advance:R.enum([`next`,`skip`,`redo`,`backtrack`]).optional().describe(`Step navigation action — required for step.`),lifecycleOwnerToken:R.string().optional().describe(`Owner capability token for layered lifecycle mutations (required in layered mode for step/backtrack/claim/reset).`),currentToken:R.string().optional().describe(`Current step execution token from status response for optimistic concurrency.`),targetStep:R.string().optional().describe(`Target step ID for backtrack action — must be a completed prior step.`),step:R.string().optional().describe(`Step id or name to read (used by read). Defaults to current step.`),source:R.string().optional().describe(`Git URL, local path, or "openspec" shorthand — required for add.`),token:R.string().optional().describe(`Auth token for private repos (used by add).`),filter_flow:R.string().optional().describe(`Filter runs by flow name (used by runs).`),filter_status:R.string().optional().describe(`Filter runs by status: active, completed, abandoned (used by runs).`),limit:R.number().int().positive().optional().describe(`Max runs to return (default 50).`)}},q(`flow`,async e=>{switch(e.action){case`list`:return od(o);case`info`:return e.name?sd({name:e.name},o):o.toTextResponse(`Missing required parameter: name`);case`start`:{if(!e.name)return o.toTextResponse(`Missing required parameter: name (flow to start)`);let t=await ed({flow:e.name,topic:e.topic,roots:e.roots,objective:e.objective,acceptanceCriteria:e.acceptanceCriteria,scope:e.scope,exclusions:e.exclusions},o),n=ld(t);return n&&a&&a(n),t}case`step`:return e.advance?ad({action:e.advance,targetStep:e.targetStep,lifecycleOwnerToken:e.lifecycleOwnerToken,currentToken:e.currentToken},o):o.toTextResponse(`Missing required parameter: advance (next/skip/redo/backtrack)`);case`status`:{let e=await rd(o);return a&&a(ld(e)),e}case`reset`:{let e=await id(o);return a&&a(null),e}case`read`:return Iu({step:e.step},o);case`runs`:return cd({flow:e.filter_flow,status:e.filter_status,limit:e.limit},o);case`add`:return e.source?Bu({source:e.source,name:e.name,token:e.token},o):o.toTextResponse(`Missing required parameter: source`);case`remove`:return e.name?Vu({name:e.name},o):o.toTextResponse(`Missing required parameter: name`);case`update`:return e.name?Hu({name:e.name},o):o.toTextResponse(`Missing required parameter: name`);case`backtrack`:return e.targetStep?td({targetStep:e.targetStep,lifecycleOwnerToken:e.lifecycleOwnerToken,currentToken:e.currentToken},o):o.toTextResponse(`Missing required parameter: targetStep for backtrack action`);case`claim`:return nd({currentToken:e.currentToken},o);default:return o.toTextResponse(`Unknown action: ${e.action}`)}}))}const dd=M(`tools`);function fd(e){let t=U(`evidence_map`);e.registerTool(`evidence_map`,{title:t.title,description:`Track verified/assumed/unresolved claims for complex tasks. Gate readiness: YIELD (proceed), HOLD (unknowns), HARD_BLOCK (critical gaps). Persists across calls.`,inputSchema:{action:R.enum([`create`,`add`,`update`,`get`,`gate`,`list`,`delete`]).describe(`Operation to perform`),task_id:R.string().optional().describe(`Task identifier (required for all except list)`),tier:R.enum([`floor`,`standard`,`critical`]).optional().describe(`FORGE tier (required for create)`),claim:R.string().optional().describe(`Critical-path claim text (for add)`),status:R.enum([`V`,`A`,`U`]).optional().describe(`Evidence status: V=Verified, A=Assumed, U=Unresolved`),receipt:R.string().optional().describe(`Evidence receipt: tool→ref for V, reasoning for A, attempts for U`),id:R.number().optional().describe(`Entry ID (for update)`),critical_path:R.boolean().default(!0).describe(`Whether this claim is on the critical path`),unknown_type:R.enum([`contract`,`convention`,`freshness`,`runtime`,`data-flow`,`impact`]).optional().describe(`Typed unknown classification`),safety_gate:R.enum([`provenance`,`commitment`,`coverage`]).optional().describe(`Safety gate tag: provenance (claim→evidence), commitment (user-approved), coverage (nothing dropped)`),retry_count:R.number().default(0).describe(`Retry count for gate evaluation (0 = first attempt)`),max_retries:R.number().int().min(0).optional().describe(`Maximum retries before escalating. Default: 3`),timeout_action:R.enum([`iterate`,`retry`,`manual`,`terminate`]).optional().describe(`Action to take when gate retries are exhausted. Default: manual`),cwd:R.string().optional().describe(`Working directory for evidence map storage (default: server cwd). Use root_path from forge_ground to match.`)},annotations:t.annotations},q(`evidence_map`,async({action:e,task_id:t,tier:n,claim:r,status:i,receipt:a,id:o,critical_path:s,unknown_type:c,safety_gate:l,retry_count:u,max_retries:d,timeout_action:f,cwd:p})=>{try{switch(e){case`create`:if(!t)throw Error(`task_id required for create`);if(!n)throw Error(`tier required for create`);return Dt({action:`create`,taskId:t,tier:n},p),{content:[{type:`text`,text:`Created evidence map "${t}" (tier: ${n}).\n\n---\n_Next: Use \`evidence_map\` with action "add" to record critical-path claims._`}]};case`add`:{if(!t)throw Error(`task_id required for add`);if(!r)throw Error(`claim required for add`);if(!i)throw Error(`status required for add`);let e=Dt({action:`add`,taskId:t,claim:r,status:i,receipt:a??``,criticalPath:s,unknownType:c,safetyGate:l},p),n=e.autoCreated?[`⚠️ Evidence map "${t}" was auto-created with tier "standard". Use \`create\` action to set a specific tier.`,``,`Added entry #${e.entry?.id} to "${t}": [${i}] ${r}`]:[`Added entry #${e.entry?.id} to "${t}": [${i}] ${r}`];return e.summary&&n.push(``,e.summary),{content:[{type:`text`,text:n.join(`
191
- `)}]}}case`update`:{if(!t)throw Error(`task_id required for update`);if(o===void 0)throw Error(`id required for update`);if(!i)throw Error(`status required for update`);let e=Dt({action:`update`,taskId:t,id:o,status:i,receipt:a??``},p),n=[`Updated entry #${o} in "${t}" → ${i}`];return e.summary&&n.push(``,e.summary),{content:[{type:`text`,text:n.join(`
192
- `)}]}}case`get`:{if(!t)throw Error(`task_id required for get`);let e=Dt({action:`get`,taskId:t},p);return e.state?{content:[{type:`text`,text:[`## Evidence Map: ${t} (${e.state.tier})`,``,e.formattedMap??`No entries.`,``,`_${e.state.entries.length} entries — created ${e.state.createdAt}_`].join(`
193
- `)}]}:{content:[{type:`text`,text:`Evidence map "${t}" not found.`}]}}case`gate`:{if(!t)throw Error(`task_id required for gate`);let e=Dt({action:`gate`,taskId:t,retryCount:u,maxRetries:d,timeoutAction:f},p);if(!e.gate)return{content:[{type:`text`,text:`Evidence map "${t}" not found.`}]};let n=e.gate,r=[`## FORGE Gate: **${n.verdict}**`,``,`**Reason:** ${n.reason}`,``,`**Stats:** ${n.stats.verified}V / ${n.stats.assumed}A / ${n.stats.unresolved}U (${n.stats.total} total)`];return n.action&&r.push(``,`**Recommended action:** ${n.action}`),n.retriesRemaining!==void 0&&r.push(`**Retries remaining:** ${n.retriesRemaining}`),n.summary&&r.push(``,`**Summary:** ${n.summary}`),n.warnings.length>0&&r.push(``,`**Warnings:**`,...n.warnings.map(e=>`- ⚠️ ${e}`)),n.unresolvedCritical.length>0&&r.push(``,`**Blocking entries:**`,...n.unresolvedCritical.map(e=>`- #${e.id}: ${e.claim} [${e.unknownType??`untyped`}]`)),n.safetyGates&&(r.push(``,`**Safety Gates:**`,`- Provenance: ${n.safetyGates.provenance}`,`- Commitment: ${n.safetyGates.commitment}`,`- Coverage: ${n.safetyGates.coverage}`),n.safetyGates.failures.length>0&&r.push(``,`**Safety failures:**`,...n.safetyGates.failures.map(e=>`- \u{1F6D1} ${e}`))),n.annotation&&r.push(``,`**Annotation:**`,n.annotation),e.formattedMap&&r.push(``,`---`,``,e.formattedMap),r.push(``,`---`,`_Next: ${n.verdict===`YIELD`?`Proceed to implementation.`:n.action===`iterate`?`Re-run the build loop, then evaluate the gate again.`:n.action===`retry`?`Re-evaluate the gate after refreshing evidence.`:n.action===`manual`?`Ask for human review before proceeding.`:`Abort the current path and terminate the task.`}_`),{content:[{type:`text`,text:r.join(`
194
- `)}]}}case`list`:{let e=Dt({action:`list`},p);return!e.states||e.states.length===0?{content:[{type:`text`,text:`No evidence maps found.`}]}:{content:[{type:`text`,text:e.states.map(e=>`- **${e.taskId}** (${e.tier}) — ${e.entries.length} entries — ${e.updatedAt}`).join(`
195
- `)}]}}case`delete`:if(!t)throw Error(`task_id required for delete`);return{content:[{type:`text`,text:Dt({action:`delete`,taskId:t},p).deleted?`Deleted evidence map "${t}".`:`Evidence map "${t}" not found.`}]}}}catch(e){return dd.error(`Evidence map error`,N(e)),K(`INTERNAL`,`Evidence map error: ${e instanceof Error?e.message:String(e)}`)}}))}function pd(e,t){let n=U(`digest`);e.registerTool(`digest`,{title:n.title,description:`Compress multiple text sources (handoffs, debates, phase summaries) into a token-budgeted digest. Jointly ranks across all sources, pins structured fields (status, files, decisions, blockers), and allocates budget by priority weight.`,outputSchema:Tc,inputSchema:{sources:R.array(R.object({id:R.string().describe(`Source identifier (e.g., "phase-2-handoff")`),text:R.string().max(5e5).describe(`Source text to compress`),weight:R.number().min(0).default(1).describe(`Priority weight (higher = more budget)`)})).min(1).max(20).describe(`Text sources to compress`),query:R.string().describe(`Focus query — what matters for the next step?`),max_chars:R.number().min(100).max(5e4).default(4e3).describe(`Target budget in characters`),pin_fields:R.array(R.string()).optional().describe(`Key fields to always extract (default: status, files, decisions, blockers, next)`),segmentation:R.enum([`paragraph`,`sentence`,`line`]).default(`paragraph`).describe(`How to split text for scoring`),token_budget:R.number().min(50).max(12500).optional().describe(`Token budget — overrides max_chars (approx 4 chars per token). Use to fit output into a specific context window.`)},annotations:n.annotations},async({sources:e,query:n,max_chars:r,pin_fields:i,segmentation:a,token_budget:o})=>{try{let s=await wt(t,{sources:e,query:n,maxChars:o?o*4:r,pinFields:i,segmentation:a}),c=[`## Digest (${s.totalOriginalChars} → ${s.totalCompressedChars} chars, ${(s.ratio*100).toFixed(0)}%)`,s.ref?`Ref: ${s.ref}`:void 0,``],l=Object.keys(s.fields);if(l.length>0){c.push(`### Extracted Fields`);for(let e of l){let t=s.fields[e];c.push(`**${e}:**`);for(let e of t)c.push(` - [${e.sourceId}] ${e.value}`)}c.push(``)}c.push(`### Compressed Content`,``,s.text),c.push(``,`### Source Stats`);for(let e of s.sourceStats)c.push(`- **${e.id}**: ${e.originalChars} → ${e.keptChars} chars (${e.segmentsKept}/${e.segmentsTotal} segments)`);c.push(``,`---`,"_Next: Use the digest as compressed context for the next phase. Use `stash` to persist it if needed._");let u=c.filter(e=>typeof e==`string`).join(`
196
- `);return{content:[{type:`text`,text:u}],structuredContent:{text:u,ref:s.ref,fields:s.fields,sourceStats:s.sourceStats,totalOriginalChars:s.totalOriginalChars,totalCompressedChars:s.totalCompressedChars,ratio:s.ratio}}}catch(e){return dd.error(`Digest failed`,N(e)),{...K(`INTERNAL`,`Digest failed: ${e instanceof Error?e.message:String(e)}`),structuredContent:{text:``,ref:void 0,fields:{},sourceStats:[],totalOriginalChars:0,totalCompressedChars:0,ratio:0}}}})}function md(e,t,n){let r=U(`forge_ground`);e.registerTool(`forge_ground`,{title:r.title,description:`Execute the complete FORGE Ground phase in a single call. Chains: tier classification → scope map → typed unknown seeds → constraint loading → file summaries → evidence map creation. Replaces 5-15 manual tool calls.`,inputSchema:{task:R.string().describe(`Task description`),files:R.array(R.string()).min(1).max(100).describe(`Target files being modified (absolute paths)`),root_path:R.string().describe(`Root path of the codebase`),max_constraints:R.number().min(0).max(10).default(3).describe(`Max constraint entries to load from AI Kit memory`),force_tier:R.enum([`floor`,`standard`,`critical`]).optional().describe(`Force a specific tier (skips auto-classification)`),task_id:R.string().optional().describe(`Custom task ID for evidence map (auto-generated if omitted)`)},annotations:r.annotations},q(`forge_ground`,async({task:e,files:r,root_path:i,max_constraints:a,force_tier:o,task_id:s},c)=>{try{let l=await jt(t,n,{task:e,files:r,rootPath:i,maxConstraints:a,forceTier:o,taskId:s}),u=ol(c).createTask(`FORGE Ground`,3);u.progress(0,`Classification: ${l.tier}`),u.progress(1,`Files analyzed: ${l.fileSummaries.length}`),u.progress(2,`Unknowns: ${l.typedUnknownSeeds.length}`),u.complete(`FORGE Ground complete: tier=${l.tier}`);let d=[`## FORGE Ground: **${l.tier.toUpperCase()}**`,`Estimated output: ~${l.estimatedTokens} tokens`,``];if(l.classifyTriggers.length>0){d.push(`### Classification Triggers`);for(let e of l.classifyTriggers)d.push(`- **${e.rule}** (${e.source}): ${e.detail}`);d.push(``)}if(l.fileSummaries.length>0){d.push(`### Target Files`);for(let e of l.fileSummaries)d.push(`- **${e.path}** (${e.lines} lines) — exports: ${e.exports.join(`, `)||`none`} — functions: ${e.functions.join(`, `)||`none`}`);d.push(``)}if(l.typedUnknownSeeds.length>0){d.push(`### Typed Unknown Seeds`);for(let e of l.typedUnknownSeeds)d.push(`- [${e.type}] ${e.description} → \`${e.suggestedTool}\``);d.push(``)}if(l.constraints.length>0){d.push(`### Constraint Seed`);for(let e of l.constraints)d.push(`- **${e.source}** (${(e.relevance*100).toFixed(0)}%): ${e.snippet}`);d.push(``)}if(l.scopeMap){d.push(`### Scope Map: ${l.scopeMap.files.length} files (~${l.scopeMap.totalEstimatedTokens} tokens)`);for(let e of l.scopeMap.files.slice(0,5))d.push(`- ${e.path} (${(e.relevance*100).toFixed(0)}%) — ${e.reason}`);l.scopeMap.files.length>5&&d.push(`- _...and ${l.scopeMap.files.length-5} more_`),d.push(``)}l.evidenceMapTaskId&&(d.push(`**Evidence Map:** \`${l.evidenceMapTaskId}\` (initialized)`),d.push(``)),d.push(`### Ceremony Guidance`);let f=l.ceremony;return d.push(`- **Ground:** ${f.ground}`,`- **Build:** ${f.build}`,`- **Break:** ${f.break}`,`- **Evidence Map:** ${f.evidenceMap}`,`- **Gate:** ${f.gate}`),d.push(``,`---`,`_Next: ${l.tier===`floor`?`Proceed to Build phase.`:"Use `evidence_map` to track claims during Build, then `evidence_map` gate after Break."}_`),{content:[{type:`text`,text:d.join(`
197
- `)}]}}catch(e){return dd.error(`FORGE Ground failed`,N(e)),K(`INTERNAL`,`FORGE Ground failed: ${e instanceof Error?e.message:String(e)}`)}}))}const hd=M(`tools:git`);function gd(e){let t=U(`git`);e.registerTool(`git`,{title:t.title,description:`Unified git operations — branch/status/commit context, diff parsing, changelog generation.`,outputSchema:Sc,inputSchema:{action:R.enum([`context`,`diff_parse`,`changelog`]).describe(`Which git sub-operation to perform`),cwd:R.string().optional().describe(`Repository root or working directory`),commit_count:R.number().min(1).max(50).default(5).optional().describe(`How many recent commits to include (context only)`),include_diff:R.boolean().default(!1).optional().describe(`Include diff stat for working tree changes (context only)`),diff:R.string().max(1e6).optional().describe(`Raw unified diff text (diff_parse only)`),from:R.string().max(200).optional().describe(`Start ref (tag, SHA, HEAD~N) — required for changelog`),to:R.string().max(200).default(`HEAD`).optional().describe(`End ref (changelog only)`),format:R.enum([`grouped`,`chronological`,`per-scope`]).default(`grouped`).optional().describe(`Output format (changelog only)`),include_breaking:R.boolean().default(!0).optional().describe(`Highlight breaking changes (changelog only)`)},annotations:t.annotations},async({action:e,cwd:t,commit_count:n,include_diff:r,diff:i,from:a,to:o,format:s,include_breaking:c})=>{try{switch(e){case`context`:{let e=await It({cwd:t,commitCount:n,includeDiff:r}),i=[`Git root: ${e.gitRoot}`,`Branch: ${e.branch}`,`Staged: ${e.status.staged.length}`,...e.status.staged.map(e=>` - ${e}`),`Modified: ${e.status.modified.length}`,...e.status.modified.map(e=>` - ${e}`),`Untracked: ${e.status.untracked.length}`,...e.status.untracked.map(e=>` - ${e}`),``,`Recent commits:`];if(e.recentCommits.length===0)i.push(` none`);else for(let t of e.recentCommits)i.push(` - ${t.hash} ${t.message}`),i.push(` ${t.author} @ ${t.date}`);return e.diff&&i.push(``,`Diff stat:`,e.diff),{content:[{type:`text`,text:i.join(`
198
- `)}],structuredContent:{gitRoot:e.gitRoot,branch:e.branch,commitCount:e.recentCommits.length,hasUncommitted:e.status.staged.length>0||e.status.modified.length>0||e.status.untracked.length>0,recentCommits:e.recentCommits.map(e=>({hash:e.hash,message:e.message,author:e.author,date:e.date}))}}}case`diff_parse`:{if(!i)return K(`VALIDATION`,`diff is required for diff_parse action`);let e=Ct({diff:i.replace(/\\n/g,`
199
- `).replace(/\\t/g,` `)});if(e.length===0)return{content:[{type:`text`,text:`No diff files found.`}]};let t=[];for(let n of e){let e=n.oldPath?` (from ${n.oldPath})`:``;t.push(`${n.path}${e} [${n.status}] +${n.additions} -${n.deletions} (${n.hunks.length} hunks)`);for(let e of n.hunks){let n=e.header?` ${e.header}`:``;t.push(` @@ -${e.oldStart},${e.oldLines} +${e.newStart},${e.newLines} @@${n}`)}}return{content:[{type:`text`,text:t.join(`
200
- `)}]}}case`changelog`:{if(!a)return K(`VALIDATION`,`from is required for changelog action`);let e=ot({from:a,to:o,format:s,includeBreaking:c,cwd:t}),n=`${e.stats.total} commits (${Object.entries(e.stats.types).map(([e,t])=>`${t} ${e}`).join(`, `)})`;return{content:[{type:`text`,text:`${e.markdown}\n---\n_${n}_`}]}}}}catch(e){return hd.error(`Git operation failed`,N(e)),K(`INTERNAL`,`Git operation failed: ${e instanceof Error?e.message:String(e)}`)}})}const _d=M(`tools`),vd=R.object({id:R.string().optional().describe(`Node ID (auto-generated if omitted)`),type:R.string().describe(`Node type (entity, service, api, concept, decision)`),name:R.string().describe(`Display name`),properties:R.record(R.string(),R.unknown()).optional().describe(`Arbitrary properties`),sourceRecordId:R.string().optional().describe(`Back-link to knowledge record ID`),sourcePath:R.string().optional().describe(`Source file path`)}),yd=R.object({id:R.string().optional().describe(`Edge ID (auto-generated if omitted)`),fromId:R.string().describe(`Source node ID`),toId:R.string().describe(`Target node ID`),type:R.string().describe(`Relationship type (depends-on, implements, calls, affects)`),weight:R.number().min(0).max(1).optional().describe(`Relationship weight`),properties:R.record(R.string(),R.unknown()).optional().describe(`Arbitrary properties`)});function bd(e,t,n){let r=U(`graph`);e.registerTool(`graph`,{title:r.title,description:`Query the auto-populated code knowledge graph (modules, symbols, imports) to answer
201
- structural questions vector search cannot.
202
-
203
- Common flow (when you don't have a node_id yet — TWO STEPS):
204
- 1) Discover: graph({action:'find_nodes', name_pattern:'<module-or-symbol>'})
205
- 2) Explore: graph({action:'neighbors', node_id, direction:'incoming'|'outgoing'})
206
-
207
- Single-step read actions:
208
- • symbol360 — full context (definition + references + imports) for a named symbol
209
- • traverse — walk N hops from a node
210
- • depth_traverse — bounded-depth traversal
211
- • find_edges — list edges matching criteria
212
- • cohesion — module cohesion score
213
- • stats — graph size/health
214
- • validate — integrity check
215
-
216
- Mutating actions (use deliberately): add, delete, clear, set_community,
217
- detect_communities, trace_process, delete_process.
218
-
219
- Complements: \`symbol\` (single lookup), \`trace\` (call-chain AST), \`blast_radius\` (change impact).`,outputSchema:xc,inputSchema:{action:R.enum([`find_nodes`,`find_edges`,`neighbors`,`traverse`,`stats`,`validate`,`add`,`delete`,`clear`,`detect_communities`,`set_community`,`trace_process`,`list_processes`,`delete_process`,`depth_traverse`,`cohesion`,`symbol360`]).describe(`Action: find_nodes (search nodes), find_edges (search edges), neighbors (direct connections), traverse (multi-hop), stats (graph overview), validate (check graph integrity), add (insert nodes/edges), delete (remove nodes), clear (remove all), detect_communities (find clusters), set_community (label a node), trace_process (persist execution flow), list_processes (list traced flows), delete_process (remove a flow), depth_traverse (bucket traversal by depth), cohesion (score a community), symbol360 (full node context)`),node_type:R.string().optional().describe(`Node type filter (for find_nodes)`),name_pattern:R.string().optional().describe(`Name substring match (for find_nodes)`),source_path:R.string().optional().describe(`Source path filter`),node_id:R.string().optional().describe(`Node ID (for neighbors, traverse, delete)`),edge_type:R.string().optional().describe(`Edge type filter`),from_id:R.string().optional().describe(`Source node ID (for find_edges)`),to_id:R.string().optional().describe(`Target node ID (for find_edges)`),direction:R.enum([`outgoing`,`incoming`,`both`]).default(`both`).describe(`Traversal direction`),max_depth:R.number().min(1).max(5).default(2).describe(`Max traversal depth`),limit:R.number().min(1).max(100).default(50).describe(`Max results`),max_tokens:R.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),nodes:R.array(vd).max(500).optional().describe(`Nodes to add (for action=add)`),edges:R.array(yd).max(500).optional().describe(`Edges to add (for action=add)`),community:R.string().optional().describe(`Community label (for set_community, cohesion)`),process_id:R.string().optional().describe(`Process ID (for delete_process)`),label:R.string().optional().describe(`Label for process tracing (for trace_process)`),enrich:R.boolean().default(!1).optional().describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens.`)},annotations:r.annotations},q(`graph`,async e=>{try{let r=await Rt(t,{action:e.action,nodeType:e.node_type,namePattern:e.name_pattern,sourcePath:e.source_path,nodeId:e.node_id,edgeType:e.edge_type,fromId:e.from_id,toId:e.to_id,direction:e.direction,maxDepth:e.max_depth,limit:e.limit,nodes:e.nodes,edges:e.edges,community:e.community,processId:e.process_id,label:e.label}),i=[r.summary],a=at(r.nodes??[]);if(r.nodes&&r.nodes.length>0){i.push(`
220
- ### Nodes`);for(let e of r.nodes){let t=Object.keys(e.properties).length>0?` — ${JSON.stringify(e.properties)}`:``;i.push(`- **${e.name}** (${e.type}, id: \`${e.id}\`)${t}`)}}if(r.edges&&r.edges.length>0){i.push(`
221
- ### Edges`);for(let e of r.edges){let t=bn(e.fromId,a),n=bn(e.toId,a);i.push(`- \`${t}\` —[${e.type}]→ \`${n}\`${e.weight===1?``:` (weight: ${e.weight})`}`)}}if(r.stats&&(i.push(`\nNode types: ${JSON.stringify(r.stats.nodeTypes)}`),i.push(`Edge types: ${JSON.stringify(r.stats.edgeTypes)}`)),r.validation){if(i.push(`
222
- ### Validation`),i.push(`- **Valid**: ${r.validation.valid?`yes`:`no`}`),r.validation.danglingEdges.length>0){i.push(`- **Dangling edges**:`);for(let e of r.validation.danglingEdges)i.push(` - \`${e.edgeId}\` references missing node \`${e.missingNodeId}\``)}r.validation.orphanNodes.length>0&&i.push(`- **Orphan nodes**: ${r.validation.orphanNodes.map(e=>`\`${e}\``).join(`, `)}`)}if(r.communities){i.push(`
223
- ### Communities`);let e=r.communities,t=e.slice(0,15),n=e.slice(15);for(let e of t){let t=Object.entries(e.types).sort((e,t)=>t[1]-e[1]).map(([e,t])=>`${e}(${t})`).join(`, `),n=e.samples.map(e=>`\`${e.name}\``).join(`, `);i.push(`- **${e.id.slice(0,8)}…**: ${e.nodeCount} node(s) — ${t} — ${n}`)}if(n.length>0){let e=n.reduce((e,t)=>e+t.nodeCount,0),t={};for(let e of n)for(let[n,r]of Object.entries(e.types))t[n]=(t[n]??0)+r;let r=Object.entries(t).sort((e,t)=>t[1]-e[1]).map(([t,n])=>`${t}(${Math.round(n/e*100)}%)`).join(`, `);i.push(`+ **${n.length} smaller communities** (${e} nodes): ${r}`)}}if(r.process&&(i.push(`
224
- ### Process`),i.push(`- **${r.process.label}** (id: \`${r.process.id}\`)`),i.push(`- Entry: \`${r.process.entryNodeId}\``),i.push(`- Steps: ${r.process.steps.map(e=>`\`${e}\``).join(` → `)}`)),r.processes&&r.processes.length>0){i.push(`
225
- ### Processes`);for(let e of r.processes)i.push(`- **${e.label}** (id: \`${e.id}\`) — ${e.steps.length} step(s)`)}if(r.depthGroups){i.push(`
226
- ### Depth Groups`);for(let[e,t]of Object.entries(r.depthGroups))i.push(`- **Depth ${e}**: ${t.map(e=>`${e.name} (${e.type})`).join(`, `)}`)}if(r.cohesionScore!==void 0&&i.push(`\n**Cohesion Score**: ${(r.cohesionScore*100).toFixed(1)}%`),r.symbol360){let e=r.symbol360;i.push(`
227
- ### 360° Symbol View`),i.push(`- **Node**: ${e.node.name} (${e.node.type})`),i.push(`- **Community**: ${e.community??`none`}`),i.push(`- **Incoming**: ${e.incoming.length} edge(s)`),i.push(`- **Outgoing**: ${e.outgoing.length} edge(s)`),i.push(`- **Processes**: ${e.processes.length}`)}i.push("\n---\n_Next: Use `graph(traverse)` to explore connections, `graph(add)` to insert entities, `graph(symbol360)` for full node context, or `graph(detect_communities)` to find clusters._");let o=i.join(`
228
- `);if(e.enrich&&n){let t=await G(n,{query:`graph ${e.action} ${e.name_pattern??e.node_id??e.community??``}`.trim(),filePath:e.source_path});o+=Ac(t)}return{content:[{type:`text`,text:e.max_tokens?Bn(o,e.max_tokens):o}],structuredContent:{nodes:(r.nodes??[]).map(e=>({id:e.id,name:e.name,type:e.type,...e.sourcePath?{sourcePath:e.sourcePath}:{}})),edges:(r.edges??[]).map(e=>({fromId:e.fromId,toId:e.toId,fromName:bn(e.fromId,a),toName:bn(e.toId,a),type:e.type})),communities:(r.communities??[]).map(e=>({id:e.id,nodeCount:e.nodeCount,types:e.types,samples:e.samples.slice(0,3)})),totalNodes:r.stats?.nodeCount??r.nodes?.length??0,totalEdges:r.stats?.edgeCount??r.edges?.length??0,query:e.action}}}catch(e){return _d.error(`Graph query failed`,N(e)),K(`INTERNAL`,`Graph query failed: ${e instanceof Error?e.message:String(e)}`)}}))}const xd=M(`tools:infra`);function Sd(e){let t=U(`process`);e.registerTool(`process`,{title:t.title,description:`Start, stop, inspect, list, and tail logs for in-memory managed child processes.`,inputSchema:{action:R.enum([`start`,`stop`,`status`,`list`,`logs`]).describe(`Process action to perform`),id:R.string().optional().describe(`Managed process ID`),command:R.string().optional().describe(`Executable to start`),args:R.array(R.string()).optional().describe(`Arguments for start actions`),tail:R.number().min(1).max(500).optional().describe(`Log lines to return for logs actions`)},annotations:t.annotations},q(`process`,async({action:e,id:t,command:n,args:r,tail:i})=>{try{switch(e){case`start`:if(!t||!n)throw Error(`id and command are required for start`);return{content:[{type:`text`,text:JSON.stringify(en(t,n,r??[]))}]};case`stop`:if(!t)throw Error(`id is required for stop`);return{content:[{type:`text`,text:JSON.stringify(nn(t)??null)}]};case`status`:if(!t)throw Error(`id is required for status`);return{content:[{type:`text`,text:JSON.stringify(tn(t)??null)}]};case`list`:return{content:[{type:`text`,text:JSON.stringify(Qt())}]};case`logs`:if(!t)throw Error(`id is required for logs`);return{content:[{type:`text`,text:JSON.stringify($t(t,i))}]}}}catch(e){return xd.error(`Process action failed`,N(e)),K(`INTERNAL`,`Process action failed: ${e instanceof Error?e.message:String(e)}`)}}))}function Cd(e){let t=U(`web_fetch`);e.registerTool(`web_fetch`,{title:t.title,description:`PREFERRED web fetcher — fetch one or many URLs and convert to LLM-optimized markdown. Pass one URL or multiple for parallel fetching. Supports CSS selectors, 4 output modes (markdown/raw/links/outline), smart paragraph-boundary truncation. Strips scripts/styles/nav automatically.`,inputSchema:{urls:R.array(R.string().url()).min(1).max(10).describe('URLs to fetch (1–10). Single URL: `["https://..."]`. Multiple fetched in parallel.'),mode:R.enum([`markdown`,`raw`,`links`,`outline`]).default(`markdown`).describe(`Output mode: markdown (clean content), raw (HTML), links (extracted URLs), outline (heading hierarchy)`),selector:R.string().optional().describe(`CSS selector to extract a specific element instead of auto-detecting main content`),max_length:R.number().min(500).max(1e5).default(15e3).describe(`Max characters in output — truncates at paragraph boundaries`),include_metadata:R.boolean().default(!0).describe(`Include page title, description, and URL as a header`),include_links:R.boolean().default(!1).describe(`Append extracted links list at the end`),include_images:R.boolean().default(!1).describe(`Include image alt texts inline`),timeout:R.number().min(1e3).max(12e4).default(3e4).describe(`Request timeout in milliseconds`),allow_localhost:R.boolean().default(!1).describe(`Allow requests to localhost/loopback addresses (127.0.0.1, localhost, ::1). Default false for SSRF protection. Set true for local dev servers.`)},annotations:t.annotations},q(`web_fetch`,async({urls:e,mode:t,selector:n,max_length:r,include_metadata:i,include_links:a,include_images:o,timeout:s,allow_localhost:c})=>{let l=e,u=async(e,l)=>{let u=await Hn({url:e,mode:t,selector:n,maxLength:r,includeMetadata:i,includeLinks:a,includeImages:o,timeout:s,allowLocalhost:c}),d=[l?`## ${l} ${u.title||`Web Page`}\n> Source: ${e}`:`## ${u.title||`Web Page`}`,``,u.content];return u.truncated&&d.push(``,`_Original length: ${u.originalLength.toLocaleString()} chars_`),d.join(`
229
- `)};if(l.length===1)try{return{content:[{type:`text`,text:await u(l[0])+"\n\n---\n_Next: Use `remember` to save key findings, or `web_fetch` with a `selector` to extract a specific section._"}]}}catch(e){let t=e instanceof Error?e.message:String(e);return/HTTP [45]\d{2}/.test(t)?xd.warn(`Web fetch failed`,{error:t}):xd.error(`Web fetch failed`,N(e)),{...K(`INTERNAL`,`Web fetch failed: ${t}`)}}let d=l.length,f=await Promise.allSettled(l.map((e,t)=>u(e,`[${t+1}/${d}]`))),p=[],m=0;for(let e=0;e<f.length;e++){let t=f[e];if(t.status===`fulfilled`)p.push(t.value);else{m++;let n=t.reason instanceof Error?t.reason.message:String(t.reason);/HTTP [45]\d{2}/.test(n)?xd.warn(`Web fetch failed`,{url:l[e],error:n}):xd.error(`Web fetch failed`,{url:l[e],...N(t.reason)}),p.push(`## ❌ Failed: ${l[e]}\n\n${n}`)}}let h=`_Fetched ${f.length-m}/${f.length} URLs successfully._`;p.push(``,`---`,h,"_Next: Use `remember` to save key findings, or `web_fetch` with a `selector` to extract a specific section._");let g=p.join(`
230
-
231
- `);return m===f.length?K(`INTERNAL`,g):{content:[{type:`text`,text:g}]}}))}function wd(e,t,n){if(!(!e||typeof e!=`string`)&&!(e.includes(`..`)||e.startsWith(`/`)||e.startsWith(`[`)))return{type:`resource_link`,uri:`aikit://curated/${e}`,name:t??e,mimeType:`text/markdown`,...n?{description:n}:{}}}function Td(e){let t=new Set,n=[];for(let r of e){let e=wd(r.path,r.title,r.category?`[${r.category}]`:void 0);e&&!t.has(e.uri)&&(t.add(e.uri),n.push(e))}return n}function Ed(e){if(e.startsWith(`.ai/curated/`))return e.slice(12)}const Dd={decisions:`decision`,patterns:`pattern`,conventions:`pattern`,context:`analysis`,session:`step-summary`},Od=new Set([`decision`,`pattern`,`file-card`,`analysis`,`search-result`,`step-summary`]),kd=R.enum([`remember`,`read`,`update`,`forget`,`list`,`history`,`diff`,`recover`,`orphaned`,`withdraw`,`flush`,`flagged`,`lesson`,`gap-analysis`]),Ad=R.enum([`create`,`confirm`,`contradict`,`list-lessons`,`auto-observe`,`prune`,`group`,`promote`,`demote`]),jd=R.enum([`confidence`,`recent`]),Md=R.string().min(3).max(120).describe(`Short descriptive title for the knowledge entry`),Nd=R.string().min(10).max(1e5),Pd=R.string().regex(/^[a-z][a-z0-9-]*$/).describe(`Category slug (e.g., "decisions", "patterns", "conventions", "api-contracts")`),Fd=R.array(R.string()).default([]).describe(`Optional tags for filtering`),Id=R.string().describe(`Relative path within .ai/curated/ (e.g., "decisions/use-lancedb.md")`),Ld=R.string().min(3),Rd=R.number().int().min(0).max(100).describe(`Lesson confidence from 0-100`),zd=R.object({title:Md,content:Nd.describe(`The markdown content to store`),category:Pd,tags:Fd,force:R.boolean().optional().describe(`When true, supersede flagged similar entries without waiting for confirmation`)}),Bd=R.object({path:Id}),Vd=R.object({path:Id,content:Nd.describe(`New markdown content to replace existing content`),reason:Ld.max(1e3).describe(`Why this update is being made (recorded in changelog)`)}),Hd=R.object({path:R.string().describe(`Relative path within .ai/curated/ (e.g., "decisions/deprecated-approach.md")`),reason:Ld.describe(`Why this entry is being removed`)}),Ud=R.object({category:R.string().optional().describe(`Filter by category (e.g., "decisions", "patterns")`),tag:R.string().optional().describe(`Filter by tag`),limit:R.number().int().min(1).max(200).default(50).describe(`Maximum entries to return`),offset:R.number().int().min(0).default(0).describe(`Pagination offset`)}),Wd=R.object({title:Md,context:Nd.describe(`What happened (the situation)`),insight:Nd.describe(`What was learned (the lesson)`),evidence:Nd.describe(`Proof or justification`),confidence:Rd.default(50),tags:Fd.optional().default([])}),Gd=R.object({path:Id.optional(),id:Id.optional(),reason:Ld.max(1e3).optional()}).refine(e=>!!(e.path??e.id),{message:`path or id is required`,path:[`path`]}),Kd=R.object({topic:R.string().optional(),minConfidence:Rd.optional(),tag:R.string().optional(),tags:R.array(R.string()).optional(),sortBy:jd.default(`confidence`),includeArchived:R.boolean().default(!1),limit:R.number().int().min(1).max(200).default(50),offset:R.number().int().min(0).default(0)}),qd=R.object({bufferPath:R.string().optional()}),Jd=R.object({maxConfidence:Rd.optional(),minIdleDays:R.number().int().min(1).optional(),safetyDays:R.number().int().min(0).optional(),maxPrune:R.number().int().min(1).max(1e3).optional(),dryRun:R.boolean().default(!0)}),Yd=R.object({similarityThreshold:R.number().min(0).max(1).optional(),minGroupSize:R.number().int().min(2).max(1e3).optional(),maxGroups:R.number().int().min(1).max(1e3).optional(),dryRun:R.boolean().default(!0)}),Xd=R.object({minWorkspaces:R.number().int().min(2).max(1e3).optional(),minAvgConfidence:Rd.optional(),similarityThreshold:R.number().min(0).max(1).optional(),dryRun:R.boolean().default(!0)}),Zd=R.object({action:kd.describe(`Knowledge operation to perform`),title:Md.optional(),content:Nd.optional(),category:Pd.optional(),tags:R.array(R.string()).optional().describe(`Optional tags for remember`),path:Id.optional(),reason:Ld.max(1e3).optional(),scope:R.enum([`curated`,`flow`]).optional().describe(`Storage scope: curated (default) or flow-scoped ephemeral context`),profile:R.string().optional().describe(`Role profile for withdraw filtering (e.g., "implementer", "reviewer", "debugger")`),budget:R.number().int().min(100).max(5e4).optional().describe(`Maximum character budget for withdraw results (default: 6000)`),token_budget:R.number().int().min(50).max(12500).optional().describe(`Token budget (overrides budget). Approx 4 chars per token.`),tag:R.string().optional().describe(`Filter by tag when action="list"`),id:Id.optional().describe(`Alias for path when action="lesson"`),subAction:Ad.optional().describe(`Lesson sub-action when action="lesson"`),bufferPath:R.string().optional().describe(`Optional observation buffer path for lesson auto-observe`),context:Nd.optional().describe(`What happened (the situation) for lesson creation`),insight:Nd.optional().describe(`What was learned (the lesson) for lesson creation`),evidence:Nd.optional().describe(`Proof or justification for lesson creation`),confidence:Rd.optional(),minConfidence:Rd.optional().describe(`Minimum confidence when listing lessons`),topic:R.string().optional().describe(`Topic filter when listing lessons`),sortBy:jd.optional().describe(`Sort lessons by confidence or recency`),includeArchived:R.boolean().optional().describe(`Include auto-archived lessons in list-lessons`),maxConfidence:Rd.optional().describe(`Prune lessons below this effective confidence`),minIdleDays:R.number().int().min(1).optional().describe(`Minimum idle days required before pruning a lesson`),safetyDays:R.number().int().min(0).optional().describe(`Never prune if accessed within this many days`),maxPrune:R.number().int().min(1).max(1e3).optional().describe(`Maximum number of lessons to prune in one run`),similarityThreshold:R.number().min(0).max(1).optional().describe(`Minimum Jaccard similarity required to group lesson titles`),minGroupSize:R.number().int().min(2).max(1e3).optional().describe(`Minimum number of lessons required to form a group`),maxGroups:R.number().int().min(1).max(1e3).optional().describe(`Maximum number of lesson groups to create in one run`),minWorkspaces:R.number().int().min(2).max(1e3).optional().describe(`Minimum number of distinct workspaces required before promoting a lesson`),minAvgConfidence:Rd.optional().describe(`Minimum average lesson confidence required before promoting a lesson`),dryRun:R.boolean().optional().describe(`Preview the operation without modifying stored lessons`),limit:R.number().int().min(1).max(200).optional().describe(`Maximum entries to return for list/history operations`),offset:R.number().int().min(0).optional().describe(`Pagination offset when action="list"`),force:R.boolean().optional().describe(`When true, supersede flagged similar entries without waiting for confirmation`),from_sha:R.string().optional().describe(`Start SHA for diff (older version). If omitted with to_sha, shows full content.`),to_sha:R.string().optional().describe(`End SHA for diff (newer version). If omitted, uses the latest two versions.`),max_tokens:R.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),enrich:R.boolean().default(!1).optional().describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens.`)}),Qd=M(`tools`);function $d(e,t){return[`knowledge`,e,t.path,t.id,t.title,t.topic,t.category,t.tag,t.profile].filter(e=>typeof e==`string`&&e.length>0).join(` `)}async function ef(e,t,n){let r=e.content?.find(e=>typeof e==`object`&&!!e&&`type`in e&&e.type===`text`);if(!r)return e;let i=r.text??``;if(t.enrich&&n){let e=await G(n,{query:$d(t.action,t)});i+=Ac(e)}t.max_tokens&&(i=Bn(i,t.max_tokens));let a=Vl(i),o=Hl(i,a),s=a&&e.structuredContent&&typeof e.structuredContent==`object`?{...e.structuredContent,ref:a}:a?{ref:a}:e.structuredContent;return{...e,content:e.content.map(e=>e.type===`text`?{...e,text:o}:e),structuredContent:s}}function tf(e,t,n,r){b(e,t,n);let i=e.memoryMetaGet(t);if(!i)return;let a=g(i,{..._,...r});return a?(y(e,t,a),v(e,t,n)??e.memoryMetaGet(t)):i}function nf(e,t){return`\n\n### ${e}\n${t.map(e=>`- **${e.title}** (${e.id}) — similarity ${e.similarity.toFixed(3)}`).join(`
232
- `)}`}async function rf(e,t,r,i){if(typeof e.list!=`function`||typeof e.read!=`function`)return[];let a=n(i),o=await e.list({category:r,limit:a.maxCompare,orderBy:`updated`,order:`desc`});return o.length===0?[]:u(t,await Promise.all(o.map(async t=>{let n=await e.read(t.path);return{id:t.path,title:n.title,content:n.content,path:t.path}})),a)}function af(e,t,n){return{superseded:e.filter(e=>n||e.similarity>=t).map(e=>({id:e.entryId,title:e.title,similarity:e.similarity})),supersessionCandidates:n?[]:e.filter(e=>e.similarity<t).map(e=>({id:e.entryId,title:e.title,similarity:e.similarity}))}}function of(e){if(!e)return`analysis`;let t=Dd[e]??e;return Od.has(t)?t:`analysis`}function sf(e){let t=[...new Set(e.issues.filter(e=>e.code===`invalid_type`&&/received undefined$/i.test(e.message)).map(e=>e.path.join(`.`)).filter(e=>e.length>0))];if(t.length>0)return`Missing required fields: ${t.join(`, `)}`;let n=e.issues.map(e=>`${e.path.length>0?`${e.path.join(`.`)}: `:``}${e.message}`).join(`; `);return n.length>0?`Invalid parameters: ${n}`:`Invalid parameters.`}function cf(e,t){return e??t??``}function lf(e){return[...new Set([...e??[],`lesson`])]}function uf(e,t,n){if(e)return e.memoryMetaCreate(t,`working`),e.memoryMetaUpdateConfidence(t,n),e.memoryMetaGet(t)}function df(e,t,n,r=d){if(!e)return;let i=f(r);e.memoryMetaCreate(t,`working`),e.memoryMetaTouch(t);let a=n??e.memoryMetaGet(t)?.confidence??50,o=Math.min(100,a+i.implicitUseIncrement);return e.memoryMetaUpdateConfidence(t,o),e.memoryMetaGet(t)}function ff(e){let t=e.matchAll(/(?:\.ai\/curated\/)?(lessons\/[A-Za-z0-9._/%-]+\.md)/g);return[...new Set(Array.from(t,e=>e[1]))]}async function pf(e,t,n){let r=await e.read(n),i=a(r.content),o=t?.memoryMetaGet(n)?.confidence??i.confidence??50;return{entry:r,confidence:o,meta:uf(t,n,o)??t?.memoryMetaGet(n)}}function mf(e){if(typeof e!=`object`||!e)return e;let t=e;if(t.title)return e;let n=typeof t.topic==`string`&&t.topic||typeof t.insight==`string`&&t.insight||``;if(!n)return e;let r=n.length<=120?n:`${n.slice(0,117)}...`;return{...t,title:r}}async function hf(e){if(e){let t=L(e);try{return await Ke(t),t}catch{return}}let t=(await We(Gn(),{withFileTypes:!0})).filter(e=>e.isFile()&&e.name.startsWith(`aikit-obs-`)&&e.name.endsWith(`.jsonl`)).map(e=>I(Gn(),e.name)),n=await Promise.all(t.map(async e=>{try{return{path:e,mtimeMs:(await Ke(e)).mtimeMs}}catch{return{path:e,mtimeMs:0}}}));return n.sort((e,t)=>t.mtimeMs-e.mtimeMs),n[0]?.path}function gf(e,t){return t.map(t=>({path:t.path,title:t.title,similarity:p(e,t.title)})).filter(e=>e.similarity>.8).sort((e,t)=>t.similarity-e.similarity)[0]}function _f(e){let t=[`Lesson prune ${e.dryRun?`preview`:`completed`}: ${e.pruned.length} lessons selected.`,`Skipped ${e.skipped} lessons.`];return e.pruned.length>0&&(t.push(``,`Pruned:`),t.push(...e.pruned.map(e=>`- ${e}`))),t.join(`
233
- `)}function vf(e){let t=[`Lesson grouping ${e.dryRun?`preview`:`completed`}: ${e.groupsCreated} groups, ${e.lessonsGrouped} lessons.`];return e.groups.length>0&&(t.push(``,`Groups:`),t.push(...e.groups.map(e=>`- ${e.label}: ${e.members.join(`, `)}`))),t.join(`
234
- `)}function yf(e,n){let r=e;return new t(n,r.store,r.embedder)}function bf(e,t){let n=e.candidates.filter(e=>e.action===`promote`),r=e.candidates.filter(e=>e.action===`skip`),i=[`Lesson promotion ${t?`preview`:`completed`}: ${n.length} candidates ready.`,`Skipped ${r.length} candidates.`];return n.length>0&&(i.push(``,`Candidates:`),i.push(...n.map(e=>`- ${e.insight} (${e.foundIn.join(`, `)}) avg ${e.avgConfidence}/100`))),r.length>0&&(i.push(``,`Skipped:`),i.push(...r.map(e=>`- ${e.insight}: ${e.reason}`))),e.promoted.length>0&&(i.push(``,`Promoted:`),i.push(...e.promoted.map(e=>`- ${e}`))),i.join(`
235
- `)}async function xf(e,t){let r=e;if(r.scope===`flow`&&t.flowContextAdapter){let{title:e,content:n,category:i}=r,a=(e??`untitled`).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-|-$/g,``),o=of(i),s=o?`${o}/${a}.md`:`${a}.md`,c=`# ${e}\n\n${n??``}`;return await t.flowContextAdapter.write(s,c),{content:[{type:`text`,text:`Deposited flow context at \`${s}\``}]}}let{curated:i,policyStore:a,evolutionCollector:o,resourceNotifier:c,stateStore:l,supersessionConfig:u}=t,{title:d,content:f,category:p,tags:m,force:h=!1}=zd.parse(e),g=n(u),_=await rf(i,f,p,g),v=await i.remember(d,f,p,m);l?.memoryMetaCreate(v.path,`working`);let y=af(_,g.autoThreshold,h);if(l)for(let e of y.superseded)s(l,e.id,v.path);let b=``;if(a){let e=a.classify(d,f,m);o&&o.recordClassification(d,e.matchingRules.map(e=>e.ruleId),e.pushRecommended),e.matchingRules.length>0&&(b=`\n\n### Classification Signals\n${e.matchingRules.map(e=>` - **${e.ruleId}** (${e.category}, weight: ${e.pushWeight}) — matched: ${e.matchedPatterns.join(`, `)}`).join(`
236
- `)}\n- **Push recommended**: ${e.pushRecommended?`yes`:`no`} (max weight: ${e.maxPushWeight})`,e.pushRecommended&&(b+=`
237
-
238
- > 💡 This entry matches push rules. Consider \`er_push\` to share with Enterprise RAG.`))}c&&c.notifyAfterCuratedWrite(v.path).catch(()=>{});let x=wd(v.path,d,`[${p}]`),S=y.superseded.length>0?nf(`Superseded Entries`,y.superseded):``,C=y.supersessionCandidates.length>0?nf(`Supersession Suggestions`,y.supersessionCandidates):``;return{content:[{type:`text`,text:`Remembered: **${d}**\n\nStored at \`.ai/curated/${v.path}\` and indexed for semantic search.${b}${S}${C}\n\n---\n_Next: Use \`search\` to verify the entry is findable, or \`knowledge({ action: "list" })\` to see all curated entries._`},...x?[x]:[]],structuredContent:{path:v.path,superseded:y.superseded,supersessionCandidates:y.supersessionCandidates}}}async function Sf(e,{curated:t,stateStore:n,retentionConfig:r,consolidationConfig:i}){let{path:a}=Bd.parse(e),o=await t.read(a),s=n?tf(n,a,r,i):void 0,c=[`## ${o.title}`,`- **Path**: .ai/curated/${a}`,`- **Category**: ${o.category}`,o.tags.length?`- **Tags**: ${o.tags.join(`, `)}`:null,`- **Version**: ${o.version}`,`- **Created**: ${o.created}`,o.updated===o.created?null:`- **Updated**: ${o.updated}`,s?`- **Tier**: ${s.tier}`:null,s?`- **Retention**: ${s.retentionScore.toFixed(3)}`:null,``].filter(e=>e!==null).join(`
239
- `),l=wd(a,o.title,`[${o.category}]`);return{content:[{type:`text`,text:`${c}\n${o.content}\n\n---\n_Next: Use \`knowledge({ action: "update", ... })\` to modify this entry, or \`search\` to find related entries._`},...l?[l]:[]]}}async function Cf(e,{curated:t,resourceNotifier:n}){let{path:r,content:i,reason:a}=Vd.parse(e),o=await t.update(r,i,a);return n&&n.notifyAfterCuratedWrite(r).catch(()=>{}),{content:[{type:`text`,text:`Updated: \`.ai/curated/${o.path}\` → version ${o.version}\n\nReason: ${a}\n\n---\n_Next: Use \`knowledge({ action: "read", path: "${o.path}" })\` to verify the updated content, or \`search\` to test searchability._`}]}}async function wf(e,{curated:t,resourceNotifier:n}){let{path:r,reason:i}=Hd.parse(e),a=L(t.curatedDir,r);if(P(a))try{vt(`forget`,[{path:a,content:F(a,`utf-8`)}],`forget: ${r}`)}catch{}let o=await t.forget(r,i);return Qd.info(`Forgot entry`,{path:o.path,reason:i}),n&&(n.notifyAfterCuratedWrite().catch(()=>{}),n.notifyResourceListChanged().catch(()=>{})),{content:[{type:`text`,text:`Forgotten: \`.ai/curated/${o.path}\`\n\nRemoved from disk and vector store.\nReason: ${i}\n\n---\n_Next: Use \`knowledge({ action: "list" })\` to verify removal, or \`search\` to confirm the entry is no longer returned._`}]}}async function Tf(e,t){if(e.scope===`flow`&&t.flowContextAdapter){let e=await t.flowContextAdapter.list();if(e.length===0)return{content:[{type:`text`,text:`## Flow Context
240
-
241
- No flow context entries found.`}]};let n=e.map(e=>` - \`${e.path}\` (${e.size} chars)`).join(`
242
- `);return{content:[{type:`text`,text:`## Flow Context (${e.length} entries)\n\n${n}`}]}}let{curated:n,stateStore:r,retentionConfig:i}=t,{category:a,tag:o,limit:s,offset:c}=Ud.parse(e),l=await n.listPage({category:a,tag:o,limit:s,offset:c,orderBy:`updated`,order:`desc`}),u=l.entries,d=u.map(e=>({entry:e,retentionMeta:r?v(r,e.path,i):void 0})),f={entries:d.map(({entry:e,retentionMeta:t})=>({path:e.path,title:e.title,category:e.category,tags:e.tags,version:e.version,preview:e.contentPreview?.slice(0,120)??``,...t?{retentionScore:t.retentionScore,tier:t.tier}:{}})),totalCount:l.totalCount,returnedCount:u.length,limit:l.limit,offset:l.offset,hasMore:l.hasMore};if(u.length===0)return{content:[{type:`text`,text:`No curated knowledge entries found.`+(a?` (category: ${a})`:``)+(o?` (tag: ${o})`:``)}],structuredContent:f};let p=d.map(({entry:e,retentionMeta:t})=>{let n=e.tags.length>0?` [${e.tags.join(`, `)}]`:``,r=t?` | tier ${t.tier} | retention ${t.retentionScore.toFixed(3)}`:``;return`- **${e.title}** (v${e.version})${n}${r}\n \`${e.path}\` — ${e.contentPreview.slice(0,80)}…`}).join(`
243
- `),m=Td(u),h=l.hasMore?`\n\n_Showing ${u.length} of ${l.totalCount} entries. Request \`offset: ${l.offset+u.length}\` for next page._`:l.totalCount>u.length?`\n\n_Showing ${u.length} of ${l.totalCount} entries._`:``;return{content:[{type:`text`,text:`## Curated Knowledge (${u.length} of ${l.totalCount} entries)\n\n${p}${h}\n\n---\n_Next: Use \`knowledge({ action: "read", path: "..." })\` to view full content of any entry, or \`knowledge({ action: "remember", ... })\` to store new knowledge._`},...m],structuredContent:f}}async function Ef(e,{curated:t}){let{path:n}=Bd.parse(e),r=e.limit??20,i=await t.history(n,r);if(i.length===0)return{content:[{type:`text`,text:`No git history available for this entry. Git-backing may not be available or the entry predates git-backing.`}]};let a=i.map((e,t)=>`${t+1}. **${e.date}** \`${e.sha.slice(0,8)}\` — ${e.message}`).join(`
244
- `);return{content:[{type:`text`,text:`## History for \`${n}\` (${i.length} entries)\n\n${a}\n\n_Use \`knowledge({ action: "diff", path: "${n}", from_sha: "...", to_sha: "..." })\` to compare versions._`}]}}async function Df(e,{curated:t}){let{path:n}=Bd.parse(e),{from_sha:r,to_sha:i}=e,a=await t.diff(n,r,i);return a?{content:[{type:`text`,text:`## Diff for \`${n}\`\n\n\`\`\`diff\n${a}\n\`\`\``}]}:{content:[{type:`text`,text:`No diff available. Git-backing may not be available or the entry has no history.`}]}}async function Of(e,{curated:t}){let{path:n}=Bd.parse(e),r=await t.recover(n);return r?{content:[{type:`text`,text:`✅ Recovered \`${r.path}\` (version ${r.version}) from git history. The entry has been restored to the filesystem and re-indexed.`}]}:{content:[{type:`text`,text:`No git history found for \`${n}\`. Cannot recover — the entry either never existed or was never git-backed.`}]}}async function kf(e,{curated:t}){let n=await t.listOrphaned();if(n.length===0)return{content:[{type:`text`,text:`No orphaned entries found. All git-backed entries have corresponding filesystem files.`}]};let r=n.map((e,t)=>`${t+1}. \`${e.path}\` — last: ${e.lastMessage}`).join(`
245
- `);return{content:[{type:`text`,text:`## Orphaned Knowledge Entries (${n.length})\n\nThese entries exist in git but are missing from the filesystem:\n\n${r}\n\n_Use \`knowledge({ action: "recover", path: "..." })\` to restore any of these entries._`}]}}async function Af(e,{curated:t,stateStore:n,retentionConfig:r,lessonConfig:a}){if(!n)return{content:[{type:`text`,text:`Retention state store not available.`}],structuredContent:{entries:[],totalCount:0}};let o=S(n,r),s=f(a??d),l=await t.list({category:`lessons`}),u=(await Promise.all(l.filter(e=>e.tags.includes(`lesson`)).map(async e=>{let r=n.memoryMetaGet(e.path);return r||=(await pf(t,n,e.path)).meta,!r||!i(r,s)?null:{path:e.path,title:e.title,confidence:c(r.confidence,r.lastAccessedAt,r.createdAt,s),createdAt:r.createdAt,lastAccessedAt:r.lastAccessedAt,supersededBy:r.supersededBy}}))).filter(e=>e!==null).sort((e,t)=>e.confidence-t.confidence||Date.parse(e.lastAccessedAt??e.createdAt)-Date.parse(t.lastAccessedAt??t.createdAt));if(o.length===0&&u.length===0)return{content:[{type:`text`,text:`No flagged knowledge entries found below the current retention threshold.`}],structuredContent:{entries:[],totalCount:0}};let p=o.length===0?`### Retention
246
- None.`:`### Retention\n${o.map(e=>`- \`${e.entryId}\` — score ${e.retentionScore.toFixed(3)}, tier ${e.tier}, accesses ${e.accessCount}`).join(`
247
- `)}`,m=u.length===0?`### Stale Lessons
248
- None.`:`### Stale Lessons\n${u.map(e=>`- **${e.title}** (\`${e.path}\`) — effective confidence ${e.confidence}/100, last access ${e.lastAccessedAt??e.createdAt}`).join(`
249
- `)}`;return{content:[{type:`text`,text:`## Flagged Knowledge Entries (${o.length+u.length})\n\n${p}\n\n${m}`}],structuredContent:{entries:o,staleLessons:u,totalCount:o.length+u.length}}}const jf=/^(export|import|function|class|interface|type|const|let|var|→|├|└|─|##)/,Mf=/^(decision|rationale|status|context|consequence)/i,Nf=/finding|recommendation|warning|error|issue/i,Pf=/status|done|decision|blocker|next|file|created|modified/i,Ff=/(score|relevance)/i,If=/[/.]|\\.(ts|js)$/i;function Lf(e){return e.split(/\r?\n/u).map(e=>e.replace(/[ \t]+$/u,``)).join(`
250
- `).replace(/\n{3,}/gu,`
251
-
252
- `).trim()}function Rf(e,t){if(e.length<=t)return e;let n=e.split(`
253
- `),r=[],i=0;for(let e of n){let n=r.length===0?e.length:e.length+1;if(i+n>t)break;r.push(e),i+=n}return r.length>0?r.join(`
254
- `):e.slice(0,t).trimEnd()}function zf(e,t,n){return Rf(e,Math.max(1,Math.floor(n*t)))}function Bf(e,t){if(e.length<50)return e;let n=Lf(t);return!n||n.length<e.length*.2?e:n}function Vf(e,t,n){let r=new Set;for(let n=0;n<Math.min(t,e.length);n+=1)r.add(n);return e.forEach((e,t)=>{n(e,t)&&r.add(t)}),e.filter((e,t)=>r.has(t)).join(`
255
- `)}function Hf(e,t){e.includes(t)||e.push(t)}function Uf(e){return Bf(e,zf(Vf(e.split(/\r?\n/u),3,e=>jf.test(e)||e.startsWith(`- `)),.6,e.length))}function Wf(e){let t=e.split(/\r?\n/u),n=[];return t.forEach((e,t)=>{if(t<5||Ff.test(e)||If.test(e)||/^Content:/i.test(e)){if(/^Content:/i.test(e)){Hf(n,`Content: ${e.replace(/^Content:\s*/i,``).trim().slice(0,200)}`);return}Hf(n,e)}}),Bf(e,n.join(`
256
- `))}function Gf(e){let t=e.split(/\r?\n/u),n=new Set;for(let e=0;e<t.length&&t[e].trim()!==``;e+=1)n.add(e);return t.forEach((e,t)=>{(e.startsWith(`- `)||e.startsWith(`* `)||Mf.test(e))&&n.add(t)}),Bf(e,zf(t.filter((e,t)=>n.has(t)).join(`
257
- `),.7,e.length))}function Kf(e){let t=e.split(/\r?\n/u),n=new Set,r=!1;for(let e=0;e<Math.min(2,t.length);e+=1)n.add(e);return t.forEach((e,t)=>{if(e.startsWith("```")){n.add(t),r=!r;return}(r||e.startsWith(`##`)||e.startsWith(`- `)||e.startsWith(`* `))&&n.add(t)}),Bf(e,zf(t.filter((e,t)=>n.has(t)).join(`
258
- `),.65,e.length))}function qf(e){return Bf(e,zf(e.split(/\r?\n/u).filter(e=>e.startsWith(`#`)||e.startsWith(`- `)||/\d/.test(e)||/\d+%/.test(e)||Nf.test(e)).join(`
259
- `),.6,e.length))}function Jf(e){return Bf(e,zf(e.split(/\r?\n/u).filter(e=>e.startsWith(`- `)||e.startsWith(`* `)||Pf.test(e)).join(`
260
- `),.5,e.length))}function Yf(e,t){switch(e){case`file-card`:return Uf(t);case`search-result`:return Wf(t);case`decision`:return Gf(t);case`pattern`:return Kf(t);case`analysis`:return qf(t);case`step-summary`:return Jf(t)}}const Xf=/^### (Context|Insight|Evidence|Key|Finding|Result|Decision)/imu;function Zf(e,t){let n=e.trim();if(!n||n.length<=t)return n;let r=n.split(/\\r?\\n/u),i=new Set;for(let e=0;e<r.length;e++)if(/^#{1,3}\s/mu.test(r[e])&&i.size===0){i.add(e);for(let t=e+1;t<r.length;t++)if(r[t].trim().length>0){i.add(t);break}}r.forEach((e,t)=>{if((/^\s*[-*]\s/mu.test(e)||/^\d+\.\s/mu.test(e))&&i.add(t),Xf.test(e)){i.add(t);let e=r[t+1]?.trim();e&&!/^[#>-]/.test(e)&&i.add(t+1)}/^(Confidence|Source|Tags?):/imu.test(e)&&i.add(t)}),n.length>t&&r.forEach((e,t)=>{i.has(t)||/\b(always|never|prefer|use|should|must|requires?|detected|confirmed|verified)\b/im.test(e)&&i.add(t)});let a=r.filter((e,t)=>i.has(t)).join(`
261
- `).trim();return a.length<=t?Lf(a):Rf(Lf(a),t)}function Qf(e,t,n,r){let i=t?.trim()??``,a=`(confidence: ${n}/100)`,o=`**${e}** ${a} — ${i}`.trim();if(o.length<=r)return o;let s=`**${e}** ${a}`;if(s.length<=r)return s;let c=r-a.length-8;return`**${e.length>c?`${e.slice(0,Math.max(0,c-3))}...`:e}** ${a}`}const $f={decision:6,pattern:5,"file-card":4,analysis:3,"search-result":2,"step-summary":1},ep={"search-result":864e5,"file-card":1728e5,analysis:1728e5,"step-summary":2592e5,decision:6048e5,pattern:6048e5},tp={implementer:{name:`implementer`,contextTypes:[`file-card`,`decision`,`pattern`],priority:{...$f}},documenter:{name:`documenter`,contextTypes:[`decision`,`pattern`,`step-summary`],priority:{...$f}},reviewer:{name:`reviewer`,contextTypes:[`file-card`,`search-result`,`decision`,`pattern`,`step-summary`,`analysis`],priority:{...$f}},researcher:{name:`researcher`,contextTypes:[`search-result`,`decision`,`analysis`],priority:{...$f}},debugger:{name:`debugger`,contextTypes:[`file-card`,`search-result`,`pattern`,`analysis`],priority:{...$f}}};function np(e){return tp[e]}function rp(e,t,n=Date.now()){let r=n-t;if(r<36e5)return!1;let i=ep[e];return i==null?!1:r>i}function ip(e,t,n){if(n<=0)return[];let r=new Set(t.contextTypes),i=e.filter(e=>r.has(e.type)).map((e,t)=>({entry:e,index:t})).sort((e,n)=>{let r=t.priority[n.entry.type]-t.priority[e.entry.type];return r===0?e.index-n.index:r}),a=[],o=0;for(let{entry:e}of i){let t=Yf(e.type,e.content),r=t.length;o+r>n||(a.push({type:e.type,content:t}),o+=r)}return a}async function ap(e,{curated:t,flowContextAdapter:n,stateStore:r,retentionConfig:i,consolidationConfig:a,lessonConfig:o}){let s=R.object({profile:R.string(),budget:R.number().int().min(100).max(5e4).default(6e3).describe(`Character budget for withdraw results`),token_budget:R.number().int().min(50).max(12500).optional().describe(`Token budget (overrides budget). Approx 4 chars per token.`)}).parse(e),c=s.token_budget?s.token_budget*4:s.budget;if(!n)return{content:[{type:`text`,text:`Flow context not available — no active flow or adapter not configured.`}]};let l=np(s.profile);if(!l)return{content:[{type:`text`,text:`Unknown profile: "implementer, documenter, reviewer, researcher, debugger".`}]};let u=await n.list();if(u.length===0)return{content:[{type:`text`,text:`No flow context available yet. Context is deposited automatically as agents use search, file_summary, and other analysis tools.`}]};let p=Date.now(),m=u.filter(e=>{let t=e.path.split(`/`)[0];return Od.has(t)?!rp(t,e.mtimeMs,p):!0}),h=(await Promise.all(m.map(async e=>{let t=e.path.split(`/`),o=t[0];if(t.length<2||!Od.has(o))return null;let s=await n.read(e.path);return s?(r&&tf(r,e.path,i,a),{type:o,content:s}):null}))).filter(e=>e!==null),g=ip(h,l,c),_=f(o??d),v=[...new Set(g.flatMap(e=>ff(e.content)))];if(await Promise.all(v.map(async e=>{let n=r?.memoryMetaGet(e)?.confidence;if(n===void 0)try{n=(await pf(t,r,e)).confidence}catch{return}df(r,e,n,_)})),g.length===0)return{content:[{type:`text`,text:`No relevant context for profile "${s.profile}". ${h.length} entries available but none match your role's context types.`}]};let y=g.map(e=>`### [${e.type}]\n${e.content}`).join(`
262
-
263
- `),b=g.reduce((e,t)=>e+t.content.length,0);return{content:[{type:`text`,text:`## Flow Context (${g.length}/${h.length} entries, ${b} chars, profile: ${s.profile})\n\n${y}`}]}}async function op(e,{flowContextAdapter:t}){return t?{content:[{type:`text`,text:`Flushed ${await t.flushAll()} flow context entries.`}]}:{content:[{type:`text`,text:`Flow context not available — no active flow or adapter not configured.`}]}}async function sp(e){try{let t=await e.getStats(),n=await e.validate(),r=t.nodeCount,i=t.edgeCount,a=await e.findNodes({limit:1e4}),o=a.slice(0,500),s=Math.max(0,a.length-500),c=[];for(let t=0;t<o.length;t+=50){let n=o.slice(t,t+50),r=await Promise.allSettled(n.map(t=>e.getNeighbors(t.id,{direction:`both`,maxDepth:1})));for(let e=0;e<n.length;e++){let t=r[e],i=t.status===`fulfilled`&&t.value.nodes!=null&&t.value.nodes.length>0;c.push({id:n[e].id,hasNeighbors:i})}}let l=[];for(let e=0;e<o.length;e++)c[e].hasNeighbors||l.push({id:o[e].id,name:o[e].name,type:o[e].type});let u=l.length,d=r>0?u/r:0,f=[];if(t.communities)for(let[e,n]of Object.entries(t.communities))Array.isArray(n)&&n.length<3&&f.push({name:e,nodeCount:n.length,nodes:n});let p={danglingEdgeCount:n.danglingEdges.length,orphanNodeCount:n.orphanNodes.length},m=t.communityCount??0,h=m>0?f.length/m:0,g=i>0?p.danglingEdgeCount/i:0,_=Math.max(d,h,g),v=_<.1?`healthy`:_<.3?`fair`:`poor`,y={summary:[`# Knowledge Gap Analysis`,``,`**${r}** nodes, **${i}** edges across **${m}** communities.`,`**Overall health: ${v.toUpperCase()}**`,``,`## Key Metrics`,``,`| Metric | Value | Threshold |`,`|--------|-------|-----------|`,`| Isolated nodes | ${u} / ${r} (${(d*100).toFixed(1)}%)${s>0?` *(${s} unchecked)*`:``} | < 10% healthy |`,`| Thin communities | ${f.length} / ${m} (${(h*100).toFixed(1)}%) | < 10% healthy |`,`| Dangling edges | ${p.danglingEdgeCount} / ${i} (${(g*100).toFixed(1)}%) | < 10% healthy |`,``].join(`
264
- `),metadata:{analyzedAt:new Date().toISOString(),nodeCount:r,edgeCount:i},isolatedNodes:l,uncheckedNodeCount:s,thinCommunities:f,graphIntegrity:p,combinedScore:{overall:v,isolatedNodeRatio:d,thinCommunityRatio:h,integrityRatio:g}},b=[];if(s>0&&b.push(``,`> **Note:** ${s} nodes were not checked for isolation (limit: 500). Unchecked nodes are not classified as isolated.`),l.length>0){b.push(``,`## Isolated Nodes`);for(let e of l.slice(0,20))b.push(`- **${e.name}** (${e.type}, id: \`${e.id}\`)`);l.length>20&&b.push(`- ... and ${l.length-20} more`)}if(f.length>0){b.push(``,`## Thin Communities`);for(let e of f)b.push(`- **${e.name}**: ${e.nodeCount} node(s) — ${e.nodes.join(`, `)}`)}if(p.danglingEdgeCount>0){b.push(``,`## Dangling Edges (graph integrity)`);for(let e of n.danglingEdges.slice(0,20))b.push(`- Edge \`${e.edgeId}\` → missing node \`${e.missingNodeId}\``)}return p.orphanNodeCount>0&&(b.push(``,`## Orphan Nodes`),b.push(`- ${n.orphanNodes.join(`, `)}`)),y.summary+=b.join(`
265
- `),{content:[{type:`text`,text:y.summary}],isError:!1,report:y}}catch(e){return{content:[{type:`text`,text:`Gap analysis failed: ${e instanceof Error?e.message:N(e)}`}],isError:!0,report:null}}}async function cp(e,{curated:t,stateStore:n,resourceNotifier:r}){let i=mf(e),{title:a,context:o,insight:s,evidence:c,confidence:l,tags:u}=Wd.parse(i),d=h({title:a,context:o,insight:s,evidence:c,confidence:l,tags:u}),f=await t.remember(a,d,`lessons`,lf(u));return uf(n,f.path,l),r&&r.notifyAfterCuratedWrite(f.path).catch(()=>{}),{content:[{type:`text`,text:`Recorded lesson: **${a}**\n\nStored at \`.ai/curated/${f.path}\` with confidence ${l}/100.`}],structuredContent:{path:f.path,confidence:l,category:`lessons`,tags:lf(u)}}}async function lp(e,t,n){let{curated:i,stateStore:a,resourceNotifier:o,retentionConfig:s,consolidationConfig:c,lessonConfig:u}=n,p=Gd.parse(e);if(t===`contradict`&&!p.reason)throw new R.ZodError([{code:`custom`,path:[`reason`],message:`reason is required`}]);let m=cf(p.path,p.id),h=f(u??d);a&&tf(a,m,s,c);let{entry:g,confidence:_}=await pf(i,a,m),v=r(_,t,h),y=l(g.content,v),b=t===`confirm`?p.reason??`Confirmed lesson confidence`:`Contradicted lesson confidence: ${p.reason}`,x=await i.update(m,y,b);return a&&a.memoryMetaUpdateConfidence(m,v),o&&o.notifyAfterCuratedWrite(m).catch(()=>{}),{content:[{type:`text`,text:`${t===`confirm`?`Confirmed`:`Contradicted`} lesson: \`${m}\`\n\nConfidence ${_}/100 → ${v}/100.`}],structuredContent:{path:x.path,confidence:v,previousConfidence:_,version:x.version}}}async function up(e,{curated:t,stateStore:n,lessonConfig:r}){let{topic:i,minConfidence:a,tag:s,tags:l,sortBy:u,includeArchived:p,limit:h,offset:g}=Kd.parse(e),_=lf([...l??[],...s?[s]:[]]),v=f(r??d),y=Math.max(h+g,500),b=await t.listPage({category:`lessons`,...s?{tag:s}:{},limit:y,orderBy:`updated`,order:`desc`}),x=b.entries,S=await Promise.all(x.filter(e=>e.tags.includes(`lesson`)).map(async e=>{let{confidence:r,meta:i}=await pf(t,n,e.path),a=i??n?.memoryMetaGet(e.path);a&&a.supersededBy===null&&o(a,v)&&n?.memoryMetaSetSuperseded(e.path,m);let s=n?.memoryMetaGet(e.path)??a,l=s?.createdAt??e.created,u=s?.confidence??r,d=c(u,s?.lastAccessedAt,l,v),f=s?.lastAccessedAt??s?.createdAt??null;return{path:e.path,title:e.title,category:e.category,tags:e.tags,version:e.version,preview:e.contentPreview,confidence:d,storedConfidence:u,createdAt:l,lastAccessedAt:s?.lastAccessedAt??null,recency:f,archived:s?.supersededBy===m,supersededBy:s?.supersededBy??null}})),C=S.filter(e=>e.archived).length,w=S.filter(e=>p?!0:e.supersededBy===null).filter(e=>a===void 0?!0:e.confidence>=a).filter(e=>_.length===0?!0:_.every(t=>e.tags.includes(t))).filter(e=>i?`${e.title}\n${e.preview}\n${e.tags.join(` `)}`.toLowerCase().includes(i.toLowerCase()):!0).sort((e,t)=>u===`recent`?Date.parse(t.recency??``)-Date.parse(e.recency??``)||t.confidence-e.confidence:t.confidence-e.confidence||Date.parse(t.recency??``)-Date.parse(e.recency??``)),T=w.slice(g,g+h);if(w.forEach(e=>{df(n,e.path,e.storedConfidence,v)}),T.length===0)return{content:[{type:`text`,text:`No lessons matched the requested filters.`}],structuredContent:{entries:[],totalCount:w.length,scannedCount:S.length,limit:h,offset:g,hasMore:w.length>g+h||b.hasMore,archivedCount:C}};let E=T.map(e=>{let t=e.recency?` | recent ${e.recency}`:``;return`- **${e.title}** (${e.confidence}/100)${t}\n \`${e.path}\` — ${e.preview.slice(0,80)}…`}).join(`
266
- `);return{content:[{type:`text`,text:`## Lessons (${T.length} of ${w.length})\n\n${E}`}],structuredContent:{entries:T.map(({storedConfidence:e,...t})=>t),totalCount:w.length,scannedCount:S.length,limit:h,offset:g,hasMore:w.length>g+h||b.hasMore,archivedCount:C}}}async function dp(e,{curated:t,stateStore:n,resourceNotifier:r}){let{bufferPath:i}=qd.parse(e),a=await hf(i);if(!a)return{content:[{type:`text`,text:`No observation buffer found for auto-observe.`}],structuredContent:{bufferPath:null,observations:0,createdCount:0,skippedCount:0,candidates:[]}};let o=Vi(F(a,`utf8`)),s=Bi(o,gi),c=await t.list({category:`lessons`}),l=[],u=[];try{for(let e of s){let i=gf(e.title,c);if(i){u.push({title:e.title,path:i.path,similarity:i.similarity});continue}let a=h({title:e.title,context:e.context,insight:e.insight,evidence:e.evidence,confidence:e.confidence,tags:e.tags}),o=await t.remember(e.title,a,`lessons`,lf(e.tags));uf(n,o.path,e.confidence),l.push({path:o.path,title:e.title,detector:e.detector}),c.push({path:o.path,title:e.title,category:`lessons`,tags:lf(e.tags),version:1,created:new Date().toISOString(),updated:new Date().toISOString(),contentPreview:e.insight}),r&&r.notifyAfterCuratedWrite(o.path).catch(()=>{})}}finally{try{Fe(a)}catch{}}let d=[`Auto-observe processed ${o.length} observations from \`${a}\`.`,`Created ${l.length} lessons and skipped ${u.length} duplicates from ${s.length} candidates.`];return l.length>0&&(d.push(``,`Created:`),d.push(...l.map(e=>`- **${e.title}** (${e.path})`))),u.length>0&&(d.push(``,`Skipped:`),d.push(...u.map(e=>`- **${e.title}** matched ${e.path} (${e.similarity.toFixed(2)})`))),{content:[{type:`text`,text:d.join(`
267
- `)}],structuredContent:{bufferPath:a,observations:o.length,createdCount:l.length,skippedCount:u.length,candidates:s.map(e=>({title:e.title,detector:e.detector,confidence:e.confidence,tags:e.tags})),created:l,skipped:u}}}async function fp(e,t){switch(e.subAction??`create`){case`create`:return cp(e,t);case`confirm`:return lp(e,`confirm`,t);case`contradict`:return lp(e,`contradict`,t);case`list-lessons`:return up(e,t);case`auto-observe`:return dp(e,t);case`prune`:{if(!t.stateStore)return K(`VALIDATION`,`StateStore required for lesson/prune`);let n=Jd.parse(e),r=await E(t.curated,t.stateStore,{maxConfidence:n.maxConfidence,minIdleDays:n.minIdleDays,safetyDays:n.safetyDays,maxPrune:n.maxPrune,dryRun:n.dryRun},t.lessonConfig?f(t.lessonConfig):d);return{content:[{type:`text`,text:_f(r)}],structuredContent:r}}case`group`:{if(!t.stateStore)return K(`VALIDATION`,`StateStore required for lesson/group`);let n=Yd.parse(e),r=await T(t.curated,t.stateStore,{similarityThreshold:n.similarityThreshold,minGroupSize:n.minGroupSize,maxGroups:n.maxGroups,dryRun:n.dryRun});return{content:[{type:`text`,text:vf(r)}],structuredContent:r}}case`promote`:{if(!Te())return{content:[{type:`text`,text:`Promotion requires user-level install (not workspace-scoped).`}]};let n=Xd.parse(e),r={minWorkspaces:n.minWorkspaces??ne.minWorkspaces,minAvgConfidence:n.minAvgConfidence??ne.minAvgConfidence,similarityThreshold:n.similarityThreshold??ne.similarityThreshold,dryRun:n.dryRun},i=await D(te(await k(),r),yf(t.curated,O()),r);return{content:[{type:`text`,text:bf(i,r.dryRun)}],structuredContent:i}}case`demote`:{if(!Te())return{content:[{type:`text`,text:`Demotion requires user-level install.`}]};let n=cf(e.path,e.id);if(!n)return{content:[{type:`text`,text:`Missing required "path" or "id" parameter for demote.`}]};let r=await ee(yf(t.curated,O()),n);return{content:[{type:`text`,text:r.removed?`Demoted: ${n}`:`Not found in global: ${n}`}],structuredContent:r}}}}async function pp(e,t,n){switch(e){case`remember`:return xf(t,n);case`read`:return Sf(t,n);case`update`:return Cf(t,n);case`forget`:return wf(t,n);case`list`:return Tf(t,n);case`history`:return Ef(t,n);case`diff`:return Df(t,n);case`recover`:return Of(t,n);case`orphaned`:return kf(t,n);case`withdraw`:return ap(t,n);case`flush`:return op(t,n);case`flagged`:return Af(t,n);case`lesson`:return fp(t,n);case`gap-analysis`:return n.graphStore?sp(n.graphStore):{content:[{type:`text`,text:`Gap analysis requires a graph store (not available).`}],isError:!0}}}function mp(e,t,n,r,i,a,o,s,c,l,u,d,f){let p=U(`knowledge`),m={curated:t,policyStore:n,evolutionCollector:r,resourceNotifier:i,flowContextAdapter:a,stateStore:o,retentionConfig:s,consolidationConfig:l,supersessionConfig:c,lessonConfig:u,graphStore:f};e.registerTool(`knowledge`,{title:p.title,description:"Operate on curated knowledge entries with a single tool. Use `action` to remember, read, update, forget, list, history, diff, recover, orphaned, withdraw, flush, flagged, lesson, or gap-analysis entries. gap-analysis runs a knowledge graph health check: isolated nodes, thin communities, dangling edges.",inputSchema:Zd.shape,annotations:p.annotations},q(`knowledge`,async({action:e,...t})=>{try{let n=Zd.parse({action:e,...t});return await ef(await pp(n.action,n,m),n,d)}catch(e){return e instanceof R.ZodError?K(`VALIDATION`,sf(e)):(Qd.error(`Knowledge operation failed`,N(e)),K(`INTERNAL`,`Knowledge operation failed: ${e instanceof Error?e.message:String(e)}`))}}))}const hp=M(`tools:manipulation`);function gp(e){return e.sources[0]?.path??Oe()}function _p(e,t){let n=L(t,e),r=Be(t,n);if(r.startsWith(`..`)||ze(r))throw Error(`Path "${e}" escapes workspace root: ${t}`);return n}function vp(e,t){let n=U(`rename`),r=gp(t);e.registerTool(`rename`,{title:n.title,description:`Rename a symbol across files using whole-word regex matching for exports, imports, and general usage references.`,inputSchema:{old_name:R.string().describe(`Existing symbol name to replace`),new_name:R.string().describe(`New symbol name to use`),root_path:R.string().describe(`Root directory to search within`),extensions:R.array(R.string()).optional().describe(`Optional file extensions to include, such as .ts,.tsx,.js,.jsx`),dry_run:R.boolean().default(!0).describe(`Preview changes without writing files`)},annotations:n.annotations},q(`rename`,async({old_name:e,new_name:t,root_path:n,extensions:i,dry_run:a},o)=>{let s;try{s=ol(o).createTask(`Rename Symbol`,2),s.progress(0,`Scanning for references`);let c=_p(n,r);s.progress(1,`Applying renames`);let l=await gn({oldName:e,newName:t,rootPath:c,extensions:i,dryRun:a});return s.complete(`Rename complete`),{content:[{type:`text`,text:JSON.stringify(l)}]}}catch(e){return s?.fail?.(`Rename failed`),hp.error(`Rename failed`,N(e)),K(`INTERNAL`,`Rename failed: ${e instanceof Error?e.message:String(e)}`)}}))}function yp(e,t){let n=U(`codemod`),r=gp(t);e.registerTool(`codemod`,{title:n.title,description:`Apply regex-based codemod rules across files and return structured before/after changes for each affected line.`,inputSchema:{root_path:R.string().describe(`Root directory to transform within`),rules:R.array(R.object({description:R.string().describe(`What the codemod rule does`),pattern:R.string().describe(`Regex pattern in string form`),replacement:R.string().describe(`Replacement string with optional capture groups`)})).min(1).describe(`Codemod rules to apply`),dry_run:R.boolean().default(!0).describe(`Preview changes without writing files`)},annotations:n.annotations},q(`codemod`,async({root_path:e,rules:t,dry_run:n},i)=>{let a;try{a=ol(i).createTask(`Codemod`,2),a.progress(0,`Scanning files`);let o=_p(e,r);a.progress(1,`Applying transforms`);let s=await ht({rootPath:o,rules:t,dryRun:n});return a.complete(`Codemod complete`),{content:[{type:`text`,text:JSON.stringify(s)}]}}catch(e){return a?.fail?.(`Codemod failed`),hp.error(`Codemod failed`,N(e)),K(`INTERNAL`,`Codemod failed: ${e instanceof Error?e.message:String(e)}`)}}))}const bp=[`list_tools`];function xp(e,t,n){let r=[...new Set(n)].sort();e.registerTool(`list_tools`,{title:U(`list_tools`).title,description:`List the available AI Kit tools with names, titles, and categories.`,inputSchema:{category:R.string().optional().describe(`Optional category filter`)},annotations:U(`list_tools`).annotations},async({category:e})=>{let t=e?.trim().toLowerCase();return{content:[{type:`text`,text:r.filter(e=>t?(mo[e]?.category??[]).some(e=>e.toLowerCase()===t):!0).map(e=>{let t=mo[e]??{title:e,category:[]},n=t.category?.join(`, `)||`uncategorized`;return`${e}: ${t.title} [${n}]`}).join(`
268
- `)||`No tools matched the filter.`}]}})}const Sp=M(`server`),Cp=ue(Or),wp={"@huggingface/transformers":`4.2.0`,"onnxruntime-common":`1.24.3`,"onnxruntime-node":`1.24.3`};function Tp(e){return e.replace(/\\/g,`/`)}function Ep(e){return process.platform===`win32`?e.replace(/\//g,Ve):e}function Dp(){return L(Re(le(import.meta.url)),`..`,`..`,`..`)}function Op(e){return Tp(e).includes(`/_npx/`)}function kp(e){return/^(1|true)$/i.test(process.env.AIKIT_DISABLE_DEP_REPAIR??``)?!1:/^(1|true)$/i.test(process.env.AIKIT_ALLOW_DEP_REPAIR??``)?!0:Op(e)}function Ap(e,t){let n=Tp(e),r=`/node_modules/${t}/`,i=n.lastIndexOf(r);if(i<0)return null;let a=i+r.length-1,o=n.slice(0,a),s=o.search(/[A-Za-z]:\/|\//);return s<0?null:Ep(o.slice(s))}function jp(e,t){if(!e)return wp[t]??`latest`;try{return JSON.parse(F(I(e,`package.json`),`utf8`)).version??wp[t]??`latest`}catch{return wp[t]??`latest`}}function Mp(e){let t=Tp(e).toLowerCase();return/(cannot find module|cannot find package|module not found|err_module_not_found)/i.test(e)?t.includes(`@huggingface/transformers`)||t.includes(`transformers.node`)||t.includes(`onnxruntime-common`)||t.includes(`onnxruntime-node`):!1}function Np(e){if(!Mp(e))return[];let t=Tp(e).toLowerCase(),n=new Map;if(t.includes(`@huggingface/transformers`)){let t=Ap(e,`@huggingface/transformers`);n.set(`@huggingface/transformers`,`@huggingface/transformers@${jp(t,`@huggingface/transformers`)}`)}if(t.includes(`onnxruntime-common`)){let t=Ap(e,`onnxruntime-common`);n.set(`onnxruntime-common`,`onnxruntime-common@${jp(t,`onnxruntime-common`)}`)}if(t.includes(`onnxruntime-node`)){let t=Ap(e,`onnxruntime-node`);n.set(`onnxruntime-node`,`onnxruntime-node@${jp(t,`onnxruntime-node`)}`)}return Array.from(n.values())}function Pp(e){if(!/index\.js/i.test(e)||!Tp(e).includes(`@huggingface`))return!1;let t=Ap(e,`@huggingface/transformers`);if(!t)return!1;let n=I(t,`index.js`),r=I(t,`dist`,`transformers.node.mjs`);return P(n)||!P(r)?!1:(Ie(n,[`// Auto-generated by AI Kit runtime dependency repair.`,`export * from './dist/transformers.node.mjs';`,`export { default } from './dist/transformers.node.mjs';`,``].join(`
269
- `),`utf8`),Sp.info(`Auto-heal: created @huggingface/transformers index.js shim`,{path:n}),!0)}async function Fp(e,t={}){let n=Np(e),r=t.packageRoot??Dp(),i=Pp(e);if(n.length===0)return{attempted:i,repaired:i,packages:n,reason:i?`created transformer index shim`:`no missing runtime dependency detected`};if(!kp(r))return{attempted:i,repaired:i,packages:n,reason:`runtime dependency auto-install disabled outside npx cache; set AIKIT_ALLOW_DEP_REPAIR=1 to enable`};let a=process.platform===`win32`?`npm.cmd`:`npm`,o=[`install`,`--no-save`,`--package-lock=false`,`--no-audit`,`--no-fund`,`--omit=dev`,`--prefer-online`,`--ignore-scripts`,...n];Sp.warn(`Auto-heal: repairing missing runtime dependencies`,{packages:n,packageRoot:r});try{return await Cp(a,o,{cwd:r,timeout:t.timeoutMs??6e4,windowsHide:!0}),Sp.info(`Auto-heal: runtime dependency repair completed`,{packages:n,packageRoot:r}),{attempted:!0,repaired:!0,packages:n,reason:`npm install repair completed`}}catch(e){let t=e instanceof Error?e.message:String(e);return Sp.warn(`Auto-heal: runtime dependency repair failed`,{packages:n,packageRoot:r,...N(e)}),{attempted:!0,repaired:i,packages:n,reason:i?`created transformer shim but npm repair failed`:`npm repair failed`,error:t}}}const Ip=M(`tools`);let Lp=!1;function Rp(e){let t=e instanceof Error?e.message:String(e);return Mp(t)||/embedder worker|embedding worker|circuit breaker|timed out|killed|respawn|ipc_channel|epipe|econnreset/i.test(t)}async function zp(e,t,n){try{return await e.embedBatch(t,n)}catch(r){if((await Fp(r instanceof Error?r.message:String(r))).repaired)return e.embedBatch(t,n);throw r}}async function Bp(e,t,n){for(let r of n.steps)if(!(r.status!==`success`||!r.output))try{let i=we(n.path,12),a=`produced/onboard/${r.name}/${i}.md`,o=Ye(`sha256`).update(r.output).digest(`hex`).slice(0,16),s=new Date().toISOString(),c=r.output.length>2e3?r.output.split(/(?=^## )/m).filter(e=>e.trim().length>0):[r.output],l=c.map((e,t)=>({id:Ye(`sha256`).update(`${a}::${t}`).digest(`hex`).slice(0,16),content:e.trim(),sourcePath:a,contentType:`produced-knowledge`,chunkIndex:t,totalChunks:c.length,startLine:0,endLine:0,fileHash:o,indexedAt:s,origin:`produced`,tags:[`onboard`,r.name],category:`analysis`,version:1})),u=await zp(t,l.map(e=>e.content));await e.upsert(l,u)}catch(e){if(Rp(e)){let t=e instanceof Error?e.message:String(e);_e.instance().reportDegraded(`embedder`,t),Ip.warn(`Auto-persist onboard disabled — embedder unavailable`,{stepName:r.name,...N(e)});return}Ip.warn(`Auto-persist onboard step failed`,{stepName:r.name,...N(e)})}}async function Vp(e,t,n){if(n.autoRemember?.length)for(let r of n.autoRemember)try{let n=Ye(`sha256`).update(`onboard-remember::${r.title}`).digest(`hex`).slice(0,16),i=new Date().toISOString(),a={id:n,content:`# ${r.title}\n\n${r.content}`,sourcePath:`curated/onboard/${r.category}/${n}.md`,contentType:`curated`,chunkIndex:0,totalChunks:1,startLine:0,endLine:0,fileHash:Ye(`sha256`).update(r.content).digest(`hex`).slice(0,16),indexedAt:i,origin:`curated`,tags:r.tags,category:r.category,version:1},[o]=await zp(t,[a.content]);await e.upsert([a],[o])}catch(e){if(Rp(e)){let t=e instanceof Error?e.message:String(e);_e.instance().reportDegraded(`embedder`,t),Ip.warn(`Auto-persist remember disabled — embedder unavailable`,{title:r.title,...N(e)});return}Ip.warn(`Auto-persist remember entry failed`,{title:r.title,...N(e)})}}function Hp(e,t,n,r,i,a,o,s){let c=U(`onboard`);e.registerTool(`onboard`,{title:c.title,description:`Onboard a codebase: run all analyses (structure, deps, symbols, patterns, diagram) and persist to AI Kit memory + ~/.aikit/workspaces/. Also supports explore (context package), trace (BFS traversal), diff (impact analysis), and routes (framework detection) via dedicated modes. Output goes to ~/.aikit/workspaces/<name>/ — never inside the project.`,inputSchema:{path:R.string().describe(`Root path of the codebase to onboard`),mode:R.enum([`memory`,`generate`]).default(`generate`).describe(`Output mode: generate (default) = persist to AI Kit + write workspace files; memory = AI Kit vector store only`),out_dir:R.string().optional().describe(`Custom output directory (default: ~/.aikit/workspaces/<name>/onboard/)`),enrich:R.boolean().default(!0).describe(`Append curated knowledge and graph context to output. Adds ~150-250 tokens. Default true for planning tools — set false to save tokens when enrichment is not needed.`),explore:R.string().optional().describe(`Explore mode: given a topic, return entry points, related symbols, and code snippets as a single context package. Uses indexed knowledge from previous onboard.`),trace:R.string().optional().describe(`Trace mode: BFS traversal from a symbol. Returns callers and/or callees.`),direction:R.enum([`callers`,`callees`,`both`]).optional().default(`both`).describe(`Trace direction (default: both).`),maxDepth:R.number().min(1).max(10).optional().default(2).describe(`Trace max traversal depth (default: 2, max: 10).`),diff:R.union([R.boolean(),R.string()]).optional().describe(`Diff mode: analyze git diff for impact assessment. true = auto-detect, string = explicit diff content.`),routes:R.boolean().optional().describe(`Routes mode: detect web framework routes (Express, FastAPI, Django, NestJS).`),framework:R.enum([`express`,`fastify`,`nextjs`]).optional().describe(`Framework to scan for routes. Omit to detect all supported frameworks.`),update:R.boolean().optional().describe(`Incremental update mode: load existing index from ~/.aikit/workspaces/, re-extract changed files, merge.`),detail:R.enum([`summary`,`standard`,`full`]).optional().default(`standard`).describe(`Output detail level: summary (key concepts only), standard (recommended), full (all data).`),language:R.string().optional().describe(`Output language for localized content. Supported: en, zh, ja, ko, ru.`),llm_sampling:R.boolean().default(!1).optional().describe(`Enable LLM-based semantic enrichment (module summaries, architectural roles, tags). Uses the session LLM via MCP sampling.`)},annotations:c.annotations},q(`onboard`,async({path:e,mode:r,out_dir:s,enrich:c,explore:l,trace:u,direction:d,maxDepth:f,diff:p,routes:m,framework:h,update:g,detail:_,language:v,llm_sampling:y},b)=>{try{if(Lp)return{content:[{type:`text`,text:`Onboard is already running. Please wait for it to complete before starting another.`}]};Lp=!0,Ip.info(`Starting onboard`,{path:e,mode:r,explore:l,trace:u,diff:p,routes:m,update:g});let x=await Xt({path:e,mode:r,outDir:s,explore:l,trace:u,direction:d,maxDepth:f,diff:typeof p==`string`?p:p===!0,routes:m,framework:h,update:g,detail:_,language:v,enrich:y??!1,llmCall:y&&o?.available?async(e,t)=>(await o.createMessage({prompt:e,systemPrompt:t,maxTokens:4e3,timeoutMs:6e4,modelPreferences:{intelligencePriority:.8,speedPriority:.5,costPriority:.3}})).text:void 0}),S=ol(b).createTask(`Onboard`,x.steps.length);for(let e=0;e<x.steps.length;e++){let t=x.steps[e];S.progress(e,`${t.name}: ${t.status}`)}S.complete(`Onboard complete: ${x.steps.filter(e=>e.status===`success`).length}/${x.steps.length} steps succeeded`),Bp(t,n,x),x.autoRemember?.length&&Vp(t,n,x).catch(e=>{Ip.debug(`Auto-persist autoRemember failed`,N(e))}),i&&(i.onboardComplete=!0,i.onboardTimestamp=new Date().toISOString());let C=[`## Onboard Complete`,``,`**Path:** \`${x.path}\``,`**Mode:** ${x.mode}`,`**Duration:** ${x.totalDurationMs}ms`,``];x.outDir&&(C.push(`**Output directory:** \`${x.outDir}\``),C.push(``)),C.push(`### Analysis Results`,``);let w=[],T=[];for(let e of x.steps)e.status===`success`?w.push(`- ✓ **${e.name}** (${e.durationMs}ms) — ${e.output.length} chars`):T.push(`- ✗ **${e.name}** — ${e.error}`);C.push(...w),T.length>0&&C.push(``,`### Failed`,``,...T),C.push(``,`---`,``);for(let e of x.steps)e.status===`success`&&C.push(`### ${e.name}`,``,e.output,``,`---`,``);C.push(`_All results auto-saved to AI Kit memory._`,x.mode===`generate`?` Files written to \`${x.outDir}\`.`:``,' Next: Use `search` to query the knowledge, or `knowledge({ action: "remember", ... })` to add custom insights.');let E=C.join(`
270
- `);if(c&&a){let e=await G(a,{query:`onboard codebase conventions`});E+=Ac(e)}return{content:[{type:`text`,text:E}]}}catch(e){return Ip.error(`Onboard failed`,N(e)),K(`INTERNAL`,`Onboard failed: ${e instanceof Error?e.message:String(e)}`)}finally{Lp=!1}}))}const Up=M(`tools:persistence`);function Wp(e){let t=U(`queue`);e.registerTool(`queue`,{title:t.title,description:`Manage task queues with optional DAG dependencies. Push items with dependsOn for wave-based execution. Take next, mark done/failed, list queues.`,inputSchema:{action:R.enum([`create`,`push`,`next`,`done`,`fail`,`get`,`list`,`clear`,`delete`,`dag`]).describe(`Queue action`),name:R.string().optional().describe(`Queue name (required for most actions)`),title:R.string().optional().describe(`Item title (required for push)`),id:R.string().optional().describe(`Item ID (required for done/fail)`),data:R.unknown().optional().describe(`Arbitrary data to attach to a queue item`),error:R.string().optional().describe(`Error message (required for fail)`),dependsOn:R.array(R.string()).optional().describe(`Item IDs this task depends on. Dependent items start as blocked until deps complete.`)},annotations:t.annotations},q(`queue`,async({action:e,name:t,title:n,id:r,data:i,error:a,dependsOn:o})=>{try{switch(e){case`create`:if(!t)throw Error(`name is required for create`);return{content:[{type:`text`,text:JSON.stringify(an(t))}]};case`push`:if(!t)throw Error(`name is required for push`);if(!n)throw Error(`title is required for push`);return{content:[{type:`text`,text:JSON.stringify(pn(t,n,i,void 0,o))}]};case`next`:{if(!t)throw Error(`name is required for next`);let e=fn(t);return{content:[{type:`text`,text:JSON.stringify(e)}]}}case`done`:if(!t)throw Error(`name is required for done`);if(!r)throw Error(`id is required for done`);return{content:[{type:`text`,text:JSON.stringify(cn(t,r))}]};case`fail`:if(!t)throw Error(`name is required for fail`);if(!r)throw Error(`id is required for fail`);if(!a)throw Error(`error is required for fail`);return{content:[{type:`text`,text:JSON.stringify(ln(t,r,a))}]};case`get`:if(!t)throw Error(`name is required for get`);return{content:[{type:`text`,text:JSON.stringify(un(t))}]};case`list`:return{content:[{type:`text`,text:JSON.stringify(dn())}]};case`clear`:if(!t)throw Error(`name is required for clear`);return{content:[{type:`text`,text:JSON.stringify({cleared:rn(t)})}]};case`delete`:if(!t)throw Error(`name is required for delete`);return{content:[{type:`text`,text:JSON.stringify({deleted:sn(t)})}]};case`dag`:if(!t)throw Error(`name is required for dag`);return{content:[{type:`text`,text:JSON.stringify(on(t))}]}}}catch(e){return Up.error(`Queue action failed`,N(e)),K(`INTERNAL`,`Queue action failed: ${e instanceof Error?e.message:String(e)}`)}}))}const Gp=M(`tools`);function Kp(e){let t=[`## Rule: ${e.id}`,``,`- **Status**: ${e.enabled?`enabled`:`disabled`}`,`- **Description**: ${e.description??`—`}`,`- **Category**: ${e.category??`—`}`,`- **Push weight**: ${e.pushWeight??`—`}`];return e.patterns?.length&&t.push(`- **Patterns**: ${e.patterns.join(`, `)}`),e.examples?.length&&t.push(`- **Examples**: ${e.examples.join(`, `)}`),t.join(`
271
- `)}function qp(e,t){let n=U(`er_update_policy`);e.registerTool(`er_update_policy`,{title:n.title,description:`Manage ER push classification rules. Supports listing, updating, creating, and deleting rules that determine when knowledge should be pushed to Enterprise RAG.`,inputSchema:{action:R.enum([`list`,`get`,`update`,`create`,`delete`]).describe(`Action to perform on classification rules`),rule_id:R.string().optional().describe(`Rule ID (required for get, update, delete)`),changes:R.object({patterns:R.array(R.string()).optional(),category:R.string().optional(),pushWeight:R.number().min(0).max(1).optional(),description:R.string().optional(),examples:R.array(R.string()).optional(),enabled:R.boolean().optional()}).optional().describe(`Changes to apply (for update action)`),new_rule:R.object({id:R.string().regex(/^[a-z][a-z0-9-]*$/),patterns:R.array(R.string()).min(1),category:R.string(),pushWeight:R.number().min(0).max(1),description:R.string(),examples:R.array(R.string()).default([]),enabled:R.boolean().default(!0)}).optional().describe(`New rule definition (for create action)`)},annotations:n.annotations},q(`er_update_policy`,async({action:e,rule_id:n,changes:r,new_rule:i})=>{try{if(e===`list`){let e=t.getRules();return{content:[{type:`text`,text:`## Classification Rules\n\n${e.map(e=>`- **${e.id}** (${e.enabled?`enabled`:`disabled`}) — ${e.description}\n Category: ${e.category} | Weight: ${e.pushWeight} | Patterns: ${e.patterns.join(`, `)}`).join(`
272
- `)}\n\n---\n_${e.length} rules total. Use \`action: "update"\` to modify a rule._`}]}}if(e===`get`){if(!n)return K(`VALIDATION`,'`rule_id` is required for "get" action.');let e=t.getRule(n);return e?{content:[{type:`text`,text:Kp(e)}]}:K(`NOT_FOUND`,`Rule "${n}" not found.`)}if(e===`update`){if(!n||!r)return K(`VALIDATION`,'`rule_id` and `changes` are required for "update" action.');let e=t.updateRule(n,r);return e?{content:[{type:`text`,text:`${Kp(e)}\n\n---\n_Updated. Next: Use \`action: "list"\` to verify._`}]}:K(`NOT_FOUND`,`Rule "${n}" not found.`)}return e===`create`?i?{content:[{type:`text`,text:`${Kp(t.addRule(i))}\n\n---\n_Created. Next: Test classification with \`remember\`._`}]}:K(`VALIDATION`,'`new_rule` is required for "create" action.'):e===`delete`?n?t.deleteRule(n)?{content:[{type:`text`,text:`Deleted rule **${n}**.\n\n---\n_Next: Use \`action: "list"\` to verify._`}]}:K(`NOT_FOUND`,`Rule "${n}" not found.`):K(`VALIDATION`,'`rule_id` is required for "delete" action.'):K(`VALIDATION`,`Unknown action: ${e}`)}catch(e){return Gp.error(`Policy update failed`,N(e)),K(`INTERNAL`,`Policy update failed: ${e instanceof Error?e.message:String(e)}`)}}))}const Jp=new Map([{type:`markdown`,category:`content`,description:`Markdown content rendered with the marked parser.`,valueShape:`string`,relevantSkills:[`present`,`docs`]},{type:`code`,category:`content`,description:`Formatted code block rendered inside pre/code tags.`,valueShape:`string`,relevantSkills:[`present`,`docs`]},{type:`mermaid`,category:`visualization`,description:`Mermaid diagram source rendered in a mermaid pre block.`,valueShape:`string`,vendorScripts:[`mermaid`],relevantSkills:[`present`,`c4-architecture`,`docs`]},{type:`architecture-diagram`,category:`visualization`,description:`Architecture diagram with positioned components, connections, and boundary groups. Produces SVG with mermaid rendering.`,vendorScripts:[`mermaid`],valueShape:`object ({ components, connections, boundaries? })`,since:`1.0`,relevantSkills:[`present`,`c4-architecture`,`onboard`],usageExample:`{
273
- type: 'architecture-diagram',
274
- value: {
275
- components: [
276
- { id: 'api', label: 'API Server', type: 'backend' },
277
- { id: 'web', label: 'Web App', type: 'frontend' }
278
- ],
279
- connections: [
280
- { from: 'web', to: 'api', label: 'HTTPS' }
281
- ]
282
- }
283
- }`},{type:`workflow-diagram`,category:`visualization`,description:`Workflow/pipeline diagram with lane-based columns, typed nodes, and edges. Produces SVG with mermaid rendering.`,vendorScripts:[`mermaid`],valueShape:`object ({ lanes, nodes, edges })`,since:`1.0`,relevantSkills:[`present`,`docs`]},{type:`sequence-diagram`,category:`visualization`,description:`Sequence diagram with participants and time-ordered messages. Produces SVG with mermaid rendering.`,vendorScripts:[`mermaid`],valueShape:`object ({ participants, messages })`,since:`1.0`,relevantSkills:[`present`,`docs`]},{type:`dataflow-diagram`,category:`visualization`,description:`Data flow diagram with stage-based columns, nodes, and classification-colored edges. Produces SVG with mermaid rendering.`,vendorScripts:[`mermaid`],valueShape:`object ({ stages, nodes, flows })`,since:`1.0`,relevantSkills:[`present`,`onboard`]},{type:`lifecycle-diagram`,category:`visualization`,description:`Lifecycle state machine with lanes, states, and transitions. Produces SVG with mermaid rendering.`,vendorScripts:[`mermaid`],valueShape:`object ({ lanes, states, transitions })`,since:`1.0`,relevantSkills:[`present`,`docs`]},{type:`table`,category:`data`,description:`Tabular data rendered from records or explicit headers and rows.`,valueShape:`Record<string, unknown>[] | { headers: string[]; rows: unknown[][] }`,relevantSkills:[`present`,`docs`]},{type:`metrics`,category:`data`,description:`Metric cards showing label/value pairs with optional trend and status.`,valueShape:`Array<{ label: string; value: string | number; trend?: string | number; status?: string }>`,relevantSkills:[`present`]},{type:`cards`,category:`visualization`,description:`Card grid for titled items with optional body, badge, and status.`,valueShape:`Array<{ title: string; body?: string; badge?: string; status?: string; description?: string }>`,relevantSkills:[`present`,`docs`]},{type:`tree`,category:`visualization`,description:`Hierarchical object or name/children tree rendered recursively.`,valueShape:`{ name: string; children?: unknown[] } | Record<string, unknown>`,relevantSkills:[`present`]},{type:`graph`,category:`visualization`,description:`Node and edge graph rendered as a Mermaid flow graph in HTML mode.`,valueShape:`{ nodes: Array<{ id: string; label?: string }>; edges: Array<{ from: string; to: string; label?: string }> }`,vendorScripts:[`mermaid`],relevantSkills:[`present`,`c4-architecture`]},{type:`chart`,category:`data`,description:`Structured chart definition rendered as SVG.`,valueShape:`{ chartType: string; data: Record<string, unknown>[]; xKey: string; yKeys: string[] }`,relevantSkills:[`present`]},{type:`timeline`,category:`interactive`,description:`Timeline entries rendered as a vertical sequence of events.`,valueShape:`Array<{ title: string; description?: string; timestamp?: string; status?: string }>`,relevantSkills:[`present`]},{type:`checklist`,category:`interactive`,description:`Checklist items with boolean checked state.`,valueShape:`Array<{label, checked}> | {items: Array<{label, checked}>}`,relevantSkills:[`present`]},{type:`comparison`,category:`interactive`,description:`Side-by-side comparison columns with titled item lists.`,valueShape:`Array<{title, items}> | {columns: Array<{title, items}>}`,relevantSkills:[`present`]},{type:`status-board`,category:`interactive`,description:`Status categories containing labeled status items.`,valueShape:`Array<{category, items}> | {items: Array<{category, items}>}`,relevantSkills:[`present`]},{type:`stat-group`,category:`data`,description:`Colored stat/gauge cards with label, value, and tone. Ideal for summary counts, KPI dashboards, and status overviews.`,valueShape:`Array<{ label: string; value: string | number; color?: string }>`,since:`1.0`,relevantSkills:[`present`],usageExample:`{
284
- type: 'stat-group',
285
- title: 'Status Overview',
286
- value: [
287
- { label: 'Passed', value: '42', color: 'green' },
288
- { label: 'Failed', value: '3', color: 'red' },
289
- { label: 'Pending', value: '7', color: 'yellow' },
290
- ],
291
- }`},{type:`alert`,category:`content`,description:`Alert/callout box with icon, title, and body text. Tone supports: info (default), success, warning, danger, accent.`,valueShape:`string | { title?: string; value?: string; tone?: string; severity?: string }`,since:`1.0`,relevantSkills:[`present`],usageExample:`{
292
- type: 'alert',
293
- title: 'Critical Path — Complete',
294
- value: 'All delivery stages are wired end-to-end.',
295
- tone: 'success',
296
- }`},{type:`prompt`,category:`interactive`,description:`Prompt payload rendered through the prompt display helper.`,valueShape:`unknown`,relevantSkills:[`present`]},{type:`progress`,category:`interactive`,description:`Progress bar with current value and optional maximum.`,valueShape:`{label, value, max?} | {items: Array<{label, value, max?, color?}>}`,relevantSkills:[`present`]},{type:`docs-browser`,category:`interactive`,description:`Documentation file list with inline content previews for chat-safe rendering.`,valueShape:`{ files: Array<{ path: string; title?: string; content?: string; status?: "current" | "stale" | "missing" }>; title?: string }`,relevantSkills:[`present`,`docs`],usageExample:`{
297
- type: 'docs-browser',
298
- value: {
299
- title: 'Project Docs',
300
- files: [
301
- { path: 'docs/README.md', title: 'Overview', status: 'current' },
302
- { path: 'docs/api.md', title: 'API Reference', status: 'stale' },
303
- ],
304
- },
305
- }`},{type:`text`,category:`content`,description:`Plain text content rendered through the markdown parser.`,valueShape:`string`},{type:`heading`,category:`content`,description:`Single heading with configurable level from h1 to h6.`,valueShape:`string`},{type:`paragraph`,category:`content`,description:`Single paragraph rendered inside a p tag.`,valueShape:`string`},{type:`separator`,category:`layout`,description:`Horizontal rule used to separate adjacent blocks.`,valueShape:`undefined`},{type:`actions`,category:`layout`,description:`Action bar containing button and select action definitions.`,valueShape:`Array<{ type: string; id: string; label: string; variant?: string; options?: Array<string | { label: string; value: string }> }>`},{type:`diff`,category:`content`,description:`Diff view with +/- lines for showing changes between text.`,valueShape:`string | { content: string } | { before: string; after: string }`},{type:`finding`,category:`content`,description:`Finding with severity pill showing title, severity, and detail.`,valueShape:`{ title?: string; severity?: string; detail?: unknown }`},{type:`kv`,category:`data`,description:`Key-value pairs rendered as labeled entries.`,valueShape:`Array<{ key: string; value: unknown }> | Record<string, unknown>`},{type:`tags`,category:`data`,description:`Tag pills rendered with optional tone/color.`,valueShape:`Array<string | { text?: string; label?: string; status?: string; tone?: string; color?: string }> | { items: Array<...> }`},{type:`list`,category:`content`,description:`Bullet list items rendered as an unordered list.`,valueShape:`string[]`},{type:`lifecycle-flow`,category:`visualization`,description:`SVG flow diagram with labeled steps, edges, and status colors.`,valueShape:`{ title?: string; steps: Array<{ id: string; label: string; type?: string; status?: string; description?: string }>; edges?: Array<{ from: string; to: string; label?: string }> }`},{type:`component-detail`,category:`visualization`,description:`Component detail view with name, type, technology, responsibilities, interfaces, dependencies, metrics, and code links.`,valueShape:`{ name: string; description?: string; type?: string; technology?: string; responsibilities?: string[]; interfaces?: Array<{ name: string; type: string; description?: string }>; dependencies?: Array<{ name: string; relationship?: string }>; metrics?: Record<string, string | number>; codeLinks?: Array<{ href: string; label: string }> }`},{type:`data-table-schema`,category:`data`,description:`Schema table with field names, types, constraints, and indexes.`,valueShape:`{ name: string; description?: string; fields: Array<{ name: string; type: string; required?: boolean; default?: unknown; constraints?: string[]; description?: string }>; indexes?: Array<{ name: string; columns: string[]; unique?: boolean }> }`},{type:`annotation`,category:`interactive`,description:`Annotation groups with COMMENT, DELETION, and GLOBAL_COMMENT types.`,valueShape:`Array<{ id: string; type: "COMMENT" | "DELETION" | "GLOBAL_COMMENT"; body: string; author?: string; createdAt?: string }>`},{type:`approval`,category:`interactive`,description:`Approval widget with radio options and optional comment textarea.`,valueShape:`{ prompt: string; options: Array<{ id: string; label: string; description?: string }>; requireComment?: boolean }`},{type:`docs-hub`,category:`content`,description:`Doc hub card grid with titled pages, descriptions, categories, and statuses.`,valueShape:`{ title?: string; description?: string; pages?: Array<{ title: string; description?: string; href?: string; icon?: string; category?: string; status?: "draft" | "published" | "deprecated" }> }`}].map(e=>[e.type,{...e}]));function Yp(){let e={};for(let[t,n]of Jp)n.vendorScripts?.length&&(e[t]=n.vendorScripts);return e}function Xp(e){return Jp.has(e)}const Zp=new Map;function Qp(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,`\\$&`)}function $p(e){let t=`(?=[^>]*\\bid=['"]${Qp(e)}['"])`;return RegExp(`(<script\\b(?=[^>]*\\btype=['"]application\\/json['"])${t}[^>]*>)[\\s\\S]*?(<\/script>)`,`i`)}function em(e){Zp.has(e.id)&&console.warn(`[viewer-registry] Overwriting viewer template "${e.id}"`),Zp.set(e.id,e)}function tm(e){return Zp.get(e)}function nm(e){return typeof e==`string`&&Zp.has(e)}function rm(){return[...Zp.values()]}function im(e,t,n,r){let i=$p(n);if(!i.test(e))throw Error(`No <script type="application/json" id="${n}"> found in template`);let a=r?r(t):t,o=JSON.stringify(a??null).replace(/<\/script/gi,`<\\/script`).replace(/<script/gi,`\\u003Cscript`).replace(/-->/g,`--\\u003E`).replace(/<!--/g,`\\u003C!--`);return e.replace(i,`$1\n${o}\n$2`)}const am=import.meta.dirname??Re(le(import.meta.url)),om={type:`object`,properties:{title:{type:`string`},description:{type:`string`},layout:{type:`object`,properties:{direction:{type:`string`},spacing:{type:`number`},layerSpacing:{type:`number`}}},nodes:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},type:{type:`string`,enum:[`person`,`system`,`container`,`component`,`database`,`queue`,`external`,`boundary`]},label:{type:`string`},technology:{type:`string`},icon:{type:`string`},description:{type:`string`}},required:[`id`,`type`,`label`]}},edges:{type:`array`,items:{type:`object`,properties:{source:{type:`string`},target:{type:`string`},label:{type:`string`},style:{type:`string`,enum:[`sync`,`async`,`dashed`,`dotted`,`solid`]}},required:[`source`,`target`]},default:[]}},required:[`nodes`]},sm={type:`object`,properties:{nodes:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},label:{type:`string`},type:{type:`string`,enum:[`start-end`,`manual`,`automated`,`integration`,`decision`,`prerequisite`]},description:{type:`string`}},required:[`id`,`label`]}},edges:{type:`array`,items:{type:`object`,properties:{source:{type:`string`},target:{type:`string`},label:{type:`string`},type:{type:`string`,enum:[`standard`,`loop-back`,`exception`]}},required:[`source`,`target`]}}},required:[`nodes`]},cm={type:`object`,properties:{title:{type:`string`},description:{type:`string`},phases:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},label:{type:`string`},outcome:{type:`string`},batches:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},order:{type:`number`},parallel:{type:`boolean`},label:{type:`string`},tasks:{type:`array`,items:{type:`object`,properties:{id:{type:`string`},title:{type:`string`},agent:{type:`string`},files:{type:`array`,items:{type:`string`},default:[]},status:{type:`string`,enum:[`pending`,`in-progress`,`done`,`blocked`]},dependsOn:{type:`array`,items:{type:`string`},default:[]}},required:[`id`,`title`]},default:[]}},required:[`id`,`tasks`]},default:[]}},required:[`id`,`label`,`batches`]}}},required:[`phases`]};function lm(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function um(e,t){return lm(t)?{...t,kind:e}:{kind:e}}function dm(e){let t=e===`canvas.html`?[I(am,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,`src`,`canvas`,`index.html`),I(am,`..`,`..`,`scaffold`,`general`,`viewers`,`src`,`canvas`,`index.html`)]:[],n=C(`server`,[I(`viewers`,`dist`,e),I(`viewers`,e)]),r=[...t,...n?[n]:[],I(am,`..`,`..`,`..`,`viewers`,e),I(am,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,`src`,`static`,e),I(am,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,`dist`,e),I(am,`..`,`..`,`..`,`..`,`..`,`scaffold`,`general`,`viewers`,e),I(am,`..`,`..`,`scaffold`,`general`,`viewers`,`dist`,e),I(am,`..`,`..`,`scaffold`,`general`,`viewers`,e),I(am,`..`,`viewers`,`dist`,e),I(am,`..`,`viewers`,e)];for(let e of r)try{return F(e,`utf8`)}catch{}throw Error(`Viewer HTML not found: ${e}. Searched: ${r.join(`, `)}`)}let fm,pm,mm,hm,gm,_m,vm;function ym(){return fm??=dm(`c4-viewer.html`),fm}function bm(){return pm??=dm(`tour-viewer.html`),pm}function xm(){return mm??=dm(`canvas.html`),mm}function Sm(){return hm??=dm(`architecture-static.html`),hm}function Cm(){return gm??=dm(`process-flow-static.html`),gm}function wm(){return _m??=dm(`task-plan-static.html`),_m}function Tm(){return vm??=dm(`code-review-viewer.html`),vm}const Em={type:`object`,properties:{title:{type:`string`,description:`PR or review title`},repo:{type:`string`,description:`Repository identifier (e.g., owner/repo)`},author:{type:`string`,description:`Author display name`},date:{type:`string`,description:`Date or relative time string`},branch:{type:`string`,description:`Source branch name`},targetBranch:{type:`string`,default:`main`},description:{type:`string`,description:`PR or change description`},additions:{type:`number`,default:0},deletions:{type:`number`,default:0},summary:{type:`string`,description:`Overall review summary`},summaryTitle:{type:`string`,default:`Summary`},conclusion:{type:`array`,items:{type:`string`},description:`Conclusion paragraphs`},files:{type:`array`,items:{type:`object`,properties:{path:{type:`string`},additions:{type:`number`,default:0},deletions:{type:`number`,default:0},risk:{type:`string`,enum:[`safe`,`medium`,`attention`],default:`safe`},collapsed:{type:`boolean`,default:!0},diff:{type:`array`,items:{type:`object`,properties:{t:{type:`string`,enum:[`add`,`del`,`ctx`,`hunk`],default:`ctx`},n:{type:`string`,description:`Line number`},c:{type:`string`,description:`Code content`}}}},comments:{type:`array`,items:{type:`object`,properties:{line:{type:`number`},text:{type:`string`},blocking:{type:`boolean`,default:!1}}}}},required:[`path`]}}},required:[`files`]};function Dm(){em({id:`c4@1`,label:`C4 Architecture Diagram`,description:`Interactive C4 architecture diagram with zoom, pan, and ELK auto-layout`,inputSchema:om,injectId:`diagram-data`,supportedTransports:[`browser`],resolveHtml:ym}),em({id:`c4-static@1`,label:`C4 Architecture Diagram (Static)`,description:`Static SVG architecture diagram for inline rendering`,inputSchema:om,injectId:`diagram-data`,supportedTransports:[`mcp-app`],resolveHtml:Sm}),em({id:`tour@1`,label:`Code Tour Viewer`,description:`Interactive code tour with step navigation and dependency graph`,inputSchema:{type:`object`,properties:{title:{type:`string`},description:{type:`string`},estimatedTime:{type:`string`},steps:{type:`array`,items:{type:`object`,properties:{stepNumber:{type:`number`},id:{type:`string`},title:{type:`string`},file:{type:`string`},explanation:{type:`string`},description:{type:`string`},learnsConcept:{type:`string`},duration:{type:`string`},line:{type:`number`},code:{type:`string`}},required:[`id`,`title`]}},dependencies:{type:`array`,items:{type:`object`,properties:{source:{type:`string`},target:{type:`string`}},required:[`source`,`target`]},default:[]}},required:[`steps`]},injectId:`tour-data`,supportedTransports:[`browser`],resolveHtml:bm}),em({id:`process-flow-static@1`,label:`Process Flow Diagram (Static)`,description:`Static SVG process flow diagram for inline rendering`,inputSchema:sm,injectId:`diagram-data`,supportedTransports:[`mcp-app`],resolveHtml:Cm}),em({id:`task-plan-static@1`,label:`Task Execution Plan (Static)`,description:`Static SVG task execution plan for inline rendering`,inputSchema:cm,injectId:`diagram-data`,supportedTransports:[`mcp-app`],resolveHtml:wm}),em({id:`process-flow@1`,label:`Process Flow Diagram (Interactive)`,description:`Interactive process flow diagram with ReactFlow`,inputSchema:sm,injectId:`diagram-data`,supportedTransports:[`browser`],resolveHtml:xm,transformData:e=>um(`process-flow`,e)}),em({id:`code-review@1`,label:`Code Review`,description:`Annotated code review with diff display, risk map, and review bubbles. Supports text selection annotations when used with actions.`,inputSchema:Em,injectId:`review-data`,supportedTransports:[`mcp-app`,`browser`],resolveHtml:Tm})}function Om(){let e=new Pr;for(let t of Lr.list())e.register(t);return e.register(Ir),e.register(Vr),e.register(Hr),e.register(Rr),e}function km(e,t){return e?.supportedTransports.includes(t)??!1}const Am=Om();function jm(e){if(e.template)return Am.get(e.template)}function Mm(e){if((e.actions?.length??0)>0)return!0;if(e.template&&nm(e.template)){let t=tm(e.template);return t?.supportedTransports.includes(`browser`)===!0&&!t.supportedTransports.includes(`mcp-app`)}let t=jm(e);return km(t,`browser`)&&!km(t,`mcp-app`)}Dm();const Y={TIMEOUT:`timeout`,DUPLICATE_CALLBACK:`duplicate_callback`,INVALID_NONCE:`invalid_nonce`,INVALID_ORIGIN:`invalid_origin`,SESSION_NOT_FOUND:`session_not_found`,SESSION_LIMIT_REACHED:`session_limit_reached`,ASSET_NOT_FOUND:`asset_not_found`,ASSET_FORBIDDEN:`asset_forbidden`,RATE_LIMITED:`rate_limited`,PAYLOAD_TOO_LARGE:`payload_too_large`,UNSUPPORTED_MEDIA_TYPE:`unsupported_media_type`,INVALID_TRANSITION:`invalid_transition`,ANNOTATION_CAP_EXCEEDED:`annotation_cap_exceeded`},Nm={[Y.TIMEOUT]:408,[Y.DUPLICATE_CALLBACK]:409,[Y.INVALID_NONCE]:400,[Y.INVALID_ORIGIN]:403,[Y.SESSION_NOT_FOUND]:404,[Y.SESSION_LIMIT_REACHED]:429,[Y.ASSET_NOT_FOUND]:404,[Y.ASSET_FORBIDDEN]:403,[Y.RATE_LIMITED]:429,[Y.PAYLOAD_TOO_LARGE]:413,[Y.UNSUPPORTED_MEDIA_TYPE]:415,[Y.INVALID_TRANSITION]:400,[Y.ANNOTATION_CAP_EXCEEDED]:403};function Pm(e,t,n){return{code:e,message:t,httpStatus:n??Nm[e]}}const Fm={created:[`rendering`,`errored`,`cleaned_up`,`timed_out`,`cancelled`,`responded`],rendering:[`listening`,`errored`,`cleaned_up`,`timed_out`,`cancelled`],listening:[`connected`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],connected:[`responded`,`timed_out`,`cancelled`,`errored`,`cleaned_up`],responded:[`cleaned_up`],timed_out:[`cleaned_up`],cancelled:[`cleaned_up`],errored:[`cleaned_up`],cleaned_up:[]};function Im(e,t,n,r){return Fm[e].includes(t)?{ok:!0,to:t,entry:{from:e,to:t,timestamp:Date.now(),trigger:r}}:{ok:!1,error:{code:`invalid_transition`,message:`Cannot transition from "${e}" to "${t}"`,from:e,to:t}}}function Lm(e){return Fm[e].length===0}const Rm=1024,zm=new Set([`user-closed`,`host-dismissed`,`replaced`]);function Bm(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Vm(e,t,n){let r={code:e,message:t};return n!==void 0&&(r.details=n),{kind:`error`,error:r}}function Hm(e,t,n,r){e.writeHead(t,{"Content-Type":`application/json`,"Access-Control-Allow-Origin":r??`null`}),e.end(JSON.stringify(n))}async function Um(e){return await new Promise((t,n)=>{let r=[],i=0;e.on(`data`,t=>{if(i+=t.length,i>65536){n(Error(`Callback payload exceeds 64KB limit`)),e.destroy();return}r.push(t)}),e.on(`end`,()=>t(Buffer.concat(r).toString(`utf8`))),e.on(`error`,n)})}function Wm(e,t){if(typeof e!=`string`||e.length!==t.length)return!1;let n=Buffer.from(e,`hex`),r=Buffer.from(t,`hex`);return n.length===r.length?Qe(n,r):!1}function Gm(e,t){let n=e.headers.origin;if(n!==void 0)return n===t;let r=e.headers.referer;return r==null?!0:r.startsWith(t)}function Km(e){return(e.headers[`content-type`]??``).startsWith(`application/json`)}function qm(e){for(let[t,n]of Object.entries(e)){let e=typeof n==`string`?n:JSON.stringify(n);if(Buffer.byteLength(e,`utf8`)>8192)return`Form field "${t}" exceeds 8KB limit`}return null}function Jm(e){return Array.isArray(e)&&e.length>Rm?`Selection exceeds ${Rm} items (got ${e.length})`:null}function Ym(e,t,n){let r=typeof e.actionId==`string`?e.actionId:``,i=n.find(e=>e.id===r);if(!i)return Vm(`INVALID_ACTION`,`Unknown actionId: ${r||`(missing)`}`);let a=typeof e.selection==`string`||Array.isArray(e.selection)?e.selection:void 0,o=Bm(e.formData)?e.formData:void 0,s={surfaceId:t,actionId:i.id,actionType:i.type,timestamp:typeof e.timestamp==`string`?e.timestamp:new Date().toISOString(),sourceTransport:`browser`};return e.value!==void 0&&(s.value=e.value),a!==void 0&&(s.selection=a),o!==void 0&&(s.formData=o),e.annotations!==void 0&&(s.annotations=e.annotations),typeof e.label==`string`?s.label=e.label:i.label&&(s.label=i.label),{kind:`result`,result:s}}function Xm(e){switch(e.kind){case`timeout`:return`timed_out`;case`cancelled`:return`cancelled`;case`error`:return`errored`;case`result`:return`responded`;default:return`errored`}}function Zm(e,t,n,r,i){let a=i??Xe(16).toString(`hex`),o=`created`,s=[],c=!1,l,u,d=new Promise(e=>{u=e}),f=e=>{if(Lm(o))return l;let t=Xm(e),i=Im(o,t,s,`resolve`);return i.ok?(o=t,s.push(i.entry),l=e,u?.(e),n&&r&&n.transitionSession(r,t,`resolve`),e):l};return{nonce:a,promise:d,get state(){return o},get stateHistory(){return s},settleTimeout(e){return f({kind:`timeout`,waitedMs:e})},settleCancelled(e){return f({kind:`cancelled`,reason:e})},settleError(e,t,n){return f(Vm(e,t,n))},async handle(n,r,i){if(!Km(n)){let e=f(Vm(Y.UNSUPPORTED_MEDIA_TYPE,`Content-Type must be application/json`));return Hm(r,415,{ok:!1,error:Y.UNSUPPORTED_MEDIA_TYPE},i),e}if(!Gm(n,i)){let e=n.headers.origin??n.headers.referer??`(missing)`,t=f(Vm(Y.INVALID_ORIGIN,`Unexpected callback origin: ${e}`));return Hm(r,403,{ok:!1,error:Y.INVALID_ORIGIN},i),t}let o=``;try{o=await Um(n)}catch(e){let t=f(Vm(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Unable to read callback payload`));return Hm(r,413,{ok:!1,error:Y.PAYLOAD_TOO_LARGE},i),t}let s;try{let e=JSON.parse(o);if(!Bm(e))throw Error(`Callback payload must be an object`);s=e}catch(e){let t=f(Vm(`INVALID_PAYLOAD`,e instanceof Error?e.message:`Malformed callback payload`));return Hm(r,400,{ok:!1,error:`invalid-json`},i),t}if(c){let e=Vm(Y.DUPLICATE_CALLBACK,`Nonce has already been used`);return Hm(r,403,{ok:!1,error:Y.DUPLICATE_CALLBACK},i),e}if(!Wm(typeof s.nonce==`string`?s.nonce:``,a)){let e=f(Vm(Y.INVALID_NONCE,`Callback nonce did not match`));return Hm(r,403,{ok:!1,error:Y.INVALID_NONCE},i),e}c=!0;let l=Jm(s.selection);if(l){let e=f(Vm(`SELECTION_TOO_LARGE`,l));return Hm(r,413,{ok:!1,error:`selection-too-large`},i),e}if(Bm(s.formData)){let e=qm(s.formData);if(e){let t=f(Vm(`PAYLOAD_FIELD_TOO_LARGE`,e));return Hm(r,413,{ok:!1,error:`field-too-large`},i),t}}if(s.kind===`cancelled`){let e=typeof s.reason==`string`?s.reason:``;if(!zm.has(e)){let t=f(Vm(`INVALID_CANCEL_REASON`,`Unsupported cancel reason: ${e||`(missing)`}`));return Hm(r,400,{ok:!1,error:`invalid-cancel-reason`},i),t}let t=f({kind:`cancelled`,reason:e});return Hm(r,200,{ok:!0,kind:`cancelled`},i),t}let u=f(Ym(s,e,t));return Hm(r,u.kind===`error`?400:200,{ok:u.kind!==`error`,kind:u.kind},i),u}}}const Qm=`Install AI Kit with <code>${J(`npx -y @vpxa/aikit@latest init --user`)}</code>.`;function $m(e){let t=Date.now();return{id:e.id,state:`created`,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport,createdAt:t,updatedAt:t,stateHistory:[],responsePromise:null,resolveOutcome:null,cleanupCallbacks:[],nonceConsumed:!1}}var eh=class{sessions;maxSessions;rejectedCount;constructor(e=16){this.sessions=new Map,this.maxSessions=e,this.rejectedCount=0}createSession(e){if(this.sessions.size>=this.maxSessions)return this.rejectedCount++,{ok:!1,error:Pm(Y.SESSION_LIMIT_REACHED,`Session limit reached`)};let t=Ze(),n=$m({id:t,nonce:e.nonce,surfaceId:e.surfaceId,transport:e.transport});return this.sessions.set(t,n),{ok:!0,session:n}}getSession(e){return this.sessions.get(e)||Pm(Y.SESSION_NOT_FOUND,`Session ${e} not found`)}transitionSession(e,t,n){let r=this.sessions.get(e);if(!r)return{ok:!1,error:Pm(Y.SESSION_NOT_FOUND,`Session ${e} not found`)};let i=Im(r.state,t,r.stateHistory,n);return i.ok?(r.state=i.to,r.stateHistory.push(i.entry),r.updatedAt=Date.now(),{ok:!0,record:r}):{ok:!1,error:Pm(Y.INVALID_TRANSITION,i.error.message)}}consumeNonce(e){let t=this.sessions.get(e);return t?t.nonceConsumed?{ok:!1,error:Pm(Y.DUPLICATE_CALLBACK,`Nonce already consumed`)}:(t.nonceConsumed=!0,t.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Pm(Y.SESSION_NOT_FOUND,`Session ${e} not found`)}}removeSession(e){return this.sessions.delete(e)}cleanupStale(e){let t=Date.now(),n=0;for(let[r,i]of this.sessions.entries())i.state!==`connected`&&t-i.updatedAt>e&&(i.resolveOutcome&&(i.resolveOutcome({outcome:`timeout`}),i.resolveOutcome=null,i.responsePromise=null),this.sessions.delete(r),n++);return n}shutdown(){for(let[,e]of this.sessions.entries()){e.resolveOutcome&&(e.resolveOutcome({outcome:`shutdown`}),e.resolveOutcome=null,e.responsePromise=null);for(let t of e.cleanupCallbacks)try{t()}catch{}e.cleanupCallbacks=[]}this.sessions.clear()}get activeCount(){return this.sessions.size}get rejectedSessionCount(){return this.rejectedCount}setResponseResolver(e,t){let n=this.sessions.get(e);return n?(n.resolveOutcome=t,n.updatedAt=Date.now(),{ok:!0}):{ok:!1,error:Pm(Y.SESSION_NOT_FOUND,`Session ${e} not found`)}}};const th=String.raw`(function(){
306
- 'use strict';
307
-
308
- var SVG_NS = 'http://www.w3.org/2000/svg';
309
- var DEFAULT_DIRECTION = 'TD';
310
- var HORIZONTAL_GAP = 60;
311
- var VERTICAL_GAP = 80;
312
- var OUTER_PADDING = 32;
313
- var GROUP_PADDING = 18;
314
- var FONT_SIZE = 14;
315
- var LINE_HEIGHT = 18;
316
- var CHAR_WIDTH = 8;
317
- var MAX_RENDER_PASSES = 1;
318
-
319
- function createSvg(tag) {
320
- return document.createElementNS(SVG_NS, tag);
321
- }
322
-
323
- function setAttrs(node, attrs) {
324
- var keys = Object.keys(attrs);
325
- for (var i = 0; i < keys.length; i += 1) {
326
- var key = keys[i];
327
- var value = attrs[key];
328
- if (value !== undefined && value !== null) {
329
- node.setAttribute(key, String(value));
330
- }
331
- }
332
- return node;
333
- }
334
-
335
- function pushUnique(list, value) {
336
- if (list.indexOf(value) === -1) {
337
- list.push(value);
338
- }
339
- }
340
-
341
- function stripQuotes(value) {
342
- var text = String(value || '').trim();
343
- if (text.length >= 2) {
344
- var first = text.charAt(0);
345
- var last = text.charAt(text.length - 1);
346
- if ((first === '"' && last === '"') || (first === '\'' && last === '\'')) {
347
- return text.slice(1, -1);
348
- }
349
- }
350
- return text;
351
- }
352
-
353
- function normalizeLabel(value) {
354
- var text = stripQuotes(value);
355
- return text.replace(/<br\s*\/?>/gi, '\n').replace(/\\n/g, '\n').trim();
356
- }
357
-
358
- function isTopLevel(depths, quote) {
359
- return !quote && depths.square === 0 && depths.round === 0 && depths.curly === 0;
360
- }
361
-
362
- function splitTopLevel(text, delimiter) {
363
- var items = [];
364
- var current = '';
365
- var quote = '';
366
- var depths = { square: 0, round: 0, curly: 0 };
367
-
368
- for (var i = 0; i < text.length; i += 1) {
369
- var ch = text.charAt(i);
370
- var prev = i > 0 ? text.charAt(i - 1) : '';
371
-
372
- if (quote) {
373
- current += ch;
374
- if (ch === quote && prev !== '\\') {
375
- quote = '';
376
- }
377
- continue;
378
- }
379
-
380
- if (ch === '"' || ch === '\'') {
381
- quote = ch;
382
- current += ch;
383
- continue;
384
- }
385
-
386
- if (ch === '[') depths.square += 1;
387
- else if (ch === ']') depths.square = Math.max(0, depths.square - 1);
388
- else if (ch === '(') depths.round += 1;
389
- else if (ch === ')') depths.round = Math.max(0, depths.round - 1);
390
- else if (ch === '{') depths.curly += 1;
391
- else if (ch === '}') depths.curly = Math.max(0, depths.curly - 1);
392
-
393
- if (ch === delimiter && isTopLevel(depths, quote)) {
394
- if (current.trim()) {
395
- items.push(current.trim());
396
- }
397
- current = '';
398
- continue;
399
- }
400
-
401
- current += ch;
402
- }
403
-
404
- if (current.trim()) {
405
- items.push(current.trim());
406
- }
407
-
408
- return items;
409
- }
410
-
411
- function stripComment(line) {
412
- var quote = '';
413
- var depths = { square: 0, round: 0, curly: 0 };
414
-
415
- for (var i = 0; i < line.length; i += 1) {
416
- var ch = line.charAt(i);
417
- var next = i + 1 < line.length ? line.charAt(i + 1) : '';
418
- var prev = i > 0 ? line.charAt(i - 1) : '';
419
-
420
- if (quote) {
421
- if (ch === quote && prev !== '\\') {
422
- quote = '';
423
- }
424
- continue;
425
- }
426
-
427
- if (ch === '"' || ch === '\'') {
428
- quote = ch;
429
- continue;
430
- }
431
-
432
- if (ch === '[') depths.square += 1;
433
- else if (ch === ']') depths.square = Math.max(0, depths.square - 1);
434
- else if (ch === '(') depths.round += 1;
435
- else if (ch === ')') depths.round = Math.max(0, depths.round - 1);
436
- else if (ch === '{') depths.curly += 1;
437
- else if (ch === '}') depths.curly = Math.max(0, depths.curly - 1);
438
-
439
- if (ch === '%' && next === '%' && isTopLevel(depths, quote)) {
440
- return line.slice(0, i);
441
- }
442
- }
443
-
444
- return line;
445
- }
446
-
447
- function extractStatements(source) {
448
- var lines = String(source || '').split(/\r?\n/);
449
- var statements = [];
450
-
451
- for (var i = 0; i < lines.length; i += 1) {
452
- var line = stripComment(lines[i]).trim();
453
- if (!line) {
454
- continue;
455
- }
456
-
457
- var parts = splitTopLevel(line, ';');
458
- for (var j = 0; j < parts.length; j += 1) {
459
- if (parts[j]) {
460
- statements.push(parts[j]);
461
- }
462
- }
463
- }
464
-
465
- return statements;
466
- }
467
-
468
- function readBalanced(text, index, open, close) {
469
- var depth = 0;
470
- var quote = '';
471
-
472
- for (var i = index; i < text.length; i += 1) {
473
- var ch = text.charAt(i);
474
- var prev = i > 0 ? text.charAt(i - 1) : '';
475
-
476
- if (quote) {
477
- if (ch === quote && prev !== '\\') {
478
- quote = '';
479
- }
480
- continue;
481
- }
482
-
483
- if (ch === '"' || ch === '\'') {
484
- quote = ch;
485
- continue;
486
- }
487
-
488
- if (text.slice(i, i + open.length) === open) {
489
- depth += 1;
490
- i += open.length - 1;
491
- continue;
492
- }
493
-
494
- if (text.slice(i, i + close.length) === close) {
495
- depth -= 1;
496
- i += close.length - 1;
497
- if (depth === 0) {
498
- return {
499
- value: text.slice(index + open.length, i - close.length + 1),
500
- index: i + 1,
501
- };
502
- }
503
- }
504
- }
505
-
506
- throw new Error('Unterminated node shape');
507
- }
508
-
509
- function skipWhitespace(text, index) {
510
- var cursor = index;
511
- while (cursor < text.length && /\s/.test(text.charAt(cursor))) {
512
- cursor += 1;
513
- }
514
- return cursor;
515
- }
516
-
517
- function readIdentifier(text, index) {
518
- var cursor = skipWhitespace(text, index);
519
- var start = cursor;
520
-
521
- while (cursor < text.length) {
522
- var ch = text.charAt(cursor);
523
- if (/\s/.test(ch) || ch === '[' || ch === '(' || ch === '{' || ch === '-' || ch === '=' || ch === '.' || ch === '|' || ch === ';') {
524
- break;
525
- }
526
- cursor += 1;
527
- }
528
-
529
- if (cursor === start) {
530
- return null;
531
- }
532
-
533
- return {
534
- value: text.slice(start, cursor),
535
- index: cursor,
536
- };
537
- }
538
-
539
- function readNodeRef(text, index) {
540
- var idToken = readIdentifier(text, index);
541
- if (!idToken) {
542
- return null;
543
- }
544
-
545
- var id = idToken.value.trim();
546
- var cursor = skipWhitespace(text, idToken.index);
547
- var shape = 'rect';
548
- var label = id;
549
-
550
- if (text.slice(cursor, cursor + 2) === '((') {
551
- var circle = readBalanced(text, cursor, '((', '))');
552
- shape = 'circle';
553
- label = normalizeLabel(circle.value);
554
- cursor = circle.index;
555
- } else if (text.slice(cursor, cursor + 2) === '([') {
556
- var stadium = readBalanced(text, cursor, '([', '])');
557
- shape = 'stadium';
558
- label = normalizeLabel(stadium.value);
559
- cursor = stadium.index;
560
- } else if (text.slice(cursor, cursor + 2) === '{{') {
561
- var hexagon = readBalanced(text, cursor, '{{', '}}');
562
- shape = 'hexagon';
563
- label = normalizeLabel(hexagon.value);
564
- cursor = hexagon.index;
565
- } else if (text.slice(cursor, cursor + 2) === '[(') {
566
- var cylinder = readBalanced(text, cursor, '[(', ')]');
567
- shape = 'rect';
568
- label = normalizeLabel(cylinder.value);
569
- cursor = cylinder.index;
570
- } else if (text.charAt(cursor) === '[') {
571
- var rect = readBalanced(text, cursor, '[', ']');
572
- shape = 'rect';
573
- label = normalizeLabel(rect.value);
574
- cursor = rect.index;
575
- } else if (text.charAt(cursor) === '(') {
576
- var rounded = readBalanced(text, cursor, '(', ')');
577
- shape = 'rounded';
578
- label = normalizeLabel(rounded.value);
579
- cursor = rounded.index;
580
- } else if (text.charAt(cursor) === '{') {
581
- var diamond = readBalanced(text, cursor, '{', '}');
582
- shape = 'diamond';
583
- label = normalizeLabel(diamond.value);
584
- cursor = diamond.index;
585
- }
586
-
587
- return {
588
- node: {
589
- id: id,
590
- label: label || id,
591
- shape: shape,
592
- },
593
- index: cursor,
594
- };
595
- }
596
-
597
- function edgePattern(match, style, arrow) {
598
- return {
599
- match: match,
600
- style: style,
601
- arrow: arrow,
602
- };
603
- }
604
-
605
- var EDGE_PATTERNS = [
606
- edgePattern(/^\s*-\.->\|([^|]+)\|\s*/, 'dotted', true),
607
- edgePattern(/^\s*==>\|([^|]+)\|\s*/, 'thick', true),
608
- edgePattern(/^\s*-->\|([^|]+)\|\s*/, 'solid', true),
609
- edgePattern(/^\s*---\|([^|]+)\|\s*/, 'solid', false),
610
- edgePattern(/^\s*--\s+(.+?)\s+-->\s*/, 'solid', true),
611
- edgePattern(/^\s*-\.->\s*/, 'dotted', true),
612
- edgePattern(/^\s*==>\s*/, 'thick', true),
613
- edgePattern(/^\s*-->\s*/, 'solid', true),
614
- edgePattern(/^\s*---\s*/, 'solid', false),
615
- ];
616
-
617
- function readEdge(text, index) {
618
- var remainder = text.slice(index);
619
-
620
- for (var i = 0; i < EDGE_PATTERNS.length; i += 1) {
621
- var pattern = EDGE_PATTERNS[i];
622
- var match = remainder.match(pattern.match);
623
- if (!match) {
624
- continue;
625
- }
626
-
627
- return {
628
- index: index + match[0].length,
629
- style: pattern.style,
630
- arrow: pattern.arrow,
631
- label: match[1] ? normalizeLabel(match[1]) : '',
632
- };
633
- }
634
-
635
- return null;
636
- }
637
-
638
- function newGraph(direction) {
639
- return {
640
- direction: direction,
641
- nodesById: Object.create(null),
642
- nodeOrder: [],
643
- edges: [],
644
- subgraphs: [],
645
- };
646
- }
647
-
648
- function addNode(graph, ref, activeGroups) {
649
- var node = graph.nodesById[ref.id];
650
-
651
- if (!node) {
652
- node = {
653
- id: ref.id,
654
- label: ref.label || ref.id,
655
- shape: ref.shape || 'rect',
656
- groups: [],
657
- rank: 0,
658
- width: 0,
659
- height: 0,
660
- lines: [],
661
- x: 0,
662
- y: 0,
663
- order: graph.nodeOrder.length,
664
- };
665
- graph.nodesById[ref.id] = node;
666
- graph.nodeOrder.push(ref.id);
667
- }
668
-
669
- if (ref.label && ref.label !== ref.id) {
670
- node.label = ref.label;
671
- }
672
- if (ref.shape && ref.shape !== 'rect') {
673
- node.shape = ref.shape;
674
- }
675
-
676
- for (var i = 0; i < activeGroups.length; i += 1) {
677
- var groupId = activeGroups[i];
678
- pushUnique(node.groups, groupId);
679
- for (var j = 0; j < graph.subgraphs.length; j += 1) {
680
- if (graph.subgraphs[j].id === groupId) {
681
- pushUnique(graph.subgraphs[j].members, node.id);
682
- }
683
- }
684
- }
685
-
686
- return node;
687
- }
688
-
689
- function addEdge(graph, fromNode, edgeDef, toNode) {
690
- graph.edges.push({
691
- from: fromNode.id,
692
- to: toNode.id,
693
- label: edgeDef.label || '',
694
- style: edgeDef.style,
695
- arrow: edgeDef.arrow,
696
- });
697
- }
698
-
699
- function parseDirection(statement) {
700
- var match = statement.match(/^(graph|flowchart)\s+(TD|TB|BT|LR|RL)\b/i);
701
- if (!match) {
702
- return null;
703
- }
704
- var direction = match[2].toUpperCase();
705
- return direction === 'TB' ? 'TD' : direction;
706
- }
707
-
708
- function parseMermaid(source) {
709
- var statements = extractStatements(source);
710
- var direction = DEFAULT_DIRECTION;
711
-
712
- if (statements.length > 0) {
713
- var explicitDirection = parseDirection(statements[0]);
714
- if (explicitDirection) {
715
- direction = explicitDirection;
716
- statements.shift();
717
- }
718
- }
719
-
720
- var graph = newGraph(direction);
721
- var activeGroups = [];
722
- var groupCount = 0;
723
-
724
- for (var i = 0; i < statements.length; i += 1) {
725
- var statement = statements[i];
726
- if (!statement) {
727
- continue;
728
- }
729
-
730
- if (/^subgraph\b/i.test(statement)) {
731
- groupCount += 1;
732
- var title = normalizeLabel(statement.replace(/^subgraph\s+/i, '')) || ('Subgraph ' + groupCount);
733
- var group = {
734
- id: 'subgraph_' + groupCount,
735
- title: title,
736
- members: [],
737
- };
738
- graph.subgraphs.push(group);
739
- activeGroups.push(group.id);
740
- continue;
741
- }
742
-
743
- if (/^end$/i.test(statement)) {
744
- activeGroups.pop();
745
- continue;
746
- }
747
-
748
- var first = readNodeRef(statement, 0);
749
- if (!first) {
750
- throw new Error('Unable to parse node: ' + statement);
751
- }
752
-
753
- var fromNode = addNode(graph, first.node, activeGroups.slice());
754
- var cursor = first.index;
755
- var consumedEdge = false;
756
-
757
- while (true) {
758
- var edge = readEdge(statement, cursor);
759
- if (!edge) {
760
- break;
761
- }
762
-
763
- cursor = edge.index;
764
- var next = readNodeRef(statement, cursor);
765
- if (!next) {
766
- throw new Error('Edge is missing a target node: ' + statement);
767
- }
768
-
769
- var toNode = addNode(graph, next.node, activeGroups.slice());
770
- addEdge(graph, fromNode, edge, toNode);
771
- fromNode = toNode;
772
- cursor = next.index;
773
- consumedEdge = true;
774
- }
775
-
776
- if (!consumedEdge) {
777
- var tail = statement.slice(cursor).trim();
778
- if (tail) {
779
- throw new Error('Unexpected trailing content: ' + tail);
780
- }
781
- }
782
- }
783
-
784
- return graph;
785
- }
786
-
787
- function createMeasurer() {
788
- var svg = null;
789
- var text = null;
790
-
791
- return function measureLine(line) {
792
- var sample = String(line || '');
793
-
794
- try {
795
- if (!svg) {
796
- svg = createSvg('svg');
797
- setAttrs(svg, {
798
- width: 0,
799
- height: 0,
800
- style: 'position:absolute;left:-9999px;top:-9999px;overflow:hidden;pointer-events:none',
801
- 'aria-hidden': 'true',
802
- });
803
- text = createSvg('text');
804
- setAttrs(text, {
805
- 'font-size': FONT_SIZE,
806
- 'font-family': 'var(--dt-font-sans, ui-sans-serif, system-ui, sans-serif)',
807
- });
808
- svg.appendChild(text);
809
- if (document.body) {
810
- document.body.appendChild(svg);
811
- }
812
- }
813
-
814
- if (text && typeof text.getBBox === 'function') {
815
- text.textContent = sample || ' ';
816
- var box = text.getBBox();
817
- if (box && box.width) {
818
- return box.width;
819
- }
820
- }
821
- } catch (_error) {
822
- return sample.length * CHAR_WIDTH;
823
- }
824
-
825
- return Math.max(16, sample.length * CHAR_WIDTH);
826
- };
827
- }
828
-
829
- var measureLine = createMeasurer();
830
-
831
- function splitLabelLines(label) {
832
- var lines = String(label || '').split(/\n+/).map(function(line) {
833
- return line.trim();
834
- }).filter(Boolean);
835
- return lines.length ? lines : [''];
836
- }
837
-
838
- function sizeNode(node) {
839
- if (node.stateKind === 'start') {
840
- node.lines = [];
841
- node.width = 18;
842
- node.height = 18;
843
- return;
844
- }
845
-
846
- if (node.stateKind === 'end') {
847
- node.lines = [];
848
- node.width = 24;
849
- node.height = 24;
850
- return;
851
- }
852
-
853
- var lines = splitLabelLines(node.label || node.id);
854
- var maxWidth = 0;
855
-
856
- for (var i = 0; i < lines.length; i += 1) {
857
- maxWidth = Math.max(maxWidth, measureLine(lines[i]));
858
- }
859
-
860
- var width = Math.max(72, Math.ceil(maxWidth + 28));
861
- var height = Math.max(44, lines.length * LINE_HEIGHT + 18);
862
-
863
- if (node.shape === 'circle') {
864
- var diameter = Math.max(width, height);
865
- width = diameter;
866
- height = diameter;
867
- } else if (node.shape === 'diamond') {
868
- width = Math.max(width + 16, 88);
869
- height = Math.max(height + 12, 56);
870
- } else if (node.shape === 'hexagon') {
871
- width = Math.max(width + 18, 92);
872
- } else if (node.shape === 'stadium') {
873
- width = Math.max(width + 12, 88);
874
- }
875
-
876
- node.lines = lines;
877
- node.width = width;
878
- node.height = height;
879
- }
880
-
881
- function buildAdjacency(graph) {
882
- var incoming = Object.create(null);
883
- var outgoing = Object.create(null);
884
- var indegree = Object.create(null);
885
-
886
- for (var i = 0; i < graph.nodeOrder.length; i += 1) {
887
- var id = graph.nodeOrder[i];
888
- incoming[id] = [];
889
- outgoing[id] = [];
890
- indegree[id] = 0;
891
- }
892
-
893
- for (var j = 0; j < graph.edges.length; j += 1) {
894
- var edge = graph.edges[j];
895
- outgoing[edge.from].push(edge);
896
- incoming[edge.to].push(edge);
897
- if (edge.from !== edge.to) {
898
- indegree[edge.to] += 1;
899
- }
900
- }
901
-
902
- return {
903
- incoming: incoming,
904
- outgoing: outgoing,
905
- indegree: indegree,
906
- };
907
- }
908
-
909
- function topologicalOrder(graph, adjacency) {
910
- var queue = [];
911
- var order = [];
912
- var seen = Object.create(null);
913
-
914
- for (var i = 0; i < graph.nodeOrder.length; i += 1) {
915
- var id = graph.nodeOrder[i];
916
- if (adjacency.indegree[id] === 0) {
917
- queue.push(id);
918
- }
919
- }
920
-
921
- while (queue.length) {
922
- var current = queue.shift();
923
- if (seen[current]) {
924
- continue;
925
- }
926
- seen[current] = true;
927
- order.push(current);
928
-
929
- var outgoing = adjacency.outgoing[current];
930
- for (var j = 0; j < outgoing.length; j += 1) {
931
- var edge = outgoing[j];
932
- if (edge.from === edge.to) {
933
- continue;
934
- }
935
- adjacency.indegree[edge.to] -= 1;
936
- if (adjacency.indegree[edge.to] === 0) {
937
- queue.push(edge.to);
938
- }
939
- }
940
- }
941
-
942
- for (var k = 0; k < graph.nodeOrder.length; k += 1) {
943
- var fallbackId = graph.nodeOrder[k];
944
- if (!seen[fallbackId]) {
945
- order.push(fallbackId);
946
- }
947
- }
948
-
949
- return order;
950
- }
951
-
952
- function assignRanks(graph, adjacency, order) {
953
- var ranks = Object.create(null);
954
-
955
- for (var i = 0; i < graph.nodeOrder.length; i += 1) {
956
- ranks[graph.nodeOrder[i]] = 0;
957
- }
958
-
959
- for (var j = 0; j < order.length; j += 1) {
960
- var id = order[j];
961
- var edges = adjacency.outgoing[id];
962
- for (var k = 0; k < edges.length; k += 1) {
963
- var edge = edges[k];
964
- if (edge.from === edge.to) {
965
- continue;
966
- }
967
- ranks[edge.to] = Math.max(ranks[edge.to], ranks[edge.from] + 1);
968
- }
969
- }
970
-
971
- var layers = [];
972
- for (var m = 0; m < graph.nodeOrder.length; m += 1) {
973
- var node = graph.nodesById[graph.nodeOrder[m]];
974
- node.rank = ranks[node.id] || 0;
975
- if (!layers[node.rank]) {
976
- layers[node.rank] = [];
977
- }
978
- layers[node.rank].push(node.id);
979
- }
980
-
981
- return layers;
982
- }
983
-
984
- function barycenterSort(layers, graph, adjacency) {
985
- function positions(layer) {
986
- var map = Object.create(null);
987
- for (var i = 0; i < layer.length; i += 1) {
988
- map[layer[i]] = i;
989
- }
990
- return map;
991
- }
992
-
993
- for (var pass = 0; pass < 2; pass += 1) {
994
- for (var rank = 1; rank < layers.length; rank += 1) {
995
- if (!layers[rank] || layers[rank].length < 2) {
996
- continue;
997
- }
998
-
999
- var previous = layers[rank - 1] || [];
1000
- var prevPos = positions(previous);
1001
- layers[rank].sort(function(a, b) {
1002
- var aIncoming = adjacency.incoming[a];
1003
- var bIncoming = adjacency.incoming[b];
1004
- var aSum = 0;
1005
- var bSum = 0;
1006
- var aCount = 0;
1007
- var bCount = 0;
1008
-
1009
- for (var i = 0; i < aIncoming.length; i += 1) {
1010
- if (prevPos[aIncoming[i].from] !== undefined) {
1011
- aSum += prevPos[aIncoming[i].from];
1012
- aCount += 1;
1013
- }
1014
- }
1015
- for (var j = 0; j < bIncoming.length; j += 1) {
1016
- if (prevPos[bIncoming[j].from] !== undefined) {
1017
- bSum += prevPos[bIncoming[j].from];
1018
- bCount += 1;
1019
- }
1020
- }
1021
-
1022
- var aValue = aCount ? aSum / aCount : graph.nodesById[a].order;
1023
- var bValue = bCount ? bSum / bCount : graph.nodesById[b].order;
1024
- if (aValue === bValue) {
1025
- return graph.nodesById[a].order - graph.nodesById[b].order;
1026
- }
1027
- return aValue - bValue;
1028
- });
1029
- }
1030
-
1031
- for (var reverseRank = layers.length - 2; reverseRank >= 0; reverseRank -= 1) {
1032
- if (!layers[reverseRank] || layers[reverseRank].length < 2) {
1033
- continue;
1034
- }
1035
-
1036
- var next = layers[reverseRank + 1] || [];
1037
- var nextPos = positions(next);
1038
- layers[reverseRank].sort(function(a, b) {
1039
- var aOutgoing = adjacency.outgoing[a];
1040
- var bOutgoing = adjacency.outgoing[b];
1041
- var aSum = 0;
1042
- var bSum = 0;
1043
- var aCount = 0;
1044
- var bCount = 0;
1045
-
1046
- for (var i = 0; i < aOutgoing.length; i += 1) {
1047
- if (nextPos[aOutgoing[i].to] !== undefined) {
1048
- aSum += nextPos[aOutgoing[i].to];
1049
- aCount += 1;
1050
- }
1051
- }
1052
- for (var j = 0; j < bOutgoing.length; j += 1) {
1053
- if (nextPos[bOutgoing[j].to] !== undefined) {
1054
- bSum += nextPos[bOutgoing[j].to];
1055
- bCount += 1;
1056
- }
1057
- }
1058
-
1059
- var aValue = aCount ? aSum / aCount : graph.nodesById[a].order;
1060
- var bValue = bCount ? bSum / bCount : graph.nodesById[b].order;
1061
- if (aValue === bValue) {
1062
- return graph.nodesById[a].order - graph.nodesById[b].order;
1063
- }
1064
- return aValue - bValue;
1065
- });
1066
- }
1067
- }
1068
- }
1069
-
1070
- function directionOrder(length, direction) {
1071
- var items = [];
1072
- if (direction === 'BT' || direction === 'RL') {
1073
- for (var i = length - 1; i >= 0; i -= 1) {
1074
- items.push(i);
1075
- }
1076
- return items;
1077
- }
1078
- for (var j = 0; j < length; j += 1) {
1079
- items.push(j);
1080
- }
1081
- return items;
1082
- }
1083
-
1084
- function layoutGraph(graph) {
1085
- for (var i = 0; i < graph.nodeOrder.length; i += 1) {
1086
- sizeNode(graph.nodesById[graph.nodeOrder[i]]);
1087
- }
1088
-
1089
- var adjacency = buildAdjacency(graph);
1090
- var order = topologicalOrder(graph, adjacency);
1091
- var layers = assignRanks(graph, buildAdjacency(graph), order);
1092
- barycenterSort(layers, graph, buildAdjacency(graph));
1093
-
1094
- var direction = graph.direction;
1095
- var mainAxis = direction === 'LR' || direction === 'RL' ? 'x' : 'y';
1096
- var crossAxis = mainAxis === 'x' ? 'y' : 'x';
1097
- var rankOrder = directionOrder(layers.length, direction);
1098
- var layerSpans = [];
1099
- var layerCross = [];
1100
- var totalMain = OUTER_PADDING;
1101
- var maxCross = 0;
1102
-
1103
- for (var layerIndex = 0; layerIndex < rankOrder.length; layerIndex += 1) {
1104
- var rank = rankOrder[layerIndex];
1105
- var layer = layers[rank] || [];
1106
- var mainSize = 0;
1107
- var crossSize = 0;
1108
-
1109
- for (var nodeIndex = 0; nodeIndex < layer.length; nodeIndex += 1) {
1110
- var node = graph.nodesById[layer[nodeIndex]];
1111
- mainSize = Math.max(mainSize, mainAxis === 'x' ? node.width : node.height);
1112
- crossSize += (crossAxis === 'x' ? node.width : node.height);
1113
- }
1114
-
1115
- if (layer.length > 1) {
1116
- crossSize += (layer.length - 1) * (crossAxis === 'x' ? HORIZONTAL_GAP : VERTICAL_GAP);
1117
- }
1118
-
1119
- layerSpans[rank] = mainSize;
1120
- layerCross[rank] = crossSize;
1121
- totalMain += mainSize;
1122
- if (layerIndex < rankOrder.length - 1) {
1123
- totalMain += mainAxis === 'x' ? HORIZONTAL_GAP : VERTICAL_GAP;
1124
- }
1125
- maxCross = Math.max(maxCross, crossSize);
1126
- }
1127
-
1128
- totalMain += OUTER_PADDING;
1129
- maxCross += OUTER_PADDING * 2;
1130
-
1131
- var currentMain = OUTER_PADDING;
1132
- for (var ranked = 0; ranked < rankOrder.length; ranked += 1) {
1133
- var currentRank = rankOrder[ranked];
1134
- var currentLayer = layers[currentRank] || [];
1135
- var layerMainSize = layerSpans[currentRank] || 0;
1136
- var crossStart = OUTER_PADDING + (maxCross - OUTER_PADDING * 2 - (layerCross[currentRank] || 0)) / 2;
1137
-
1138
- for (var entry = 0; entry < currentLayer.length; entry += 1) {
1139
- var currentNode = graph.nodesById[currentLayer[entry]];
1140
- var nodeMainSize = mainAxis === 'x' ? currentNode.width : currentNode.height;
1141
- var nodeCrossSize = crossAxis === 'x' ? currentNode.width : currentNode.height;
1142
- var centerMain = currentMain + layerMainSize / 2;
1143
- var centerCross = crossStart + nodeCrossSize / 2;
1144
-
1145
- if (mainAxis === 'x') {
1146
- currentNode.x = centerMain;
1147
- currentNode.y = centerCross;
1148
- } else {
1149
- currentNode.x = centerCross;
1150
- currentNode.y = centerMain;
1151
- }
1152
-
1153
- crossStart += nodeCrossSize + (crossAxis === 'x' ? HORIZONTAL_GAP : VERTICAL_GAP);
1154
- }
1155
-
1156
- currentMain += layerMainSize + (mainAxis === 'x' ? HORIZONTAL_GAP : VERTICAL_GAP);
1157
- }
1158
-
1159
- graph.bounds = {
1160
- width: mainAxis === 'x' ? totalMain : maxCross,
1161
- height: mainAxis === 'x' ? maxCross : totalMain,
1162
- };
1163
- }
1164
-
1165
- function nodeBounds(node) {
1166
- return {
1167
- left: node.x - node.width / 2,
1168
- right: node.x + node.width / 2,
1169
- top: node.y - node.height / 2,
1170
- bottom: node.y + node.height / 2,
1171
- };
1172
- }
1173
-
1174
- function computeGroupBounds(graph) {
1175
- for (var i = 0; i < graph.subgraphs.length; i += 1) {
1176
- var group = graph.subgraphs[i];
1177
- if (!group.members.length) {
1178
- group.bounds = null;
1179
- continue;
1180
- }
1181
-
1182
- var minX = Infinity;
1183
- var minY = Infinity;
1184
- var maxX = -Infinity;
1185
- var maxY = -Infinity;
1186
-
1187
- for (var j = 0; j < group.members.length; j += 1) {
1188
- var node = graph.nodesById[group.members[j]];
1189
- if (!node) {
1190
- continue;
1191
- }
1192
- var bounds = nodeBounds(node);
1193
- minX = Math.min(minX, bounds.left);
1194
- minY = Math.min(minY, bounds.top);
1195
- maxX = Math.max(maxX, bounds.right);
1196
- maxY = Math.max(maxY, bounds.bottom);
1197
- }
1198
-
1199
- group.bounds = {
1200
- x: minX - GROUP_PADDING,
1201
- y: minY - GROUP_PADDING - 12,
1202
- width: Math.max(80, maxX - minX + GROUP_PADDING * 2),
1203
- height: Math.max(50, maxY - minY + GROUP_PADDING * 2 + 12),
1204
- };
1205
- }
1206
- }
1207
-
1208
- function attachText(parent, x, y, lines, className) {
1209
- var text = createSvg('text');
1210
- setAttrs(text, {
1211
- x: x,
1212
- y: y,
1213
- fill: 'var(--dt-text-primary)',
1214
- 'font-size': FONT_SIZE,
1215
- 'font-family': 'var(--dt-font-sans, ui-sans-serif, system-ui, sans-serif)',
1216
- 'text-anchor': 'middle',
1217
- 'dominant-baseline': 'middle',
1218
- class: className || '',
1219
- });
1220
-
1221
- var offset = -((lines.length - 1) * LINE_HEIGHT) / 2;
1222
- for (var i = 0; i < lines.length; i += 1) {
1223
- var tspan = createSvg('tspan');
1224
- setAttrs(tspan, {
1225
- x: x,
1226
- y: y + offset + i * LINE_HEIGHT,
1227
- });
1228
- tspan.textContent = lines[i];
1229
- text.appendChild(tspan);
1230
- }
1231
-
1232
- parent.appendChild(text);
1233
- return text;
1234
- }
1235
-
1236
- function drawNode(parent, node) {
1237
- var group = createSvg('g');
1238
- setAttrs(group, { class: 'mini-mermaid-node' });
1239
- var fill = 'var(--dt-bg-secondary)';
1240
- var stroke = 'var(--dt-border-default)';
1241
- var bounds = nodeBounds(node);
1242
-
1243
- if (node.stateKind === 'start') {
1244
- var startCircle = createSvg('circle');
1245
- setAttrs(startCircle, {
1246
- cx: node.x,
1247
- cy: node.y,
1248
- r: node.width / 2,
1249
- fill: 'var(--dt-text-primary)',
1250
- stroke: 'var(--dt-text-primary)',
1251
- 'stroke-width': 1,
1252
- });
1253
- group.appendChild(startCircle);
1254
- parent.appendChild(group);
1255
- return;
1256
- }
1257
-
1258
- if (node.stateKind === 'end') {
1259
- var endOuter = createSvg('circle');
1260
- setAttrs(endOuter, {
1261
- cx: node.x,
1262
- cy: node.y,
1263
- r: node.width / 2,
1264
- fill: 'var(--dt-bg-canvas)',
1265
- stroke: 'var(--dt-text-primary)',
1266
- 'stroke-width': 1.5,
1267
- });
1268
- group.appendChild(endOuter);
1269
-
1270
- var endInner = createSvg('circle');
1271
- setAttrs(endInner, {
1272
- cx: node.x,
1273
- cy: node.y,
1274
- r: Math.max(4, node.width / 2 - 5),
1275
- fill: 'var(--dt-text-primary)',
1276
- stroke: 'none',
1277
- });
1278
- group.appendChild(endInner);
1279
- parent.appendChild(group);
1280
- return;
1281
- }
1282
-
1283
- if (node.shape === 'diamond') {
1284
- var diamond = createSvg('polygon');
1285
- var diamondPoints = [
1286
- node.x + ',' + bounds.top,
1287
- bounds.right + ',' + node.y,
1288
- node.x + ',' + bounds.bottom,
1289
- bounds.left + ',' + node.y,
1290
- ].join(' ');
1291
- setAttrs(diamond, { points: diamondPoints, fill: fill, stroke: stroke, 'stroke-width': 1.5 });
1292
- group.appendChild(diamond);
1293
- } else if (node.shape === 'circle') {
1294
- var circle = createSvg('ellipse');
1295
- setAttrs(circle, {
1296
- cx: node.x,
1297
- cy: node.y,
1298
- rx: node.width / 2,
1299
- ry: node.height / 2,
1300
- fill: fill,
1301
- stroke: stroke,
1302
- 'stroke-width': 1.5,
1303
- });
1304
- group.appendChild(circle);
1305
- } else if (node.shape === 'hexagon') {
1306
- var inset = Math.max(14, node.width * 0.16);
1307
- var hexagon = createSvg('polygon');
1308
- var hexPoints = [
1309
- (bounds.left + inset) + ',' + bounds.top,
1310
- (bounds.right - inset) + ',' + bounds.top,
1311
- bounds.right + ',' + node.y,
1312
- (bounds.right - inset) + ',' + bounds.bottom,
1313
- (bounds.left + inset) + ',' + bounds.bottom,
1314
- bounds.left + ',' + node.y,
1315
- ].join(' ');
1316
- setAttrs(hexagon, { points: hexPoints, fill: fill, stroke: stroke, 'stroke-width': 1.5 });
1317
- group.appendChild(hexagon);
1318
- } else {
1319
- var rect = createSvg('rect');
1320
- var radius = 8;
1321
- if (node.shape === 'stadium') {
1322
- radius = node.height / 2;
1323
- } else if (node.shape !== 'rounded') {
1324
- radius = 4;
1325
- }
1326
- setAttrs(rect, {
1327
- x: bounds.left,
1328
- y: bounds.top,
1329
- width: node.width,
1330
- height: node.height,
1331
- rx: radius,
1332
- ry: radius,
1333
- fill: fill,
1334
- stroke: stroke,
1335
- 'stroke-width': 1.5,
1336
- });
1337
- group.appendChild(rect);
1338
- }
1339
-
1340
- attachText(group, node.x, node.y, node.lines, 'mini-mermaid-node-label');
1341
- parent.appendChild(group);
1342
- }
1343
-
1344
- function edgeAnchors(source, target, direction) {
1345
- if (source.id === target.id) {
1346
- return {
1347
- start: { x: source.x + source.width * 0.22, y: source.y - source.height / 2 },
1348
- end: { x: source.x + source.width / 2, y: source.y - source.height * 0.18 },
1349
- };
1350
- }
1351
-
1352
- var vertical = direction === 'TD' || direction === 'BT';
1353
-
1354
- if (vertical) {
1355
- if (Math.abs(target.y - source.y) >= Math.abs(target.x - source.x)) {
1356
- return target.y >= source.y ? {
1357
- start: { x: source.x, y: source.y + source.height / 2 },
1358
- end: { x: target.x, y: target.y - target.height / 2 },
1359
- } : {
1360
- start: { x: source.x, y: source.y - source.height / 2 },
1361
- end: { x: target.x, y: target.y + target.height / 2 },
1362
- };
1363
- }
1364
-
1365
- return target.x >= source.x ? {
1366
- start: { x: source.x + source.width / 2, y: source.y },
1367
- end: { x: target.x - target.width / 2, y: target.y },
1368
- } : {
1369
- start: { x: source.x - source.width / 2, y: source.y },
1370
- end: { x: target.x + target.width / 2, y: target.y },
1371
- };
1372
- }
1373
-
1374
- if (Math.abs(target.x - source.x) >= Math.abs(target.y - source.y)) {
1375
- return target.x >= source.x ? {
1376
- start: { x: source.x + source.width / 2, y: source.y },
1377
- end: { x: target.x - target.width / 2, y: target.y },
1378
- } : {
1379
- start: { x: source.x - source.width / 2, y: source.y },
1380
- end: { x: target.x + target.width / 2, y: target.y },
1381
- };
1382
- }
1383
-
1384
- return target.y >= source.y ? {
1385
- start: { x: source.x, y: source.y + source.height / 2 },
1386
- end: { x: target.x, y: target.y - target.height / 2 },
1387
- } : {
1388
- start: { x: source.x, y: source.y - source.height / 2 },
1389
- end: { x: target.x, y: target.y + target.height / 2 },
1390
- };
1391
- }
1392
-
1393
- function buildEdgePath(edge, source, target, direction) {
1394
- var anchors = edgeAnchors(source, target, direction);
1395
- var start = anchors.start;
1396
- var end = anchors.end;
1397
-
1398
- if (edge.from === edge.to) {
1399
- return [
1400
- 'M', start.x, start.y,
1401
- 'C', start.x + 34, start.y - 36, end.x + 22, end.y - 34, end.x, end.y,
1402
- ].join(' ');
1403
- }
1404
-
1405
- var dx = end.x - start.x;
1406
- var dy = end.y - start.y;
1407
- var vertical = direction === 'TD' || direction === 'BT';
1408
- var radius = 16;
1409
-
1410
- if (vertical) {
1411
- var midY = start.y + dy / 2;
1412
- if (Math.abs(dx) < 8) {
1413
- return ['M', start.x, start.y, 'L', end.x, end.y].join(' ');
1414
- }
1415
- return [
1416
- 'M', start.x, start.y,
1417
- 'L', start.x, midY - radius,
1418
- 'Q', start.x, midY, start.x + (dx > 0 ? radius : -radius), midY,
1419
- 'L', end.x - (dx > 0 ? radius : -radius), midY,
1420
- 'Q', end.x, midY, end.x, midY + radius,
1421
- 'L', end.x, end.y,
1422
- ].join(' ');
1423
- }
1424
-
1425
- var midX = start.x + dx / 2;
1426
- if (Math.abs(dy) < 8) {
1427
- return ['M', start.x, start.y, 'L', end.x, end.y].join(' ');
1428
- }
1429
- return [
1430
- 'M', start.x, start.y,
1431
- 'L', midX - radius, start.y,
1432
- 'Q', midX, start.y, midX, start.y + (dy > 0 ? radius : -radius),
1433
- 'L', midX, end.y - (dy > 0 ? radius : -radius),
1434
- 'Q', midX, end.y, midX + radius, end.y,
1435
- 'L', end.x, end.y,
1436
- ].join(' ');
1437
- }
1438
-
1439
- function edgeMidpoint(edge, source, target) {
1440
- if (edge.from === edge.to) {
1441
- return {
1442
- x: source.x + source.width * 0.4,
1443
- y: source.y - source.height * 0.9,
1444
- };
1445
- }
1446
- return {
1447
- x: (source.x + target.x) / 2,
1448
- y: (source.y + target.y) / 2,
1449
- };
1450
- }
1451
-
1452
- function drawLabel(parent, x, y, textValue) {
1453
- var label = String(textValue || '').trim();
1454
- if (!label) {
1455
- return;
1456
- }
1457
-
1458
- var width = Math.max(24, measureLine(label) + 12);
1459
- var group = createSvg('g');
1460
- var rect = createSvg('rect');
1461
- setAttrs(rect, {
1462
- x: x - width / 2,
1463
- y: y - 10,
1464
- width: width,
1465
- height: 20,
1466
- rx: 6,
1467
- ry: 6,
1468
- fill: 'var(--dt-bg-canvas)',
1469
- stroke: 'var(--dt-border-default)',
1470
- 'stroke-width': 0.75,
1471
- });
1472
- group.appendChild(rect);
1473
-
1474
- var text = createSvg('text');
1475
- setAttrs(text, {
1476
- x: x,
1477
- y: y + 1,
1478
- fill: 'var(--dt-text-primary)',
1479
- 'font-size': 12,
1480
- 'font-family': 'var(--dt-font-sans, ui-sans-serif, system-ui, sans-serif)',
1481
- 'text-anchor': 'middle',
1482
- 'dominant-baseline': 'middle',
1483
- });
1484
- text.textContent = label;
1485
- group.appendChild(text);
1486
- parent.appendChild(group);
1487
- }
1488
-
1489
- function drawEdges(parent, graph) {
1490
- for (var i = 0; i < graph.edges.length; i += 1) {
1491
- var edge = graph.edges[i];
1492
- var source = graph.nodesById[edge.from];
1493
- var target = graph.nodesById[edge.to];
1494
- if (!source || !target) {
1495
- continue;
1496
- }
1497
-
1498
- var path = createSvg('path');
1499
- setAttrs(path, {
1500
- d: buildEdgePath(edge, source, target, graph.direction),
1501
- fill: 'none',
1502
- stroke: 'var(--dt-text-primary)',
1503
- 'stroke-width': edge.style === 'thick' ? 2.5 : 1.6,
1504
- 'stroke-dasharray': edge.style === 'dotted' ? '4 5' : '',
1505
- 'stroke-linecap': 'round',
1506
- 'stroke-linejoin': 'round',
1507
- 'marker-end': edge.arrow ? 'url(#mini-mermaid-arrow)' : '',
1508
- });
1509
- parent.appendChild(path);
1510
-
1511
- if (edge.label) {
1512
- var midpoint = edgeMidpoint(edge, source, target);
1513
- drawLabel(parent, midpoint.x, midpoint.y, edge.label);
1514
- }
1515
- }
1516
- }
1517
-
1518
- function drawSubgraphs(parent, graph) {
1519
- for (var i = 0; i < graph.subgraphs.length; i += 1) {
1520
- var group = graph.subgraphs[i];
1521
- if (!group.bounds) {
1522
- continue;
1523
- }
1524
-
1525
- var rect = createSvg('rect');
1526
- setAttrs(rect, {
1527
- x: group.bounds.x,
1528
- y: group.bounds.y,
1529
- width: group.bounds.width,
1530
- height: group.bounds.height,
1531
- rx: 12,
1532
- ry: 12,
1533
- fill: 'rgba(127, 127, 127, 0.06)',
1534
- stroke: 'var(--dt-border-default)',
1535
- 'stroke-width': 1,
1536
- 'stroke-dasharray': '6 5',
1537
- });
1538
- parent.appendChild(rect);
1539
-
1540
- var label = createSvg('text');
1541
- setAttrs(label, {
1542
- x: group.bounds.x + 14,
1543
- y: group.bounds.y + 18,
1544
- fill: 'var(--dt-text-primary)',
1545
- 'font-size': 12,
1546
- 'font-family': 'var(--dt-font-sans, ui-sans-serif, system-ui, sans-serif)',
1547
- 'font-weight': '600',
1548
- });
1549
- label.textContent = group.title;
1550
- parent.appendChild(label);
1551
- }
1552
- }
1553
-
1554
- function ensureMarkers(defs) {
1555
- var marker = createSvg('marker');
1556
- setAttrs(marker, {
1557
- id: 'mini-mermaid-arrow',
1558
- viewBox: '0 0 10 10',
1559
- refX: 9,
1560
- refY: 5,
1561
- markerWidth: 8,
1562
- markerHeight: 8,
1563
- orient: 'auto-start-reverse',
1564
- markerUnits: 'strokeWidth',
1565
- });
1566
- var polygon = createSvg('polygon');
1567
- setAttrs(polygon, {
1568
- points: '0,0 10,5 0,10 2.5,5',
1569
- fill: 'var(--dt-text-primary)',
1570
- });
1571
- marker.appendChild(polygon);
1572
- defs.appendChild(marker);
1573
-
1574
- var openArrow = createSvg('marker');
1575
- setAttrs(openArrow, {
1576
- id: 'mini-mermaid-open-arrow',
1577
- viewBox: '0 0 10 10',
1578
- refX: 9,
1579
- refY: 5,
1580
- markerWidth: 8,
1581
- markerHeight: 8,
1582
- orient: 'auto-start-reverse',
1583
- markerUnits: 'strokeWidth',
1584
- });
1585
- var openPath = createSvg('path');
1586
- setAttrs(openPath, {
1587
- d: 'M 1 1 L 9 5 L 1 9',
1588
- fill: 'none',
1589
- stroke: 'var(--dt-text-primary)',
1590
- 'stroke-width': 1.4,
1591
- 'stroke-linecap': 'round',
1592
- 'stroke-linejoin': 'round',
1593
- });
1594
- openArrow.appendChild(openPath);
1595
- defs.appendChild(openArrow);
1596
-
1597
- var triangleArrow = createSvg('marker');
1598
- setAttrs(triangleArrow, {
1599
- id: 'mini-mermaid-triangle-arrow',
1600
- viewBox: '0 0 10 10',
1601
- refX: 9,
1602
- refY: 5,
1603
- markerWidth: 9,
1604
- markerHeight: 9,
1605
- orient: 'auto-start-reverse',
1606
- markerUnits: 'strokeWidth',
1607
- });
1608
- var triangle = createSvg('polygon');
1609
- setAttrs(triangle, {
1610
- points: '0,0 10,5 0,10',
1611
- fill: 'var(--dt-bg-canvas)',
1612
- stroke: 'var(--dt-text-primary)',
1613
- 'stroke-width': 1.1,
1614
- 'stroke-linejoin': 'round',
1615
- });
1616
- triangleArrow.appendChild(triangle);
1617
- defs.appendChild(triangleArrow);
1618
-
1619
- var filledDiamond = createSvg('marker');
1620
- setAttrs(filledDiamond, {
1621
- id: 'mini-mermaid-diamond-arrow',
1622
- viewBox: '0 0 12 10',
1623
- refX: 10,
1624
- refY: 5,
1625
- markerWidth: 11,
1626
- markerHeight: 9,
1627
- orient: 'auto-start-reverse',
1628
- markerUnits: 'strokeWidth',
1629
- });
1630
- var filledDiamondShape = createSvg('polygon');
1631
- setAttrs(filledDiamondShape, {
1632
- points: '0,5 5,0 10,5 5,10',
1633
- fill: 'var(--dt-text-primary)',
1634
- stroke: 'var(--dt-text-primary)',
1635
- 'stroke-width': 1,
1636
- 'stroke-linejoin': 'round',
1637
- });
1638
- filledDiamond.appendChild(filledDiamondShape);
1639
- defs.appendChild(filledDiamond);
1640
-
1641
- var openDiamond = createSvg('marker');
1642
- setAttrs(openDiamond, {
1643
- id: 'mini-mermaid-open-diamond-arrow',
1644
- viewBox: '0 0 12 10',
1645
- refX: 10,
1646
- refY: 5,
1647
- markerWidth: 11,
1648
- markerHeight: 9,
1649
- orient: 'auto-start-reverse',
1650
- markerUnits: 'strokeWidth',
1651
- });
1652
- var openDiamondShape = createSvg('polygon');
1653
- setAttrs(openDiamondShape, {
1654
- points: '0,5 5,0 10,5 5,10',
1655
- fill: 'var(--dt-bg-canvas)',
1656
- stroke: 'var(--dt-text-primary)',
1657
- 'stroke-width': 1,
1658
- 'stroke-linejoin': 'round',
1659
- });
1660
- openDiamond.appendChild(openDiamondShape);
1661
- defs.appendChild(openDiamond);
1662
- }
1663
-
1664
- function createRootSvg(width, height, label) {
1665
- var svg = createSvg('svg');
1666
- setAttrs(svg, {
1667
- width: '100%',
1668
- viewBox: '0 0 ' + Math.max(120, Math.ceil(width)) + ' ' + Math.max(80, Math.ceil(height)),
1669
- role: 'img',
1670
- 'aria-label': label,
1671
- style: 'display:block;overflow:visible;background:var(--dt-bg-canvas)',
1672
- preserveAspectRatio: 'xMidYMid meet',
1673
- });
1674
-
1675
- var defs = createSvg('defs');
1676
- ensureMarkers(defs);
1677
- svg.appendChild(defs);
1678
- return svg;
1679
- }
1680
-
1681
- function renderSvg(graph) {
1682
- layoutGraph(graph);
1683
- computeGroupBounds(graph);
1684
-
1685
- var svg = createRootSvg(graph.bounds.width, graph.bounds.height, 'Mermaid flowchart diagram');
1686
-
1687
- if (!graph.nodeOrder.length) {
1688
- var empty = createSvg('text');
1689
- setAttrs(empty, {
1690
- x: 24,
1691
- y: 32,
1692
- fill: 'var(--dt-text-secondary, var(--dt-text-primary))',
1693
- 'font-size': FONT_SIZE,
1694
- 'font-family': 'var(--dt-font-sans, ui-sans-serif, system-ui, sans-serif)',
1695
- });
1696
- empty.textContent = 'Empty diagram';
1697
- svg.appendChild(empty);
1698
- return svg;
1699
- }
1700
-
1701
- var groupLayer = createSvg('g');
1702
- drawSubgraphs(groupLayer, graph);
1703
- svg.appendChild(groupLayer);
1704
-
1705
- var edgeLayer = createSvg('g');
1706
- setAttrs(edgeLayer, { class: 'mini-mermaid-edges' });
1707
- drawEdges(edgeLayer, graph);
1708
- svg.appendChild(edgeLayer);
1709
-
1710
- var nodeLayer = createSvg('g');
1711
- setAttrs(nodeLayer, { class: 'mini-mermaid-nodes' });
1712
- for (var i = 0; i < graph.nodeOrder.length; i += 1) {
1713
- drawNode(nodeLayer, graph.nodesById[graph.nodeOrder[i]]);
1714
- }
1715
- svg.appendChild(nodeLayer);
1716
- return svg;
1717
- }
1718
-
1719
- function appendText(parent, x, y, textValue, options) {
1720
- var text = createSvg('text');
1721
- setAttrs(text, {
1722
- x: x,
1723
- y: y,
1724
- fill: options && options.fill ? options.fill : 'var(--dt-text-primary)',
1725
- 'font-size': options && options.size ? options.size : FONT_SIZE,
1726
- 'font-family': 'var(--dt-font-sans, ui-sans-serif, system-ui, sans-serif)',
1727
- 'font-weight': options && options.weight ? options.weight : '400',
1728
- 'text-anchor': options && options.anchor ? options.anchor : 'start',
1729
- 'dominant-baseline': options && options.baseline ? options.baseline : 'middle',
1730
- class: options && options.className ? options.className : '',
1731
- });
1732
- text.textContent = textValue;
1733
- parent.appendChild(text);
1734
- return text;
1735
- }
1736
-
1737
- function appendLeftText(parent, x, y, lines, options) {
1738
- for (var i = 0; i < lines.length; i += 1) {
1739
- appendText(parent, x, y + i * LINE_HEIGHT, lines[i], {
1740
- anchor: 'start',
1741
- baseline: 'hanging',
1742
- weight: options && options.weight ? options.weight : '400',
1743
- size: options && options.size ? options.size : FONT_SIZE,
1744
- fill: options && options.fill ? options.fill : 'var(--dt-text-primary)',
1745
- className: options && options.className ? options.className : '',
1746
- });
1747
- }
1748
- }
1749
-
1750
- function cleanedLines(source) {
1751
- var raw = String(source || '').split(/\r?\n/);
1752
- var lines = [];
1753
-
1754
- for (var i = 0; i < raw.length; i += 1) {
1755
- var line = stripComment(raw[i]).trim();
1756
- if (line) {
1757
- lines.push(line);
1758
- }
1759
- }
1760
-
1761
- return lines;
1762
- }
1763
-
1764
- function boxAnchor(source, target) {
1765
- var dx = target.x - source.x;
1766
- var dy = target.y - source.y;
1767
-
1768
- if (Math.abs(dx) >= Math.abs(dy)) {
1769
- return dx >= 0 ? { x: source.x + source.width / 2, y: source.y } : { x: source.x - source.width / 2, y: source.y };
1770
- }
1771
-
1772
- return dy >= 0 ? { x: source.x, y: source.y + source.height / 2 } : { x: source.x, y: source.y - source.height / 2 };
1773
- }
1774
-
1775
- function drawStraightLine(parent, x1, y1, x2, y2, options) {
1776
- var line = createSvg('line');
1777
- setAttrs(line, {
1778
- x1: x1,
1779
- y1: y1,
1780
- x2: x2,
1781
- y2: y2,
1782
- fill: 'none',
1783
- stroke: options && options.stroke ? options.stroke : 'var(--dt-text-primary)',
1784
- 'stroke-width': options && options.strokeWidth ? options.strokeWidth : 1.6,
1785
- 'stroke-dasharray': options && options.dash ? options.dash : '',
1786
- 'stroke-linecap': 'round',
1787
- 'stroke-linejoin': 'round',
1788
- 'marker-start': options && options.markerStart ? options.markerStart : '',
1789
- 'marker-end': options && options.markerEnd ? options.markerEnd : '',
1790
- });
1791
- parent.appendChild(line);
1792
- return line;
1793
- }
1794
-
1795
- function ensureSequenceParticipant(participants, participantsById, id, label) {
1796
- if (!participantsById[id]) {
1797
- participantsById[id] = { id: id, label: label || id, width: 0, x: 0 };
1798
- participants.push(participantsById[id]);
1799
- }
1800
- if (label && (!participantsById[id].label || participantsById[id].label === id || label !== id)) {
1801
- participantsById[id].label = label;
1802
- }
1803
- return participantsById[id];
1804
- }
1805
-
1806
- function renderSequenceDiagram(source) {
1807
- var lines = cleanedLines(source);
1808
- var participants = [];
1809
- var participantsById = Object.create(null);
1810
- var entries = [];
1811
-
1812
- for (var i = 0; i < lines.length; i += 1) {
1813
- var line = lines[i];
1814
- if (i === 0 && /^sequenceDiagram\b/i.test(line)) {
1815
- continue;
1816
- }
1817
-
1818
- var participantMatch = line.match(/^participant\s+([A-Za-z0-9_.-]+)(?:\s+as\s+(.+))?$/i);
1819
- if (participantMatch) {
1820
- ensureSequenceParticipant(participants, participantsById, participantMatch[1], normalizeLabel(participantMatch[2] || participantMatch[1]));
1821
- continue;
1822
- }
1823
-
1824
- var noteMatch = line.match(/^Note\s+over\s+([^:]+):\s*(.+)$/i);
1825
- if (noteMatch) {
1826
- var refs = noteMatch[1].split(',');
1827
- var noteRefs = [];
1828
- for (var refIndex = 0; refIndex < refs.length; refIndex += 1) {
1829
- var refId = refs[refIndex].trim();
1830
- if (!refId) {
1831
- continue;
1832
- }
1833
- ensureSequenceParticipant(participants, participantsById, refId, refId);
1834
- noteRefs.push(refId);
1835
- }
1836
- if (noteRefs.length) {
1837
- entries.push({ type: 'note', refs: noteRefs, text: normalizeLabel(noteMatch[2]) });
1838
- }
1839
- continue;
1840
- }
1841
-
1842
- var messageMatch = line.match(/^([A-Za-z0-9_.-]+)\s*(-->>|->>|-->|->)\s*([A-Za-z0-9_.-]+)(?:\s*:\s*(.+))?$/);
1843
- if (messageMatch) {
1844
- ensureSequenceParticipant(participants, participantsById, messageMatch[1], messageMatch[1]);
1845
- ensureSequenceParticipant(participants, participantsById, messageMatch[3], messageMatch[3]);
1846
- entries.push({
1847
- type: 'message',
1848
- from: messageMatch[1],
1849
- to: messageMatch[3],
1850
- arrow: messageMatch[2],
1851
- text: normalizeLabel(messageMatch[4] || ''),
1852
- });
1853
- }
1854
- }
1855
-
1856
- if (!participants.length) {
1857
- throw new Error('Sequence diagram is missing participants');
1858
- }
1859
-
1860
- var totalParticipantWidth = 0;
1861
- for (var participantIndex = 0; participantIndex < participants.length; participantIndex += 1) {
1862
- var participant = participants[participantIndex];
1863
- participant.width = Math.max(96, Math.ceil(measureLine(participant.label) + 28));
1864
- totalParticipantWidth += participant.width;
1865
- }
1866
-
1867
- var gap = Math.max(HORIZONTAL_GAP, 48);
1868
- var width = OUTER_PADDING * 2 + totalParticipantWidth + gap * Math.max(0, participants.length - 1);
1869
- var boxHeight = 34;
1870
- var topY = OUTER_PADDING + 18;
1871
- var cursorX = OUTER_PADDING;
1872
-
1873
- for (var position = 0; position < participants.length; position += 1) {
1874
- participants[position].x = cursorX + participants[position].width / 2;
1875
- cursorX += participants[position].width + gap;
1876
- }
1877
-
1878
- var contentY = topY + boxHeight + 26;
1879
- for (var entryIndex = 0; entryIndex < entries.length; entryIndex += 1) {
1880
- var entry = entries[entryIndex];
1881
- entry.y = contentY;
1882
- if (entry.type === 'note') {
1883
- entry.lines = splitLabelLines(entry.text);
1884
- entry.height = Math.max(42, entry.lines.length * LINE_HEIGHT + 18);
1885
- contentY += entry.height + 14;
1886
- } else {
1887
- contentY += 42;
1888
- }
1889
- }
1890
-
1891
- var height = contentY + OUTER_PADDING;
1892
- var svg = createRootSvg(width, height, 'Mermaid sequence diagram');
1893
-
1894
- for (var drawParticipantIndex = 0; drawParticipantIndex < participants.length; drawParticipantIndex += 1) {
1895
- var drawParticipant = participants[drawParticipantIndex];
1896
- var left = drawParticipant.x - drawParticipant.width / 2;
1897
-
1898
- var participantRect = createSvg('rect');
1899
- setAttrs(participantRect, {
1900
- x: left,
1901
- y: topY,
1902
- width: drawParticipant.width,
1903
- height: boxHeight,
1904
- rx: 8,
1905
- ry: 8,
1906
- fill: 'var(--dt-bg-secondary)',
1907
- stroke: 'var(--dt-border-default)',
1908
- 'stroke-width': 1.5,
1909
- });
1910
- svg.appendChild(participantRect);
1911
- attachText(svg, drawParticipant.x, topY + boxHeight / 2 + 1, [drawParticipant.label], '');
1912
-
1913
- var lifeline = createSvg('line');
1914
- setAttrs(lifeline, {
1915
- x1: drawParticipant.x,
1916
- y1: topY + boxHeight,
1917
- x2: drawParticipant.x,
1918
- y2: height - OUTER_PADDING / 2,
1919
- stroke: 'var(--dt-text-secondary, var(--dt-text-primary))',
1920
- 'stroke-width': 1.2,
1921
- 'stroke-dasharray': '6 6',
1922
- });
1923
- svg.appendChild(lifeline);
1924
- }
1925
-
1926
- for (var drawEntryIndex = 0; drawEntryIndex < entries.length; drawEntryIndex += 1) {
1927
- var drawEntry = entries[drawEntryIndex];
1928
-
1929
- if (drawEntry.type === 'note') {
1930
- var leftParticipant = participantsById[drawEntry.refs[0]];
1931
- var rightParticipant = participantsById[drawEntry.refs[drawEntry.refs.length - 1]];
1932
- var noteWidth = Math.max(measureLine(drawEntry.text) + 26, Math.abs(rightParticipant.x - leftParticipant.x) + 40);
1933
- var noteX = (leftParticipant.x + rightParticipant.x) / 2;
1934
- var noteRect = createSvg('rect');
1935
- setAttrs(noteRect, {
1936
- x: noteX - noteWidth / 2,
1937
- y: drawEntry.y - 12,
1938
- width: noteWidth,
1939
- height: drawEntry.height,
1940
- rx: 10,
1941
- ry: 10,
1942
- fill: 'var(--dt-bg-secondary)',
1943
- stroke: 'var(--dt-border-default)',
1944
- 'stroke-width': 1.2,
1945
- });
1946
- svg.appendChild(noteRect);
1947
- attachText(svg, noteX, drawEntry.y - 12 + drawEntry.height / 2, drawEntry.lines, '');
1948
- continue;
1949
- }
1950
-
1951
- var fromParticipant = participantsById[drawEntry.from];
1952
- var toParticipant = participantsById[drawEntry.to];
1953
- var messageY = drawEntry.y;
1954
- var dashed = drawEntry.arrow === '-->>' || drawEntry.arrow === '-->';
1955
- var closedArrow = drawEntry.arrow === '->>' || drawEntry.arrow === '-->>';
1956
-
1957
- if (fromParticipant.id === toParticipant.id) {
1958
- var loopPath = createSvg('path');
1959
- var loopX = fromParticipant.x + 34;
1960
- setAttrs(loopPath, {
1961
- d: ['M', fromParticipant.x, messageY, 'L', loopX, messageY, 'L', loopX, messageY + 20, 'L', fromParticipant.x + 8, messageY + 20].join(' '),
1962
- fill: 'none',
1963
- stroke: 'var(--dt-text-primary)',
1964
- 'stroke-width': 1.6,
1965
- 'stroke-dasharray': dashed ? '6 5' : '',
1966
- 'marker-end': closedArrow ? 'url(#mini-mermaid-arrow)' : 'url(#mini-mermaid-open-arrow)',
1967
- 'stroke-linecap': 'round',
1968
- 'stroke-linejoin': 'round',
1969
- });
1970
- svg.appendChild(loopPath);
1971
- if (drawEntry.text) {
1972
- appendText(svg, loopX + 6, messageY + 10, drawEntry.text, { anchor: 'start', baseline: 'middle', size: 12 });
1973
- }
1974
- continue;
1975
- }
1976
-
1977
- drawStraightLine(svg, fromParticipant.x, messageY, toParticipant.x, messageY, {
1978
- dash: dashed ? '6 5' : '',
1979
- markerEnd: closedArrow ? 'url(#mini-mermaid-arrow)' : 'url(#mini-mermaid-open-arrow)',
1980
- });
1981
-
1982
- if (drawEntry.text) {
1983
- appendText(svg, (fromParticipant.x + toParticipant.x) / 2, messageY - 11, drawEntry.text, { anchor: 'middle', baseline: 'middle', size: 12 });
1984
- }
1985
- }
1986
-
1987
- return svg;
1988
- }
1989
-
1990
- function parseClassDiagram(source) {
1991
- var lines = cleanedLines(source);
1992
- var classes = [];
1993
- var classesById = Object.create(null);
1994
- var relations = [];
1995
- var currentClass = null;
1996
-
1997
- function ensureClass(id) {
1998
- if (!classesById[id]) {
1999
- classesById[id] = { id: id, name: id, attributes: [], methods: [], width: 0, height: 0, x: 0, y: 0 };
2000
- classes.push(classesById[id]);
2001
- }
2002
- return classesById[id];
2003
- }
2004
-
2005
- for (var i = 0; i < lines.length; i += 1) {
2006
- var line = lines[i];
2007
- if (i === 0 && /^classDiagram\b/i.test(line)) {
2008
- continue;
2009
- }
2010
- if (currentClass) {
2011
- if (line === '}') {
2012
- currentClass = null;
2013
- continue;
2014
- }
2015
- if (/\([^)]*\)/.test(line)) {
2016
- currentClass.methods.push(line);
2017
- } else {
2018
- currentClass.attributes.push(line);
2019
- }
2020
- continue;
2021
- }
2022
-
2023
- var classBlockMatch = line.match(/^class\s+([A-Za-z0-9_.-]+)\s*\{$/i);
2024
- if (classBlockMatch) {
2025
- currentClass = ensureClass(classBlockMatch[1]);
2026
- continue;
2027
- }
2028
-
2029
- var classMatch = line.match(/^class\s+([A-Za-z0-9_.-]+)$/i);
2030
- if (classMatch) {
2031
- ensureClass(classMatch[1]);
2032
- continue;
2033
- }
2034
-
2035
- var relationMatch = line.match(/^([A-Za-z0-9_.-]+)\s+(<\|--|\*--|o--|-->|--|\.\.>)\s+([A-Za-z0-9_.-]+)(?:\s*:\s*(.+))?$/);
2036
- if (relationMatch) {
2037
- ensureClass(relationMatch[1]);
2038
- ensureClass(relationMatch[3]);
2039
- relations.push({ left: relationMatch[1], right: relationMatch[3], type: relationMatch[2], label: normalizeLabel(relationMatch[4] || '') });
2040
- }
2041
- }
2042
-
2043
- return { classes: classes, classesById: classesById, relations: relations };
2044
- }
2045
-
2046
- function renderClassDiagram(source) {
2047
- var diagram = parseClassDiagram(source);
2048
- if (!diagram.classes.length) {
2049
- throw new Error('Class diagram is empty');
2050
- }
2051
-
2052
- var maxWidth = 0;
2053
- var maxHeight = 0;
2054
- for (var i = 0; i < diagram.classes.length; i += 1) {
2055
- var classDef = diagram.classes[i];
2056
- var classWidth = Math.max(120, measureLine(classDef.name) + 28);
2057
- var maxMemberWidth = classWidth;
2058
- var lineIndex;
2059
-
2060
- for (lineIndex = 0; lineIndex < classDef.attributes.length; lineIndex += 1) {
2061
- maxMemberWidth = Math.max(maxMemberWidth, measureLine(classDef.attributes[lineIndex]) + 24);
2062
- }
2063
- for (lineIndex = 0; lineIndex < classDef.methods.length; lineIndex += 1) {
2064
- maxMemberWidth = Math.max(maxMemberWidth, measureLine(classDef.methods[lineIndex]) + 24);
2065
- }
2066
-
2067
- var attrHeight = classDef.attributes.length ? classDef.attributes.length * LINE_HEIGHT + 12 : 0;
2068
- var methodHeight = classDef.methods.length ? classDef.methods.length * LINE_HEIGHT + 12 : 0;
2069
- classDef.width = Math.ceil(maxMemberWidth);
2070
- classDef.height = 34 + attrHeight + methodHeight + (classDef.attributes.length && classDef.methods.length ? 6 : 0) + 12;
2071
- maxWidth = Math.max(maxWidth, classDef.width);
2072
- maxHeight = Math.max(maxHeight, classDef.height);
2073
- }
2074
-
2075
- var columns = Math.min(4, Math.max(1, Math.ceil(Math.sqrt(diagram.classes.length))));
2076
- var rows = Math.ceil(diagram.classes.length / columns);
2077
- var width = OUTER_PADDING * 2 + columns * maxWidth + Math.max(0, columns - 1) * HORIZONTAL_GAP;
2078
- var height = OUTER_PADDING * 2 + rows * maxHeight + Math.max(0, rows - 1) * VERTICAL_GAP;
2079
- var svg = createRootSvg(width, height, 'Mermaid class diagram');
2080
-
2081
- for (var classIndex = 0; classIndex < diagram.classes.length; classIndex += 1) {
2082
- var current = diagram.classes[classIndex];
2083
- var column = classIndex % columns;
2084
- var row = Math.floor(classIndex / columns);
2085
- current.x = OUTER_PADDING + column * (maxWidth + HORIZONTAL_GAP) + maxWidth / 2;
2086
- current.y = OUTER_PADDING + row * (maxHeight + VERTICAL_GAP) + maxHeight / 2;
2087
- }
2088
-
2089
- for (var relationIndex = 0; relationIndex < diagram.relations.length; relationIndex += 1) {
2090
- var relation = diagram.relations[relationIndex];
2091
- var fromClass = diagram.classesById[relation.left];
2092
- var toClass = diagram.classesById[relation.right];
2093
- var relationFrom = fromClass;
2094
- var relationTo = toClass;
2095
- var markerEnd = '';
2096
- var dash = '';
2097
-
2098
- if (relation.type === '<|--' || relation.type === '*--' || relation.type === 'o--') {
2099
- relationFrom = toClass;
2100
- relationTo = fromClass;
2101
- }
2102
-
2103
- if (relation.type === '<|--') {
2104
- markerEnd = 'url(#mini-mermaid-triangle-arrow)';
2105
- } else if (relation.type === '*--') {
2106
- markerEnd = 'url(#mini-mermaid-diamond-arrow)';
2107
- } else if (relation.type === 'o--') {
2108
- markerEnd = 'url(#mini-mermaid-open-diamond-arrow)';
2109
- } else if (relation.type === '-->') {
2110
- markerEnd = 'url(#mini-mermaid-open-arrow)';
2111
- } else if (relation.type === '..>') {
2112
- markerEnd = 'url(#mini-mermaid-open-arrow)';
2113
- dash = '6 5';
2114
- }
2115
-
2116
- var relationStart = boxAnchor(relationFrom, relationTo);
2117
- var relationEnd = boxAnchor(relationTo, relationFrom);
2118
- drawStraightLine(svg, relationStart.x, relationStart.y, relationEnd.x, relationEnd.y, { dash: dash, markerEnd: markerEnd });
2119
- if (relation.label) {
2120
- drawLabel(svg, (relationStart.x + relationEnd.x) / 2, (relationStart.y + relationEnd.y) / 2 - 10, relation.label);
2121
- }
2122
- }
2123
-
2124
- for (var drawClassIndex = 0; drawClassIndex < diagram.classes.length; drawClassIndex += 1) {
2125
- var drawClass = diagram.classes[drawClassIndex];
2126
- var bounds = { left: drawClass.x - drawClass.width / 2, top: drawClass.y - drawClass.height / 2 };
2127
-
2128
- var outer = createSvg('rect');
2129
- setAttrs(outer, {
2130
- x: bounds.left,
2131
- y: bounds.top,
2132
- width: drawClass.width,
2133
- height: drawClass.height,
2134
- rx: 8,
2135
- ry: 8,
2136
- fill: 'var(--dt-bg-secondary)',
2137
- stroke: 'var(--dt-border-default)',
2138
- 'stroke-width': 1.5,
2139
- });
2140
- svg.appendChild(outer);
2141
-
2142
- var headerHeight = 34;
2143
- drawStraightLine(svg, bounds.left, bounds.top + headerHeight, bounds.left + drawClass.width, bounds.top + headerHeight, {
2144
- stroke: 'var(--dt-border-default)',
2145
- strokeWidth: 1,
2146
- });
2147
- attachText(svg, drawClass.x, bounds.top + headerHeight / 2 + 1, [drawClass.name], '');
2148
-
2149
- var contentY = bounds.top + headerHeight + 10;
2150
- if (drawClass.attributes.length) {
2151
- appendLeftText(svg, bounds.left + 10, contentY, drawClass.attributes, { size: 13 });
2152
- contentY += drawClass.attributes.length * LINE_HEIGHT + 8;
2153
- }
2154
- if (drawClass.methods.length) {
2155
- drawStraightLine(svg, bounds.left, contentY - 4, bounds.left + drawClass.width, contentY - 4, {
2156
- stroke: 'var(--dt-border-default)',
2157
- strokeWidth: 1,
2158
- });
2159
- appendLeftText(svg, bounds.left + 10, contentY + 4, drawClass.methods, { size: 13 });
2160
- }
2161
- }
2162
-
2163
- return svg;
2164
- }
2165
-
2166
- function ensureStateNode(graph, id, label, shape, stateKind) {
2167
- var node = graph.nodesById[id];
2168
- if (!node) {
2169
- node = {
2170
- id: id,
2171
- label: label,
2172
- shape: shape,
2173
- groups: [],
2174
- rank: 0,
2175
- width: 0,
2176
- height: 0,
2177
- lines: [],
2178
- x: 0,
2179
- y: 0,
2180
- order: graph.nodeOrder.length,
2181
- stateKind: stateKind || '',
2182
- };
2183
- graph.nodesById[id] = node;
2184
- graph.nodeOrder.push(id);
2185
- }
2186
- node.label = label;
2187
- node.shape = shape;
2188
- node.stateKind = stateKind || node.stateKind || '';
2189
- return node;
2190
- }
2191
-
2192
- function parseStateDiagram(source) {
2193
- var lines = cleanedLines(source);
2194
- var graph = newGraph('TD');
2195
-
2196
- for (var i = 0; i < lines.length; i += 1) {
2197
- var line = lines[i];
2198
- if (i === 0 && /^stateDiagram(?:-v2)?\b/i.test(line)) {
2199
- continue;
2200
- }
2201
-
2202
- var match = line.match(/^(.+?)\s*-->\s*(.+?)(?:\s*:\s*(.+))?$/);
2203
- if (!match) {
2204
- continue;
2205
- }
2206
-
2207
- var fromToken = match[1].trim();
2208
- var toToken = match[2].trim();
2209
- var fromNode = fromToken === '[*]' ? ensureStateNode(graph, '__state_start__', '', 'circle', 'start') : ensureStateNode(graph, fromToken, normalizeLabel(fromToken), 'rounded', '');
2210
- var toNode = toToken === '[*]' ? ensureStateNode(graph, '__state_end__', '', 'circle', 'end') : ensureStateNode(graph, toToken, normalizeLabel(toToken), 'rounded', '');
2211
-
2212
- addEdge(graph, fromNode, { label: normalizeLabel(match[3] || ''), style: 'solid', arrow: true }, toNode);
2213
- }
2214
-
2215
- return graph;
2216
- }
2217
-
2218
- function renderStateDiagram(source) {
2219
- var svg = renderSvg(parseStateDiagram(source));
2220
- svg.setAttribute('aria-label', 'Mermaid state diagram');
2221
- return svg;
2222
- }
2223
-
2224
- function parseGanttChart(source) {
2225
- var lines = cleanedLines(source);
2226
- var title = '';
2227
- var sections = [];
2228
- var sectionsByName = Object.create(null);
2229
- var tasks = [];
2230
- var tasksById = Object.create(null);
2231
- var currentSection = null;
2232
- var nextDateSlot = 0;
2233
- var dateSlots = Object.create(null);
2234
-
2235
- function ensureSection(name) {
2236
- if (!sectionsByName[name]) {
2237
- sectionsByName[name] = { name: name, tasks: [], index: sections.length };
2238
- sections.push(sectionsByName[name]);
2239
- }
2240
- return sectionsByName[name];
2241
- }
2242
-
2243
- for (var i = 0; i < lines.length; i += 1) {
2244
- var line = lines[i];
2245
- if (i === 0 && /^gantt\b/i.test(line)) {
2246
- continue;
2247
- }
2248
- var titleMatch = line.match(/^title\s+(.+)$/i);
2249
- if (titleMatch) {
2250
- title = normalizeLabel(titleMatch[1]);
2251
- continue;
2252
- }
2253
- if (/^dateFormat\b/i.test(line)) {
2254
- continue;
2255
- }
2256
- var sectionMatch = line.match(/^section\s+(.+)$/i);
2257
- if (sectionMatch) {
2258
- currentSection = ensureSection(normalizeLabel(sectionMatch[1]));
2259
- continue;
2260
- }
2261
-
2262
- var separator = line.indexOf(':');
2263
- if (separator === -1) {
2264
- continue;
2265
- }
2266
- if (!currentSection) {
2267
- currentSection = ensureSection('Tasks');
2268
- }
2269
-
2270
- var taskName = normalizeLabel(line.slice(0, separator));
2271
- var fields = line.slice(separator + 1).split(',');
2272
- var taskId = stripQuotes((fields[0] || '').trim()) || ('task_' + (tasks.length + 1));
2273
- var startExpr = (fields[1] || '').trim();
2274
- var durationField = (fields[2] || fields[fields.length - 1] || '').trim();
2275
- var durationMatch = durationField.match(/(\d+)\s*d/i);
2276
- var task = {
2277
- id: taskId,
2278
- name: taskName,
2279
- startExpr: startExpr,
2280
- duration: durationMatch ? Math.max(1, Number(durationMatch[1])) : 1,
2281
- section: currentSection,
2282
- start: null,
2283
- end: null,
2284
- };
2285
- tasks.push(task);
2286
- tasksById[task.id] = task;
2287
- currentSection.tasks.push(task);
2288
- }
2289
-
2290
- var autoCursor = 0;
2291
- for (var pass = 0; pass < tasks.length + 1; pass += 1) {
2292
- for (var taskIndex = 0; taskIndex < tasks.length; taskIndex += 1) {
2293
- var task = tasks[taskIndex];
2294
- if (task.start !== null) {
2295
- continue;
2296
- }
2297
- var afterMatch = task.startExpr.match(/^after\s+(.+)$/i);
2298
- if (afterMatch) {
2299
- var dependency = tasksById[afterMatch[1].trim()];
2300
- if (!dependency || dependency.end === null) {
2301
- continue;
2302
- }
2303
- task.start = dependency.end + 1;
2304
- } else if (task.startExpr) {
2305
- if (dateSlots[task.startExpr] === undefined) {
2306
- dateSlots[task.startExpr] = nextDateSlot;
2307
- nextDateSlot += task.duration + 1;
2308
- }
2309
- task.start = dateSlots[task.startExpr];
2310
- } else {
2311
- task.start = autoCursor;
2312
- }
2313
-
2314
- task.end = task.start + task.duration;
2315
- autoCursor = Math.max(autoCursor, task.end + 1);
2316
- }
2317
- }
2318
-
2319
- for (var fallbackIndex = 0; fallbackIndex < tasks.length; fallbackIndex += 1) {
2320
- if (tasks[fallbackIndex].start === null) {
2321
- tasks[fallbackIndex].start = autoCursor;
2322
- tasks[fallbackIndex].end = autoCursor + tasks[fallbackIndex].duration;
2323
- autoCursor = tasks[fallbackIndex].end + 1;
2324
- }
2325
- }
2326
-
2327
- return { title: title, sections: sections, tasks: tasks };
2328
- }
2329
-
2330
- function renderGanttChart(source) {
2331
- var gantt = parseGanttChart(source);
2332
- if (!gantt.tasks.length) {
2333
- throw new Error('Gantt chart is empty');
2334
- }
2335
-
2336
- var labelWidth = 0;
2337
- var maxEnd = 0;
2338
- for (var i = 0; i < gantt.tasks.length; i += 1) {
2339
- labelWidth = Math.max(labelWidth, measureLine(gantt.tasks[i].name) + 18);
2340
- maxEnd = Math.max(maxEnd, gantt.tasks[i].end || 0);
2341
- }
2342
- for (var sectionIndex = 0; sectionIndex < gantt.sections.length; sectionIndex += 1) {
2343
- labelWidth = Math.max(labelWidth, measureLine(gantt.sections[sectionIndex].name) + 18);
2344
- }
2345
-
2346
- labelWidth = Math.max(120, labelWidth);
2347
- var scaleX = 28;
2348
- var titleHeight = gantt.title ? 30 : 0;
2349
- var rows = gantt.tasks.length + gantt.sections.length;
2350
- var width = OUTER_PADDING * 2 + labelWidth + 24 + Math.max(4, maxEnd + 1) * scaleX;
2351
- var height = OUTER_PADDING * 2 + titleHeight + 28 + rows * 28 + 20;
2352
- var svg = createRootSvg(width, height, 'Mermaid gantt chart');
2353
- var chartLeft = OUTER_PADDING + labelWidth + 20;
2354
- var currentY = OUTER_PADDING;
2355
-
2356
- if (gantt.title) {
2357
- appendText(svg, width / 2, currentY + 10, gantt.title, { anchor: 'middle', baseline: 'middle', weight: '600' });
2358
- currentY += titleHeight;
2359
- }
2360
-
2361
- var axisY = currentY + 14;
2362
- drawStraightLine(svg, chartLeft, axisY + 10, width - OUTER_PADDING, axisY + 10, { stroke: 'var(--dt-border-default)', strokeWidth: 1 });
2363
- for (var tick = 0; tick <= maxEnd + 1; tick += 1) {
2364
- var tickX = chartLeft + tick * scaleX;
2365
- drawStraightLine(svg, tickX, axisY + 10, tickX, height - OUTER_PADDING, { stroke: 'var(--dt-border-default)', strokeWidth: 0.8 });
2366
- appendText(svg, tickX + scaleX / 2, axisY, String(tick + 1), {
2367
- anchor: 'middle',
2368
- baseline: 'middle',
2369
- size: 11,
2370
- fill: 'var(--dt-text-secondary, var(--dt-text-primary))',
2371
- });
2372
- }
2373
-
2374
- currentY = axisY + 28;
2375
- for (var drawSectionIndex = 0; drawSectionIndex < gantt.sections.length; drawSectionIndex += 1) {
2376
- var section = gantt.sections[drawSectionIndex];
2377
- appendText(svg, OUTER_PADDING, currentY, section.name, { anchor: 'start', baseline: 'middle', weight: '600', size: 13 });
2378
- drawStraightLine(svg, OUTER_PADDING, currentY + 10, width - OUTER_PADDING, currentY + 10, {
2379
- stroke: 'var(--dt-border-default)',
2380
- strokeWidth: 1,
2381
- });
2382
- currentY += 18;
2383
-
2384
- for (var taskIndex = 0; taskIndex < section.tasks.length; taskIndex += 1) {
2385
- var task = section.tasks[taskIndex];
2386
- var barX = chartLeft + task.start * scaleX + 2;
2387
- var barWidth = Math.max(18, task.duration * scaleX - 4);
2388
- appendText(svg, OUTER_PADDING + 4, currentY + 8, task.name, { anchor: 'start', baseline: 'middle', size: 13 });
2389
-
2390
- var bar = createSvg('rect');
2391
- setAttrs(bar, {
2392
- x: barX,
2393
- y: currentY - 2,
2394
- width: barWidth,
2395
- height: 18,
2396
- rx: 6,
2397
- ry: 6,
2398
- fill: 'var(--dt-bg-secondary)',
2399
- 'fill-opacity': String(Math.max(0.45, 0.95 - drawSectionIndex * 0.12)),
2400
- stroke: 'var(--dt-text-primary)',
2401
- 'stroke-width': 1,
2402
- });
2403
- svg.appendChild(bar);
2404
-
2405
- if (barWidth > measureLine(task.name) + 12) {
2406
- appendText(svg, barX + barWidth / 2, currentY + 7, task.name, { anchor: 'middle', baseline: 'middle', size: 11 });
2407
- }
2408
- currentY += 28;
2409
- }
2410
- }
2411
-
2412
- return svg;
2413
- }
2414
-
2415
- function parseErDiagram(source) {
2416
- var lines = cleanedLines(source);
2417
- var entities = [];
2418
- var entitiesById = Object.create(null);
2419
- var relationships = [];
2420
- var currentEntity = null;
2421
-
2422
- function ensureEntity(id) {
2423
- if (!entitiesById[id]) {
2424
- entitiesById[id] = { id: id, name: id, attributes: [], width: 0, height: 0, x: 0, y: 0 };
2425
- entities.push(entitiesById[id]);
2426
- }
2427
- return entitiesById[id];
2428
- }
2429
-
2430
- for (var i = 0; i < lines.length; i += 1) {
2431
- var line = lines[i];
2432
- if (i === 0 && /^erDiagram\b/i.test(line)) {
2433
- continue;
2434
- }
2435
- if (currentEntity) {
2436
- if (line === '}') {
2437
- currentEntity = null;
2438
- continue;
2439
- }
2440
- var attrMatch = line.match(/^([A-Za-z0-9_.-]+)\s+([A-Za-z0-9_.-]+)(?:\s+(PK|FK))?$/i);
2441
- if (attrMatch) {
2442
- currentEntity.attributes.push({ type: attrMatch[1], name: attrMatch[2], key: attrMatch[3] || '' });
2443
- }
2444
- continue;
2445
- }
2446
-
2447
- var entityMatch = line.match(/^([A-Za-z0-9_.-]+)\s*\{$/);
2448
- if (entityMatch) {
2449
- currentEntity = ensureEntity(entityMatch[1]);
2450
- continue;
2451
- }
2452
-
2453
- var relationMatch = line.match(/^([A-Za-z0-9_.-]+)\s+(\|\||o\{|\|\{|o\|)\-\-(\|\||o\{|\|\{|o\|)\s+([A-Za-z0-9_.-]+)(?:\s*:\s*(.+))?$/);
2454
- if (relationMatch) {
2455
- ensureEntity(relationMatch[1]);
2456
- ensureEntity(relationMatch[4]);
2457
- relationships.push({
2458
- from: relationMatch[1],
2459
- to: relationMatch[4],
2460
- fromCardinality: relationMatch[2],
2461
- toCardinality: relationMatch[3],
2462
- label: normalizeLabel(relationMatch[5] || ''),
2463
- });
2464
- }
2465
- }
2466
-
2467
- return { entities: entities, entitiesById: entitiesById, relationships: relationships };
2468
- }
2469
-
2470
- function drawErToken(parent, token, x, y, angle) {
2471
- var dx = Math.cos(angle);
2472
- var dy = Math.sin(angle);
2473
- var nx = -dy;
2474
- var ny = dx;
2475
-
2476
- function drawPart(kind, offset) {
2477
- var cx = x + dx * offset;
2478
- var cy = y + dy * offset;
2479
-
2480
- if (kind === 'o') {
2481
- var circle = createSvg('circle');
2482
- setAttrs(circle, {
2483
- cx: cx,
2484
- cy: cy,
2485
- r: 4,
2486
- fill: 'var(--dt-bg-canvas)',
2487
- stroke: 'var(--dt-text-primary)',
2488
- 'stroke-width': 1.2,
2489
- });
2490
- parent.appendChild(circle);
2491
- return;
2492
- }
2493
-
2494
- if (kind === '|') {
2495
- drawStraightLine(parent, cx - nx * 7, cy - ny * 7, cx + nx * 7, cy + ny * 7, { stroke: 'var(--dt-text-primary)', strokeWidth: 1.6 });
2496
- return;
2497
- }
2498
-
2499
- if (kind === '{') {
2500
- var baseX = cx - dx * 5;
2501
- var baseY = cy - dy * 5;
2502
- drawStraightLine(parent, baseX, baseY, cx + nx * 7, cy + ny * 7, { stroke: 'var(--dt-text-primary)', strokeWidth: 1.3 });
2503
- drawStraightLine(parent, baseX, baseY, cx, cy, { stroke: 'var(--dt-text-primary)', strokeWidth: 1.3 });
2504
- drawStraightLine(parent, baseX, baseY, cx - nx * 7, cy - ny * 7, { stroke: 'var(--dt-text-primary)', strokeWidth: 1.3 });
2505
- }
2506
- }
2507
-
2508
- drawPart(token.charAt(0), 6);
2509
- drawPart(token.charAt(1), 15);
2510
- }
2511
-
2512
- function renderErDiagram(source) {
2513
- var diagram = parseErDiagram(source);
2514
- if (!diagram.entities.length) {
2515
- throw new Error('ER diagram is empty');
2516
- }
2517
-
2518
- var maxWidth = 0;
2519
- var maxHeight = 0;
2520
- for (var i = 0; i < diagram.entities.length; i += 1) {
2521
- var entity = diagram.entities[i];
2522
- var entityWidth = Math.max(140, measureLine(entity.name) + 28);
2523
- for (var attributeIndex = 0; attributeIndex < entity.attributes.length; attributeIndex += 1) {
2524
- var attribute = entity.attributes[attributeIndex];
2525
- var attributeLabel = attribute.type + ' ' + attribute.name + (attribute.key ? ' ' + attribute.key : '');
2526
- entityWidth = Math.max(entityWidth, measureLine(attributeLabel) + 24);
2527
- }
2528
- entity.width = Math.ceil(entityWidth);
2529
- entity.height = 36 + Math.max(1, entity.attributes.length) * LINE_HEIGHT + 18;
2530
- maxWidth = Math.max(maxWidth, entity.width);
2531
- maxHeight = Math.max(maxHeight, entity.height);
2532
- }
2533
-
2534
- var columns = Math.min(3, Math.max(1, Math.ceil(Math.sqrt(diagram.entities.length))));
2535
- var rows = Math.ceil(diagram.entities.length / columns);
2536
- var width = OUTER_PADDING * 2 + columns * maxWidth + Math.max(0, columns - 1) * HORIZONTAL_GAP;
2537
- var height = OUTER_PADDING * 2 + rows * maxHeight + Math.max(0, rows - 1) * VERTICAL_GAP;
2538
- var svg = createRootSvg(width, height, 'Mermaid ER diagram');
2539
-
2540
- for (var entityIndex = 0; entityIndex < diagram.entities.length; entityIndex += 1) {
2541
- var currentEntity = diagram.entities[entityIndex];
2542
- var column = entityIndex % columns;
2543
- var row = Math.floor(entityIndex / columns);
2544
- currentEntity.x = OUTER_PADDING + column * (maxWidth + HORIZONTAL_GAP) + maxWidth / 2;
2545
- currentEntity.y = OUTER_PADDING + row * (maxHeight + VERTICAL_GAP) + maxHeight / 2;
2546
- }
2547
-
2548
- for (var relationIndex = 0; relationIndex < diagram.relationships.length; relationIndex += 1) {
2549
- var relation = diagram.relationships[relationIndex];
2550
- var fromEntity = diagram.entitiesById[relation.from];
2551
- var toEntity = diagram.entitiesById[relation.to];
2552
- var start = boxAnchor(fromEntity, toEntity);
2553
- var end = boxAnchor(toEntity, fromEntity);
2554
-
2555
- drawStraightLine(svg, start.x, start.y, end.x, end.y, { stroke: 'var(--dt-text-primary)', strokeWidth: 1.4 });
2556
-
2557
- var forwardAngle = Math.atan2(end.y - start.y, end.x - start.x);
2558
- drawErToken(svg, relation.fromCardinality, start.x, start.y, forwardAngle);
2559
- drawErToken(svg, relation.toCardinality, end.x, end.y, forwardAngle + Math.PI);
2560
- if (relation.label) {
2561
- drawLabel(svg, (start.x + end.x) / 2, (start.y + end.y) / 2 - 10, relation.label);
2562
- }
2563
- }
2564
-
2565
- for (var drawEntityIndex = 0; drawEntityIndex < diagram.entities.length; drawEntityIndex += 1) {
2566
- var drawEntity = diagram.entities[drawEntityIndex];
2567
- var bounds = { left: drawEntity.x - drawEntity.width / 2, top: drawEntity.y - drawEntity.height / 2 };
2568
-
2569
- var outer = createSvg('rect');
2570
- setAttrs(outer, {
2571
- x: bounds.left,
2572
- y: bounds.top,
2573
- width: drawEntity.width,
2574
- height: drawEntity.height,
2575
- rx: 8,
2576
- ry: 8,
2577
- fill: 'var(--dt-bg-canvas)',
2578
- stroke: 'var(--dt-border-default)',
2579
- 'stroke-width': 1.5,
2580
- });
2581
- svg.appendChild(outer);
2582
-
2583
- var header = createSvg('rect');
2584
- setAttrs(header, {
2585
- x: bounds.left,
2586
- y: bounds.top,
2587
- width: drawEntity.width,
2588
- height: 34,
2589
- rx: 8,
2590
- ry: 8,
2591
- fill: 'var(--dt-bg-secondary)',
2592
- stroke: 'var(--dt-border-default)',
2593
- 'stroke-width': 1.2,
2594
- });
2595
- svg.appendChild(header);
2596
-
2597
- drawStraightLine(svg, bounds.left, bounds.top + 34, bounds.left + drawEntity.width, bounds.top + 34, {
2598
- stroke: 'var(--dt-border-default)',
2599
- strokeWidth: 1,
2600
- });
2601
- attachText(svg, drawEntity.x, bounds.top + 18, [drawEntity.name], '');
2602
-
2603
- var attrLines = [];
2604
- for (var attrIndex = 0; attrIndex < drawEntity.attributes.length; attrIndex += 1) {
2605
- var entityAttr = drawEntity.attributes[attrIndex];
2606
- attrLines.push(entityAttr.type + ' ' + entityAttr.name + (entityAttr.key ? ' ' + entityAttr.key : ''));
2607
- }
2608
- appendLeftText(svg, bounds.left + 10, bounds.top + 42, attrLines.length ? attrLines : ['(no attributes)'], { size: 13 });
2609
- }
2610
-
2611
- return svg;
2612
- }
2613
-
2614
- function renderBlock(pre) {
2615
- var source = pre.textContent || '';
2616
- if (!source.trim()) {
2617
- return;
2618
- }
2619
-
2620
- var firstLine = source.trim().split('\n')[0].trim();
2621
- var svg;
2622
-
2623
- if (/^sequenceDiagram/i.test(firstLine)) {
2624
- svg = renderSequenceDiagram(source);
2625
- } else if (/^classDiagram/i.test(firstLine)) {
2626
- svg = renderClassDiagram(source);
2627
- } else if (/^stateDiagram/i.test(firstLine)) {
2628
- svg = renderStateDiagram(source);
2629
- } else if (/^gantt/i.test(firstLine)) {
2630
- svg = renderGanttChart(source);
2631
- } else if (/^erDiagram/i.test(firstLine)) {
2632
- svg = renderErDiagram(source);
2633
- } else {
2634
- svg = renderSvg(parseMermaid(source));
2635
- }
2636
-
2637
- pre.innerHTML = '';
2638
- pre.style.whiteSpace = 'normal';
2639
- pre.style.overflowX = 'auto';
2640
- pre.setAttribute('data-mini-mermaid-rendered', 'true');
2641
- pre.appendChild(svg);
2642
- }
2643
-
2644
- function renderAll() {
2645
- if (!document || typeof document.querySelectorAll !== 'function') {
2646
- return;
2647
- }
2648
-
2649
- var blocks = document.querySelectorAll('pre.mermaid');
2650
- for (var i = 0; i < blocks.length; i += 1) {
2651
- var block = blocks[i];
2652
- if (!block || block.getAttribute('data-mini-mermaid-rendered') === 'true') {
2653
- continue;
2654
- }
2655
-
2656
- try {
2657
- renderBlock(block);
2658
- } catch (_error) { console.error("[mini-mermaid] renderBlock error:", _error, "source:", block.textContent && block.textContent.substring(0, 80)); block.removeAttribute('data-mini-mermaid-rendered');
2659
- }
2660
- }
2661
- }
2662
-
2663
- function init() {
2664
- if (document.readyState === 'loading') {
2665
- document.addEventListener('DOMContentLoaded', function onReady() {
2666
- document.removeEventListener('DOMContentLoaded', onReady);
2667
- renderAll();
2668
- });
2669
- return;
2670
- }
2671
- renderAll();
2672
- }
2673
-
2674
- window.__aikit_initMermaid = function() {
2675
- for (var i = 0; i < MAX_RENDER_PASSES; i += 1) {
2676
- init();
2677
- }
2678
- };
2679
-
2680
- window.__aikitMiniMermaid = {
2681
- renderAll: renderAll,
2682
- parse: parseMermaid,
2683
- };
2684
-
2685
- init();
2686
- })();`;function nh(){let e;return()=>{if(e!==void 0)return e;try{e=F(ce(import.meta.url).resolve(`mermaid/dist/mermaid.min.js`),`utf-8`)}catch{e=``}return e}}const rh={id:`mermaid`,cdn:`https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js`,inlineSource:th,initScript:`window.__aikit_initMermaid = function() {
2687
- if (typeof mermaid === 'undefined') return;
2688
- if (document.readyState === 'loading') {
2689
- document.addEventListener('DOMContentLoaded', window.__aikit_initMermaid);
2690
- return;
2691
- }
2692
-
2693
- var theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'default';
2694
- if (!document.documentElement.getAttribute('data-theme')) {
2695
- theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'default';
2696
- }
2697
- mermaid.initialize({ startOnLoad: false, theme: theme });
2698
- mermaid.run();
2699
- };`,onload:`window.__aikit_initMermaid&&window.__aikit_initMermaid()`,local:{route:`/vendor/mermaid.min.js`,getSource:nh()}},ih=new Map([[`mermaid`,rh]]);function ah(e,t){if(!e?.length)return;let n=[];for(let r of e){let e=ih.get(r);if(e){if(t===`browser`){n.push({inlineSource:e.inlineSource,onload:e.onload});continue}if(t===`mcp-app`){n.push({inlineSource:e.inlineSource,onload:e.onload});continue}n.push({src:e.cdn,initScript:e.initScript,onload:e.onload})}}return n.length>0?n:void 0}function oh(){let e=[];for(let t of ih.values())t.local&&e.push({route:t.local.route,getSource:t.local.getSource,cdn:t.cdn});return e}const sh=300*1e3,ch=15*1e3,lh=`/@aikit/blocks-interactive/dist/`;var uh=class{maxTokens;refillPerSecond;tokens;lastRefill;constructor(e,t){this.maxTokens=e,this.refillPerSecond=t,this.tokens=e,this.lastRefill=Date.now()}tryConsume(){return this.#e(),this.tokens>=1?(--this.tokens,!0):!1}#e(){let e=Date.now(),t=(e-this.lastRefill)/1e3;this.tokens=Math.min(this.maxTokens,this.tokens+t*this.refillPerSecond),this.lastRefill=e}};let dh=null,fh=null;const ph=new Map,mh=new uh(10,10),hh=new uh(50,50);function gh(){return dh||(dh={manager:new eh,server:null,port:0},process.on(`exit`,()=>{dh?.manager.shutdown()})),dh.manager}async function _h(){if(!dh)throw Error(`Browser server state not initialized`);let e=dh;if(e.server)return e.port;if(fh)return fh;let t=Wr((e,t)=>{Sh(e,t)});return e.server=t,fh=new Promise((n,r)=>{t.listen(0,`127.0.0.1`,()=>{let i=t.address();typeof i==`object`&&i?(e.port=i.port,n(i.port)):r(Error(`Failed to resolve local browser address`))}),t.on(`error`,r)}),fh}let vh;function yh(){return vh===void 0&&(vh=w(`blocks-interactive`)),vh}function bh(e){if(!e.startsWith(lh))return null;let t=yh();if(!t)return null;let n=L(I(t,`dist`,e.slice(32))),r=L(I(t,`dist`)),i=process.platform===`win32`?`\\`:`/`;return!n.startsWith(r+i)&&n!==r?null:n}function xh(e){return`script-src 'nonce-${e}' 'strict-dynamic'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self'; frame-ancestors 'self'`}function Sh(e,t){let n=dh;if(!n){Mh(t);return}try{let r=new URL(e.url??`/`,`http://${e.headers.host??`127.0.0.1`}`).pathname,i=e.method??`GET`;if(i===`OPTIONS`){t.writeHead(204,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`POST, GET, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type`}),t.end();return}if(r.startsWith(`/__aikit_clipboard.png`)){if(i!==`POST`){Ch(t,405,`METHOD_NOT_ALLOWED`,`Clipboard capture requires POST.`);return}Ih(t,Nh(e,n));return}if(r.startsWith(`/__aikit_screenshot.png`)){Fh(t,Nh(e,n));return}if(r.startsWith(`/__aikit_system_clipboard`)){if(i!==`POST`){Ch(t,405,`METHOD_NOT_ALLOWED`,`System clipboard write requires POST.`);return}Lh(e,t);return}let a=r.match(/^\/present\/([^/]+)(?:\/(.*))?$/);if(a){let r=a[1],i=a[2]??``,o=ph.get(r);if(!o){Ch(t,404,Y.SESSION_NOT_FOUND,`Session ${r} not found`);return}if(o.hasClientConnected=!0,n.manager.transitionSession(r,`connected`,`client-connect`),i===``||i===`/`){t.writeHead(200,{"Content-Type":`text/html; charset=utf-8`,"Content-Security-Policy":xh(o.callbackSession.nonce)}),t.end(o.html);return}if(i===`viewer`){if(!o.viewerHtml){t.writeHead(404,{"Content-Type":`text/plain`}),t.end(`Not Found`);return}t.writeHead(200,{"Content-Type":`text/html; charset=utf-8`}),t.end(o.viewerHtml);return}if(i===`callback`){if(!mh.tryConsume()){Ch(t,429,Y.RATE_LIMITED,`Too many requests`);return}o.callbackSession.handle(e,t,`http://127.0.0.1:${n.port}`).catch(()=>{Mh(t)});return}t.writeHead(404,{"Content-Type":`text/plain`}),t.end(`Not Found`);return}let o=oh().find(t=>e.url===t.route);if(o){let e=o.getSource();if(e){t.writeHead(200,{"Content-Type":`application/javascript; charset=utf-8`,"Cache-Control":`public, max-age=86400`}),t.end(e);return}t.writeHead(302,{Location:o.cdn}),t.end();return}if(r.startsWith(lh)){if(!hh.tryConsume()){Ch(t,429,Y.RATE_LIMITED,`Too many requests`);return}let e=bh(r);if(e)try{let n=F(e,`utf8`);t.writeHead(200,{"Content-Type":`application/javascript; charset=utf-8`}),t.end(n);return}catch{}}t.writeHead(404,{"Content-Type":`text/plain`}),t.end(`Not Found`)}catch{Mh(t)}}function Ch(e,t,n,r){if(!e.headersSent)try{e.writeHead(t,{"Content-Type":`application/json; charset=utf-8`}),e.end(JSON.stringify({error:n,message:r}))}catch{try{e.end()}catch{}}}function wh(e){let t=J(e.id),n=J(e.label);if(e.type===`select`||e.type===`multi-select`)return`<label class="present-action-field"><span>${n}</span><select data-action-id="${t}"${e.type===`multi-select`?` multiple`:``}>${(e.options??[]).map(e=>`<option value="${J(e.value)}">${J(e.label)}</option>`).join(``)}</select></label>`;if(e.type===`form-submit`){let r=e.schema;if(r)return`<form class="present-form" data-action-id="${t}" data-action-label="${n}">${Object.entries(r).map(([e,t])=>{let n=J(t.description??e);return`<label class="present-action-field"><span>${n}</span><input type="${t.type===`number`?`number`:t.type===`boolean`?`checkbox`:`text`}" class="present-text-input" name="${J(e)}" placeholder="${n}" /></label>`}).join(``)}<button type="submit" class="present-action-btn present-action-primary">${n}</button></form>`}return`<button type="button" class="present-action-btn present-action-${J(e.variant??`default`)}" data-action-id="${t}" data-action-label="${n}">${n}</button>`}function Th(e){return e.length===0?``:`<div class="bk-actions">${e.map(wh).join(``)}</div>`}function Eh(e,t){if(e.length===0)return``;let n=JSON.stringify(t);return`<style>
2700
- .present-surface-title { margin: 0 0 0.75rem; font-size: 1.875rem; }
2701
- .present-surface-description { margin: 0; color: var(--muted-foreground, #6b7280); }
2702
- .present-actions-list { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: flex-end; }
2703
- .present-action-btn,
2704
- .present-action-field select {
2705
- font: inherit;
2706
- font-size: 0.9375rem;
2707
- line-height: 1.2;
2708
- border-radius: 0.75rem;
2709
- border: 1px solid var(--border, #d0d5dd);
2710
- min-height: 2.5rem;
2711
- }
2712
- .present-action-btn {
2713
- display: inline-flex;
2714
- align-items: center;
2715
- justify-content: center;
2716
- padding: 0.5rem 1rem;
2717
- background: var(--card, #ffffff);
2718
- color: var(--card-foreground, #101828);
2719
- cursor: pointer;
2720
- text-align: center;
2721
- transition:
2722
- background 120ms ease,
2723
- color 120ms ease,
2724
- border-color 120ms ease;
2725
- }
2726
- .present-action-field {
2727
- display: grid;
2728
- gap: 0.35rem;
2729
- min-width: 14rem;
2730
- }
2731
- .present-action-field span {
2732
- color: var(--muted-foreground, #6b7280);
2733
- font-size: 0.8125rem;
2734
- font-weight: 500;
2735
- }
2736
- .present-action-field select {
2737
- padding: 0.5rem 1rem;
2738
- background: var(--card, #ffffff);
2739
- color: var(--foreground, #101828);
2740
- cursor: pointer;
2741
- }
2742
- .present-action-btn:hover,
2743
- .present-action-btn:focus-visible,
2744
- .present-action-field select:hover,
2745
- .present-action-field select:focus-visible {
2746
- background: var(--accent, #f3f4f6);
2747
- color: var(--accent-foreground, #101828);
2748
- outline: none;
2749
- }
2750
- .present-form {
2751
- display: flex;
2752
- flex-direction: column;
2753
- gap: 0.75rem;
2754
- }
2755
- .present-action-primary {
2756
- background: var(--primary, #2563eb) !important;
2757
- color: var(--primary-foreground, #ffffff) !important;
2758
- border-color: var(--primary, #2563eb) !important;
2759
- }
2760
- /* ── Per-action status feedback ── */
2761
- .present-action-btn:disabled {
2762
- cursor: default;
2763
- opacity: 0.7;
2764
- }
2765
- .present-action-btn[data-action-status="sending"] {
2766
- pointer-events: none;
2767
- opacity: 0.8;
2768
- }
2769
- .present-action-btn[data-action-status="sending"]::after {
2770
- content: '';
2771
- display: inline-block;
2772
- width: 1em;
2773
- height: 1em;
2774
- margin-left: 0.5rem;
2775
- border: 2px solid transparent;
2776
- border-top-color: currentColor;
2777
- border-radius: 50%;
2778
- animation: present-spin 0.6s linear infinite;
2779
- }
2780
- @keyframes present-spin {
2781
- to { transform: rotate(360deg); }
2782
- }
2783
- .present-action-btn[data-action-status="success"] {
2784
- border-color: var(--success, #16a34a) !important;
2785
- background: var(--success-subtle, rgba(22, 163, 74, 0.1)) !important;
2786
- color: var(--success, #16a34a) !important;
2787
- }
2788
- .present-action-btn[data-action-status="error"] {
2789
- border-color: var(--danger, #dc2626) !important;
2790
- background: var(--danger-subtle, rgba(220, 38, 38, 0.1)) !important;
2791
- color: var(--danger, #dc2626) !important;
2792
- }
2793
- </style>
2794
- <script nonce="${J(t)}">
2795
- (() => {
2796
- const nonce = ${n};
2797
- let settled = false;
2798
- const controls = Array.from(document.querySelectorAll('[data-action-id]'));
2799
-
2800
- function setActionStatus(actionId, status) {
2801
- // Look up the action element by matching data-action-id
2802
- // Using Array.find + getAttribute to avoid CSS selector injection
2803
- var el = null;
2804
- for (var i = 0; i < controls.length; i++) {
2805
- if (controls[i].getAttribute('data-action-id') === actionId) {
2806
- el = controls[i];
2807
- break;
2808
- }
2809
- }
2810
- if (el) {
2811
- el.setAttribute('data-action-status', status);
2812
- }
2813
- }
2814
-
2815
- function disableControls() {
2816
- for (const control of controls) {
2817
- control.disabled = true;
2818
- }
2819
- }
2820
-
2821
- /**
2822
- * Collect annotations from the annotation layer (if present).
2823
- * Returns null if no annotations exist or layer not initialized.
2824
- */
2825
- function collectAnnotations() {
2826
- try {
2827
- var layer = window.__annotationLayer;
2828
- if (!layer) return null;
2829
- var exporter = layer.getExporter();
2830
- var json = exporter.exportJSON();
2831
- var annotations = JSON.parse(json);
2832
- return annotations.length > 0 ? annotations : null;
2833
- } catch (_e) {
2834
- return null;
2835
- }
2836
- }
2837
-
2838
- async function sendPayload(payload) {
2839
- // Bundle annotations with the action payload
2840
- var annotations = collectAnnotations();
2841
- if (annotations) {
2842
- payload.annotations = annotations;
2843
- }
2844
-
2845
- settled = true;
2846
- disableControls();
2847
- setActionStatus(payload.actionId, 'sending');
2848
- try {
2849
- const response = await fetch('/callback', {
2850
- method: 'POST',
2851
- headers: { 'Content-Type': 'application/json' },
2852
- body: JSON.stringify({ nonce, ...payload }),
2853
- });
2854
- if (response.ok) {
2855
- setActionStatus(payload.actionId, 'success');
2856
- } else {
2857
- setActionStatus(payload.actionId, 'error');
2858
- }
2859
- } catch {
2860
- setActionStatus(payload.actionId, 'error');
2861
- }
2862
- }
2863
-
2864
- for (const control of controls) {
2865
- if (control.tagName === 'SELECT' || control.tagName === 'INPUT' || control.tagName === 'FORM') {
2866
- continue;
2867
- }
2868
-
2869
- control.addEventListener('click', () => {
2870
- void sendPayload({
2871
- actionId: control.dataset.actionId,
2872
- value: 'clicked',
2873
- label: control.dataset.actionLabel,
2874
- timestamp: new Date().toISOString(),
2875
- });
2876
- });
2877
- }
2878
-
2879
- // Handle form-submit
2880
- for (const form of document.querySelectorAll('form.present-form[data-action-id]')) {
2881
- form.addEventListener('submit', (e) => {
2882
- e.preventDefault();
2883
- const formData = {};
2884
- for (const input of form.querySelectorAll('input[name]')) {
2885
- formData[input.name] = input.type === 'checkbox' ? input.checked : input.value;
2886
- }
2887
- const actionId = form.dataset.actionId;
2888
- void sendPayload({
2889
- actionId: actionId,
2890
- value: formData,
2891
- label: form.dataset.actionLabel,
2892
- timestamp: new Date().toISOString(),
2893
- });
2894
- });
2895
- }
2896
-
2897
- for (const control of document.querySelectorAll('select[data-action-id]')) {
2898
- control.addEventListener('change', () => {
2899
- const selected = Array.from(control.selectedOptions).map((option) => option.value);
2900
- if (selected.length === 0) return;
2901
-
2902
- void sendPayload({
2903
- actionId: control.dataset.actionId,
2904
- selection: control.multiple ? selected : selected[0],
2905
- value: control.multiple ? selected : selected[0],
2906
- timestamp: new Date().toISOString(),
2907
- });
2908
- });
2909
- }
2910
-
2911
- window.addEventListener('beforeunload', () => {
2912
- if (settled || !navigator.sendBeacon) return;
2913
- const body = JSON.stringify({ nonce, kind: 'cancelled', reason: 'user-closed' });
2914
- navigator.sendBeacon('/callback', new Blob([body], { type: 'application/json' }));
2915
- });
2916
- })();
2917
- <\/script>`}function Dh(e){try{if(process.platform===`win32`){Or(`cmd`,[`/c`,`start`,``,e],{windowsHide:!0});return}if(process.platform===`darwin`){Or(`open`,[e]);return}Or(`xdg-open`,[e])}catch{}}async function Oh(e){try{let t=$n();return await t.launch(`ui`),t.resetIdleTimer(),await t.open(e),!0}catch{return Dh(e),!1}}function kh(e,t,n){let r=[e.title];return e.description&&r.push(e.description),r.push(``,`Opened in browser at ${t}`,n),r.join(`
2918
- `)}function Ah(e){return e.some(e=>e.id!==`__dismiss`)}function jh(e){return e.replace(`</head>`,`${Fg}\n</head>`).replace(`</body>`,`${Ig}\n</body>`)}function Mh(e){if(!e.headersSent)try{e.writeHead(500,{"Content-Type":`text/plain`}),e.end(`Internal Server Error`)}catch{try{e.end()}catch{}}}function Nh(e,t){let n=e.headers.referer;return typeof n==`string`&&n.length>0?n:`http://127.0.0.1:${t.port}`}async function Ph(e,t){let n=$n(),r=`ss-${Date.now()}`;n.isLaunched()||await n.launch(`headless`);let{base64:i}=await n.screenshot(r,{fullPage:t?.fullPage!==!1,format:t?.format,quality:t?.quality,annotate:t?.annotate});return Buffer.from(i,`base64`)}async function Fh(e,t){if(!t){e.writeHead(503,{"Content-Type":`text/plain; charset=utf-8`}),e.end(`Screenshot target is not ready.`);return}try{let n=await Ph(t);e.writeHead(200,{"Content-Type":`image/png`,"Cache-Control":`no-store`}),e.end(n)}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`[present] Screenshot capture failed:`,n),Mh(e)}}async function Ih(e,t){if(!t){Ch(e,503,`CLIPBOARD_CAPTURE_TARGET_MISSING`,`Clipboard target is not ready.`);return}try{let n=await Ph(t);e.writeHead(200,{"Content-Type":`image/png`,"Cache-Control":`no-store`}),e.end(n)}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`[present] Clipboard capture failed:`,n),Ch(e,500,`CLIPBOARD_CAPTURE_FAILED`,`Clipboard capture failed: ${n}`)}}async function Lh(e,t){let n=[];e.on(`data`,e=>n.push(e)),e.on(`end`,async()=>{let e=Buffer.concat(n);if(e.length===0){Ch(t,400,`EMPTY_BODY`,`No image data received.`);return}try{await Rh(e),t.writeHead(200,{"Content-Type":`application/json`}),t.end(JSON.stringify({ok:!0}))}catch(e){let n=e instanceof Error?e.message:String(e);console.warn(`[present] System clipboard write failed:`,n),Ch(t,500,`SYSTEM_CLIPBOARD_WRITE_FAILED`,`System clipboard write failed: ${n}`)}}),e.on(`error`,e=>{console.warn(`[present] System clipboard write request error:`,e.message),Ch(t,500,`REQUEST_ERROR`,`Request stream error.`)})}async function Rh(e){let t=I(Gn(),`aikit-clipboard-${Date.now()}-${Xe(4).toString(`hex`)}.png`);Ie(t,e);try{if(process.platform===`win32`){let e=[`Add-Type -AssemblyName System.Drawing;`,`Add-Type -AssemblyName System.Windows.Forms;`,`$path = '${t.replace(/'/g,`''`)}';`,`$img = [System.Drawing.Image]::FromFile($path);`,`$img2 = [System.Drawing.Bitmap]::FromImage($img);`,`$img.Dispose();`,`[System.Windows.Forms.Clipboard]::SetImage($img2);`,`Start-Sleep -Milliseconds 500;`,`$img2.Dispose();`].join(` `);await new Promise((t,n)=>{Dr(`powershell.exe -NoProfile -STA -Command "${e.replace(/"/g,`\\"`)}"`,{timeout:15e3},e=>{e?n(Error(`PowerShell clipboard write failed: ${e.message}`)):t()})})}else if(process.platform===`darwin`)await new Promise((e,n)=>{Dr(`osascript -e 'set the clipboard to (read (POSIX file "${t}") as picture)'`,{timeout:15e3},t=>{t?n(Error(`macOS clipboard write failed: ${t.message}`)):e()})});else try{await new Promise((e,n)=>{Dr(`wl-copy --type image/png < "${t}" 2>/dev/null`,{timeout:1e4},(t,r)=>{t?n(Error(`wl-copy failed: ${t.message}`)):e(r)})});return}catch{await new Promise((e,n)=>{Dr(`xclip -selection clipboard -t image/png -i "${t}"`,{timeout:15e3},t=>{t?n(Error(`Linux clipboard write failed (tried wl-copy then xclip): ${t.message}. Install wl-clipboard (Wayland) or xclip (X11) for clipboard image support.`)):e()})})}}finally{try{Fe(t)}catch{}}}function zh(e,t){return e.replace(/'\/callback'/g,`'/present/${t}/callback'`).replace(/"\/callback"/g,`"/present/${t}/callback"`)}function Bh(e,t){return e.replace(/src="\/viewer"/g,`src="/present/${t}/viewer"`)}async function Vh(e,t){if(pg(`<html><body style="font-family:system-ui;padding:2rem;color:#888;text-align:center"><p>Content opened in browser window.</p></body></html>`),e.data!=null&&t.inputSchema){let n=Tn({data:e.data,schema:t.inputSchema});if(!n.valid){let e=n.errors.map(e=>` ${e.path}: ${e.message}${e.expected?` (expected: ${e.expected}, got: ${e.received})`:``}`).join(`
2919
- `);return{content:[{type:`text`,text:`[ERROR:VALIDATION] Template "${t.id}" data validation failed:\n${e}\n\nExpected schema: ${JSON.stringify(t.inputSchema,null,2)}`}],structuredContent:{kind:`error`,error:{code:`VIEWER_DATA_INVALID`,message:`Template "${t.id}" data validation failed:\n${e}\n\nExpected schema: ${JSON.stringify(t.inputSchema,null,2)}`}},isError:!0}}}let n=jh(im(t.resolveHtml(),e.data??null,t.injectId,t.transformData)),r=gh(),i=Xe(16).toString(`hex`),a=r.createSession({surfaceId:`viewer`,transport:`viewer`,nonce:i});if(!a.ok)return{content:[{type:`text`,text:`${e.title}\n\nUnable to start local browser transport.`}],structuredContent:{kind:`error`,error:{code:`BROWSER_START_FAILED`,message:a.error.message}},isError:!0};let o=a.session.id,s=Zm(`viewer`,e.actions??[],r,o,i),c=Bh(Fr({title:e.title,subtitle:e.description,html:[`<div class="present-viewer-container">`,` <iframe class="present-viewer-iframe" src="/viewer" sandbox="allow-scripts allow-same-origin"></iframe>`,` ${Lg(i)}`,`</div>`].join(`
2920
- `),css:[[`.present-viewer-container {`,` flex: 1;`,` min-height: calc(100vh - 12rem);`,` position: relative;`,` border-radius: 0.75rem;`,` overflow: hidden;`,` border: none;`,`}`,`.present-viewer-iframe {`,` border: none;`,` width: 100%;`,` height: 100%;`,` position: absolute;`,` inset: 0;`,` border-radius: inherit;`,`}`].join(`
2921
- `)],islands:[],payload:void 0,nonce:i,generatedAt:new Date().toISOString(),colorScheme:e.colorScheme,lang:e.lang,dir:e.dir,transport:`browser`,exportPolicy:`local-interactive`,imageExportMode:`browser-server`,footerContentHtml:Qm}),o);ph.set(o,{callbackSession:s,html:c,viewerHtml:n,hasClientConnected:!1,createdAt:Date.now()});let l=``;try{l=`http://127.0.0.1:${await _h()}/present/${o}`}catch(t){return ph.delete(o),r.removeSession(o),{content:[{type:`text`,text:`${e.title}\n\nUnable to start local browser transport.`}],structuredContent:{kind:`error`,error:{code:`BROWSER_START_FAILED`,message:t instanceof Error?t.message:`Unable to start browser transport`}},isError:!0}}return await Oh(l),setTimeout(()=>{ph.delete(o),r.removeSession(o)},sh),{content:[{type:`text`,text:kh(e,l,`Rendered.`)}],structuredContent:{kind:`rendered`,reason:`no-response-required`}}}async function Hh(e){pg(`<html><body style="font-family:system-ui;padding:2rem;color:#888;text-align:center"><p>Content opened in browser window.</p></body></html>`);let t=gh(),n=Xe(16).toString(`hex`),r=Ur(e,{transport:`browser`,registry:Am,blockVendorScripts:Yp(),nonce:n}),i=t.createSession({surfaceId:r.surfaceId,transport:`browser`,nonce:n});if(!i.ok)return{content:[{type:`text`,text:`${e.title}\n\nUnable to start local browser transport.`}],structuredContent:{kind:`error`,error:{code:`BROWSER_START_FAILED`,message:i.error.message}},isError:!0};let a=i.session.id,o=Zm(r.surfaceId,r.actions,t,a,n),s=ah(r.vendorScripts,`browser`);oh();let c=r.actions.length>0?Th(r.actions):``,l=r.actions.length>0?Eh(r.actions,o.nonce):``,u=Fr({title:e.title,subtitle:e.description,html:[r.html,c,l].filter(Boolean).join(`
2922
- `),css:r.css,islands:r.islands,payload:r.payload,nonce:r.nonce,generatedAt:new Date().toISOString(),colorScheme:e.colorScheme,lang:e.lang,dir:e.dir,transport:`browser`,exportPolicy:r.exportPolicy,imageExportMode:`browser-server`,footerContentHtml:Qm,headScripts:s}),d=zh(r.actions.length>0?Ug(u,r.nonce):u,a);ph.set(a,{callbackSession:o,html:d,hasClientConnected:!1,createdAt:Date.now()});let f=``;try{f=`http://127.0.0.1:${await _h()}/present/${a}`;let e=ph.get(a);e&&e.hasClientConnected}catch(n){return ph.delete(a),t.removeSession(a),t.shutdown(),{content:[{type:`text`,text:`${e.title}\n\nUnable to start local browser transport.`}],structuredContent:o.settleError(`BROWSER_START_FAILED`,n instanceof Error?n.message:`Unable to start browser transport`),isError:!0}}let p=await Oh(f);if(!Ah(r.actions))return setTimeout(()=>{ph.delete(a);try{t.removeSession(a)}catch{}},sh),{content:[{type:`text`,text:kh(e,f,`Rendered.`)}],structuredContent:{kind:`rendered`,reason:`no-response-required`}};let m=await Promise.race([o.promise,new Promise(e=>{setTimeout(()=>{ph.get(a)?.hasClientConnected||(ph.delete(a),e(o.settleError(`BROWSER_CONNECT_TIMEOUT`,p?`No browser client connected within ${ch}ms.`:`Fell back to system browser, but no browser client connected within ${ch}ms.`)))},ch)}),new Promise(e=>{setTimeout(()=>e(o.settleTimeout(sh)),sh)})]);setTimeout(()=>{ph.delete(a);try{t.removeSession(a)}catch{}},sh);let h=m.kind===`result`?`Selected action: ${m.result.actionId}`:m.kind===`timeout`?`Timed out after ${m.waitedMs}ms.`:m.kind===`cancelled`?`Cancelled: ${m.reason}.`:m.kind===`error`?`Error: ${m.error.message}`:`Rendered.`;return{content:[{type:`text`,text:kh(e,f,h)}],structuredContent:m,isError:m.kind===`error`}}const Uh={id:`browser`,priority:20,canHandle(e,t){let n=Mg(e);return Mm(n)||!!t.preferBrowser&&!!Ng(n)},async render(e,t){return Hh(e)}},Wh=`openai/outputTemplate`,Gh=`ui/resourceUri`,Kh={connectDomains:[],resourceDomains:[]},qh={connect_domains:[],resource_domains:[]};function Jh(e){return{ui:{resourceUri:e,visibility:[`model`,`app`]},[Gh]:e,[Wh]:e,"openai/widgetAccessible":!0}}function Yh(){return{ui:{prefersBorder:!1,csp:Kh},"openai/widgetDescription":`AI Kit renders structured visual surfaces such as dashboards, charts, reports, and diagrams.`,"openai/widgetPrefersBorder":!1,"openai/widgetCSP":qh}}function Xh(e){return{ui:{resourceUri:e},[Gh]:e,[Wh]:e}}function Zh(e){return{...e,schemaVersion:1}}function Qh(e){try{let t=Ur(e,{transport:`mcp-app`,registry:Am,blockVendorScripts:Yp()}),n=ah(t.vendorScripts,`mcp-app`),r=Fr({title:e.title,subtitle:e.description,html:t.html,css:t.css,islands:t.islands,payload:t.payload,nonce:t.nonce,colorScheme:e.colorScheme,lang:e.lang,dir:e.dir,transport:`mcp-app`,exportPolicy:t.exportPolicy,imageExportMode:`disabled`,showToolbox:t.exportPolicy!==`static-only`,showInstallGuide:!1,footerContentHtml:Qm,headScripts:n}),i={kind:`rendered`,reason:`no-response-required`},a=zg(r);pg(a);let o=Pg(e,i,{includeSurfaceHeader:!1}),s=dg(),c=gg(s);return c&&mg(c,a),{content:[{type:`text`,text:o}],structuredContent:Zh(e),_meta:Xh(s),ui:{type:`resource`,uri:s}}}catch(t){return Gg(`RENDER_FAILED`,t instanceof Error?t.message:`Failed to render ChannelSurface`,void 0,e.title)}}const $h={id:`mcp-app`,priority:30,canHandle(e,t){return!0},async render(e,t){return Qh(e)}};var eg=class{handlers=[];register(e){let t=this.handlers.findIndex(t=>t.id===e.id);t===-1?this.handlers.push(e):this.handlers[t]=e}unregister(e){let t=this.handlers.findIndex(t=>t.id===e);t!==-1&&this.handlers.splice(t,1)}select(e,t){return[...this.handlers].sort((e,t)=>(e.priority??99)-(t.priority??99)).find(n=>n.canHandle(e,t))??null}getAll(){return[...this.handlers]}};function tg(e){return`<script nonce="${J(e)}">
2923
- window.addEventListener('message', function(e) {
2924
- if (e.data && e.data.type === 'aikit-viewer-height') {
2925
- var container = document.querySelector('.present-viewer-container');
2926
- if (container) { container.style.minHeight = e.data.height + 'px'; }
2927
- }
2928
- });
2929
- <\/script>`}async function ng(e,t){try{let n=Rg(im(t.resolveHtml(),e.data??null,t.injectId,t.transformData)).replace(/&/g,`&amp;`).replace(/"/g,`&quot;`),r=Xe(16).toString(`hex`),i={kind:`rendered`,reason:`no-response-required`};pg(zg(Fr({title:e.title,subtitle:e.description,html:[`<div class="present-viewer-container">`,` <iframe class="present-viewer-iframe" srcdoc="${n}" sandbox="allow-scripts allow-same-origin"></iframe>`,` ${Lg(r)}`,` ${tg(r)}`,`</div>`].join(`
2930
- `),css:[[`.present-viewer-container {`,` flex: 1;`,` min-height: 640px;`,` position: relative;`,` border-radius: 0.75rem;`,` overflow: hidden;`,` border: none;`,`}`,`.present-viewer-iframe {`,` border: none;`,` width: 100%;`,` height: 100%;`,` position: absolute;`,` inset: 0;`,` border-radius: inherit;`,`}`].join(`
2931
- `)],islands:[],payload:void 0,nonce:r,generatedAt:new Date().toISOString(),footerContentHtml:Qm,colorScheme:e.colorScheme,lang:e.lang,dir:e.dir,transport:`mcp-app`,exportPolicy:`local-interactive`,imageExportMode:`disabled`})));let a=Pg(e,i,{includeSurfaceHeader:!1}),o=dg();return{content:[{type:`text`,text:a}],structuredContent:Zh(e),_meta:Xh(o),ui:{type:`resource`,uri:o}}}catch(t){return Gg(`VIEWER_RENDER_FAILED`,t instanceof Error?t.message:`Failed to render viewer template`,void 0,e.title)}}const rg={id:`viewer`,priority:10,canHandle(e,t){return e.template?tm(e.template)!=null:!1},async render(e,t){let n=tm(e.template??``);if(!n)return Gg(`VIEWER_NOT_FOUND`,`Viewer template "${e.template}" not found`,void 0,e.title);if(e.data!=null&&n.inputSchema){let t=Tn({data:e.data,schema:n.inputSchema});if(!t.valid){let r=t.errors.map(e=>` ${e.path}: ${e.message}${e.expected?` (expected: ${e.expected}, got: ${e.received})`:``}`).join(`
2932
- `);return Gg(`VIEWER_DATA_INVALID`,`Template "${n.id}" data validation failed:\n${r}\n\nExpected schema: ${JSON.stringify(n.inputSchema,null,2)}`,void 0,e.title)}}let r=n.supportedTransports.includes(`browser`),i=n.supportedTransports.includes(`mcp-app`);return t.preferBrowser||r&&!i?await Vh(e,n):i?ng(e,n):Gg(`VIEWER_TRANSPORT_UNSUPPORTED`,`Viewer template "${n.id}" does not support an available transport`,void 0,e.title)}},ig=`ui://aikit/present.html`,ag=`ui://aikit/present/{id}.html`,og=M(`present`);let sg=0,cg=``;const lg=new Map,ug=new Map;function dg(){return`ui://aikit/present/${`${Date.now().toString(36)}_${(++sg).toString(36)}`}.html`}function fg(){return cg}function pg(e){cg=e}function mg(e,t){let n=ug.get(e);n&&clearTimeout(n),lg.set(e,t),ug.set(e,setTimeout(()=>{lg.delete(e),ug.delete(e)},3e4))}function hg(e){return lg.get(e)}function gg(e){return e.match(/\/present\/(.+)\.html$/)?.[1]}const _g=new eg;_g.register(rg),_g.register(Uh),_g.register($h);function vg(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const yg=/\\u[0-9a-fA-F]{4}/,bg=/^\s*\|(?:[^|\r\n]+\|){2,}\s*$/,xg=/^\s*\|?(?:\s*:?-{3,}:?\s*\|){2,}\s*$/,Sg=/\b(cli|terminal|tty|console|command(?:-|\s)?line)\b/i;function Cg(e){let t=[e.value,e.markdown,e.text,e.content];for(let e of t)if(typeof e==`string`&&e.trim().length>0)return e}function wg(e){let t=e.split(/\r?\n/);for(let e=0;e<t.length-1;e+=1)if(bg.test(t[e])&&xg.test(t[e+1]))return!0;return!1}function Tg(e){let t=e.trim().split(`|`),n=+(t[0]?.trim()===``),r=t.at(-1)?.trim()===``?t.length-1:t.length;return t.slice(n,r).map(e=>e.trim())}function Eg(e,t){if(t<2)return!1;let n=e.trim();return n.startsWith(`|`)?Tg(n).length===t:!1}function Dg(e){let t=e.split(/\r?\n/),n=[],r=[],i=()=>{r.length!==0&&(n.push({type:`text`,content:r.join(`
2933
- `)}),r.length=0)},a=0;for(;a<t.length;){let e=t[a],o=t[a+1];if(o!==void 0&&bg.test(e)&&xg.test(o)){let r=Tg(e),o=[];i();let s=a+2;for(;s<t.length&&Eg(t[s],r.length);)o.push(Tg(t[s])),s+=1;n.push({type:`table`,headers:r,rows:o}),a=s;continue}r.push(e),a+=1}return i(),n}function Og(e){let t=Cg(e);return!t||!wg(t)?[e]:Dg(t).flatMap(e=>{if(e.type===`text`){let t=e.content.trim();return t.length>0?[{type:`markdown`,value:t}]:[]}return[{type:`table`,value:{headers:e.headers,rows:e.rows}}]})}function kg(e){if(typeof e==`string`)return Sg.test(e);if(Array.isArray(e))return e.some(e=>kg(e));if(!vg(e))return!1;let t=[`client`,`clientInfo`,`host`,`source`,`mode`,`name`,`title`,`channel`];return Object.entries(e).some(([e,n])=>t.includes(e)?kg(n):!1)}function Ag(e,t){return{preferBrowser:[t,e._meta,vg(e.metadata)?e.metadata.source:void 0].some(e=>kg(e))}}const jg={id:`__dismiss`,type:`button`,label:`Done`,variant:`default`};function Mg(e){if((e.actions?.length??0)>0||!e.template)return e;let t=jm(e);return t?.supportedTransports.includes(`browser`)===!0&&!t.supportedTransports.includes(`mcp-app`)?{...e,actions:[jg]}:e}function Ng(e){if(!e.template)return!0;let t=tm(e.template);return t?t.supportedTransports.includes(`browser`):jm(e)?.supportedTransports.includes(`browser`)??!1}function Pg(e,t,n={}){let r=n.includeSurfaceHeader??!0,i=r?[e.title]:[];return r&&e.description&&i.push(e.description),Br(t)?i.push(``,`Selected action: ${t.result.actionId}`):zr(t)?i.push(``,`Error: ${t.error.message}`):t.kind===`timeout`?i.push(``,`Timed out after ${t.waitedMs}ms.`):t.kind===`cancelled`?i.push(``,`Cancelled: ${t.reason}.`):r||i.push(`Rendered inline.`),i.join(`
2934
- `)}const Fg=`<style>
2935
- .toolbar, .badge, .aikit-header, .aikit-footer { display: none !important; }
2936
- body { padding-top: 0 !important; margin-top: 0 !important; }
2937
- </style>`,Ig=`<script>
2938
- window.addEventListener('message', function(e) {
2939
- // Accept from any origin — theme change is cosmetic-only.
2940
- // Strict origin check breaks in MCP host custom protocols (ui://, vscode-webview://)
2941
- // where window.location.origin can be "null" or protocol-specific.
2942
- if (e.data && e.data.type === 'aikit-theme-change') {
2943
- // Guard: only accept valid theme values — future extensibility safety
2944
- if (e.data.theme === 'light' || e.data.theme === 'dark') {
2945
- document.documentElement.setAttribute('data-theme', e.data.theme);
2946
- }
2947
- }
2948
- });
2949
- <\/script>`;function Lg(e){return`<script nonce="${e}">
2950
- (function() {
2951
- var iframe = document.querySelector('.present-viewer-iframe');
2952
- if (!iframe) return;
2953
- var sendTheme = function() {
2954
- var theme = document.documentElement.getAttribute('data-theme');
2955
- if (theme && iframe.contentWindow) {
2956
- iframe.contentWindow.postMessage({ type: 'aikit-theme-change', theme: theme }, '*');
2957
- }
2958
- };
2959
- var trySend = function() {
2960
- if (iframe.contentWindow) { sendTheme(); }
2961
- else { document.addEventListener('DOMContentLoaded', sendTheme, { once: true }); }
2962
- };
2963
- var observer = new MutationObserver(sendTheme);
2964
- observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
2965
- iframe.addEventListener('load', sendTheme);
2966
- trySend();
2967
- })();
2968
- <\/script>`}function Rg(e){let t=e.replace(`</head>`,`${Fg}\n</head>`);t===e&&og.warn(`injectEmbeddedViewerRuntime: </head> not found — viewer style not injected`);let n=t.replace(`</body>`,`<script>
2969
- (function() {
2970
- function report() {
2971
- var h = document.documentElement.scrollHeight;
2972
- window.parent.postMessage({ type: 'aikit-viewer-height', height: h }, window.location.origin);
2973
- }
2974
- var ro = new ResizeObserver(report);
2975
- ro.observe(document.documentElement);
2976
- report();
2977
- })();
2978
- <\/script>\n${Ig}\n</body>`);return n===t&&og.warn(`injectEmbeddedViewerRuntime: </body> not found — runtime scripts not injected`),n}function zg(e){let t=`<script>
2979
- (function(){
2980
- var last=0;
2981
- function notify(){
2982
- var h=Math.ceil(document.documentElement.scrollHeight);
2983
- if(h!==last){last=h;window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/size-changed",params:{height:h}},window.location.origin)}
2984
- }
2985
- notify();
2986
- if(typeof ResizeObserver!=="undefined"){new ResizeObserver(notify).observe(document.documentElement)}
2987
- else{setInterval(notify,500)}
2988
- })();
2989
- <\/script>`;return e.includes(`</body>`)?e.replace(`</body>`,`${t}</body>`):`${e}${t}`}let Bg=``;function Vg(e){return`<script${e?` nonce="${J(e)}"`:``}>
2990
- (function(){
2991
- var readyState = document.readyState;
2992
- var boot = function() {
2993
- if (typeof AnnotationInit === 'undefined') return;
2994
- AnnotationInit();
2995
- };
2996
- if (readyState === 'loading') {
2997
- document.addEventListener('DOMContentLoaded', boot, { once: true });
2998
- } else {
2999
- boot();
3000
- }
3001
- })();
3002
- <\/script>`}function Hg(e){Bg=e||``}function Ug(e,t){if(!Bg)return e;let n=`${`<script${t?` nonce="${J(t)}"`:``}>${Bg}<\/script>`}\n${Vg(t||``)}`;return e.includes(`</body>`)?e.replace(`</body>`,`${n}\n</body>`):`${e}${n}`}function Wg(e,t){return[`<!DOCTYPE html>`,`<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">`,`<title>Error — ${J(e)}</title>`,`<style>`,` * { box-sizing: border-box; margin: 0; padding: 0; }`,` body { font-family: system-ui, -apple-system, sans-serif; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 2rem; background: #fafafa; color: #333; }`,` .error-card { max-width: 560px; width: 100%; padding: 2.5rem; border-radius: 1rem; background: #fff; border: 1px solid #e5e7eb; box-shadow: 0 1px 3px rgba(0,0,0,0.06); }`,` .error-badge { display: inline-block; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: #dc2626; background: #fef2f2; border: 1px solid #fecaca; border-radius: 0.375rem; padding: 0.25rem 0.625rem; margin-bottom: 1rem; }`,` .error-title { font-size: 1.25rem; font-weight: 600; margin-bottom: 0.75rem; color: #111; }`,` .error-message { font-size: 0.875rem; line-height: 1.6; color: #6b7280; white-space: pre-wrap; word-break: break-word; }`,`</style></head><body>`,`<div class="error-card">`,` <span class="error-badge">Render Error</span>`,` <h1 class="error-title">${J(e)}</h1>`,` <p class="error-message">${J(t)}</p>`,`</div>`,`</body></html>`].join(`
3003
- `)}function Gg(e,t,n,r){return pg(Wg(r??`Present`,t)),{content:[{type:`text`,text:`[ERROR:VALIDATION] ${t}`}],isError:!0}}function Kg(e,t){if(!vg(e)||!(`schemaVersion`in e))return{ok:!1,response:Gg(`INVALID_CHANNEL_SURFACE`,`present expects a ChannelSurface object with schemaVersion: 1`)};if(e.schemaVersion!==1)return{ok:!1,response:Gg(`UNSUPPORTED_SCHEMA_VERSION`,`Unsupported ChannelSurface schemaVersion: ${String(e.schemaVersion)}`)};if(typeof e.title==`string`&&yg.test(e.title))return{ok:!1,response:Gg(`TITLE_UNICODE_ESCAPE_NOT_ALLOWED`,`Use actual Unicode characters in title, not escape sequences.`)};let n=Array.isArray(e.blocks)?{...e,blocks:e.blocks.flatMap(e=>{if(!vg(e)||e.type!==`markdown`)return[e];let t=Cg(e);return!t||!wg(t)?[e]:Og(e)})}:e;return{ok:!0,surface:n,options:Ag(n,t)}}function qg(e){return(e.actions?.length??0)>0||e.response?.required===!0?_g.getAll().some(e=>e.id===`browser`):!1}async function Jg(e,t={}){let n=qg(e)?{...t,preferBrowser:!0}:t,r=Mg(e),i=_g.select(r,n),a;if(a=i?await i.render(r,n):Qh(r),e.blocks&&e.blocks.length>0&&a.isError!==!0)try{let t=new Set;for(let n of e.blocks){if(typeof n!=`object`||!n)continue;let e=typeof n.type==`string`?n.type:null;e&&!Xp(e)&&t.add(e)}if(t.size>0){let e=[...t].map(e=>`"${e}"`).join(`, `);og.warn(`Unknown block types: ${e}`),a.content=[{type:`text`,text:`[Block type(s) not recognized: ${e}. They rendered as raw text. Use aikit://schemas/channel-surface for supported block types.]`},...a.content]}}catch(e){og.warn(`Block type validation failed`,N(e))}if(t.compact){let{structuredContent:e,...t}=a;return t}return a}function X(e,t=``){return typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`?String(e):t}function Yg(e){return{type:`kv`,value:e}}function Xg(e){if(Array.isArray(e))return e}const Zg=[{name:`summary`,description:`Title + markdown summary + optional metrics (pass/fail counts)`,expand(e){let t=X(e.title,`Summary`),n=[{type:`heading`,value:t}],r=X(e.summary);r&&n.push({type:`markdown`,value:r});let i=Number(e.passed)||0,a=Number(e.failed)||0;if(i>0||a>0){let e=[];i>0&&e.push({label:`Passed`,value:i,status:`success`}),a>0&&e.push({label:`Failed`,value:a,status:`error`}),n.push({type:`metrics`,value:e})}return{title:t,blocks:n}}},{name:`plan`,description:`Title + heading per step + checklist items`,expand(e){let t=X(e.title,`Plan`),n=[{type:`heading`,value:t}],r=Xg(e.steps);return r&&n.push({type:`checklist`,value:{items:r}}),{title:t,blocks:n}}},{name:`understanding`,description:`Title + markdown explanation + kv pairs`,expand(e){let t=X(e.title,`Understanding`),n=[{type:`heading`,value:t}],r=X(e.explanation);return r&&n.push({type:`markdown`,value:r}),e.details&&typeof e.details==`object`&&!Array.isArray(e.details)&&n.push(Yg(e.details)),{title:t,blocks:n}}},{name:`bug-analyze`,description:`Title + heading + severity/status kv + code block + markdown`,expand(e){let t=X(e.title,`Bug Analysis`),n=[{type:`heading`,value:t}],r={};e.severity&&(r.Severity=e.severity),e.status&&(r.Status=e.status),Object.keys(r).length>0&&n.push({type:`kv`,value:r});let i=X(e.code);i&&n.push({type:`code`,value:i});let a=X(e.analysis);return a&&n.push({type:`markdown`,value:a}),{title:t,blocks:n}}},{name:`task-done`,description:`Title + checklist of completed items + optional metrics`,expand(e){let t=X(e.title,`Task Complete`),n=[{type:`heading`,value:t}],r=Xg(e.items);r&&n.push({type:`checklist`,value:{items:r}});let i=e.completed,a=e.total;if(i!==void 0||a!==void 0){let e=[];i!==void 0&&e.push({label:`Completed`,value:Number(i)||i,status:`success`}),a!==void 0&&e.push({label:`Total`,value:Number(a)||a}),n.push({type:`metrics`,value:e})}return{title:t,blocks:n}}},{name:`review`,description:`Title + criteria checklist + annotation items + approval controls`,expand(e){let t=X(e.title,`Review`),n=[{type:`heading`,value:t}],r=Xg(e.criteria);r&&n.push({type:`checklist`,value:{items:r}});let i=e.annotations;Array.isArray(i)&&i.length>0&&n.push({type:`annotation`,value:i});let a=e.approval;return a&&typeof a==`object`?n.push({type:`approval`,value:a}):n.push({type:`actions`,value:[{type:`button`,id:`approve`,label:`Approve`,variant:`primary`},{type:`button`,id:`reject`,label:`Reject`,variant:`danger`}]}),{title:t,blocks:n}}},{name:`explore`,description:`Title + heading per finding + code blocks`,expand(e){let t=X(e.title,`Exploration`),n=[{type:`heading`,value:t}],r=Xg(e.findings);if(r)for(let e of r)n.push({type:`heading`,value:X(e.heading,`Finding`)}),e.code&&n.push({type:`code`,value:e.code});return{title:t,blocks:n}}},{name:`decision`,description:`Title + kv for recommendation + comparison blocks per option`,expand(e){let t=X(e.title,`Decision`),n=[{type:`heading`,value:t}];e.recommendation&&n.push({type:`kv`,value:{Recommendation:e.recommendation}});let r=Xg(e.options);return r&&r.length>0&&n.push({type:`comparison`,value:r.map(e=>({title:X(e.title,`Option`),items:Array.isArray(e.items)?e.items:[]}))}),{title:t,blocks:n}}}],Qg=new Map;for(let e of Zg)Qg.set(e.name,e);function $g(e,t){let n=Qg.get(e);return n?n.expand(t):null}const e_={h:`heading`,m:`markdown`,t:`table`,p:`paragraph`,c:`code`,s:`separator`,M:`metrics`,C:`chart`,T:`timeline`,g:`graph`,tr:`tree`,tl:`timeline`,cl:`checklist`,pr:`progress`,sb:`status-board`,kv:`kv`,ac:`actions`,di:`mermaid`},t_=/^(#{1,6})\s/,n_=/^(`{3,}|~{3,})/,r_=/^\|.+\|.+\|/m;function i_(e){let t=e.trim(),n=t.match(t_);if(n)return{type:`heading`,value:t.slice(n[0].length)};if(n_.test(t)){let e=t.indexOf(`
3004
- `),n=t.lastIndexOf(t[0]);return{type:`code`,value:e>=0?t.slice(e+1,n).trimEnd():t}}return r_.test(t)?{type:`table`,value:t}:{type:`markdown`,value:t}}function a_(e,t){let n=e_[e];if(!n)return null;switch(e){case`M`:return{type:`metrics`,value:t};case`C`:return{type:`chart`,value:t};case`T`:case`tl`:return{type:`timeline`,value:t};case`g`:return{type:`graph`,value:t};case`tr`:return{type:`tree`,value:t};case`cl`:return{type:`checklist`,value:t};case`pr`:return{type:`progress`,value:t};case`sb`:return{type:`status-board`,value:t};case`kv`:return{type:`kv`,value:t};case`ac`:return{type:`actions`,value:t};case`di`:return{type:`mermaid`,value:t};case`s`:return{type:`separator`,value:t||!0};default:return{type:n,value:typeof t==`string`?t:String(t??``)}}}function o_(e){if(typeof e==`string`){let t=i_(e);return{type:t.type,value:t.value}}if(Array.isArray(e)){let[t,n]=e;if(typeof t==`string`){let e=a_(t,n);if(e)return e}return{type:`markdown`,value:String(t??``)}}if(typeof e==`object`&&e){let{blockId:t,...n}=e;return n}return{type:`markdown`,value:String(e??``)}}function s_(e){return{title:e.title??``,blocks:Array.isArray(e.blocks)?e.blocks.map(o_):[]}}function c_(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function l_(e){return c_(e)&&typeof e.schemaVersion==`number`&&e.schemaVersion===1}function u_(e){return c_(e)&&typeof e.schemaVersion==`number`&&e.schemaVersion!==1}function d_(e){return e.schemaVersion===1?typeof e.title!=`string`||e.title.length===0?{ok:!1,error:{code:`MISSING_TITLE`,reason:`ChannelSurface requires a non-empty title`}}:e.blocks!==void 0&&!Array.isArray(e.blocks)?{ok:!1,error:{code:`INVALID_BLOCKS`,reason:`blocks must be an array of TypedBlock objects`}}:{ok:!0,surface:e}:{ok:!1,error:{code:`UNSUPPORTED_SCHEMA_VERSION`,reason:`Unsupported schemaVersion: ${String(e.schemaVersion)}`}}}function f_(e){try{let t=re(e);return c_(t)?(t.schemaVersion===void 0&&(t.schemaVersion=1),p_(t)):{ok:!1,error:{code:`INVALID_RAW_INPUT`,reason:`raw field must contain a JSON object (ChannelSurface)`}}}catch(e){return{ok:!1,error:{code:`INVALID_RAW_JSON`,reason:`Failed to parse raw field: ${e.message}`,hint:`JSON repair attempted. Ensure the raw string contains a valid ChannelSurface object. Common LLM errors (newlines in strings, trailing commas) are auto-repaired.`}}}}function p_(e){if(Array.isArray(e)){if(e.length!==2)return{ok:!1,error:{code:`INVALID_PRESET_INPUT`,reason:`Preset input must be a [name, data] tuple`,hint:`Use [presetName, { title, ...fields }]`}};let[t,n]=e;if(typeof t!=`string`)return{ok:!1,error:{code:`INVALID_PRESET_INPUT`,reason:`Preset name must be a string`}};if(!c_(n))return{ok:!1,error:{code:`INVALID_PRESET_INPUT`,reason:`Preset data must be an object`}};let r=$g(t,n);return r?{ok:!0,surface:{schemaVersion:1,title:r.title,blocks:r.blocks}}:{ok:!1,error:{code:`UNKNOWN_PRESET`,reason:`Unknown preset: ${t}`,hint:`Available presets: summary, plan, understanding, bug-analyze, task-done, review, explore, decision`}}}if(u_(e))return{ok:!1,error:{code:`UNSUPPORTED_SCHEMA_VERSION`,reason:`Unsupported schemaVersion: ${String(e.schemaVersion)}`,hint:`Use schemaVersion: 1`}};if(c_(e)&&typeof e.raw==`string`)return f_(e.raw);if(l_(e))return d_(e);if(typeof e==`string`){let t=s_({blocks:[e]});return{ok:!0,surface:{schemaVersion:1,title:t.title||`Present`,blocks:t.blocks}}}if(c_(e)){if(!(`blocks`in e)&&!(`title`in e))return{ok:!1,error:{code:`INVALID_INPUT`,reason:`Expected a ChannelSurface object, preset tuple, or shorthand input`}};let t=s_(e);return{ok:!0,surface:{schemaVersion:1,title:t.title||`Present`,blocks:t.blocks}}}return{ok:!1,error:{code:`INVALID_INPUT`,reason:`Expected a ChannelSurface object, preset tuple, or shorthand input`}}}const m_=R.object({label:R.string(),value:R.string(),description:R.string().optional()}),h_=R.object({id:R.string().describe(`Unique action identifier`),type:R.enum([`button`,`select`,`multi-select`,`form-submit`,`text-submit`,`confirm`,`custom`]).describe(`Interactive action type`),label:R.string().describe(`Visible action label`),variant:R.enum([`primary`,`danger`,`default`]).optional(),options:R.array(m_).optional(),schema:R.record(R.string(),R.unknown()).optional()}),g_=R.object({type:R.string(),title:R.string().optional(),value:R.unknown().optional(),language:R.string().optional()}).catchall(R.unknown()),__={schemaVersion:R.literal(1).describe(`ChannelSurface schema version. Must be 1.`),title:R.string().describe(`Surface title shown to the user.`),description:R.string().optional().describe(`Optional supporting copy for the surface.`),template:R.string().optional().describe(`Optional template id such as report@1.`),layout:R.object({maxWidth:R.string().optional(),padding:R.string().optional(),columns:R.number().optional()}).optional(),blocks:R.array(g_).optional().describe(`Typed block content for the surface.`),data:R.unknown().optional().describe(`Template data payload, if the template expands data.`),actions:R.array(h_).optional().describe(`Interactive actions. Presence triggers browser transport.`),response:R.object({timeout:R.number().optional(),required:R.boolean().optional()}).optional(),metadata:R.object({surfaceId:R.string().optional(),createdAt:R.string().optional(),source:R.string().optional()}).optional(),colorScheme:R.enum([`light`,`dark`,`auto`]).optional(),lang:R.string().optional(),dir:R.enum([`ltr`,`rtl`,`auto`]).optional(),raw:R.string().optional().describe(`Raw JSON string with auto-repair. Accepts common LLM JSON errors (unescaped newlines in strings, trailing commas). Use for complex payloads with mermaid/code/markdown blocks.`),preferBrowser:R.boolean().optional().default(!0).describe(`Prefer browser transport instead of inline rendering. Default: true — most clients render in an external browser window. Set preferBrowser: false to request inline/embedded rendering (only honored when the client supports inline display; auto-falls back to browser if not).`)};R.object({surfaceId:R.string(),actionId:R.string(),actionType:R.enum([`button`,`select`,`multi-select`,`form-submit`,`text-submit`,`confirm`,`custom`]),value:R.unknown().optional(),formData:R.record(R.string(),R.unknown()).optional(),selection:R.union([R.string(),R.array(R.string())]).optional(),label:R.string().optional(),timestamp:R.string(),sourceTransport:R.enum([`mcp-app`,`browser`,`export`])});function v_(e){let t=e.server?.getClientCapabilities?.();if(!t)return`unknown`;let n=vr(t);return!n||Array.isArray(n.mimeTypes)&&n.mimeTypes.length>0&&!n.mimeTypes.includes(_r)?`unsupported`:`supported`}const y_=[{name:`summary`,description:`Title + markdown summary + optional metrics (pass/fail counts)`,inputSchema:{type:`object`,properties:{title:{type:`string`,description:`Section heading`},summary:{type:`string`,description:`Free-form markdown summary`},passed:{type:`number`,description:`Pass count for metrics`},failed:{type:`number`,description:`Fail count for metrics`}},required:[`title`]},example:JSON.stringify({title:`Build Summary`,summary:`All tests passed.`,passed:42,failed:0}),expandsTo:`blocks: [heading, markdown, metrics]`},{name:`plan`,description:`Title + heading per step + checklist items`,inputSchema:{type:`object`,properties:{title:{type:`string`},steps:{type:`array`,items:{type:`object`,properties:{label:{type:`string`},checked:{type:`boolean`}}}}},required:[`title`]},example:JSON.stringify({title:`Sprint Plan`,steps:[{label:`Write tests`,checked:!1},{label:`Deploy`,checked:!1}]}),expandsTo:`blocks: [heading, checklist]`},{name:`understanding`,description:`Title + markdown explanation + kv pairs`,inputSchema:{type:`object`,properties:{title:{type:`string`},explanation:{type:`string`},details:{type:`object`,additionalProperties:{type:`string`}}},required:[`title`,`explanation`]},example:JSON.stringify({title:`Architecture Overview`,explanation:`The system uses microservices.`,details:{Language:`TypeScript`,Runtime:`Node`}}),expandsTo:`blocks: [heading, markdown, kv]`},{name:`bug-analyze`,description:`Title + heading + severity/status kv + code block + markdown`,inputSchema:{type:`object`,properties:{title:{type:`string`},severity:{type:`string`},status:{type:`string`},code:{type:`string`},analysis:{type:`string`}},required:[`title`,`severity`,`status`]},example:JSON.stringify({title:`Null pointer in auth`,severity:`high`,status:`open`,code:`const x = obj.prop;`,analysis:`obj may be null when token missing.`}),expandsTo:`blocks: [heading, kv, code, markdown]`},{name:`task-done`,description:`Title + checklist of completed items + optional metrics`,inputSchema:{type:`object`,properties:{title:{type:`string`},items:{type:`array`,items:{type:`object`,properties:{label:{type:`string`},checked:{type:`boolean`}}}},completed:{type:`number`},total:{type:`number`}},required:[`title`,`items`]},example:JSON.stringify({title:`PR #42 Done`,items:[{label:`Lint pass`,checked:!0},{label:`Tests pass`,checked:!0}],completed:2,total:2}),expandsTo:`blocks: [heading, checklist, metrics]`},{name:`review`,description:`Title + criteria checklist + approval actions`,inputSchema:{type:`object`,properties:{title:{type:`string`,description:`Review title`},criteria:{type:`array`,description:`Checklist criteria items`,items:{type:`object`,properties:{label:{type:`string`},checked:{type:`boolean`}}}},annotations:{type:`array`,description:`Optional annotation items`,items:{type:`object`,properties:{label:{type:`string`},description:{type:`string`},severity:{type:`string`}}}},approval:{type:`object`,description:`Optional approval config`,properties:{prompt:{type:`string`},options:{type:`array`,items:{type:`object`,properties:{label:{type:`string`},value:{type:`string`}}}}}}},required:[`title`,`criteria`]},example:JSON.stringify({title:`Code Review`,criteria:[{label:`Tests included`,checked:!0},{label:`No regressions`,checked:!1}]}),expandsTo:`blocks: [heading, checklist] + actions: [approve, reject]`},{name:`explore`,description:`Title + heading per finding + code blocks`,inputSchema:{type:`object`,properties:{title:{type:`string`},findings:{type:`array`,items:{type:`object`,properties:{heading:{type:`string`},code:{type:`string`}}}}},required:[`title`,`findings`]},example:JSON.stringify({title:`Codebase Exploration`,findings:[{heading:`Auth flow`,code:`function login()`},{heading:`API routes`,code:`router.get("/api")`}]}),expandsTo:`blocks: [heading, code] per finding`},{name:`decision`,description:`Title + kv for recommendation + comparison blocks per option`,inputSchema:{type:`object`,properties:{title:{type:`string`},recommendation:{type:`string`},options:{type:`array`,items:{type:`object`,properties:{title:{type:`string`},items:{type:`array`,items:{type:`string`}}}}}},required:[`title`,`recommendation`]},example:JSON.stringify({title:`DB Choice`,recommendation:`PostgreSQL`,options:[{title:`Postgres`,items:[`ACID`,`Rich types`]},{title:`Mongo`,items:[`Schema-less`,`Horizontal`]}]}),expandsTo:`blocks: [heading, kv, comparison]`}];function b_(e,t){let n=U(`present`);try{let e=w(`present`);e&&Hg(F(L(e,`dist`,`annotation-layer.js`),`utf8`))}catch{}br(e,`present`,{title:n.title,description:"Render a ChannelSurface. Required: schemaVersion: 1, title. Supports blocks, template+data, named presets, and raw JSON string with auto-repair. Use `raw` for complex payloads (mermaid, code, many blocks) — common LLM JSON errors are auto-fixed. IMPORTANT: when using `raw`, do NOT pass `schemaVersion` or `title` at the top level — the `raw` JSON must be a self-contained ChannelSurface with its own `schemaVersion: 1`, `title`, and `blocks`. preferBrowser defaults to true (browser rendering). Set preferBrowser: false explicitly when you want inline — only honored if the client supports it; auto-falls back to browser otherwise. Actions always use browser transport. Resources: aikit://schemas/channel-surface (schema+blocks), aikit://present/presets (presets), aikit://present/templates (viewers).",inputSchema:__,annotations:n.annotations,_meta:Jh(ag)},q(`present`,async(t,n)=>{let r=t,i=typeof r.preferBrowser==`boolean`?r.preferBrowser:void 0,a=p_(t);if(!a.ok)return Gg(a.error.code,a.error.reason,void 0,`Present`);let o=Kg(a.surface,n);if(!o.ok)return o.response;let s=v_(e),c=!(i===!1&&s===`supported`);return await Jg(o.surface,{...o.options,preferBrowser:c})}));try{let t=new qn(ag,{list:void 0});e.registerResource(`Present View`,t,{description:`AI Kit present tool viewer`},async(e,t,n)=>{let r=Array.isArray(t.id)?t.id[0]:t.id,i=r?hg(r):void 0;return{contents:[{uri:e.href,mimeType:_r,_meta:Yh(),text:i??fg()??`<html><body><p>No content generated yet. Call the present tool first.</p></body></html>`}]}})}catch{}function r(){try{let e=w(`present`);if(e)return F(L(e,`dist`,`index.html`),`utf8`)}catch{}return fg()||`<html><body><p>Loading...</p></body></html>`}try{e.registerResource(`Present App`,ig,{description:`AI Kit present app - entry point`},async()=>({contents:[{uri:ig,mimeType:_r,_meta:Yh(),text:r()}]}))}catch{}try{e.registerResource(`present-templates`,`aikit://present/templates`,{description:`List all registered present viewer templates with their input schemas`},async()=>{let e=rm().map(e=>({id:e.id,label:e.label,description:e.description,transports:e.supportedTransports,inputSchema:e.inputSchema}));return{contents:[{uri:`aikit://present/templates`,mimeType:`application/json`,text:JSON.stringify(e,null,2)}]}})}catch{}try{e.registerResource(`present-presets`,`aikit://present/presets`,{description:`List all registered present presets with input schemas and examples`},async()=>({contents:[{uri:`aikit://present/presets`,mimeType:`application/json`,text:JSON.stringify(y_,null,2)}]}))}catch{}}const x_=M(`tools`);function S_(e,t){let n=new ir({structure:new or,dependencies:new tr,symbols:new sr,patterns:new ar,entryPoints:new rr,diagrams:new nr}),r=U(`produce_knowledge`);e.registerTool(`produce_knowledge`,{title:r.title,description:`Run automated codebase analysis and produce synthesis instructions. Executes Tier 1 deterministic analyzers, then returns structured baselines and instructions for you to synthesize knowledge using remember.`,inputSchema:{scope:R.string().optional().describe(`Root path to analyze (defaults to workspace root)`),aspects:R.array(R.enum([`all`,`structure`,`dependencies`,`symbols`,`patterns`,`entry-points`,`diagrams`])).default([`all`]).describe(`Which analysis aspects to run`)},annotations:r.annotations},q(`produce_knowledge`,async({scope:e,aspects:t},r)=>{let i;try{i=ol(r).createTask(`Produce Knowledge`,3),i.progress(0,`Running analyzers`);let a=e??`.`;x_.info(`Running knowledge production`,{rootPath:a,aspects:t});let o=await n.runExtraction(a,t);try{let e=I(Sn(L(a)),fe.onboard);Ae(e,{recursive:!0});let t=`<!-- Generated by produce_knowledge at ${new Date().toISOString()} -->\n\n`;for(let[n,r]of Object.entries(o))r&&typeof r==`string`&&Ie(I(e,`${n}.md`),t+r,`utf-8`);x_.info(`Knowledge persisted to .ai/context/`,{files:Object.keys(o).length})}catch(e){x_.warn(`Failed to persist knowledge to .ai/context/`,{error:N(e)})}i.progress(1,`Synthesizing results`);let s=n.buildSynthesisInstructions(o,t);return i.complete(`Knowledge production complete`),{content:[{type:`text`,text:s+`
3005
-
3006
- ---
3007
- _Next: Review the baselines above and use \`remember\` to store synthesized knowledge entries._`}]}}catch(e){return i?.fail?.(`Production failed`),x_.error(`Knowledge production failed`,N(e)),K(`INTERNAL`,`Knowledge production failed: ${e instanceof Error?e.message:String(e)}`)}}))}const C_=M(`tools`);function w_(e,t,n,r,i,a,o){let s=U(`reindex`);e.registerTool(`reindex`,{title:s.title,description:`Trigger re-indexing of the AI Kit index. Can do incremental (only changed files) or full re-index. When smart indexing is active, use force: true to override the automatic trickle indexer.`,inputSchema:{full:R.boolean().default(!1).describe(`If true, force full re-index ignoring file hashes`),force:R.boolean().default(!1).describe(`If true, override smart indexing guard and run reindex anyway`)},annotations:s.annotations},q(`reindex`,async({full:e,force:s},c)=>{try{if(t.isIndexing)return{content:[{type:`text`,text:`## Reindex Already in Progress
3008
-
3009
- A reindex operation is currently running. Search and other tools continue to work with existing data. Use \`status({})\` to check when it completes.`}]};if(o===`smart`&&!s)return{content:[{type:`text`,text:`## Smart Indexing Active
3010
-
3011
- Smart indexing (trickle mode) is enabled — files are automatically indexed as they are accessed by tools. Manual reindex is not needed.
3012
-
3013
- **If the index is severely outdated**, use \`reindex({ force: true })\` to override.
3014
-
3015
- Use \`status({})\` to check smart indexing queue status.`}]};let l=ol(c).createTask(`Reindex`,1);l.progress(0,`Starting ${e?`full`:`incremental`} reindex`),C_.info(`Starting background re-index`,{mode:e?`full`:`incremental`});let u=e=>t=>{t.phase===`chunking`&&t.currentFile&&C_.debug(`Re-index progress`,{prefix:e,current:t.filesProcessed+1,total:t.filesTotal,file:t.currentFile})};return(e?t.reindexAll(n,u(`Reindex`)):t.index(n,u(`Index`))).then(async e=>{if(C_.info(`Background re-index complete`,{filesProcessed:e.filesProcessed,chunksCreated:e.chunksCreated,durationMs:e.durationMs}),l.complete(`Reindex complete: ${e.filesProcessed} files, ${e.chunksCreated} chunks in ${e.durationMs}ms`),i)try{await i.createFtsIndex(),C_.info(`FTS index rebuilt after reindex`)}catch(e){C_.warn(`FTS index rebuild failed`,N(e))}try{let e=await r.reindexAll();C_.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){C_.warn(`Curated re-index failed`,N(e))}if(a)try{await a.notifyAfterReindex()}catch(e){C_.warn(`Post-reindex resource notification failed`,N(e))}}).catch(e=>{l.fail(`Reindex failed: ${e instanceof Error?e.message:String(e)}`),C_.error(`Background reindex failed`,N(e))}),{content:[{type:`text`,text:`## Reindex Started (Background)\n\n- **Mode**: ${e?`Full`:`Incremental`}\n- Search and other tools continue to work with existing data during reindex.\n- Completion will be logged. Use \`status({})\` to check index stats afterward.\n\n---\n_Next: Continue working — the reindex runs in the background._`}]}}catch(e){return C_.error(`Reindex failed`,N(e)),K(`INTERNAL`,`Reindex failed: ${e instanceof Error?e.message:String(e)}`)}}))}const T_=M(`tools`);function E_(e){let t=U(`replay`);e.registerTool(`replay`,{title:t.title,description:`View or clear the audit trail of recent MCP tool and CLI invocations. Shows tool name, duration, status, and input/output summaries.`,inputSchema:{action:R.enum([`list`,`clear`]).default(`list`).describe(`Action: "list" (default) to view entries, "clear" to wipe the log`),last:R.number().optional().describe(`Number of entries to return (default: 20, list only)`),tool:R.string().optional().describe(`Filter by tool name (list only)`),source:R.enum([`mcp`,`cli`]).optional().describe(`Filter by source: "mcp" or "cli" (list only)`),since:R.string().optional().describe(`ISO timestamp — only show entries after this time (list only)`)},annotations:t.annotations},q(`replay`,async({action:e,last:t,tool:n,source:r,since:i})=>{try{if(e===`clear`)return _n(),{content:[{type:`text`,text:`Replay log cleared.`}]};let a=vn({last:t,tool:n,source:r,since:i});if(a.length===0)return{content:[{type:`text`,text:`No replay entries found. Activity is logged when tools are invoked via MCP or CLI.`}]};let o=a.map(e=>`${e.ts.split(`T`)[1]?.split(`.`)[0]??e.ts} ${e.status===`ok`?`✓`:`✗`} ${e.tool} (${e.durationMs}ms) [${e.source}]\n in: ${e.input}\n out: ${e.output}`);return yn().catch(()=>{}),{content:[{type:`text`,text:`**Replay Log** (${a.length} entries)\n\n${o.join(`
3016
-
3017
- `)}`}]}}catch(e){return T_.error(`Replay failed`,N(e)),K(`INTERNAL`,`Replay failed: ${e instanceof Error?e.message:String(e)}`)}}))}const D_=M(`tools`);function O_(e){let t=U(`restore`);e.registerTool(`restore`,{title:t.title,description:`List and restore file snapshots taken before destructive operations (codemod, rename, forget). Use action=list to see available restore points, action=restore with an id to undo.`,inputSchema:{action:R.enum([`list`,`restore`]).describe(`list: show restore points, restore: apply a restore point`),id:R.string().optional().describe(`Restore point ID (required for action=restore)`),limit:R.number().min(1).max(50).default(10).describe(`Max restore points to list`)},annotations:t.annotations},async({action:e,id:t,limit:n})=>{try{if(e===`list`){let e=qt().slice(0,n);return e.length===0?{content:[{type:`text`,text:`No restore points found.`}]}:{content:[{type:`text`,text:`## Restore Points\n\n${e.map(e=>`- **${e.id}** (${e.timestamp}) — ${e.operation}: ${e.description} (${e.files.length} files)`).join(`
3018
- `)}`}]}}if(!t)throw Error(`id is required for restore action`);let r=await Cn(t);return{content:[{type:`text`,text:`Restored ${r.length} files:\n${r.map(e=>`- \`${e}\``).join(`
3019
- `)}`}]}}catch(e){return D_.error(`Restore failed`,N(e)),K(`INTERNAL`,`Restore failed: ${e instanceof Error?e.message:String(e)}`)}})}const k_=/<\/?curated-context>/gi;function A_(e){return e.replace(k_,``)}function j_(e){return`<curated-context>\n${A_(e)}\n</curated-context>`}const M_=M(`tools`);function N_(e,t,n,r){b(e,t,n);let i=e.memoryMetaGet(t);if(!i)return;let a=g(i,{..._,...r});a&&(y(e,t,a),v(e,t,n))}function P_(e,t){let n=[],r=De(),i=r?Le(r):``;i&&n.push(`[project: ${i}]`);let a=t?Mn(t,`__context_boost`):void 0;return a&&n.push(`[focus: ${a.value}]`),n.length===0?e:`${n.join(` `)} ${e}`}function F_(e,t,n){return n?e:t===`curated`?e*1.2:e}function I_(e,t){return t?e:e.map(e=>({record:e.record,score:F_(e.score,e.record.origin,t)})).sort((e,t)=>t.score-e.score)}function L_(e,t){let n=e?Math.floor(e/Math.max(1,t)):96;return Math.max(40,Math.min(160,n))}function R_(e,t){let n=e.origin===`curated`?j_(e.content):e.content,r=Bn(n,t);return{body:r,truncated:r!==n}}async function z_(e,t,n,r,i){if(!e||t>=e.config.fallbackThreshold&&n.length>0)return{results:n,triggered:!1,cacheHit:!1};let a=!1;try{let t=e.cache.get(r);return t?a=!0:(t=await e.client.search(r,i),t.length>0&&e.cache.set(r,t)),t.length>0?{results:gr(n,t,i).map(e=>({record:{id:`er:${e.sourcePath}`,content:e.content,sourcePath:e.source===`er`?`[ER] ${e.sourcePath}`:e.sourcePath,startLine:e.startLine??0,endLine:e.endLine??0,contentType:e.contentType??`documentation`,headingPath:e.headingPath,origin:e.source===`er`?`curated`:e.origin??`indexed`,category:e.category,tags:e.tags??[],chunkIndex:0,totalChunks:1,fileHash:``,indexedAt:new Date().toISOString(),version:1},score:e.score})),triggered:!0,cacheHit:a}:{results:n,triggered:!0,cacheHit:a}}catch(e){return M_.warn(`ER fallback failed`,N(e)),{results:n,triggered:!0,cacheHit:a}}}function B_(e,t,n=60){let r=new Map,i=e[0]?.score||1,a=t[0]?.score||1;for(let t=0;t<e.length;t++){let a=e[t],o=a.score/i;r.set(a.record.id,{record:a.record,score:1/(n+t+1)*o})}for(let e=0;e<t.length;e++){let i=t[e],o=i.score/a,s=r.get(i.record.id);s?s.score+=1/(n+e+1)*o:r.set(i.record.id,{record:i.record,score:1/(n+e+1)*o})}return[...r.values()].sort((e,t)=>t.score-e.score).map(({record:e,score:t})=>({record:e,score:t*(n+1)}))}function V_(e,t){let n=t.toLowerCase().split(/\s+/).filter(e=>e.length>=2);return n.length<2?e:e.map(e=>{let t=e.record.content.toLowerCase();if(t.length>5e3)return e;let r=n.map(e=>{let n=[],r=t.indexOf(e);for(;r!==-1&&n.length<10;)n.push(r),r=t.indexOf(e,r+1);return n});if(r.some(e=>e.length===0))return e;let i=t.length;for(let e of r[0]){let t=e,a=e+n[0].length;for(let i=1;i<r.length;i++){let o=r[i][0],s=Math.abs(o-e);for(let t=1;t<r[i].length;t++){let n=Math.abs(r[i][t]-e);n<s&&(s=n,o=r[i][t])}t=Math.min(t,o),a=Math.max(a,o+n[i].length)}i=Math.min(i,a-t)}let a=1+.25/(1+i/200);return{record:e.record,score:e.score*a}}).sort((e,t)=>t.score-e.score)}function H_(e){if(e.length<=1)return e;let t=new Set;return e.filter(e=>{let n=e.record.contentHash;return n?t.has(n)?!1:(t.add(n),!0):!0})}function U_(e,t,n=8){let r=new Set(t.toLowerCase().split(/\s+/).filter(e=>e.length>=2)),i=new Map,a=e.length;for(let t of e){let e=t.record.content.split(/[^a-zA-Z0-9_]+/).filter(e=>e.length>=3&&!W_.has(e.toLowerCase())),n=new Set;for(let t of e){let e=t.toLowerCase();/[_A-Z]/.test(t)&&i.set(`__id__${e}`,1),n.has(e)||(n.add(e),i.set(e,(i.get(e)??0)+1))}}let o=[];for(let[e,t]of i){if(e.startsWith(`__id__`)||r.has(e)||t>a*.8)continue;let n=Math.log(a/t),s=+!!i.has(`__id__${e}`),c=e.length>8?.5:0;o.push({term:e,score:n+s+c})}return o.sort((e,t)=>t.score-e.score).slice(0,n).map(e=>e.term)}const W_=new Set(`the.and.for.are.but.not.you.all.can.had.her.was.one.our.out.has.have.from.this.that.with.they.been.said.each.which.their.will.other.about.many.then.them.these.some.would.make.like.into.could.time.very.when.come.just.know.take.people.also.back.after.only.more.than.over.such.import.export.const.function.return.true.false.null.undefined.string.number.boolean.void.type.interface`.split(`.`));async function G_(e,t){try{let n=await e.getStats();if(!n.lastIndexedAt)return;let r=new Date(n.lastIndexedAt).getTime(),i=Date.now(),a=[...new Set(t.map(e=>e.record.sourcePath))].filter(e=>!e.startsWith(`[ER]`)).slice(0,5);if(a.length===0)return;let o=0;for(let e of a)try{(await Ke(e)).mtimeMs>r&&o++}catch{o++}if(o>0){let e=i-r,t=Math.floor(e/6e4),n=t<1?`<1 min`:`${t} min`;return`> ⚠️ **Index may be stale** — ${o} file(s) modified since last index (${n} ago). Use \`reindex\` to refresh.`}}catch{}}function K_(e,t,n,r,i,a,o,s,c,l,u){let d=U(`search`);e.registerTool(`search`,{title:d.title,description:`Search AI Kit for code, docs, and prior decisions. Default choice for discovery. Modes: hybrid (default), semantic, keyword. For multi-strategy precision queries use find; for a known file path use lookup.`,outputSchema:lc,inputSchema:{query:R.string().max(5e3).describe(`Natural language search query`),limit:R.number().min(1).max(20).default(5).describe(`Maximum results to return`),search_mode:R.enum([`hybrid`,`semantic`,`keyword`]).default(`hybrid`).describe(`Search strategy: hybrid (vector + FTS + RRF fusion, default), semantic (vector only), keyword (FTS only)`),content_type:R.enum(pe).optional().describe(`Filter by content type`),source_type:R.enum(A).optional().describe(`Coarse filter: "source" (code only), "documentation" (md, curated), "test", "config". Overrides content_type if both set.`),origin:R.enum(ve).optional().describe(`Filter by knowledge origin`),category:R.string().optional().describe(`Filter by category (e.g., decisions, patterns, conventions)`),tags:R.array(R.string()).optional().describe(`Filter by exact tag membership (any supplied tag may match)`),min_score:R.number().min(0).max(1).default(.25).describe(`Minimum similarity score`),graph_hops:R.number().min(0).max(3).default(1).describe(`Number of graph hops to augment results with connected entities (0 = disabled, 1 = direct connections, 2-3 = deeper traversal). Default 1 provides module/symbol context automatically.`),max_tokens:R.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`),min_confidence:R.enum([`extracted`,`inferred`,`ambiguous`]).optional().describe(`Minimum confidence level for results: "extracted" (guaranteed correct from source code), "inferred" (LLM-derived), "ambiguous" (uncertain, needs verification). Lower values include more results.`),dedup:R.enum([`file`,`chunk`]).default(`chunk`).describe(`Deduplication mode: "chunk" (default, show all matching chunks) or "file" (collapse chunks from same file into single result with merged line ranges)`),workspaces:R.array(R.string()).optional().describe(`Cross-workspace search: partition names or folder basenames to include. Use ["*"] for all registered workspaces. Only works in user-level install mode.`)},annotations:d.annotations},async({query:e,limit:d,search_mode:f,content_type:p,source_type:m,origin:h,category:g,tags:_,min_score:v,min_confidence:y,graph_hops:b,max_tokens:x,dedup:S,workspaces:C})=>{let w=Date.now();try{let T={limit:d,minScore:v,contentType:p,sourceType:m,origin:h,category:g,tags:_},E,D=!1,O=!1,k=``,ee=f!==`keyword`,te=P_(e,s);if(f===`keyword`)E=await n.ftsSearch(e,T),E=E.slice(0,d);else if(f===`semantic`)try{let r=await t.embedQuery(te);E=await n.search(r,T);let a=await z_(i,E[0]?.score??0,E,e,d);E=a.results,D=a.triggered,O=a.cacheHit}catch(t){ee=!1,M_.warn(`Embedder unavailable in semantic mode, falling back to FTS`,N(t)),E=await n.ftsSearch(e,{...T,limit:d}),k=`> _⚠️ Semantic search unavailable (embedder recovering). Showing keyword results instead._
3020
-
3021
- `}else{let r=[],a=[];try{let i=await t.embedQuery(te),o=n.coarseSearch,s=o?o.bind(n):n.search.bind(n);[r,a]=await Promise.all([s(i,{...T,limit:d*2}),n.ftsSearch(e,{...T,limit:d*2}).catch(()=>[])])}catch(t){ee=!1,M_.warn(`Embedder unavailable, falling back to FTS-only`,N(t)),a=await n.ftsSearch(e,{...T,limit:d*2}),k=`> _⚠️ Vector search unavailable (embedder recovering). Results from keyword search only._
3022
-
3023
- `}if(ee?r.length===0&&a.length>0?(E=a.slice(0,d),k=` (FTS-only: vector index rebuilding)`):E=a.length===0&&r.length>0?r.slice(0,d):B_(r,a).slice(0,d):E=a.slice(0,d),ee){let t=await z_(i,r[0]?.score??0,E,e,d);E=t.results,D=t.triggered,O=t.cacheHit}}E=I_(E,h).slice(0,d),a&&a.recordSearch(e,D,O),E.length>1&&(E=V_(E,e)),E=H_(E);let ne=``;if(C&&C.length>0){let n=Ll(C,u);if(n.length>0){let{stores:r,closeAll:i}=await Rl(n);try{let i;i=f===`keyword`||!ee?await Bl(r,e,{...T,limit:d}):await zl(r,await t.embedQuery(e),{...T,limit:d});for(let e of i)E.push({record:{...e.record,sourcePath:`[${e.workspace}] ${e.record.sourcePath}`},score:e.score});E=E.sort((e,t)=>t.score-e.score).slice(0,d),ne=` + ${n.length} workspace(s)`}finally{await i()}}}if(S===`file`&&E.length>1){let e=new Map;for(let t of E){let n=t.record.sourcePath,r=e.get(n);r?(t.score>r.best.score&&(r.best=t),r.ranges.push({start:t.record.startLine,end:t.record.endLine})):e.set(n,{best:t,ranges:[{start:t.record.startLine,end:t.record.endLine}]})}E=[...e.values()].sort((e,t)=>t.best.score-e.best.score).map(({best:e,ranges:t})=>({record:{...e.record,content:t.length>1?`${e.record.content}\n\n_Matched ${t.length} sections: ${t.sort((e,t)=>e.start-t.start).map(e=>`L${e.start}-${e.end}`).join(`, `)}_`:e.record.content},score:e.score}))}if(E.length>1){let e=E[0].score,t=Math.max(e*.4,.1);E=E.filter(e=>e.score>=t)}let re={extracted:3,inferred:2,ambiguous:1};if(y){let e=re[y]??0;E=E.filter(t=>(t.record.confidence?re[t.record.confidence]??2:2)>=e)}if(E.length===0){if(o?.available)try{let r=(await o.createMessage({prompt:`The search query "${e}" returned 0 results in AI Kit code search. Suggest ONE alternative search query that might find relevant results. Reply with ONLY the alternative query, nothing else.`,systemPrompt:`You are a search query optimizer for AI Kit code search. Generate a single alternative query.`,maxTokens:100,timeoutMs:1e4})).text.trim().split(`
3024
- `)[0].slice(0,500);if(r&&r!==e){let i=f===`keyword`||!ee?await n.ftsSearch(r,T):await n.search(await t.embedQuery(r),T);i.length>0&&(E=i,k=`> _Original query "${e}" returned 0 results. Auto-reformulated to "${r}"._\n\n`,M_.debug(`Smart search fallback succeeded`,{originalQuery:e,altQuery:r,resultCount:i.length}))}}catch(e){M_.debug(`Smart search fallback failed`,{error:String(e)})}if(E.length===0){let t=yt({text:`No results found for the given query.`,query:e,searchMode:f,limit:d,results:[],durationMs:Date.now()-w}),n=Vl(t.summary);return{content:[{type:`text`,text:Hl(t.summary,n)}],isError:!t.ok,structuredContent:{...t.data??{results:[],totalResults:0,searchMode:f,query:e},ref:n}}}}let ie,ae;if(b>0&&!r&&(ae="> **Note:** `graph_hops` was set but no graph store is available. Graph augmentation skipped."),b>0&&r)try{let e=await Lt(r,E.map(e=>({recordId:e.record.id,score:e.score,sourcePath:e.record.sourcePath})),{hops:b,maxPerHit:5});ie=new Map;for(let t of e)if(t.graphContext.nodes.length>0){let e=t.graphContext.nodes.slice(0,5).map(e=>` - **${e.name}** (${e.type})`).join(`
3025
- `),n=new Map;for(let e of t.graphContext.nodes)n.set(e.id,e.name);let r=t.graphContext.edges.slice(0,5).map(e=>` - ${n.get(e.fromId)??e.fromId} —[${e.type}]→ ${n.get(e.toId)??e.toId}`).join(`
3026
- `),i=[`- **Graph Context** (${b} hop${b>1?`s`:``}):`];e&&i.push(` Entities:\n${e}`),r&&i.push(` Relationships:\n${r}`),ie.set(t.recordId,i.join(`
3027
- `))}}catch(e){M_.warn(`Graph augmentation failed`,N(e)),ae=`> **Note:** Graph augmentation failed. Results shown without graph context.`}let oe=Date.now();for(let e of E)if(e.record.origin===`curated`&&e.record.indexedAt){let t=oe-new Date(e.record.indexedAt).getTime(),n=Math.max(0,t/864e5);e.score*=.95**n}if(E.sort((e,t)=>t.score-e.score),E=it(E),s)for(let e of E){if(e.record.origin!==`curated`)continue;let t=Ed(e.record.sourcePath);t&&N_(s,t,c,l)}let se=L_(x,E.length),ce=!1,le=E.map((e,t)=>{let n=e.record,r=`### Result ${t+1} (score: ${e.score.toFixed(3)})`,i=[`- **Source**: ${n.sourcePath}`,n.headingPath?`- **Section**: ${n.headingPath}`:null,`- **Type**: ${n.contentType}`,n.startLine?`- **Lines**: ${n.startLine}-${n.endLine}`:null,n.origin===`indexed`?null:`- **Origin**: ${n.origin}`,n.category?`- **Category**: ${n.category}`:null,n.tags?.length?`- **Tags**: ${n.tags.join(`, `)}`:null,ie?.get(n.id)??null].filter(Boolean).join(`
3028
- `),{body:a,truncated:o}=R_(n,se);return ce||=o,`${r}\n${i}\n\n${a}${o?`\n\n_Full content: use \`lookup\` on \`${n.sourcePath}\`._`:``}`}).join(`
3029
-
3030
- ---
3031
-
3032
- `),ue=(f===`hybrid`?`hybrid (vector + keyword RRF)`:f===`keyword`?`keyword (FTS)`:`semantic (vector)`)+ne,de=U_(E,e),fe=de.length>0?`\n_Distinctive terms: ${de.map(e=>`\`${e}\``).join(`, `)}_`:``,pe=await G_(n,E),me=[];if(E.length===0)me.push("`reindex` — no results found, index may be stale"),me.push("`find` — try federated search with glob/regex");else{let e=E[0]?.record.sourcePath;e&&me.push(`\`lookup\` — see all chunks from \`${e}\``),me.push("`symbol` — resolve a specific symbol from the results"),me.push("`compact` — compress a result file for focused reading"),me.push("reuse `ctxc_` ref above to avoid re-querying")}let he=[ae?`${ae}\n\n`:``,pe?`${pe}\n\n`:``,le,`\n\n---\n_Search mode: ${ue} | ${E.length} results_${fe}`,`\n_Next: ${me.join(` | `)}_`],ge=k+he.join(``),_e=!1;if(x){let e=Bn(ge,x);_e=e!==ge,ge=e}_e||=ce;let ve=E.map(e=>({sourcePath:e.record.sourcePath,contentType:e.record.contentType,score:e.score,...e.record.headingPath?{headingPath:e.record.headingPath}:{},...e.record.startLine?{startLine:e.record.startLine}:{},...e.record.endLine?{endLine:e.record.endLine}:{},...e.record.origin===`indexed`?{}:{origin:e.record.origin},...e.record.category?{category:e.record.category}:{},...e.record.tags?.length?{tags:e.record.tags}:{}})),ye=[ae,pe].filter(e=>!!e),A=yt({text:ge,query:e,searchMode:f,limit:d,results:ve,durationMs:Date.now()-w,truncated:_e,caveats:ye}),j=Vl(A.summary),be=new Set,xe=[];for(let e of E){if(e.record.origin!==`curated`||e.record.sourcePath.startsWith(`[`))continue;let t=Ed(e.record.sourcePath);if(!t)continue;let n=wd(t,e.record.headingPath??t);n&&!be.has(n.uri)&&(be.add(n.uri),xe.push(n))}return{content:[{type:`text`,text:Hl(A.summary,j)},...xe],isError:!A.ok,structuredContent:{...A.data??{results:[],totalResults:0,searchMode:f,query:e},ref:j}}}catch(t){M_.error(`Search failed`,N(t));let n=yt({text:`Search failed: ${t instanceof Error?t.message:String(t)}`,query:e??``,searchMode:f??`hybrid`,limit:d,results:[],durationMs:Date.now()-w}),r=Vl(n.summary);return{content:[{type:`text`,text:Hl(n.summary,r)}],structuredContent:{...n.data??{results:[],totalResults:0,searchMode:f??`hybrid`,query:e??``},ref:r}}}})}const q_=1e4,J_={defaultTtlSeconds:300,defaultLeaseTtlMinutes:10,globalEnabled:!1};function Y_(e){return e??J_}function X_(e,t){let n=e.trim();if(!n)throw Error(`${t} is required`);return n}function Z_(e,t,n){let r=X_(e,t);if(r.length>n)throw Error(`${t} exceeds max length of ${n}`);return r}function Q_(e,t){if(!Number.isFinite(e)||e<=0)throw Error(`${t} must be greater than 0`);return Math.trunc(e)}function $_(e,t=!1,n){X_(e,`workspace`);let r=Y_(n);if(!t)return e;if(!r.globalEnabled)throw Error(`Global signal scope is disabled`);return`__global__`}function ev(e,t,n){let r=Y_(n),i=$_(t.workspace,t.global??!1,r),a=Z_(t.key,`key`,500),o=Z_(t.value,`value`,q_),s=t.agent?Z_(t.agent,`agent`,500):void 0,c=Q_(t.ttlSeconds??r.defaultTtlSeconds,`ttlSeconds`);return e.signalPost(i,a,o,s,c)}function tv(e,t,n){let r=X_(t,`workspace`),i=Z_(n,`key`,500);return e.signalGet(r,i)}function nv(e,t){let n=X_(t,`workspace`);return e.signalList(n)}function rv(e,t,n){let r=X_(t,`workspace`),i=n===void 0?void 0:Z_(n,`key`,500);return e.signalClear(r,i)}function iv(e,t,n){let r=Y_(n),i=Z_(t.resource,`resource`,500),a=Z_(t.holder,`holder`,500),o=X_(t.workspace,`workspace`),s=t.intent?Z_(t.intent,`intent`,q_):void 0,c=Q_(t.ttlMinutes??r.defaultLeaseTtlMinutes,`ttlMinutes`);if(c>60)throw Error(`ttlMinutes exceeds max of 60`);let l=e.leaseAcquire(i,a,o,s,c),u=e.leaseGet(i,o);return u?{acquired:l,holder:u.holder,expiresAt:u.expiresAt}:{acquired:l}}function av(e,t,n,r){let i=X_(t,`workspace`),a=Z_(n,`resource`,500),o=Z_(r,`holder`,500);return e.leaseRelease(a,o,i)}function ov(e,t){let n=X_(t,`workspace`);return e.leaseList(n)}const sv=M(`tools:session`);function Z(e,t){if(e==null)throw Error(`${t} is required`)}function cv(e,t){if(!e||e.length===0)throw Error(`${t} are required`)}const lv={action:R.enum(`signal.post,signal.get,signal.list,signal.clear,signal.lease,signal.unlease,signal.leases,compliance.score,session.digest,stash.set,stash.get,stash.list,stash.delete,stash.clear,checkpoint.save,checkpoint.load,checkpoint.list,checkpoint.latest,checkpoint.diff,checkpoint.history,checkpoint.gc,workset.save,workset.get,workset.list,workset.delete,workset.add,workset.remove,lane.create,lane.list,lane.status,lane.diff,lane.merge,lane.discard,lane.lease,lane.unlease,lane.leases`.split(`,`)).describe(`Namespaced session action to perform (e.g. signal.post, stash.set, checkpoint.save)`),workspace:R.string().optional().describe(`Workspace identifier`),key:R.string().optional().describe(`Key (for signal get/post/clear, stash get/set/delete)`),value:R.string().optional().describe(`Value (for signal post, stash set)`),agent:R.string().optional().describe(`Agent identifier (for signal lease, lane lease)`),resource:R.string().optional().describe(`Resource path (for signal lease/unlease)`),holder:R.string().optional().describe(`Lease holder ID (for signal lease/unlease)`),intent:R.string().optional().describe(`What the holder plans to do`),ttl:R.number().optional().describe(`TTL (seconds for signals, minutes for leases)`),global:R.boolean().optional().describe(`Use global signal scope (default: false)`),last_n:R.number().min(1).max(500).optional().describe(`Max recent replay entries to score`),scope:R.enum([`tools`,`stash`,`all`]).optional().describe(`Digest scope`),since:R.string().optional().describe(`ISO timestamp — include activity after this time`),last:R.number().min(1).max(500).optional().describe(`Max replay entries to consider`),focus:R.string().optional().describe(`Focus query — prioritize entries matching this topic`),mode:R.enum([`deterministic`,`sampling`]).optional().describe(`Summary mode`),token_budget:R.number().min(100).max(8e3).optional().describe(`Target token budget`),persist:R.boolean().optional().describe(`Auto-save digest to stash for crash recovery`),label:R.string().optional().describe(`Checkpoint label / lane name / workset name`),data:R.string().max(5e5).optional().describe(`JSON object string for checkpoint save`),notes:R.string().max(1e4).optional().describe(`Optional notes for checkpoint save`),from_id:R.string().optional().describe(`Checkpoint ID to diff FROM`),to_id:R.string().optional().describe(`Checkpoint ID to diff TO`),limit:R.number().min(1).max(50).optional().describe(`Max entries to return`),keep_last:R.number().min(1).max(100).optional().describe(`Keep N recent checkpoints per label (gc)`),max_age_days:R.number().min(1).optional().describe(`Delete checkpoints older than N days (gc)`),dry_run:R.boolean().optional().describe(`Preview changes without deleting (gc)`),name:R.string().optional().describe(`Workset name or lane name`),files:R.array(R.string()).optional().describe(`File paths for workset/lane operations`),description:R.string().optional().describe(`Description (for workset save)`),id:R.string().optional().describe(`Lease ID (for lane unlease)`),symbols:R.array(R.string()).optional().describe(`Symbol names within files (for lane lease)`),ttl_minutes:R.number().optional().describe(`Lease TTL in minutes (for lane lease)`)};function uv(e,t,n){let r=U(`session`);e.registerTool(`session`,{title:r.title,description:`Unified session management — signals, compliance scoring, session digest, stash, checkpoints, worksets, and lanes. Use namespaced actions like signal.post, stash.set, checkpoint.save, workset.list, lane.create.`,inputSchema:lv,annotations:r.annotations},q(`session`,async e=>{try{let r=e.action,[i]=r.split(`.`);switch(i){case`signal`:return dv(t,r,e);case`compliance`:return fv(r,e);case`session`:return await pv(t,n,r,e);case`stash`:return mv(t,r,e);case`checkpoint`:return hv(t,r,e);case`workset`:return gv(r,e);case`lane`:return _v(r,e);default:throw Error(`Unknown session action namespace: ${i}`)}}catch(e){return sv.error(`Session operation failed`,N(e)),K(`INTERNAL`,`Session operation failed: ${e instanceof Error?e.message:String(e)}`)}}))}function dv(e,t,n){if(!e)throw Error(`stateStore is required for signal operations`);let{workspace:r,key:i,value:a,agent:o,resource:s,holder:c,intent:l,ttl:u,global:d}=n,f=J_;switch(t){case`signal.post`:{if(Z(i,`key`),a===void 0)throw Error(`value is required for signal.post`);let t=ev(e,{workspace:r,key:i,value:a,agent:o,ttlSeconds:u,global:d},f);return{content:[{type:`text`,text:JSON.stringify({id:t},null,2)}],structuredContent:{id:t}}}case`signal.get`:{Z(i,`key`);let t=tv(e,$_(r,d??!1,f),i);return{content:[{type:`text`,text:t.length===0?`[]`:JSON.stringify(t,null,2)}],structuredContent:{signals:t}}}case`signal.list`:{let t=nv(e,$_(r,d??!1,f));return{content:[{type:`text`,text:t.length===0?`[]`:JSON.stringify(t,null,2)}],structuredContent:{signals:t}}}case`signal.clear`:{let t=rv(e,$_(r,d??!1,f),i);return{content:[{type:`text`,text:JSON.stringify({cleared:t},null,2)}],structuredContent:{cleared:t}}}case`signal.lease`:{Z(s,`resource`),Z(c,`holder`);let t=iv(e,{resource:s,holder:c,workspace:r,intent:l,ttlMinutes:u},f);return{content:[{type:`text`,text:JSON.stringify(t,null,2)}],structuredContent:t}}case`signal.unlease`:{Z(s,`resource`),Z(c,`holder`);let t=av(e,r,s,c);return{content:[{type:`text`,text:JSON.stringify({released:t},null,2)}],structuredContent:{released:t}}}case`signal.leases`:{let t=ov(e,r);return{content:[{type:`text`,text:t.length===0?`[]`:JSON.stringify(t,null,2)}],structuredContent:{leases:t}}}default:throw Error(`Unknown signal action: ${t}`)}}function fv(e,t){switch(e){case`compliance.score`:{let e=t.last_n??50;return{content:[{type:`text`,text:vv(Dn(vn({last:e}),{lastN:e}))}]}}default:throw Error(`Unknown compliance action: ${e}`)}}async function pv(e,t,n,r){switch(n){case`session.digest`:{let n={scope:r.scope,since:r.since,last:r.last,focus:r.focus,mode:r.mode??`deterministic`,tokenBudget:r.token_budget??2e3,persist:r.persist??!0},i=e?{stateStore:e}:void 0;return{content:[{type:`text`,text:(n.mode===`sampling`&&t?.available?await kn(n,async(e,n,r)=>(await t.createMessage({prompt:e,systemPrompt:n,maxTokens:r})).text,i):On(n,i)).digest}]}}default:throw Error(`Unknown session action: ${n}`)}}function mv(e,t,n){if(!e)throw Error(`stateStore is required for stash operations`);let{key:r,value:i}=n;switch(t){case`stash.set`:{Z(r,`key`);let t=Pn(e,r,bv(i??``));return{content:[{type:`text`,text:`Stored stash entry "${t.key}" (${t.type}) at ${t.storedAt}.`}]}}case`stash.get`:{Z(r,`key`);let t=Mn(e,r);return{content:[{type:`text`,text:t?JSON.stringify(t):`Stash entry "${r}" not found.`}]}}case`stash.list`:{let t=Nn(e);return{content:[{type:`text`,text:t.length===0?`Stash is empty.`:t.map(e=>`- ${e.key} (${e.type}) — ${e.storedAt}`).join(`
3033
- `)}]}}case`stash.delete`:return Z(r,`key`),{content:[{type:`text`,text:jn(e,r)?`Deleted stash entry "${r}".`:`Stash entry "${r}" not found.`}]};case`stash.clear`:{let t=An(e);return{content:[{type:`text`,text:`Cleared ${t} stash entr${t===1?`y`:`ies`}.`}]}}default:throw Error(`Unknown stash action: ${t}`)}}function hv(e,t,n){if(!e)throw Error(`stateStore is required for checkpoint operations`);let{label:r,data:i,notes:a,from_id:o,to_id:s,limit:c,keep_last:l,max_age_days:u,dry_run:d}=n;switch(t){case`checkpoint.save`:return Z(r,`label`),{content:[{type:`text`,text:yv(mt(e,r,xv(i),{notes:a}))}]};case`checkpoint.load`:{Z(r,`label`);let t=pt(e,r);return{content:[{type:`text`,text:t?yv(t):`Checkpoint "${r}" not found.`}]}}case`checkpoint.list`:{let t=ft(e,{label:r,limit:c});return{content:[{type:`text`,text:t.length===0?`No checkpoints saved.`:t.map(e=>`- ${e.id} — ${e.label} (${e.createdAt})`).join(`
3034
- `)}]}}case`checkpoint.latest`:{let t=dt(e,{label:r});return{content:[{type:`text`,text:t?yv(t):`No checkpoints saved.`}]}}case`checkpoint.diff`:{Z(o,`from_id`),Z(s,`to_id`);let t=ct(e,o,s);return t?{content:[{type:`text`,text:[`## Checkpoint Diff: ${o} → ${s}`,t.added.length?`**Added:** ${t.added.join(`, `)}`:``,t.removed.length?`**Removed:** ${t.removed.join(`, `)}`:``,t.modified.length?`**Modified:** ${t.modified.join(`, `)}`:``,!t.added.length&&!t.removed.length&&!t.modified.length?`No differences found.`:``].filter(Boolean).join(`
3035
- `)}]}:{content:[{type:`text`,text:`One or both checkpoints not found.`}]}}case`checkpoint.history`:{Z(r,`label`);let t=ut(e,r,{limit:c??20});return t.length===0?{content:[{type:`text`,text:`No history found for "${r}".`}]}:{content:[{type:`text`,text:`## History: ${r}\n${t.map(e=>`- ${e.sha?e.sha.slice(0,8):e.id} — ${e.createdAt}${e.label?` (${e.label})`:``}`).join(`
3036
- `)}`}]}}case`checkpoint.gc`:{let t=lt(e,{label:r,keepLast:l,maxAgeDays:u,dryRun:d});return{content:[{type:`text`,text:[`## Checkpoint GC${t.labels.length?`: ${t.labels.join(`, `)}`:``}`,`Deleted: ${t.deleted}`,`Kept: ${t.kept}`,`Mode: ${d??!0?`dry-run`:`delete`}`,t.deletedIds.length?`Deleted IDs: ${t.deletedIds.join(`, `)}`:`Deleted IDs: none`].join(`
3037
- `)}]}}default:throw Error(`Unknown checkpoint action: ${t}`)}}function gv(e,t){let{name:n,files:r,description:i}=t;switch(e){case`workset.save`:{Z(n,`name`),cv(r,`files`);let e=wn(n,r,{description:i});return{content:[{type:`text`,text:`Saved workset "${e.name}" with ${e.files.length} files.`}]}}case`workset.get`:{Z(n,`name`);let e=Ft(n);return e?{content:[{type:`text`,text:JSON.stringify(e)}]}:{content:[{type:`text`,text:`Workset "${n}" not found.`}]}}case`workset.list`:{let e=Jt();return e.length===0?{content:[{type:`text`,text:`No worksets.`}]}:{content:[{type:`text`,text:e.map(e=>`- **${e.name}** (${e.files.length} files) — ${e.description??`no description`}`).join(`
3038
- `)}]}}case`workset.delete`:return Z(n,`name`),{content:[{type:`text`,text:St(n)?`Deleted workset "${n}".`:`Workset "${n}" not found.`}]};case`workset.add`:{Z(n,`name`),cv(r,`files`);let e=nt(n,r);return{content:[{type:`text`,text:`Added to workset "${e.name}": now ${e.files.length} files.`}]}}case`workset.remove`:{Z(n,`name`),cv(r,`files`);let e=hn(n,r);return e?{content:[{type:`text`,text:`Removed from workset "${e.name}": now ${e.files.length} files.`}]}:{content:[{type:`text`,text:`Workset "${n}" not found.`}]}}default:throw Error(`Unknown workset action: ${e}`)}}function _v(e,t){let{name:n,files:r,agent:i,intent:a,id:o,symbols:s,ttl_minutes:c}=t;switch(e){case`lane.create`:{Z(n,`name`),cv(r,`files`);let e=Bt(n,r);return{content:[{type:`text`,text:JSON.stringify(e)}]}}case`lane.list`:return{content:[{type:`text`,text:JSON.stringify(Ut())}]};case`lane.status`:return Z(n,`name`),{content:[{type:`text`,text:JSON.stringify(Gt(n))}]};case`lane.diff`:return Z(n,`name`),{content:[{type:`text`,text:JSON.stringify(Vt(n))}]};case`lane.merge`:return Z(n,`name`),{content:[{type:`text`,text:JSON.stringify(Wt(n))}]};case`lane.discard`:return Z(n,`name`),{content:[{type:`text`,text:JSON.stringify({discarded:Ht(n)})}]};case`lane.lease`:{Z(i,`agent`),cv(r,`files`),Z(a,`intent`);let e=tt({agent:i,files:r,intent:a,symbols:s,ttl_minutes:c});return{content:[{type:`text`,text:JSON.stringify(e)}]}}case`lane.unlease`:{Z(o,`id`);let e=mn({id:o});return{content:[{type:`text`,text:JSON.stringify(e)}]}}case`lane.leases`:{let e=Kt({agent:i});return{content:[{type:`text`,text:JSON.stringify(e)}]}}default:throw Error(`Unknown lane action: ${e}`)}}function vv(e){let t=[`Compliance score: ${e.score}/100`,`Calls scored: ${e.totalCalls}`,`Summary: ${e.summary}`];if(e.violations.length===0)return`${t.join(`
3039
- `)}\n\nNo violations detected.`;let n=e.violations.map(e=>`- ${e.ruleId} | ${e.tool} | ${e.timestamp}\n ${e.rule}\n Suggestion: ${e.suggestion}`);return`${t.join(`
3040
- `)}\n\nViolations:\n${n.join(`
3041
- `)}`}function yv(e){let t=[e.id,`Label: ${e.label}`,`Created: ${e.createdAt}`];return e.notes&&t.push(`Notes: ${e.notes}`),t.push(``,`Data:`,JSON.stringify(e.data)),t.join(`
3042
- `)}function bv(e){let t=e.trim();if(!t)return``;try{return JSON.parse(t)}catch{return e}}function xv(e){let t=e?.trim();if(!t)return{};let n;try{n=JSON.parse(t)}catch{throw Error(`data must be a valid JSON object string`)}if(!n||typeof n!=`object`||Array.isArray(n))throw Error(`data must be a JSON object string`);return n}let Sv={totalInputChars:0,totalOutputChars:0,callCount:0,startTime:new Date().toISOString()};function Cv(){return{...Sv}}const wv=new Map,Tv=[];function Ev(){return Array.from(wv.entries()).map(([e,t])=>({tool:e,...t}))}function Dv(){return Tv}M(`auto-gc`);function Ov(){let e=[...Dv()];if(e.length<10)return 0;e.sort((e,t)=>e-t);let t=Math.floor(e.length*.95);return e[Math.min(t,e.length-1)]}function kv(){return{state:`warming`,p95:Ov(),lastGcAt:null,gcCount:0,bufferSize:Dv().length}}function Av(e,t){return e.length<=t?e:e.slice(0,t)}function jv(e){if(!e)return 0;let t=Date.parse(e);return Number.isNaN(t)?0:t}function Mv(e){let t=Array.isArray(e)?e:[e];for(let e of t){if(!e)continue;let t=L(e,`SKILL.md`);if(P(t))try{let e=F(t,`utf-8`);return e.length>400?`${e.slice(0,400)}\n...`:e}catch{}}return null}async function Nv(e,t,n=d,r){if(!e||!t)return null;try{let[i,o,s]=await Promise.all([e.list({category:`lessons`,limit:200,orderBy:`updated`,order:`desc`}),e.list({category:`conventions`,limit:200,orderBy:`updated`,order:`desc`}),e.list({category:`session`,limit:200,orderBy:`updated`,order:`desc`})]),l=i.filter(e=>e.tags.includes(`lesson`)).map(e=>{let r=t.memoryMetaGet(e.path);return!r||r.supersededBy!=null?null:{entry:e,confidence:c(r.confidence,r.lastAccessedAt,r.createdAt,n)}}).filter(e=>e!==null).sort((e,t)=>t.confidence-e.confidence).slice(0,3);return{lessons:await Promise.all(l.map(async({entry:t,confidence:n})=>{let r=a((await e.read(t.path)).content);return{title:t.title,insight:Av(r.insight??``,150),confidence:n}})),conventions:o.map(e=>({entry:e,lastAccessedAt:t.memoryMetaGet(e.path)?.lastAccessedAt??null})).filter(({entry:e})=>(e.contentPreview?.trim()??``).length>5).sort((e,t)=>jv(t.lastAccessedAt)-jv(e.lastAccessedAt)).slice(0,2).map(({entry:e})=>({title:e.title,preview:e.contentPreview})),checkpoint:s.map(e=>({entry:e,lastAccessedAt:t.memoryMetaGet(e.path)?.lastAccessedAt??null})).sort((e,t)=>jv(t.lastAccessedAt)-jv(e.lastAccessedAt)).map(({entry:e})=>Av(e.contentPreview,200))[0]??null,workspaceSkill:Mv(r)}}catch{return null}}function Pv(e,t=600){if(!e)return{lines:[],totalChars:0,autoInjectCount:0};let n=[],r=0;for(let t of e.lessons){if(t.confidence<45)continue;let e=Qf(t.title,t.insight,t.confidence,200);n.push(`• ${e}`),r++}e.workspaceSkill&&(n.push(`• Workspace: ${e.workspaceSkill.split(`
3043
- `)[0]??``}`),r++);for(let t of e.conventions){let e=t.preview?.trim()||``;if(e){let r=e.length>120?`${e.slice(0,117)}...`:e;n.push(`• ${t.title}: ${r}`)}else n.push(`• ${t.title}`)}if(n.length===0)return{lines:[],totalChars:0,autoInjectCount:0};let i=[`━━ Knowledge ━━`,...n,`───`],a=i.join(`
3044
- `);if(a.length>t)for(;i.length>3&&a.length>t;)i.splice(1,1)[0]?.startsWith(`•`)&&r--;return{lines:i,totalChars:i.join(`
3045
- `).length,autoInjectCount:r}}const Fv=M(`tools`),Iv=14400*1e3,Lv={includePrelude:R.boolean().default(!1).describe(`Include session prelude with top lessons, conventions, and last checkpoint`)};function Rv(e,t,n,r=15e3){let i,a=new Promise(e=>{i=setTimeout(()=>{Fv.warn(`Status sub-operation "${n}" timed out after ${r}ms`),e({value:t,timedOut:!0})},r)});return Promise.race([e.then(e=>(clearTimeout(i),{value:e,timedOut:!1}),e=>(clearTimeout(i),Fv.warn(`Status sub-operation "${n}" failed: ${e instanceof Error?e.message:String(e)}`),{value:t,timedOut:!1})),a])}function zv(e){return e.onboarded?e.indexStale?{kind:`reindex`,reason:`Index stale. Run reindex() to update.`}:e.contextPressure>70?{kind:`handoff`,reason:`Context pressure high. Consider session handoff.`}:{kind:`proceed`,reason:`Ready to work.`}:{kind:`onboard`,reason:`Index not initialized. Run onboard({ path: "." }) first.`}}function Bv(){let e=lr.get(),t=cr.get();if(e)return`- **Tree-sitter (WASM)**: ✅ Available (${t.grammarCount} grammars, dir: ${t.wasmDir})`;let n=t.pathsChecked.length?t.pathsChecked.map(e=>` ${e.exists?`✓`:`✗`} ${e.path}`).join(`
3046
- `):` none`,r=t.healAttempted?` Auto-heal: ${t.healSuccess?`✓ succeeded`:`✗ failed (${t.healError??`unknown`})`}`:` Auto-heal: not attempted`;return[`- **Tree-sitter (WASM)**: ⚠ Unavailable (regex fallback)`,` Reason: ${t.reason||`unknown`}`,` Paths checked:`,n,r,` OS: ${t.os} ${t.arch} | Node: ${t.nodeVersion}`,` Fix: Reinstall package or run vendor:wasm script`].join(`
3047
- `)}const Vv=5*6e4;let Hv=null,Uv=null;function Wv(e,t,n,r){let i=Math.min(e/2e4,1),a=Math.min((t+n)/5e4,1),o=Math.min(r/200,1);return Math.round(i*40+a*35+o*25)}function Gv(){let e=Date.now();if(Hv&&e-Hv.ts<Vv)return Hv.value;try{let t=L(Wn(),`.copilot`,`.aikit-scaffold.json`);if(!P(t))return Hv={value:null,ts:e},null;let n=JSON.parse(F(t,`utf-8`)).version??null;return Hv={value:n,ts:e},n}catch{return Hv={value:null,ts:e},null}}function Kv(){let e=Date.now();if(Uv&&e-Uv.ts<Vv)return Uv.value;try{let t=L(process.cwd(),`.github`,`.aikit-scaffold.json`);if(!P(t))return Uv={value:null,ts:e},null;let n=JSON.parse(F(t,`utf-8`)).version??null;return Uv={value:n,ts:e},n}catch{return Uv={value:null,ts:e},null}}function qv(e){let t=U(`status`);e.registerTool(`status`,{title:t.title,description:`Get the current status and statistics of the AI Kit index.`,inputSchema:Lv,annotations:t.annotations},q(`status`,async()=>{let e=oe(),t=Gv(),n=Kv(),r=t!=null&&t!==e,i=n!=null&&n!==e,a=[`## AI Kit Status`,``,`⏳ **AI Kit is initializing** — index stats will be available shortly.`,``,`### Runtime`,`- **Tree-sitter (WASM)**: ${lr.get()?`✅ Available (AST analysis)`:`⚠ Unavailable (regex fallback)`}`,``,`### Version`,`- **Server**: ${e}`,`- **Scaffold (user)**: ${t??`not installed`}`,`- **Scaffold (workspace)**: ${n??`not installed`}`];if(r||i){let o=se(),s=[];r&&s.push(`user scaffold v${t}`),i&&s.push(`workspace scaffold v${n}`);let c=s.join(`, `);o.state===`success`?a.push(``,`### ✅ Upgrade Applied`,`- Server v${e} — ${c} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):o.state===`pending`?a.push(``,`### ⏳ Upgrade In Progress`,`- Server v${e} ≠ ${c}`,`- Auto-upgrade is running in the background…`):o.state===`failed`?(ie(),a.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${e} ≠ ${c}`,`- Error: ${o.error??`unknown`}`)):(ie(),a.push(``,`### ⬆ Upgrade Available`,`- Server v${e} ≠ ${c}`,`- Auto-upgrade triggered — check again shortly.`))}let o={totalRecords:0,totalFiles:0,lastIndexedAt:null,onboarded:!1,onboardDir:``,contentTypes:{},wasmAvailable:!!lr.get(),wasmDiagnostics:cr.get(),graphStats:null,curatedCount:0,serverVersion:e,scaffoldVersion:t??null,workspaceScaffoldVersion:n??null,upgradeAvailable:r||i,contextPressure:0,nextAction:zv({onboarded:!1,indexStale:!1,contextPressure:0})};return{content:[{type:`text`,text:a.join(`
3048
- `)}],structuredContent:o}}))}function Jv(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h){let g=U(`status`);e.registerTool(`status`,{title:g.title,description:`Get the current status and statistics of the AI Kit index.`,inputSchema:Lv,annotations:g.annotations},q(`status`,async({includePrelude:e=!1})=>{let g=[];try{let[_,v]=await Promise.all([Rv(t.getStats(),{totalRecords:0,totalFiles:0,lastIndexedAt:null,contentTypeBreakdown:{}},`store.getStats`),Rv(t.listSourcePaths(),[],`store.listSourcePaths`)]),y=_.value;_.timedOut&&g.push(`⚠ Index stats timed out — values may be incomplete`);let b=v.value;v.timedOut&&g.push(`⚠ File listing timed out`);let x=null,S=0,C=[`## AI Kit Status`,``,`- **Total Records**: ${y.totalRecords}`,`- **Total Files**: ${y.totalFiles}`,`- **Last Indexed**: ${y.lastIndexedAt??`Never`}`,``,`### Content Types`,...Object.entries(y.contentTypeBreakdown).map(([e,t])=>`- ${e}: ${t}`),``,`### Indexed Files`,...b.slice(0,50).map(e=>`- ${e}`),b.length>50?`\n... and ${b.length-50} more files`:``];if(n)try{let e=await Rv(n.getStats(),{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}},`graphStore.getStats`);if(e.timedOut)g.push(`⚠ Graph stats timed out`),C.push(``,`### Knowledge Graph`,`- Graph stats timed out`);else{let t=e.value;x={nodes:t.nodeCount,edges:t.edgeCount},C.push(``,`### Knowledge Graph`,`- **Nodes**: ${t.nodeCount}`,`- **Edges**: ${t.edgeCount}`,...Object.entries(t.nodeTypes).map(([e,t])=>` - ${e}: ${t}`));try{let e=await Rv(n.validate(),{valid:!0,danglingEdges:[],orphanNodes:[],stats:{nodeCount:0,edgeCount:0,nodeTypes:{},edgeTypes:{}}},`graphStore.validate`);if(!e.timedOut){let t=e.value;t.valid||C.push(`- **⚠ Integrity Issues**: ${t.danglingEdges.length} dangling edges`),t.orphanNodes.length>0&&C.push(`- **Orphan nodes**: ${t.orphanNodes.length}`)}}catch{}}}catch{C.push(``,`### Knowledge Graph`,`- Graph store unavailable`)}let w=a?.onboardDir??``,T=P(w),E=i?.onboardComplete||T;if(C.push(``,`### Onboard Status`,E?`- ✅ Complete${i?.onboardTimestamp?` (last: ${i.onboardTimestamp})`:``}`:'- ❌ Not run — call `onboard({ path: "." })` to analyze the codebase',`- **Onboard Directory**: \`${w}\``),r)try{let e=await Rv(r.count(),0,`curated.count`);e.timedOut?(g.push(`⚠ Curated knowledge count timed out`),C.push(``,`### Curated Knowledge`,`- Listing timed out`)):(S=e.value,C.push(``,`### Curated Knowledge`,S>0?`- ${S} entries`:'- Empty — use `knowledge({ action: "remember", ... })` to persist decisions'))}catch{C.push(``,`### Curated Knowledge`,`- Unable to read curated entries`)}let D=Vn().filter(e=>e.status===`watching`);if(D.length>0){C.push(``,`### File Watchers`,`- **Active**: ${D.length}`);for(let e of D){let t=e.pendingFiles?.length??0;if(C.push(` - \`${e.path}\`: ${e.eventCount} events, ${t} pending files`),t>0&&t<=10)for(let t of e.pendingFiles)C.push(` - \`${t}\``);else t>10&&C.push(` - ${t} pending files (use \`watch({ action: 'list' })\` for details)`)}}let O=Wv(y.totalRecords,x?.nodes??0,x?.edges??0,S),k=y.lastIndexedAt?new Date(y.lastIndexedAt).getTime():0,ee=k>0?Date.now()-k:1/0,te=zv({onboarded:E,indexStale:E&&ee>1440*60*1e3,contextPressure:O});C.push(``),C.push(`## 📊 Context Pressure: ${O}/100`),O>=80?C.push(`⚠️ High pressure — consider pruning stale entries or compacting context.`):O>=50?C.push(`ℹ️ Moderate pressure — AI Kit memory is well-populated.`):C.push(`✅ Low pressure — plenty of headroom for more content.`);let ne=0;if(y.lastIndexedAt){ne=new Date(y.lastIndexedAt).getTime();let e=(Date.now()-ne)/(1e3*60*60);C.push(``,`### Index Freshness`,e>24?o===`smart`?`- ⚠ Last indexed ${Math.floor(e)}h ago — smart indexing will refresh automatically`:`- ⚠ Last indexed ${Math.floor(e)}h ago — may be stale. Run \`reindex({})\``:`- ✅ Last indexed ${e<1?`less than 1h`:`${Math.floor(e)}h`} ago`)}C.push(``,`### Next Action`,`- **${te.kind}**: ${te.reason}`);let re=null,ae=t;if(typeof ae.getDiagnostics==`function`)try{let e=ae.getDiagnostics();re={adapterType:e.adapterType,vectorSearchEnabled:e.vectorSearchEnabled,ftsEnabled:e.ftsEnabled,degradedMode:e.degradedMode,dbPath:e.dbPath,dbSizeBytes:e.dbSizeBytes,embeddingDim:e.embeddingDim,vectorDtype:e.vectorDtype},C.push(``,`### Storage`,`- **Backend**: ${a?.store?.backend??`unknown`}`,`- **Adapter**: ${re.adapterType}`,`- **Vector search**: ${re.vectorSearchEnabled?`✅ enabled`:`⚠ disabled (FTS-only fallback)`}`,re.dbPath?`- **DB**: ${re.dbPath}`:``,re.dbSizeBytes==null?``:`- **DB size**: ${(re.dbSizeBytes/1024/1024).toFixed(2)} MB`,`- **Embedding dim**: ${re.embeddingDim}`,`- **Vector dtype**: ${re.vectorDtype}`)}catch{}if(o===`smart`)if(C.push(``,`### Smart Indexing`),s){let e=s();e?C.push(`- **Mode**: Smart (trickle)`,`- **Status**: ${e.running?`✅ Running`:`⏸ Stopped`}`,`- **Queue**: ${e.queueSize} files pending`,`- **Changed files**: ${e.changedFilesSize} detected`,`- **Interval**: ${Math.round(e.intervalMs/1e3)}s per batch of ${e.batchSize}`):C.push(`- **Mode**: Smart (trickle)`,`- **Status**: scheduler state unavailable (init may have failed)`)}else C.push(`- **Mode**: Smart (trickle) — scheduler state unavailable`);if(h)try{let e=h.getReport(),t=h.checkThresholds(),n=Object.entries(e.counters),r=Object.entries(e.gauges);if(n.length>0||r.length>0||t.length>0){if(C.push(``,`### 📊 Metrics`),n.length>0){C.push(`**Counters:**`);for(let[e,t]of n)C.push(`- \`${e}\`: ${t}`)}if(r.length>0){C.push(`**Gauges:**`);for(let[e,t]of r)C.push(`- \`${e}\`: ${t}`)}if(t.length>0){C.push(`**⚠ Threshold violations:**`);for(let e of t)C.push(`- ${e}`)}else(n.length>0||r.length>0)&&C.push(`- ✅ All thresholds within limits`)}}catch{C.push(``,`### 📊 Metrics`,`- Metrics unavailable`)}{let e=[];if(u)try{let t=u.getStats();e.push(`- **Decision Hooks**: ${t.count} registered${t.hooks.length>0?` (IDs: ${t.hooks.map(e=>e.id).join(`, `)})`:``}`)}catch{e.push(`- **Decision Hooks**: unavailable`)}else e.push(`- **Decision Hooks**: not configured`);if(d)try{let t=d.getStats(),n=Object.entries(t.byTool).map(([e,t])=>`${e}=${t}`).join(`, `);e.push(`- **Observations**: ${t.totalObservations} total, byTool: ${n||`none`}`)}catch{e.push(`- **Observations**: unavailable`)}else e.push(`- **Observations**: not configured`);if(f)try{let t=f.getStats(),n=Object.keys(t.byName);e.push(`- **Extractors**: ${t.count} registered${n.length>0?` (IDs: ${n.join(`, `)})`:``}`)}catch{e.push(`- **Extractors**: unavailable`)}else e.push(`- **Extractors**: not configured`);if(m)try{let t=m.getStats(),n=t.skillExists?t.isStale?`⚠ Stale`:`✅ Fresh`:`❌ No skill`;e.push(`- **Skill Compiler**: ${n}, version: ${t.skillVersion}, last compiled: ${t.lastCompiledAt?new Date(t.lastCompiledAt).toLocaleString():`Never`}`)}catch{e.push(`- **Skill Compiler**: unavailable`)}else e.push(`- **Skill Compiler**: not configured`);if(p)try{let t=p.getStats();e.push(`- **Promotion Engine**: ${t.held} candidates held, ${t.promoted} promoted, ${t.observedFacts} distinct facts tracked`)}catch{e.push(`- **Promotion Engine**: unavailable`)}else e.push(`- **Promotion Engine**: not configured`);C.push(``,`### 🧩 Feature Coverage`,...e)}let ce=0;{try{let e=a?.stateDir?I(a.stateDir,`stash`):null;if(e&&P(e)){let t=Pe(e).mtimeMs;t>ne&&(ne=t)}}catch{}let e=[];if(r)try{let t=S>0?await r.list({limit:5,orderBy:`updated`,order:`desc`}):[];for(let e of t){let t=new Date(e.updated||e.created).getTime();t>ne&&(ne=t)}e.push(...t)}catch{}if(ce=ne>0?Date.now()-ne:0,ce>=Iv){let t=Math.floor(ce/36e5);if(C.push(``,`### 🌅 Session Briefing`,`_${t}+ hours since last activity — here's what to pick up:_`,``),e.length>0){C.push(`**Recent decisions/notes:**`);for(let t of e)C.push(`- **${t.title}** (${t.category??`note`}) — ${(t.contentPreview??``).slice(0,80)}…`)}C.push(``,`**Suggested next steps:**`,'- `search({ query: "SESSION CHECKPOINT", origin: "curated" })` — find your last checkpoint',"- `restore({})` — resume from a saved checkpoint",'- `knowledge({ action: "list" })` — browse all stored knowledge')}}C.push(``,`### Runtime`,Bv());let le=_e.instance().getAll(),ue=le.filter(e=>e.status!==`healthy`);if(ue.length>0){C.push(``,`### ⚠️ Subsystem Health`);for(let e of ue){let t=Math.round((Date.now()-e.since)/1e3);C.push(`- **${e.name}**: ${e.status} (${t}s ago${e.reason?` — ${e.reason}`:``})`)}}else le.length>0&&C.push(``,`### ✅ Subsystem Health`,`- All ${le.length} subsystems healthy`);let de=me.getAll();if(de.size>0){C.push(``,`### 🔌 Circuit Breakers`);for(let[e,t]of de){let n=t.getState(),r=`- **${e}**: ${n===`closed`?`🟢`:n===`open`?`🔴`:`🟡`} ${n}`;if(n===`open`){let e=t.remainingCooldownMs();r+=` (recovery in ${Math.ceil(e/1e3)}s)`}C.push(r)}}let fe=Gv(),pe=Kv(),he=oe(),ge=fe!=null&&fe!==he,ve=pe!=null&&pe!==he;if(ge||ve){let e=se(),t=[];ge&&t.push(`user scaffold v${fe}`),ve&&t.push(`workspace scaffold v${pe}`);let n=t.join(`, `);e.state===`success`?C.push(``,`### ✅ Upgrade Applied`,`- Server v${he} — ${n} auto-upgraded successfully.`,`- _Restart the MCP server to use the updated version._`):e.state===`pending`?C.push(``,`### ⏳ Upgrade In Progress`,`- Server v${he} ≠ ${n}`,`- Auto-upgrade is running in the background…`):e.state===`failed`?(ie(),C.push(``,`### ⬆ Upgrade Available (auto-upgrade failed, retrying)`,`- Server v${he} ≠ ${n}`,`- Error: ${e.error??`unknown`}`)):(ie(),C.push(``,`### ⬆ Upgrade Available`,`- Server v${he} ≠ ${n}`,`- Auto-upgrade triggered — check again shortly.`))}g.length>0&&C.push(``,`### ⚠ Warnings`,...g.map(e=>`- ${e}`));let ye=Ev();if(ye.length>0){let e=ye.sort((e,t)=>t.callCount-e.callCount);C.push(``,`### Tool Usage This Session`,``),C.push(`| Tool | Calls | Tokens In | Tokens Out | Errors | Avg Latency |`),C.push(`|------|-------|-----------|------------|--------|-------------|`);for(let t of e.slice(0,15)){let e=Math.round(t.totalInputChars/4),n=Math.round(t.totalOutputChars/4),r=Math.round(t.totalDurationMs/t.callCount);C.push(`| ${t.tool} | ${t.callCount} | ${e.toLocaleString()} | ${n.toLocaleString()} | ${t.errorCount} | ${r}ms |`)}}let A=Cv();A.callCount>0&&(C.push(``),C.push(`### Session Token Usage`),C.push(`- Tool calls: ${A.callCount}`),C.push(`- Input chars: ${A.totalInputChars.toLocaleString()}`),C.push(`- Output chars: ${A.totalOutputChars.toLocaleString()}`),C.push(`- Est. input tokens: ${Math.round(A.totalInputChars/4).toLocaleString()}`),C.push(`- Est. total tokens: ${Math.round((A.totalInputChars+A.totalOutputChars)/4).toLocaleString()}`));let j=kv();if(j.bufferSize>=10){let e=j.state===`healthy`?`🟢`:j.state===`degraded`?`🔴`:`🟡`;C.push(``,`### Auto-GC: ${e} ${j.state}`),C.push(`- p95 latency: ${j.p95}ms | buffer: ${j.bufferSize} samples`),j.gcCount>0&&C.push(`- GC cycles triggered: ${j.gcCount}`)}if(l){let e=l.getStats();if(e.totalSubscribers>0){C.push(``,`### 🔌 Hooks (EventBus Subscribers)`),C.push(`- Total subscribers: ${e.totalSubscribers}`);for(let[t,n]of Object.entries(e.byEvent))C.push(` - ${t}: ${n} subscriber(s)`);for(let t of e.subscriptions)C.push(` - ${t.name} (${t.eventType}, ${t.policy})`);if(e.autoDisabled.length>0){C.push(``),C.push(` **Auto-disabled subscribers:**`);for(let t of e.autoDisabled)C.push(` - ${t.name} (${t.id}): ${t.reason}`)}}}if(u&&u.size>0){let e=u.getStats();C.push(``,`### 🪝 Decision Hooks`),C.push(`- Total hooks: ${e.count}`);for(let t of e.hooks){let e=t.decisionTypes.join(`, `);C.push(` - ${t.id} (order=${t.order}, policy=${t.failurePolicy}, types=[${e}])`)}}if(d){let e=d.getStats();C.push(``,`### 👁 Observations`),C.push(`- Total observations: ${e.totalObservations}`),C.push(` - Success: ${e.byError.success}, Error: ${e.byError.error}`),C.push(` - Artifacts stored: ${e.artifactCount}`),C.push(` - Truncations: ${e.truncationCount}`),C.push(` - Store entries: ${e.storeSize}`);let t=Object.entries(e.byOrigin);t.length>0&&C.push(` - By origin: ${t.map(([e,t])=>`${e}=${t}`).join(`, `)}`)}if(f){let e=f.getStats();C.push(``,`### 🧩 Extractors`),C.push(`- Total extractors: ${e.count}`);for(let[t,n]of Object.entries(e.byName))C.push(` - ${t} (${n.tools} tool(s), maxFacts: ${n.maxFactsPerEvent??`default`})`)}if(p){let e=p.getStats();if(C.push(``,`### 🏆 Promotion Engine`),C.push(`- Total evaluated: ${e.totalEvaluated}`),C.push(`- Promoted: ${e.promoted}`),C.push(`- Held: ${e.held}`),C.push(`- Rejected: ${e.rejected}`),C.push(`- Superseded: ${e.superseded}`),C.push(`- Decayed: ${e.decayed}`),C.push(`- Distinct facts tracked: ${e.observedFacts}`),e.recentDecisions.length>0){C.push(` Recent decisions:`);for(let t of e.recentDecisions.slice(-5))C.push(` - ${t.decision.status}: "${t.factTitle}" (${t.decision.reason.slice(0,80)})`)}}if(m){let e=m.getStats();C.push(``,`### 📋 Workspace Skill`),C.push(`- **Skill exists**: ${e.skillExists?`✅`:`❌`}`),C.push(`- **Stale**: ${e.isStale?`⚠ Yes — regenerating on next trigger`:`✅ Fresh`}`),C.push(`- **Last compiled**: ${e.lastCompiledAt?new Date(e.lastCompiledAt).toLocaleString():`Never`}`),C.push(`- **Version**: ${e.skillVersion}`),C.push(`- **Total compiles**: ${e.totalCompiles}`),e.failedCompiles>0&&C.push(`- **Failed compiles**: ${e.failedCompiles}`),e.skillSize>0&&C.push(`- **Skill size**: ${e.skillSize} bytes`),e.isCompiling&&C.push(`- ⏳ **Currently compiling**`),e.pendingRegeneration&&C.push(`- ⏳ **Regeneration pending**`),C.push(``," Call `skill_view('<ws-name>')` to load workspace context.")}{let e=Pt();(e.cacheSize>0||e.refReuseCount>0)&&(C.push(``,`### 🔄 Ref Reuse`),C.push(`- **Refs stored**: ${e.refStoreCount}`),C.push(`- **Refs reused**: ${e.refReuseCount}`),e.refStaleCount>0&&C.push(`- **⚠ Stale refs detected**: ${e.refStaleCount}`),C.push(`- **Cache entries**: ${e.cacheSize}`))}let be=C.join(`
3049
- `),xe=ce>=Iv,M=[a?.onboardDir?xn(L(a.onboardDir,`..`)):void 0,a?.skillDir].filter(e=>typeof e==`string`&&e.length>0);M[0];let Se=e||xe?await Nv(r,c,void 0,M.length>0?M:void 0):void 0,Ce=D.length>0?D.map(e=>({id:e.id,path:e.path,eventCount:e.eventCount,pendingFiles:e.pendingFiles??[]})):void 0,we={totalRecords:y.totalRecords,totalFiles:y.totalFiles,lastIndexedAt:y.lastIndexedAt??null,onboarded:E,onboardDir:w,contentTypes:y.contentTypeBreakdown,wasmAvailable:!!lr.get(),wasmDiagnostics:cr.get(),graphStats:x,curatedCount:S,serverVersion:he,scaffoldVersion:fe??null,workspaceScaffoldVersion:pe??null,upgradeAvailable:ge||ve,storeBackend:a?.store?.backend,storeDiagnostics:re??null,contextPressure:O,nextAction:te,workspace_skill:(()=>{if(!m)return null;try{let e=m.getStats();return{exists:e.skillExists,version:e.skillVersion,fresh:!e.isStale,last_updated:e.lastCompiledAt?new Date(e.lastCompiledAt).toISOString():null,size:e.skillSize}}catch{return null}})(),skill_warnings:m?.getWarnings(m?.resolveActiveFlowSlug()??void 0)??[],watchers:Ce,sessionTokens:{callCount:A.callCount,totalInputChars:A.totalInputChars,totalOutputChars:A.totalOutputChars,estInputTokens:Math.round(A.totalInputChars/4),estTotalTokens:Math.round((A.totalInputChars+A.totalOutputChars)/4),startTime:A.startTime},...Se===void 0?{}:{prelude:Se}};return{content:[{type:`text`,text:be+(o===`smart`?"\n\n---\n_Next: Use `search` to query indexed content or `graph({action:'find_nodes', name_pattern:'<top-level-module>'})` → then `graph({action:'neighbors', node_id})` for relationships. Smart indexing handles updates automatically._":"\n\n---\n_Next: Use `search` to query indexed content, `graph({action:'find_nodes', name_pattern:'<top-level-module>'})` → then `graph({action:'neighbors', node_id})` for relationships, or `reindex` to refresh the index._")}],structuredContent:we}}catch(e){return Fv.error(`Status failed`,N(e)),K(`INTERNAL`,`Status check failed: ${e instanceof Error?e.message:String(e)}`)}}))}const Yv=M(`tools`);function Xv(e){return e instanceof Error?(`code`in e?e.code:void 0)===`ENOENT`||e.message.startsWith(`File not found:`)||e.message.startsWith(`Path not found:`):!1}function Zv(e){let t=U(`web_search`);e.registerTool(`web_search`,{title:t.title,description:`PREFERRED web search — fans out to multiple keyless providers (DuckDuckGo + Bing-HTML + Mojeek) by default, returning a deduplicated, consensus-ranked union within a 10s deadline. Optional providers (SearXNG, Google, Brave, Bing API) join the fan-out automatically when their env vars are set. Pass one query or multiple for parallel searching.`,inputSchema:{queries:R.array(R.string().max(2e3)).min(1).max(5).describe('Search queries (1–5). Single: `["react hooks"]`. Multiple searched in parallel.'),limit:R.number().min(1).max(20).default(5).describe(`Max results per query`),site:R.string().optional().describe(`Restrict to domain (e.g., "docs.aws.amazon.com")`),provider:R.enum([`multi`,`duckduckgo`,`bing-html`,`mojeek`,`searxng`,`google`,`brave`,`bing`]).optional().describe("Search provider. Defaults to env AIKIT_SEARCH_PROVIDER, then `multi` (fan-out). Single keyless: `duckduckgo`, `bing-html`, `mojeek`. Self-hosted: `searxng` (requires SEARXNG_URL). Keyed APIs: `google` (GOOGLE_API_KEY+GOOGLE_CSE_ID), `brave` (BRAVE_API_KEY), `bing` (BING_API_KEY). Missing keys auto-fall back to duckduckgo.")},annotations:t.annotations},q(`web_search`,async({queries:e,limit:t,site:n,provider:r})=>{let i=e,a=async e=>{let i=await Un({query:e,limit:t,site:n,provider:r}),a=[`## Search: ${i.query} _(via ${i.provider})_`,``];if(i.results.length===0)a.push(`No results found.`);else for(let e of i.results)a.push(`### [${e.title}](${e.url})`,e.snippet,``);return a.join(`
3050
- `)};if(i.length===1)try{return{content:[{type:`text`,text:`${await a(i[0])}\n---\n_Next: Use \`web_fetch\` to read any of these pages in full._`}]}}catch(e){return Yv.error(`Web search failed`,N(e)),K(`INTERNAL`,`Web search failed: ${e instanceof Error?e.message:String(e)}`)}let o=await Promise.allSettled(i.map(e=>a(e))),s=[],c=0;for(let e=0;e<o.length;e++){let t=o[e];if(t.status===`fulfilled`)s.push(t.value);else{c++;let n=t.reason instanceof Error?t.reason.message:String(t.reason);Yv.error(`Web search failed`,{query:i[e],error:n}),s.push(`## ❌ Search failed: ${i[e]}\n\n${n}`)}}let l=`_Searched ${o.length-c}/${o.length} queries successfully._`;s.push(``,`---`,l,"_Next: Use `web_fetch` to read any of these pages in full._");let u=s.join(`
3051
-
3052
- `);return c===o.length?K(`INTERNAL`,u):{content:[{type:`text`,text:u}]}}))}function Qv(e){let t=U(`measure`);e.registerTool(`measure`,{title:t.title,description:`Measure code complexity, line counts, and function counts for a file or directory. Returns per-file metrics sorted by complexity.`,outputSchema:tc,inputSchema:{path:R.string().describe(`File or directory path to measure`),extensions:R.array(R.string()).optional().describe(`File extensions to include (default: .ts,.tsx,.js,.jsx)`),include_hidden:R.boolean().optional().describe(`Include hidden trees such as .generated and .cache. Default false.`),max_tokens:R.number().min(100).max(5e4).optional().describe(`Maximum token budget for the response. When set, output is truncated to fit.`)},annotations:t.annotations},q(`measure`,async({path:e,extensions:t,include_hidden:n,max_tokens:r})=>{try{let i=await Yt({path:e,extensions:t,includeHidden:n}),a=[`## Code Metrics`,``,`**Files:** ${i.summary.totalFiles}`,`**Total lines:** ${i.summary.totalLines} (${i.summary.totalCodeLines} code)`,`**Functions:** ${i.summary.totalFunctions}`,`**Avg complexity:** ${i.summary.avgComplexity}`,`**Max complexity:** ${i.summary.maxComplexity.value} (${i.summary.maxComplexity.file})`,``,`### Top files by complexity`,``,`| File | Lines | Code | Complexity | Cognitive | Functions | Imports |`,`|------|-------|------|------------|-----------|-----------|---------|`];for(let e of i.files.slice(0,20)){let t=e.cognitiveComplexity===void 0?`—`:String(e.cognitiveComplexity);a.push(`| ${e.path} | ${e.lines.total} | ${e.lines.code} | ${e.complexity} | ${t} | ${e.functions} | ${e.imports} |`)}i.files.length>20&&a.push(``,`_...and ${i.files.length-20} more files_`);let o={summary:{totalFiles:i.summary.totalFiles,totalLines:i.summary.totalLines,totalCodeLines:i.summary.totalCodeLines,totalFunctions:i.summary.totalFunctions,avgComplexity:i.summary.avgComplexity,maxComplexity:{value:i.summary.maxComplexity.value,file:i.summary.maxComplexity.file}},files:i.files.map(e=>({path:e.path,lines:e.lines.total,code:e.lines.code,complexity:e.complexity,functions:e.functions}))};return{content:[{type:`text`,text:r?Bn(a.join(`
3053
- `),r):a.join(`
3054
- `)}],structuredContent:o}}catch(e){return Xv(e)?(Yv.warn(`Measure failed`,{error:`File not found`}),K(`NOT_FOUND`,`File not found`)):(Yv.error(`Measure failed`,N(e)),K(`INTERNAL`,`Measure failed: ${e instanceof Error?e.message:String(e)}`))}}))}function $v(e){let t=U(`env`);e.registerTool(`env`,{title:t.title,description:`Get system and runtime environment info. Sensitive env vars are redacted by default.`,outputSchema:nc,inputSchema:{include_env:R.boolean().default(!1).describe(`Include environment variables`),filter_env:R.string().optional().describe(`Filter env vars by name substring`),show_sensitive:R.boolean().default(!1).describe(`Show sensitive values (keys, tokens, etc.) — redacted by default`)},annotations:t.annotations},q(`env`,async({include_env:e,filter_env:t,show_sensitive:n})=>{let r=Tt({includeEnv:e,filterEnv:t,showSensitive:n}),i=[`## Environment`,``,`**Platform:** ${r.system.platform} ${r.system.arch}`,`**OS:** ${r.system.type} ${r.system.release}`,`**Host:** ${r.system.hostname}`,`**CPUs:** ${r.system.cpus}`,`**Memory:** ${r.system.memoryFreeGb}GB free / ${r.system.memoryTotalGb}GB total`,``,`**Node:** ${r.runtime.node}`,`**V8:** ${r.runtime.v8}`,`**CWD:** ${r.cwd}`];if(r.env){i.push(``,`### Environment Variables`,``);for(let[e,t]of Object.entries(r.env))i.push(`- \`${e}\`: ${t}`)}let a={platform:r.system.platform,arch:r.system.arch,nodeVersion:r.runtime.node,cwd:r.cwd,cpus:r.system.cpus,memoryFreeGb:r.system.memoryFreeGb,memoryTotalGb:r.system.memoryTotalGb};return{content:[{type:`text`,text:i.join(`
3055
- `)}],structuredContent:a}}))}const ey=M(`register-tools`);function ty(e){try{let t=I(e,`.flows`);if(!P(t))return null;let n=je(t,{withFileTypes:!0});for(let e of n){if(!e.isDirectory())continue;let n=I(t,e.name,`meta.json`);if(P(n)&&JSON.parse(F(n,`utf-8`)).status===`active`)return e.name}}catch{return null}return null}function ny(e){let{server:t,aikit:n,config:r,elicitor:i,resourceNotifier:a,samplingClient:o,indexMode:s,getSmartState:c,getSmartScheduler:l,precomputedActiveTools:u}=e,d=new rs,f=r.sources[0]?.path??Oe(),p=xe(f),m={activeSlug:null};m.activeSlug=ty(f);let h=new bo(I(r.stateDir??``,`flow-context`),()=>m.activeSlug),g=new no;g.register(Ui()),g.register(Ya),g.register(oa),g.register(Pa),g.register(Xi),g.register(Wi),g.register(Gi),g.register(Ka),g.register(qi),g.register($a),g.register(Na(()=>m.activeSlug?{active:!0,slug:m.activeSlug}:null)),g.register(Ra),g.register(Za),g.register(ra),g.register(Ia);let _=new Ao,v=n.eventBus,y=r.skillDir?new Mo(r.skillDir,{debounceMs:5e3},v??void 0,n.curated):null,b=new oo(g,n.curated,{},h,_,v??void 0),x=u??Xs(r,[...ho,...ys],mo,xs(r)),S=e=>x.has(e),C=new Set([...x].filter(e=>!bp.includes(e)&&!So.has(e))),w=new Eo;d.use(ws(),{order:1,name:`structured-content-guard`}),d.use(yo(vo(r.tokenBudget)),{order:90,name:`compression`});let T=d.decisionHookRegistry;T.register({id:`search-budget`,order:10,scope:`search`,timeoutMs:100,failurePolicy:`degrade-with-warning`,decisionTypes:[`budgetHint`],reason:`Enforce token budget on search results`,fn:()=>({type:`decision`,hookId:`search-budget`,decision:`allow`,reason:`Budget hook active`})}),T.register({id:`find-path-containment`,order:10,scope:`find`,timeoutMs:50,failurePolicy:`fail-closed`,decisionTypes:[`deny`],reason:`Validate find scope against workspace boundaries`,fn:()=>({type:`decision`,hookId:`find-path-containment`,decision:`allow`,reason:`Path permitted`})}),T.register({id:`knowledge-mutation-safety`,order:10,scope:`knowledge`,timeoutMs:100,failurePolicy:`degrade-with-warning`,decisionTypes:[`deny`],reason:`Guard against unintended knowledge mutations`,fn:()=>({type:`decision`,hookId:`knowledge-mutation-safety`,decision:`allow`,reason:`Mutation permitted`})}),T.register({id:`check-scoped-run`,order:10,scope:`check`,timeoutMs:100,failurePolicy:`degrade-with-warning`,decisionTypes:[`allow`],reason:`Log check run scope for audit`,fn:()=>({type:`decision`,hookId:`check-scoped-run`,decision:`allow`,reason:`Check run permitted`})}),T.register({id:`test-run-scoped`,order:10,scope:`test_run`,timeoutMs:100,failurePolicy:`degrade-with-warning`,decisionTypes:[`allow`],reason:`Log test run scope for audit`,fn:()=>({type:`decision`,hookId:`test-run-scoped`,decision:`allow`,reason:`Test run permitted`})}),T.register({id:`onboard-path-correctness`,order:10,scope:`onboard`,timeoutMs:50,failurePolicy:`fail-closed`,decisionTypes:[`deny`],reason:`Validate onboard target path is valid and accessible`,fn:()=>({type:`decision`,hookId:`onboard-path-correctness`,decision:`allow`,reason:`Path valid`})}),T.register({id:`compact-budget-hints`,order:10,scope:`compact`,timeoutMs:100,failurePolicy:`degrade-with-warning`,decisionTypes:[`budgetHint`],reason:`Enforce token budget on compact output`,fn:()=>({type:`decision`,hookId:`compact-budget-hints`,decision:`allow`,reason:`Budget hook active`})}),T.register({id:`flow-step-safety`,order:10,scope:`flow`,timeoutMs:100,failurePolicy:`degrade-with-warning`,decisionTypes:[`allow`],reason:`Log flow step transitions`,fn:()=>({type:`decision`,hookId:`flow-step-safety`,decision:`allow`,reason:`Step permitted`})}),T.register({id:`present-transport-capability`,order:10,scope:`present`,timeoutMs:100,failurePolicy:`degrade-with-warning`,decisionTypes:[`allow`],reason:`Verify presentation transport is available`,fn:()=>({type:`decision`,hookId:`present-transport-capability`,decision:`allow`,reason:`Transport available`})});let E=new os(r.metricThresholds);Fs(t,d,r.toolPrefix??``,n.eventBus,()=>{let e=r.sources[0]?.path??Oe();try{return xe(e)}catch{return`partition:${Ye(`sha256`).update(e).digest(`hex`).slice(0,8)}`}}),v&&(v.subscribe({id:`sub-auto-knowledge`,eventType:`tool:after`,policy:`async`,handler:async e=>{if(!(`toolName`in e)||!(`args`in e)||!(`result`in e))return;let t=e;try{E.incrementCounter(`tool.call`,{tool:t.toolName}),t.isError&&E.incrementCounter(`tool.error`,{tool:t.toolName}),b.push({toolName:t.toolName,args:t.args,result:t.result,durationMs:t.durationMs,isError:t.isError,timestamp:new Date(t.timestamp).toISOString(),origin:t.origin,workspaceId:t.workspaceId,requestId:t.requestId})}catch{}},name:`auto-knowledge`}),v.subscribe({id:`sub-replay`,eventType:`tool:after`,policy:`async`,handler:async e=>{if(!(`toolName`in e)||!(`args`in e)||!(`result`in e))return;let t=e;try{let{replayAppend:e}=await import(`../../tools/dist/index.js`),n=JSON.stringify(t.args),r=JSON.stringify(t.result);e({ts:new Date(t.timestamp).toISOString(),source:`mcp`,tool:t.toolName,input:n.slice(0,2e3),outputChars:r.length,inputChars:n.length,durationMs:t.durationMs,status:t.isError?`error`:`ok`,output:r.slice(0,2e3),traceId:t.requestId??``})}catch{}},name:`replay`}),v.subscribe({id:`sub-procedural`,eventType:`tool:after`,policy:`async`,handler:async e=>{if(!(`toolName`in e)||!(`isError`in e))return;let t=e;try{C.has(t.toolName)&&w.record(t.toolName,!t.isError)}catch{}},name:`procedural-memory`}),v.subscribe({id:`sub-observations`,eventType:`tool:after`,policy:`async`,handler:async e=>{if(!(`toolName`in e)||!(`result`in e))return;let t=e;try{let{ObservationEngine:e,DEFAULT_OBSERVATION_CONFIG:r}=await import(`./observations-CfglxBMB.js`),i=new e(n.stateStore,n.curated),{captureFrom:a}=r;a.includes(t.toolName)&&await i.processToolResult(t.toolName,t.result,{})}catch{}},name:`observation-capture`}),v.subscribe({id:`sub-knowledge-metrics`,eventType:`tool:after`,policy:`async`,handler:async e=>{if(!(`toolName`in e)||!(`result`in e))return;let t=e;if(t.toolName===`knowledge`)try{let e=t.result,n=t.args?.action;(n===`remember`||n===`update`)&&(E.incrementCounter(`fact.total`),(e?.status===`unchanged`||e?.result===`unchanged`)&&E.incrementCounter(`fact.duplicate`))}catch{}},name:`knowledge-metrics`}),v.subscribe({id:`sub-session`,eventType:`session:start`,policy:`async`,handler:async e=>{let t=e,n={serverVersion:t.serverVersion,workspaceRoot:t.workspaceRoot,handoff:t.handoff?`${t.handoff.from} (session ${t.handoff.sessionId})`:void 0};ey.info(`Session started`,n)},name:`session-lifecycle`}),y&&y.subscribeToEventBus(v));let D=[...x].filter(e=>bs.has(e)?vs.includes(e)?!!n.bridge:e===`er_update_policy`?!!n.policyStore:e===`er_evolve_review`?!!n.evolutionCollector:!1:!0);S(`search`)&&K_(t,n.embedder,n.store,n.graphStore,n.bridge,n.evolutionCollector,o,n.stateStore,r.memory?.retention,r.memory?.consolidation,p);let O={store:n.store,graphStore:n.graphStore,embedder:n.embedder},k={onboardComplete:n.onboardComplete,onboardTimestamp:n.onboardTimestamp};S(`status`)&&Jv(t,n.store,n.graphStore,n.curated,k,r,s,c,n.stateStore,n.eventBus,d.decisionHookRegistry,d.getObservationCompressor(),g,_,y),S(`analyze`)&&rl(t,n.store,n.embedder),S(`find`)&&ql(t,n.embedder,n.store),S(`symbol`)&&Jl(t,n.embedder,n.store,n.graphStore,O),S(`scope_map`)&&Kl(t,n.embedder,n.store,O),S(`config`)&&Fl(t,r),S(`knowledge`)&&mp(t,n.curated,n.policyStore,n.evolutionCollector,a,void 0,n.stateStore,r.memory?.retention,r.memory?.supersession,r.memory?.consolidation,r.memory?.lessons,O,n.graphStore),S(`produce_knowledge`)&&S_(t,a),S(`graph`)&&bd(t,n.graphStore),S(`onboard`)&&Hp(t,n.store,n.embedder,r,k,O,o,a),S(`reindex`)&&w_(t,n.indexer,r,n.curated,n.store,a,s),S(`check`)&&eu(t,O,r.tokenBudget),S(`test_run`)&&nu(t,O),S(`eval`)&&tu(t),S(`parse_output`)&&ru(t),S(`audit`)&&cl(t,n.store,n.embedder),S(`git`)&&gd(t),S(`rename`)&&vp(t,r),S(`codemod`)&&yp(t,r),S(`restore`)&&O_(t),S(`file_summary`)&&su(t,n.embedder,n.fileCache),S(`trace`)&&Yl(t,n.embedder,n.store,n.graphStore,O),S(`process`)&&Sd(t),S(`delegate`)&&iu(t,o),S(`queue`)&&Wp(t),S(`web_fetch`)&&Cd(t),bp.some(e=>S(e))&&xp(t,r,D),S(`evidence_map`)&&fd(t),S(`digest`)&&pd(t,n.embedder),S(`forge_ground`)&&md(t,n.embedder,n.store),S(`present`)&&b_(t,i),S(`browser`)&&er(t,r),S(`web_search`)&&Zv(t),S(`measure`)&&Qv(t),S(`env`)&&$v(t),S(`flow`)&&ud(t,r,{store:n.store?{search:async(e,t)=>(await n.store.ftsSearch(e,t)).map(e=>({content:e.record.content}))}:null,graphStore:n.graphStore,embedder:n.embedder,curated:n.curated??null,eventBus:n.eventBus??null,skillCompiler:y},e=>{m.activeSlug=e}),n.bridge&&vs.some(e=>S(e))&&(fl(t,n.bridge,n.evolutionCollector),pl(t,n.bridge),ml(t,n.bridge)),n.policyStore&&S(`er_update_policy`)&&qp(t,n.policyStore),n.evolutionCollector&&S(`er_evolve_review`)&&Ql(t,n.evolutionCollector),_s(t,n.store,n.curated,r.skillDir,n.eventBus,d.decisionHookRegistry,y),S(`session`)&&uv(t,n.stateStore,o),S(`replay`)&&E_(t)}function ry(e,t,n){let r=e=>!n||n.has(e);r(`check`)&&eu(e,void 0,t.tokenBudget),r(`eval`)&&tu(e),r(`test_run`)&&nu(e),r(`parse_output`)&&ru(e),r(`delegate`)&&iu(e),r(`git`)&&gd(e),r(`rename`)&&vp(e,t),r(`codemod`)&&yp(e,t),r(`restore`)&&O_(e),r(`queue`)&&Wp(e),r(`process`)&&Sd(e),r(`web_fetch`)&&Cd(e),bp.some(e=>r(e))&&xp(e,t,[...n??new Set(ho)]),r(`evidence_map`)&&fd(e),r(`present`)&&b_(e),r(`browser`)&&er(e,t),r(`produce_knowledge`)&&S_(e),r(`replay`)&&E_(e),r(`status`)&&qv(e),r(`flow`)&&ud(e,t),r(`web_search`)&&Zv(e),r(`measure`)&&Qv(e),r(`env`)&&$v(e)}const iy=M(`resource-notifier`);var ay=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){iy.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){iy.debug(`sendResourceUpdated failed`,{uri:e,error:String(t)})}}};const Q=M(`server`);function oy(e){let t=e?.trim().toLowerCase();return t===`1`||t===`true`||t===`yes`||t===`on`}async function sy(n){Q.info(`Initializing AI Kit components`);let r=n.store.backend,i=n.embedding,a=ye[i.model],o={model:i.model,nativeDim:i.nativeDim??a?.nativeDim??ge.nativeDim,dimensions:i.dimensions??a?.dimensions??ge.dimensions,queryPrefix:i.queryPrefix??a?.queryPrefix??ge.queryPrefix,pooling:i.pooling??a?.pooling??`mean`},s=n.store.path,c=oy(process.env.AIKIT_SPLIT_STATE),l=I(s,`aikit.db`),u={splitEnabled:c,contentDbPath:l,controlDbPath:c?I(s,`aikit-control.db`):l},d=null;if(r===`sqlite-vec`){let e=u.contentDbPath;P(s)||Ae(s,{recursive:!0}),d=await Cr(e),Q.debug(`SQLite adapter ready`,{type:d.type,vectorCapable:d.vectorCapable,dbPath:e}),d.vectorCapable||Q.warn(`┌──────────────────────────────────────────────────────────────────┐
3056
- │ ⚠ SQLite vector extension unavailable — DEGRADED MODE │
3057
- │ Vector search is disabled. Hybrid search returns FTS only. │
3058
- │ To enable: install/rebuild better-sqlite3 (native module). │
3059
- └──────────────────────────────────────────────────────────────────┘`);let t=I(s,`lance`);P(t)&&Q.info(`Old LanceDB data found at ${t} — ignored. Safe to delete after verifying sqlite-vec works.`)}let f;if(d)if(u.splitEnabled&&u.controlDbPath!==u.contentDbPath){let{migrateToSplitState:e}=await import(`../../store/dist/index.js`);await e(u),f=await Cr(u.controlDbPath),Er(f,Sr),Q.info(`State store adapter ready`,{type:f.type,dbPath:u.controlDbPath,splitEnabled:!0})}else f=d;else{let e=I(s,`aikit-state.db`);P(s)||Ae(s,{recursive:!0}),f=await Cr(e),Er(f,Sr),Q.info(`State store adapter ready`,{type:f.type,dbPath:e})}let[p,m,h,g]=await Promise.all([(async()=>{try{if(n.embedding.childProcess!==!1){let e=new Gr({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(),Q.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(),Q.debug(`Embedder loaded (in-process)`,{modelId:t.modelId,dimensions:t.dimensions}),t}catch(e){return Q.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 Tr({backend:r,path:s,adapter:d??void 0,embeddingDim:o.dimensions,embeddingProfile:o,partition:u}):await Tr({backend:r,path:s,adapter:d??void 0,embeddingDim:o.dimensions,partition:void 0});return await e.initialize(),Q.debug(`Store initialized`,{backend:r}),e})(),(async()=>{let e=d?new xr({adapter:d}):new xr({path:s});return await e.initialize(),Q.debug(`Graph store initialized`,{shared:!!d}),e})(),(async()=>{let e=await ur();if(e){let e=cr.get();Q.debug(`WASM tree-sitter enabled`,{grammars:e.grammarCount,dir:e.wasmDir})}else{let e=cr.get();Q.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})()]),_=new qr(p,m),v=wr(f),y=new Kr(n.store.path);y.load(),_.setHashCache(y);let b=n.curated.path,x=new e(b);await x.initialize();let S=new t(b,m,p,x);_.setGraphStore(h);let C=dl(n.er),w=C?new mr(n.curated.path):void 0;w&&Q.debug(`Policy store initialized`,{ruleCount:w.getRules().length});let T=C?new pr:void 0,E=L(n.sources[0]?.path??Oe(),de.aiContext),D=P(E),O=n.onboardDir?P(n.onboardDir):!1,k=D||O,ee,te=D?E:n.onboardDir;if(k&&te)try{ee=Pe(te).mtime.toISOString()}catch{}return Q.debug(`Onboard state detected`,{onboardComplete:k,onboardTimestamp:ee,aiKbExists:D,onboardDirExists:O}),{embedder:p,store:m,stateStore:v,closeStateStore:f===d?void 0:async()=>f.close(),indexer:_,curated:S,graphStore:h,fileCache:new $e,bridge:C,policyStore:w,evolutionCollector:T,onboardComplete:k,onboardTimestamp:ee,eventBus:new Lo}}function cy(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(`
3060
- `)}const ly=M(`background-task`);var uy=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,ly.info(`Background task started`,{task:e.name,pending:this.queue.length});let t=Date.now();try{await e.fn();let n=Date.now()-t;ly.info(`Background task completed`,{task:e.name,durationMs:n}),e.resolve()}catch(n){let r=Date.now()-t;ly.error(`Background task failed`,{task:e.name,durationMs:r,err:n}),e.reject(n instanceof Error?n:Error(String(n)))}}this.running=null}};const dy=M(`idle-timer`);var fy=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){dy.info(`Idle timeout reached with no active session — skipping cleanup (waiting for first tool call)`);return}if(this._busy){dy.info(`Skipping idle cleanup — background work in progress`);return}dy.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`&&dy.warn(`Idle cleanup callback failed`,{error:String(t.reason)})}};const py=M(`memory-monitor`);var my=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(),py.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`?py.warn(`Memory CRITICAL: ${n}MB RSS — consider restarting the server`):t===`warning`?py.warn(`Memory WARNING: ${n}MB RSS`):this.lastLevel!==`normal`&&py.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 hy=new Jr;function gy(e,t){return hy.run(e,async()=>{try{return await t()}finally{}})}M(`tool-timeout`);const _y=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze`,`codemod`,`audit`]);var vy=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 yy(e){return _y.has(e)?6e5:12e4}function by(e,t,n){let r=new AbortController,i=r.signal;return new Promise((a,o)=>{let s=setTimeout(()=>{let e=new vy(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 $=M(`server`),xy=new Set([`status`,`list_tools`,`describe_tool`,`config`,`env`,`present`]);function Sy(e,t=28){let n=e.replace(/\s+/g,` `).trim();return n.length<=t?n:`${n.slice(0,t-3)}...`}function Cy(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 wy(e,t,n,r){let i=[];if(n){let t=await Ty(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=>`"${Sy(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(`./prelude-CZ1LShfj.js`),o=e(await a(r,n.stateStore,void 0,t.skillDir),500);o.lines.length>0&&i.push(o.lines.join(`
3061
- `))}catch(e){$.debug?.(`Periodic prelude injection failed`,{error:String(e)})}}return i.length===0?null:`\n${i.join(`
3062
- `)}`}async function Ty(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 r=[];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 i=t.content??``;if(!(!i||i.length<20)){if(i.length<=400){let e=t.headingPath?.trim()||``,n=i.slice(0,400),a=e?`📚 ${e}: ${n}`:`📚 ${n}`;r.push(a)}else{let e=Zf(i,400),n=t.headingPath?.trim()||``,a=n?`📚 ${n}: ${e}`:`📚 ${e}`;r.push(a)}if(r.length>=2)break}}return r.length===0?null:r.join(`
3063
- `)}catch{return null}}function Ey(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||xy.has(a))return s;try{r--,i++;let e=o[0],a=await wy(t,n,Cy(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 Dy(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 Oy(e){return Mp(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(`
3064
- `):[`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(`
3065
- `)}async function ky(){try{let{existsSync:e,readFileSync:t}=await import(`node:fs`),n=I(Wn(),`.aikit`,`current-version.json`);if(!e(n))return null;let r=JSON.parse(t(n,`utf-8`));if(!r.version)return null;let i=oe();return r.version===i?null:r.version}catch{return null}}async function Ay(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(`
3066
- `),`utf8`),$.info(`Auto-heal: created ESM shim for @huggingface/transformers (.mjs wrapper → .cjs)`,{path:t}))}catch(e){$.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(Wn(),`.cache`,`huggingface`,`transformers-js`,t);try{await r(e,{recursive:!0,force:!0}),$.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}),$.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}),$.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(()=>{}),$.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(()=>{}),$.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}),$.debug(`Auto-heal: removed stale WASM temp file`,{file:e})}catch{}}}catch{}if(Mp(t)){let e=await Fp(t);e.repaired||$.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`)&&$.warn(`Auto-heal: missing module detected during initialization cleanup`,{hint:`Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve`})}function jy(e,t){let n=Xs(e,ho,mo,xs(e)),r=cy(e,n,mo),i=new Kn({name:e.serverName??he,version:oe()},{capabilities:{logging:{},completions:{},prompts:{}},instructions:r}),a=`initializing`,o=``,s=!1,c=null,l=null,u=null;function d(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 f=()=>a===`failed`?[`❌ AI Kit initialization failed — this tool is unavailable.`,``,o?`Error: ${o}`:``,``,`**${go.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.`,``,Oy(o),``,`Try restarting the MCP server to retry initialization.`].filter(Boolean).join(`
3067
- `):[`AI Kit is still initializing (loading embeddings model & store).`,``,`**${go.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(`
3068
- `);ti(i);let p=new rs;p.use(ws(),{order:1,name:`structured-content-guard`}),Fs(i,p,e.toolPrefix??``);let m=i.sendToolListChanged.bind(i);i.sendToolListChanged=()=>{};let h=[];for(let e of ho){if(!n.has(e))continue;let t=U(e),r=i.registerTool(e,{title:t.title,description:`${t.title} — initializing, available shortly`,inputSchema:{},annotations:t.annotations},async()=>({content:[{type:`text`,text:f()}]}));go.has(e)?r.remove():h.push(r)}ry(i,e,n),i.sendToolListChanged=m;let g=i.registerResource(`aikit-status`,`aikit://status`,{description:`AI Kit status (initializing...)`,mimeType:`text/plain`},async()=>({contents:[{uri:`aikit://status`,text:`AI Kit is initializing...`,mimeType:`text/plain`}]})),_=i.registerPrompt(`_init`,{description:`Initializing AI Kit…`,argsSchema:{_dummy:Qn(R.string(),()=>[])}},async()=>({messages:[]})),v,y,b=new Promise((e,t)=>{v=e,y=t}),x,S=new Promise(e=>{x=e}),C=()=>x?.(),w=(async()=>{await S;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&&$.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&&$.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 sy(e)}catch(t){let r=t instanceof Error?t.message:String(t);if(Dy(r)){let t=await ky();if(t){a=`failed`,o=`Server v${oe()} superseded by installed v${t}. Restart the MCP server to use the new version.`,$.info(o),y?.(Error(o));return}$.warn(`AI Kit initialization failed with recoverable error — attempting auto-heal retry`,{error:r}),await Ay(e,r);try{n=await sy(e),$.info(`AI Kit auto-heal successful — initialization recovered after retry`)}catch(e){a=`failed`,o=e instanceof Error?e.message:String(e),$.error(`AI Kit initialization failed after auto-heal attempt — server continuing with zero-dep tools only`,{error:o,originalError:r}),y?.(e instanceof Error?e:Error(o));return}}else{a=`failed`,o=r,$.error(`AI Kit initialization failed — server continuing with zero-dep tools only`,{error:o}),y?.(t instanceof Error?t:Error(o));return}}ae();let r=i.sendToolListChanged.bind(i);i.sendToolListChanged=()=>{};let f=i.sendPromptListChanged.bind(i);i.sendPromptListChanged=()=>{};let p=i.sendResourceListChanged.bind(i);i.sendResourceListChanged=()=>{};for(let e of h)e.remove();g.remove(),_.remove();let m=i._registeredTools??{};for(let e of go)m[e]?.remove();let b=new ay(i),x=Qr(i);ny({server:i,aikit:n,config:e,elicitor:$r(i),resourceNotifier:b,samplingClient:x,indexMode:t,getSmartState:t===`smart`?(()=>{let e=u;return e?.getState?e.getState():null}):null,getSmartScheduler:t===`smart`?()=>{let e=u;return e?{prioritize:e.prioritize.bind(e)}:null}:null}),fi(i,{curated:n.curated,store:n.store,graphStore:n.graphStore,stateStore:n.stateStore},t),i.sendToolListChanged=r,i.sendPromptListChanged=f,i.sendResourceListChanged=p,Promise.resolve(i.sendToolListChanged()).catch(()=>{}),Promise.resolve(i.sendPromptListChanged()).catch(()=>{}),Promise.resolve(i.sendResourceListChanged()).catch(()=>{});let C=i._registeredTools??{};for(let[e,t]of Object.entries(C)){if(_o.has(e))continue;let r=t.handler;t.handler=async(...i)=>{if(!n.indexer.isIndexing)return r(...i);let a=s?`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 (${Ss/1e3}s).\n\nThe existing index may be temporarily locked. Please retry shortly — indexing will complete automatically.`}],...t.config?.outputSchema?{structuredContent:As(t.config.outputSchema)}:{}}),Ss));return Promise.race([r(...i),o])}}for(let[e,t]of Object.entries(C)){let n=t.handler,r=yy(e);t.handler=async(...i)=>{try{return await by(e=>gy(e,()=>n(...i)),r,e)}catch(n){if(n instanceof vy)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:As(t.config.outputSchema)}:{}};throw n}}}let w=Object.keys(C).length;w<ho.length&&$.warn(`ALL_TOOL_NAMES count mismatch`,{expectedToolCount:ho.length,registeredToolCount:w}),$.debug(`MCP server configured`,{toolCount:ho.length,resourceCount:4});let T=new my;T.onPressure((e,t)=>{e===`warning`&&ai(),e===`critical`&&($.warn(`Memory pressure critical — consider restarting`,{rssMB:Math.round(t/1024/1024)}),ai())}),T.registerMemoryPressureCallback(()=>n.embedder.shutdown?.()),T.start();let D=new fy;l=D,D.onIdle(async()=>{if(E.isRunning||n.indexer.isIndexing){$.info(`Idle cleanup deferred — background tasks still running`),D.touch();return}$.info(`Idle cleanup: releasing cached memory (connections stay open)`);try{n.store.releaseMemory?.(),n.graphStore.releaseMemory?.()}catch{}}),D.touch();let O=!1;for(let e of Object.values(C)){let t=e.handler;e.handler=async(...e)=>{if(O||(O=!0,D.markSessionActive()),D.touch(),u){let t=d(e[0]);t.length>0&&u.prioritize(...t)}return t(...e)}}Ey(C,n,{statePath:e.stateDir??``,skillDir:e.skillDir});for(let[,e]of Object.entries(C)){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=As(t),i.structuredContent??={},r)}}process.stdin.on(`end`,()=>($.info(`stdin closed — MCP client disconnected. Shutting down.`),process.exit(0))),process.stdin.on(`error`,()=>($.info(`stdin error — MCP client disconnected. Shutting down.`),process.exit(0))),c=n,v?.(n)})(),T=async()=>{let t;try{t=await b}catch{$.warn(`Skipping initial index — AI Kit initialization failed`);return}l?.setBusy(!0);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}))});s=!0,$.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))}finally{l?.setBusy(!1)}},E=new uy,D=()=>E.schedule({name:`initial-index`,fn:T}),O=process.ppid,k=setInterval(()=>{try{process.kill(O,0)}catch{$.info(`Parent process died; shutting down`,{parentPid:O}),clearInterval(k),u?.stop&&u.stop(),import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),b.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 k.unref(),{server:i,startInit:C,ready:w,runInitialIndex:D,get aikit(){return c},scheduler:E,setSmartScheduler(e){u=e}}}const My=M(`server`);function Ny(e,t){let n=Xs(t,[...ho,...ys],mo,xs(t)),r=cy(t,n,mo),i=new Kn({name:t.serverName??he,version:oe()},{capabilities:{logging:{},completions:{},prompts:{},extensions:{roots:{}}},instructions:r}),a=i;a.setNotificationHandler(Jn,async()=>{try{let{roots:e}=await a.listRoots();if(e&&e.length>0){let n=le(e[0].uri);process.env.AIKIT_TRANSPORT===`http`?(t.sources[0]={path:n,excludePatterns:t.sources[0]?.excludePatterns??[]},t.allRoots=e.map(e=>le(e.uri)),My.info(`Workspace root updated (HTTP mode)`,{rootPath:n,sourceCount:t.sources.length})):(x(t,n),My.info(`Workspace root updated (stdio mode)`,{rootPath:n}))}}catch(e){My.debug(`MCP roots/list not available`,{error:N(e)})}}),ti(i),ny({server:i,aikit:e,config:t,elicitor:$r(i),resourceNotifier:new ay(i),samplingClient:Qr(i),precomputedActiveTools:n});let o=t.sources[0]?.path??Oe();return e.eventBus?.emit({type:`session:start`,serverVersion:oe(),workspaceRoot:o,timestamp:Date.now(),eventId:`sess-start-${Date.now()}`,workspaceId:xe(o),source:`server`}),fi(i,{curated:e.curated,store:e.store,graphStore:e.graphStore,stateStore:e.stateStore},t.indexMode),i}async function Py(e){let t=await sy(e),n=Ny(t,e);My.debug(`MCP server configured`,{toolCount:ho.length,resourceCount:2});let r=async()=>{try{let n=e.sources.map(e=>e.path).join(`, `);My.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&&My.debug(`Indexing file`,{current:e.filesProcessed+1,total:e.filesTotal,file:e.currentFile}),e.phase===`cleanup`&&My.debug(`Index cleanup`,{staleEntries:e.filesTotal-e.filesProcessed}))});My.info(`Initial index complete`,{filesProcessed:r.filesProcessed,filesSkipped:r.filesSkipped,chunksCreated:r.chunksCreated,durationMs:r.durationMs});try{await t.store.createFtsIndex()}catch(e){My.warn(`FTS index creation failed`,N(e))}try{let e=await t.curated.reindexAll();My.info(`Curated re-index complete`,{indexed:e.indexed})}catch(e){My.error(`Curated re-index failed`,N(e))}}catch(e){My.error(`Initial index failed; will retry on aikit_reindex`,N(e))}},i=async()=>{My.info(`Shutting down`),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{My.info(`Parent process died; shutting down`,{parentPid:a}),clearInterval(o),i()}},5e3);return o.unref(),{server:n,runInitialIndex:r,shutdown:i}}export{ho as ALL_TOOL_NAMES,jy as createLazyServer,Ny as createMcpServer,Py as createServer,sy as initializeAikit,Nv as n,Qr as r,ny as registerMcpTools,Pv as t};