@vpxa/aikit 0.1.377 → 0.1.378

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 (28) hide show
  1. package/package.json +1 -1
  2. package/packages/browser/dist/index.js +1 -1
  3. package/packages/claude-desktop/dist/manifest.json +1 -1
  4. package/packages/cli/dist/index.js +3 -3
  5. package/packages/cli/dist/{init-CAIdybTd.js → init-gDbVIWiP.js} +1 -1
  6. package/packages/cli/dist/{templates-3q6NnbZs.js → templates-BPC4t5yz.js} +1 -1
  7. package/packages/server/dist/bin.js +1 -1
  8. package/packages/server/dist/index.js +1 -1
  9. package/packages/server/dist/prelude-C4z3H1li.js +1 -0
  10. package/packages/server/dist/prelude-WsqQzR-u.js +2 -0
  11. package/packages/server/dist/sampling-Bpwc-4Jr.js +2 -0
  12. package/packages/server/dist/sampling-CfLD3fM_.js +1 -0
  13. package/packages/server/dist/{server-B9RF008q.js → server-D2a5Rjgk.js} +3 -3
  14. package/packages/server/dist/{server-http-4z6DRLev.js → server-http-B841uX1k.js} +1 -1
  15. package/packages/server/dist/{server-http-CUG7Wtib.js → server-http-tZxvg5ke.js} +1 -1
  16. package/packages/server/dist/{server-D3IS2SBd.js → server-jZ_r6xLb.js} +3 -3
  17. package/packages/server/dist/{server-stdio-CGrww9xa.js → server-stdio-B22xZT0d.js} +1 -1
  18. package/packages/server/dist/{server-stdio-CuhNvKfr.js → server-stdio-DpGfc6DI.js} +1 -1
  19. package/scaffold/dist/adapters/claude-code.mjs +7 -7
  20. package/scaffold/dist/definitions/bodies.mjs +10 -0
  21. package/scaffold/dist/definitions/exec-hooks.mjs +1 -1
  22. package/scaffold/general/hooks/scripts/bash-guard.mjs +76 -0
  23. package/scaffold/general/hooks/scripts/read-size-guard.mjs +61 -0
  24. package/scaffold/general/hooks/scripts/session-reminder.mjs +108 -26
  25. package/packages/server/dist/prelude-BWAg5ESi.js +0 -2
  26. package/packages/server/dist/prelude-qHhtG0FU.js +0 -1
  27. package/packages/server/dist/sampling-D61kCvwj.js +0 -2
  28. package/packages/server/dist/sampling-DIln2Pr4.js +0 -1
@@ -194,7 +194,7 @@ Output ONLY the README.md content, nothing else.`;if(t.available)try{let i=(awai
194
194
 
195
195
  `).trim();r=t?dd(t):null}let i=Array.from(e.matchAll(/^##\s+.*$/gm)),a=[];for(let[t,n]of i.entries()){let r=n[0];if(!ld.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(`
196
196
 
197
- `):null}}function pd(e,t){return t(e)}async function md(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=pd(n,t.getStepSequence),u=await $u({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}=fd(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 hd(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=null,s.currentStepBrief=n.currentStepBrief,s.currentStepPins=n.currentStepPins,s.fullContentHint=`Call flow({ action: 'read' }) for the complete step instructions.`,s}function gd(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 _d(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 Zu(`UNKNOWN_FLOW`,`Flow "${d}" not found. Use flow({ action: "list" }) to see available flows.`);let w=S.start(C.name,C.manifest,f,gd(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 Zu(`FLOW_ALREADY_ACTIVE`,e).message}`):u(`Cannot start: ${e}`)}let T=w.data,E;if(t.config.layeredKnowledge){let e=Hr(),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 md({context:t,entry:C,state:T,activeRoot:b,primaryRoot:null,roots:p??null}),ee=Vr(T,C.manifest,{objective:m,acceptanceCriteria:h,scope:g,exclusions:_}),te={...hd({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:sd,...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 Qu(e)?u(e.message):(o.error(`flow action start failed`,N(e)),u(`Error: ${l(e)}`))}}async function vd(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(!Wr(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 md({context:t,entry:p,state:h,activeRoot:e,primaryRoot:h.primaryRoot,roots:h.roots}),_={...hd({state:h,data:g,includeStatus:!0,action:`backtrack`}),_hint:h.currentStep?sd: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 Qu(e)?s(e.message):(r.error(`flow action backtrack failed`,N(e)),s(`Error: ${o(e)}`))}}async function yd(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-DIln2Pr4.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=Ur(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 Qu(e)?s(e.message):(r.error(`flow action claim failed`,N(e)),s(`Error: ${o(e)}`))}}async function bd(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 Zu(`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 md({context:e,entry:u,state:l,activeRoot:n,primaryRoot:l.primaryRoot,roots:l.roots}):ud(),f={...hd({state:l,data:d,includeStatus:!0,includeInstructionPath:!0}),_hint:l.currentStep?sd: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`,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 Qu(e)?o(e.message):(n.error(`flow action status failed`,N(e)),o(`Error: ${a(e)}`))}}async function xd(e){let{getFlows:t,log:n,resolveFlowRoot:r,stateDir:i,syncMetaToRoots:a,toErrorText:o,toTextResponse:s}=e;try{let e=await r(),{stateMachine:n}=await t(e),o=n.getStatus(),c=n.reset();if(!c.success)return s(`Reset failed: ${c.error}`);if(o.success&&o.data&&a(o.data.slug,e),o.success&&o.data?.slug)try{await Ge(I(i,`flow-context`,o.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 Sd(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?vd({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 Zu(`NO_ACTIVE_FLOW`,`No active flow. Use flow({ action: "start", name: "<flow>" }) first.`);let u=r.get(l.data.flow);if(!u)throw new Zu(`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,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 md({context:t,entry:u,state:f,activeRoot:e,primaryRoot:f.primaryRoot,roots:f.roots}),h={...hd({state:f,data:m,includeStatus:!0,action:c}),_hint:f.currentStep?sd: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 Qu(e)?s(e.message):(r.error(`flow action step failed`,N(e)),s(`Error: ${o(e)}`))}}async function Cd(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 wd(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 Zu(`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 Qu(e)?s(e.message):(r.error(`flow action info failed`,N(e)),s(`Error: ${o(e)}`))}}async function Td(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 Ed(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 Dd(e,t,n,r){let i=n&&typeof n!=`function`?n:void 0,a=typeof n==`function`?n:r,o=Xu(e,t,i),s=G(`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).`)}},Y(`flow`,async e=>{switch(e.action){case`list`:return Cd(o);case`info`:return e.name?wd({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 _d({flow:e.name,topic:e.topic,roots:e.roots,objective:e.objective,acceptanceCriteria:e.acceptanceCriteria,scope:e.scope,exclusions:e.exclusions},o),n=Ed(t);return n&&a&&a(n),t}case`step`:return e.advance?Sd({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 bd(o);return a&&a(Ed(e)),e}case`reset`:{let e=await xd(o);return a&&a(null),e}case`read`:return ed({step:e.step},o);case`runs`:return Td({flow:e.filter_flow,status:e.filter_status,limit:e.limit},o);case`add`:return e.source?id({source:e.source,name:e.name,token:e.token},o):o.toTextResponse(`Missing required parameter: source`);case`remove`:return e.name?ad({name:e.name},o):o.toTextResponse(`Missing required parameter: name`);case`update`:return e.name?od({name:e.name},o):o.toTextResponse(`Missing required parameter: name`);case`backtrack`:return e.targetStep?vd({targetStep:e.targetStep,lifecycleOwnerToken:e.lifecycleOwnerToken,currentToken:e.currentToken},o):o.toTextResponse(`Missing required parameter: targetStep for backtrack action`);case`claim`:return yd({currentToken:e.currentToken},o);default:return o.toTextResponse(`Unknown action: ${e.action}`)}}))}const Od=M(`tools`);function kd(e){let t=G(`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},Y(`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 kt({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=kt({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(`
197
+ `):null}}function pd(e,t){return t(e)}async function md(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=pd(n,t.getStepSequence),u=await $u({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}=fd(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 hd(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=null,s.currentStepBrief=n.currentStepBrief,s.currentStepPins=n.currentStepPins,s.fullContentHint=`Call flow({ action: 'read' }) for the complete step instructions.`,s}function gd(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 _d(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 Zu(`UNKNOWN_FLOW`,`Flow "${d}" not found. Use flow({ action: "list" }) to see available flows.`);let w=S.start(C.name,C.manifest,f,gd(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 Zu(`FLOW_ALREADY_ACTIVE`,e).message}`):u(`Cannot start: ${e}`)}let T=w.data,E;if(t.config.layeredKnowledge){let e=Hr(),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 md({context:t,entry:C,state:T,activeRoot:b,primaryRoot:null,roots:p??null}),ee=Vr(T,C.manifest,{objective:m,acceptanceCriteria:h,scope:g,exclusions:_}),te={...hd({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:sd,...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 Qu(e)?u(e.message):(o.error(`flow action start failed`,N(e)),u(`Error: ${l(e)}`))}}async function vd(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(!Wr(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 md({context:t,entry:p,state:h,activeRoot:e,primaryRoot:h.primaryRoot,roots:h.roots}),_={...hd({state:h,data:g,includeStatus:!0,action:`backtrack`}),_hint:h.currentStep?sd: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 Qu(e)?s(e.message):(r.error(`flow action backtrack failed`,N(e)),s(`Error: ${o(e)}`))}}async function yd(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-CfLD3fM_.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=Ur(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 Qu(e)?s(e.message):(r.error(`flow action claim failed`,N(e)),s(`Error: ${o(e)}`))}}async function bd(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 Zu(`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 md({context:e,entry:u,state:l,activeRoot:n,primaryRoot:l.primaryRoot,roots:l.roots}):ud(),f={...hd({state:l,data:d,includeStatus:!0,includeInstructionPath:!0}),_hint:l.currentStep?sd: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`,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 Qu(e)?o(e.message):(n.error(`flow action status failed`,N(e)),o(`Error: ${a(e)}`))}}async function xd(e){let{getFlows:t,log:n,resolveFlowRoot:r,stateDir:i,syncMetaToRoots:a,toErrorText:o,toTextResponse:s}=e;try{let e=await r(),{stateMachine:n}=await t(e),o=n.getStatus(),c=n.reset();if(!c.success)return s(`Reset failed: ${c.error}`);if(o.success&&o.data&&a(o.data.slug,e),o.success&&o.data?.slug)try{await Ge(I(i,`flow-context`,o.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 Sd(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?vd({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 Zu(`NO_ACTIVE_FLOW`,`No active flow. Use flow({ action: "start", name: "<flow>" }) first.`);let u=r.get(l.data.flow);if(!u)throw new Zu(`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,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 md({context:t,entry:u,state:f,activeRoot:e,primaryRoot:f.primaryRoot,roots:f.roots}),h={...hd({state:f,data:m,includeStatus:!0,action:c}),_hint:f.currentStep?sd: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 Qu(e)?s(e.message):(r.error(`flow action step failed`,N(e)),s(`Error: ${o(e)}`))}}async function Cd(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 wd(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 Zu(`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 Qu(e)?s(e.message):(r.error(`flow action info failed`,N(e)),s(`Error: ${o(e)}`))}}async function Td(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 Ed(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 Dd(e,t,n,r){let i=n&&typeof n!=`function`?n:void 0,a=typeof n==`function`?n:r,o=Xu(e,t,i),s=G(`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).`)}},Y(`flow`,async e=>{switch(e.action){case`list`:return Cd(o);case`info`:return e.name?wd({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 _d({flow:e.name,topic:e.topic,roots:e.roots,objective:e.objective,acceptanceCriteria:e.acceptanceCriteria,scope:e.scope,exclusions:e.exclusions},o),n=Ed(t);return n&&a&&a(n),t}case`step`:return e.advance?Sd({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 bd(o);return a&&a(Ed(e)),e}case`reset`:{let e=await xd(o);return a&&a(null),e}case`read`:return ed({step:e.step},o);case`runs`:return Td({flow:e.filter_flow,status:e.filter_status,limit:e.limit},o);case`add`:return e.source?id({source:e.source,name:e.name,token:e.token},o):o.toTextResponse(`Missing required parameter: source`);case`remove`:return e.name?ad({name:e.name},o):o.toTextResponse(`Missing required parameter: name`);case`update`:return e.name?od({name:e.name},o):o.toTextResponse(`Missing required parameter: name`);case`backtrack`:return e.targetStep?vd({targetStep:e.targetStep,lifecycleOwnerToken:e.lifecycleOwnerToken,currentToken:e.currentToken},o):o.toTextResponse(`Missing required parameter: targetStep for backtrack action`);case`claim`:return yd({currentToken:e.currentToken},o);default:return o.toTextResponse(`Unknown action: ${e.action}`)}}))}const Od=M(`tools`);function kd(e){let t=G(`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},Y(`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 kt({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=kt({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(`
198
198
  `)}]}}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=kt({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(`
199
199
  `)}]}}case`get`:{if(!t)throw Error(`task_id required for get`);let e=kt({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(`
200
200
  `)}]}:{content:[{type:`text`,text:`Evidence map "${t}" not found.`}]}}case`gate`:{if(!t)throw Error(`task_id required for gate`);let e=kt({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(`
@@ -3020,7 +3020,7 @@ window.addEventListener('message', function(e) {
3020
3020
  })();
3021
3021
  <\/script>`}function E_(e){w_=e||``}function D_(e,t){if(!w_)return e;let n=`${`<script${t?` nonce="${X(t)}"`:``}>${w_}<\/script>`}\n${T_(t||``)}`;return e.includes(`</body>`)?e.replace(`</body>`,`${n}\n</body>`):`${e}${n}`}function O_(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 — ${X(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">${X(e)}</h1>`,` <p class="error-message">${X(t)}</p>`,`</div>`,`</body></html>`].join(`
3022
3022
  `)}function k_(e,t,n,r){return Zg(O_(r??`Present`,t)),{content:[{type:`text`,text:`[ERROR:VALIDATION] ${t}`}],isError:!0}}function A_(e,t){if(!n_(e)||!(`schemaVersion`in e))return{ok:!1,response:k_(`INVALID_CHANNEL_SURFACE`,`present expects a ChannelSurface object with schemaVersion: 1`)};if(e.schemaVersion!==1)return{ok:!1,response:k_(`UNSUPPORTED_SCHEMA_VERSION`,`Unsupported ChannelSurface schemaVersion: ${String(e.schemaVersion)}`)};if(typeof e.title==`string`&&r_.test(e.title))return{ok:!1,response:k_(`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(!n_(e)||e.type!==`markdown`)return[e];let t=s_(e);return!t||!c_(t)?[e]:f_(e)})}:e;return{ok:!0,surface:n,options:m_(n,t)}}function j_(e){return(e.actions?.length??0)>0||e.response?.required===!0?t_.getAll().some(e=>e.id===`browser`):!1}async function M_(e,t={}){let n=j_(e)?{...t,preferBrowser:!0}:t,r=g_(e),i=t_.select(r,n),a;if(a=i?await i.render(r,n):Ig(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&&!Pm(e)&&t.add(e)}if(t.size>0){let e=[...t].map(e=>`"${e}"`).join(`, `);Wg.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){Wg.warn(`Block type validation failed`,N(e))}if(t.compact){let{structuredContent:e,...t}=a;return t}return a}function N_(e,t=``){return typeof e==`string`?e:typeof e==`number`||typeof e==`boolean`?String(e):t}function P_(e){return{type:`kv`,value:e}}function F_(e){if(Array.isArray(e))return e}const I_=[{name:`summary`,description:`Title + markdown summary + optional metrics (pass/fail counts)`,expand(e){let t=N_(e.title,`Summary`),n=[{type:`heading`,value:t}],r=N_(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=N_(e.title,`Plan`),n=[{type:`heading`,value:t}],r=F_(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=N_(e.title,`Understanding`),n=[{type:`heading`,value:t}],r=N_(e.explanation);return r&&n.push({type:`markdown`,value:r}),e.details&&typeof e.details==`object`&&!Array.isArray(e.details)&&n.push(P_(e.details)),{title:t,blocks:n}}},{name:`bug-analyze`,description:`Title + heading + severity/status kv + code block + markdown`,expand(e){let t=N_(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=N_(e.code);i&&n.push({type:`code`,value:i});let a=N_(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=N_(e.title,`Task Complete`),n=[{type:`heading`,value:t}],r=F_(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=N_(e.title,`Review`),n=[{type:`heading`,value:t}],r=F_(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=N_(e.title,`Exploration`),n=[{type:`heading`,value:t}],r=F_(e.findings);if(r)for(let e of r)n.push({type:`heading`,value:N_(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=N_(e.title,`Decision`),n=[{type:`heading`,value:t}];e.recommendation&&n.push({type:`kv`,value:{Recommendation:e.recommendation}});let r=F_(e.options);return r&&r.length>0&&n.push({type:`comparison`,value:r.map(e=>({title:N_(e.title,`Option`),items:Array.isArray(e.items)?e.items:[]}))}),{title:t,blocks:n}}}],L_=new Map;for(let e of I_)L_.set(e.name,e);function R_(e,t){let n=L_.get(e);return n?n.expand(t):null}const z_={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`},B_=/^(#{1,6})\s/,V_=/^(`{3,}|~{3,})/,H_=/^\|.+\|.+\|/m;function U_(e){let t=e.trim(),n=t.match(B_);if(n)return{type:`heading`,value:t.slice(n[0].length)};if(V_.test(t)){let e=t.indexOf(`
3023
- `),n=t.lastIndexOf(t[0]);return{type:`code`,value:e>=0?t.slice(e+1,n).trimEnd():t}}return H_.test(t)?{type:`table`,value:t}:{type:`markdown`,value:t}}function W_(e,t){let n=z_[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 G_(e){if(typeof e==`string`){let t=U_(e);return{type:t.type,value:t.value}}if(Array.isArray(e)){let[t,n]=e;if(typeof t==`string`){let e=W_(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 K_(e){return{title:e.title??``,blocks:Array.isArray(e.blocks)?e.blocks.map(G_):[]}}function q_(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function J_(e){return q_(e)&&typeof e.schemaVersion==`number`&&e.schemaVersion===1}function Y_(e){return q_(e)&&typeof e.schemaVersion==`number`&&e.schemaVersion!==1}function X_(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 Z_(e){try{let t=re(e);return q_(t)?(t.schemaVersion===void 0&&(t.schemaVersion=1),Q_(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 Q_(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(!q_(n))return{ok:!1,error:{code:`INVALID_PRESET_INPUT`,reason:`Preset data must be an object`}};let r=R_(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(Y_(e))return{ok:!1,error:{code:`UNSUPPORTED_SCHEMA_VERSION`,reason:`Unsupported schemaVersion: ${String(e.schemaVersion)}`,hint:`Use schemaVersion: 1`}};if(q_(e)&&typeof e.raw==`string`)return Z_(e.raw);if(J_(e))return X_(e);if(typeof e==`string`){let t=K_({blocks:[e]});return{ok:!0,surface:{schemaVersion:1,title:t.title||`Present`,blocks:t.blocks}}}if(q_(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=K_(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 $_=R.object({label:R.string(),value:R.string(),description:R.string().optional()}),ev=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($_).optional(),schema:R.record(R.string(),R.unknown()).optional()}),tv=R.object({type:R.string(),title:R.string().optional(),value:R.unknown().optional(),language:R.string().optional()}).catchall(R.unknown()),nv={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(tv).optional().describe(`Typed block content for the surface.`),data:R.unknown().optional().describe(`Template data payload, if the template expands data.`),actions:R.array(ev).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().describe(`Force browser transport instead of inline rendering. Set true when user explicitly requests external browser or browser transport.`)};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 rv(e){let t=e.server?.getClientCapabilities?.();if(!t)return`unknown`;let n=Mr(t);return!n||Array.isArray(n.mimeTypes)&&n.mimeTypes.length>0&&!n.mimeTypes.includes(jr)?`unsupported`:`supported`}const iv=[{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 av(e,t){let n=G(`present`);try{let e=w(`present`);e&&E_(F(L(e,`dist`,`annotation-layer.js`),`utf8`))}catch{}Pr(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`. Actions use browser transport. Resources: aikit://schemas/channel-surface (schema+blocks), aikit://present/presets (presets), aikit://present/templates (viewers).",inputSchema:nv,annotations:n.annotations,_meta:Mg(Ug)},Y(`present`,async(t,n)=>{let r=t,i=typeof r.preferBrowser==`boolean`?r.preferBrowser:void 0,a=Q_(t);if(!a.ok)return k_(a.error.code,a.error.reason,void 0,`Present`);let o=A_(a.surface,n);if(!o.ok)return o.response;let s=rv(e);return await M_(o.surface,{...o.options,preferBrowser:i??(o.options.preferBrowser||s===`unsupported`)})}));try{let t=new or(Ug,{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?$g(r):void 0;return{contents:[{uri:e.href,mimeType:jr,_meta:Ng(),text:i??Xg()??`<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 Xg()||`<html><body><p>Loading...</p></body></html>`}try{e.registerResource(`Present App`,Hg,{description:`AI Kit present app - entry point`},async()=>({contents:[{uri:Hg,mimeType:jr,_meta:Ng(),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=Vm().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(iv,null,2)}]}))}catch{}}const ov=M(`tools`);function sv(e,t){let n=new vr({structure:new br,dependencies:new hr,symbols:new xr,patterns:new yr,entryPoints:new _r,diagrams:new gr}),r=G(`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},Y(`produce_knowledge`,async({scope:e,aspects:r},i)=>{let a;try{a=_l(i).createTask(`Produce Knowledge`,3),a.progress(0,`Running analyzers`);let o=e??`.`;ov.info(`Running knowledge production`,{rootPath:o,aspects:r});let s=await n.runExtraction(o,r);try{let e=I(kn(L(o)),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(s))r&&typeof r==`string`&&Ie(I(e,`${n}.md`),t+r,`utf-8`);ov.info(`Knowledge persisted to .ai/context/`,{files:Object.keys(s).length})}catch(e){ov.warn(`Failed to persist knowledge to .ai/context/`,{error:N(e)})}try{let e=L(kn(L(o)),fe.l0Cards);Ae(e,{recursive:!0});let n=It({workspaceName:o,structure:s.structure?.output,entryPoints:s.entryPoints?.output,dependencies:s.dependencies?.output,symbols:s.symbols?.output});Ie(I(e,et),n,`utf-8`),ov.info(`L0 workspace-core card generated`,{path:I(e,et)}),t?.notifyL0CardChanged().catch(()=>{})}catch(e){ov.warn(`Failed to generate L0 workspace-core card`,{error:N(e)})}a.progress(1,`Synthesizing results`);let c=n.buildSynthesisInstructions(s,r);return a.complete(`Knowledge production complete`),{content:[{type:`text`,text:c+`
3023
+ `),n=t.lastIndexOf(t[0]);return{type:`code`,value:e>=0?t.slice(e+1,n).trimEnd():t}}return H_.test(t)?{type:`table`,value:t}:{type:`markdown`,value:t}}function W_(e,t){let n=z_[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 G_(e){if(typeof e==`string`){let t=U_(e);return{type:t.type,value:t.value}}if(Array.isArray(e)){let[t,n]=e;if(typeof t==`string`){let e=W_(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 K_(e){return{title:e.title??``,blocks:Array.isArray(e.blocks)?e.blocks.map(G_):[]}}function q_(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function J_(e){return q_(e)&&typeof e.schemaVersion==`number`&&e.schemaVersion===1}function Y_(e){return q_(e)&&typeof e.schemaVersion==`number`&&e.schemaVersion!==1}function X_(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 Z_(e){try{let t=re(e);return q_(t)?(t.schemaVersion===void 0&&(t.schemaVersion=1),Q_(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 Q_(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(!q_(n))return{ok:!1,error:{code:`INVALID_PRESET_INPUT`,reason:`Preset data must be an object`}};let r=R_(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(Y_(e))return{ok:!1,error:{code:`UNSUPPORTED_SCHEMA_VERSION`,reason:`Unsupported schemaVersion: ${String(e.schemaVersion)}`,hint:`Use schemaVersion: 1`}};if(q_(e)&&typeof e.raw==`string`)return Z_(e.raw);if(J_(e))return X_(e);if(typeof e==`string`){let t=K_({blocks:[e]});return{ok:!0,surface:{schemaVersion:1,title:t.title||`Present`,blocks:t.blocks}}}if(q_(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=K_(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 $_=R.object({label:R.string(),value:R.string(),description:R.string().optional()}),ev=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($_).optional(),schema:R.record(R.string(),R.unknown()).optional()}),tv=R.object({type:R.string(),title:R.string().optional(),value:R.unknown().optional(),language:R.string().optional()}).catchall(R.unknown()),nv={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(tv).optional().describe(`Typed block content for the surface.`),data:R.unknown().optional().describe(`Template data payload, if the template expands data.`),actions:R.array(ev).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().describe(`Force browser transport instead of inline rendering. Set true when user explicitly requests external browser or browser transport.`)};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 rv(e){let t=e.server?.getClientCapabilities?.();if(!t)return`unknown`;let n=Mr(t);return!n||Array.isArray(n.mimeTypes)&&n.mimeTypes.length>0&&!n.mimeTypes.includes(jr)?`unsupported`:`supported`}const iv=[{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 av(e,t){let n=G(`present`);try{let e=w(`present`);e&&E_(F(L(e,`dist`,`annotation-layer.js`),`utf8`))}catch{}Pr(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`. Actions use browser transport. Resources: aikit://schemas/channel-surface (schema+blocks), aikit://present/presets (presets), aikit://present/templates (viewers).",inputSchema:nv,annotations:n.annotations,_meta:Mg(Ug)},Y(`present`,async(t,n)=>{let r=t,i=typeof r.preferBrowser==`boolean`?r.preferBrowser:void 0,a=Q_(t);if(!a.ok)return k_(a.error.code,a.error.reason,void 0,`Present`);let o=A_(a.surface,n);if(!o.ok)return o.response;let s=rv(e),c=(o.surface.actions?.length??0)>0;return await M_(o.surface,{...o.options,preferBrowser:i??(o.options.preferBrowser||c&&s===`unsupported`)})}));try{let t=new or(Ug,{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?$g(r):void 0;return{contents:[{uri:e.href,mimeType:jr,_meta:Ng(),text:i??Xg()??`<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 Xg()||`<html><body><p>Loading...</p></body></html>`}try{e.registerResource(`Present App`,Hg,{description:`AI Kit present app - entry point`},async()=>({contents:[{uri:Hg,mimeType:jr,_meta:Ng(),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=Vm().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(iv,null,2)}]}))}catch{}}const ov=M(`tools`);function sv(e,t){let n=new vr({structure:new br,dependencies:new hr,symbols:new xr,patterns:new yr,entryPoints:new _r,diagrams:new gr}),r=G(`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},Y(`produce_knowledge`,async({scope:e,aspects:r},i)=>{let a;try{a=_l(i).createTask(`Produce Knowledge`,3),a.progress(0,`Running analyzers`);let o=e??`.`;ov.info(`Running knowledge production`,{rootPath:o,aspects:r});let s=await n.runExtraction(o,r);try{let e=I(kn(L(o)),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(s))r&&typeof r==`string`&&Ie(I(e,`${n}.md`),t+r,`utf-8`);ov.info(`Knowledge persisted to .ai/context/`,{files:Object.keys(s).length})}catch(e){ov.warn(`Failed to persist knowledge to .ai/context/`,{error:N(e)})}try{let e=L(kn(L(o)),fe.l0Cards);Ae(e,{recursive:!0});let n=It({workspaceName:o,structure:s.structure?.output,entryPoints:s.entryPoints?.output,dependencies:s.dependencies?.output,symbols:s.symbols?.output});Ie(I(e,et),n,`utf-8`),ov.info(`L0 workspace-core card generated`,{path:I(e,et)}),t?.notifyL0CardChanged().catch(()=>{})}catch(e){ov.warn(`Failed to generate L0 workspace-core card`,{error:N(e)})}a.progress(1,`Synthesizing results`);let c=n.buildSynthesisInstructions(s,r);return a.complete(`Knowledge production complete`),{content:[{type:`text`,text:c+`
3024
3024
 
3025
3025
  ---
3026
3026
  _Next: Review the baselines above and use \`remember\` to store synthesized knowledge entries._`}]}}catch(e){return a?.fail?.(`Production failed`),ov.error(`Knowledge production failed`,N(e)),J(`INTERNAL`,`Knowledge production failed: ${e instanceof Error?e.message:String(e)}`)}}))}const cv=M(`tools`);function lv(e,t,n,r,i,a,o){let s=G(`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},Y(`reindex`,async({full:e,force:s},c)=>{try{if(t.isIndexing)return{content:[{type:`text`,text:`## Reindex Already in Progress
@@ -3072,7 +3072,7 @@ Data matches the schema.`}]};let r=[`## Validation: FAILED`,``,`**${n.errors.len
3072
3072
  │ Vector search is disabled. Hybrid search returns FTS only. │
3073
3073
  │ To enable: install/rebuild better-sqlite3 (native module). │
3074
3074
  └──────────────────────────────────────────────────────────────────┘`);let t=I(s,`lance`);P(t)&&Vy.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 Lr(u.controlDbPath),Br(f,Ir),Vy.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 Lr(e),Br(f,Ir),Vy.info(`State store adapter ready`,{type:f.type,dbPath:e})}let[p,m,h,g]=await Promise.all([(async()=>{if(n.embedding.childProcess!==!1){let e=new ni({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(),Vy.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(),Vy.debug(`Embedder loaded (in-process)`,{modelId:t.modelId,dimensions:t.dimensions}),t})(),(async()=>{let e=r===`sqlite-vec`?await zr({backend:r,path:s,adapter:d??void 0,embeddingDim:o.dimensions,embeddingProfile:o,partition:u}):await zr({backend:r,path:s,adapter:d??void 0,embeddingDim:o.dimensions,partition:void 0});return await e.initialize(),Vy.debug(`Store initialized`,{backend:r}),e})(),(async()=>{let e=d?new Fr({adapter:d}):new Fr({path:s});return await e.initialize(),Vy.debug(`Graph store initialized`,{shared:!!d}),e})(),(async()=>{let e=await wr();if(e){let e=Sr.get();Vy.debug(`WASM tree-sitter enabled`,{grammars:e.grammarCount,dir:e.wasmDir})}else{let e=Sr.get();Vy.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 ii(p,m),v=Rr(f),y=new ri(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=Sl(n.er),w=C?new Or(n.curated.path):void 0;w&&Vy.debug(`Policy store initialized`,{ruleCount:w.getRules().length});let T=C?new Dr: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 Vy.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 zo}}function Wy(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(`
3075
- `)}const Gy=M(`background-task`);var Ky=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,Gy.info(`Background task started`,{task:e.name,pending:this.queue.length});let t=Date.now();try{await e.fn();let n=Date.now()-t;Gy.info(`Background task completed`,{task:e.name,durationMs:n}),e.resolve()}catch(n){let r=Date.now()-t;Gy.error(`Background task failed`,{task:e.name,durationMs:r,err:n}),e.reject(n instanceof Error?n:Error(String(n)))}}this.running=null}};const qy=M(`idle-timer`);var Jy=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){qy.info(`Idle timeout reached with no active session — skipping cleanup (waiting for first tool call)`);return}if(this._busy){qy.info(`Skipping idle cleanup — background work in progress`);return}qy.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`&&qy.warn(`Idle cleanup callback failed`,{error:String(t.reason)})}};const Yy=M(`memory-monitor`);var Xy=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(),Yy.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`?Yy.warn(`Memory CRITICAL: ${n}MB RSS — consider restarting the server`):t===`warning`?Yy.warn(`Memory WARNING: ${n}MB RSS`):this.lastLevel!==`normal`&&Yy.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 Zy=new ai;function Qy(e,t){return Zy.run(e,async()=>{try{return await t()}finally{}})}M(`tool-timeout`);const $y=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze`,`codemod`,`audit`]);var eb=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 tb(e){return $y.has(e)?6e5:12e4}function nb(e,t,n){let r=new AbortController,i=r.signal;return new Promise((a,o)=>{let s=setTimeout(()=>{let e=new eb(n,t);i.aborted||r.abort(e),o(e)},t);s.unref();try{e(i).then(a,o).finally(()=>clearTimeout(s))}catch(e){clearTimeout(s),o(e instanceof Error?e:Error(String(e)))}})}const Q=M(`server`),rb=new Set([`status`,`list_tools`,`describe_tool`,`config`,`env`,`present`]);function ib(e,t=28){let n=e.replace(/\s+/g,` `).trim();return n.length<=t?n:`${n.slice(0,t-3)}...`}function ab(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 ob(e,t,n,r){let i=[];if(n){let t=await sb(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=>`"${ib(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-qHhtG0FU.js`),o=e(await a(r,n.stateStore,void 0,t.l0CardDir),500);o.lines.length>0&&i.push(o.lines.join(`
3075
+ `)}const Gy=M(`background-task`);var Ky=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,Gy.info(`Background task started`,{task:e.name,pending:this.queue.length});let t=Date.now();try{await e.fn();let n=Date.now()-t;Gy.info(`Background task completed`,{task:e.name,durationMs:n}),e.resolve()}catch(n){let r=Date.now()-t;Gy.error(`Background task failed`,{task:e.name,durationMs:r,err:n}),e.reject(n instanceof Error?n:Error(String(n)))}}this.running=null}};const qy=M(`idle-timer`);var Jy=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){qy.info(`Idle timeout reached with no active session — skipping cleanup (waiting for first tool call)`);return}if(this._busy){qy.info(`Skipping idle cleanup — background work in progress`);return}qy.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`&&qy.warn(`Idle cleanup callback failed`,{error:String(t.reason)})}};const Yy=M(`memory-monitor`);var Xy=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(),Yy.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`?Yy.warn(`Memory CRITICAL: ${n}MB RSS — consider restarting the server`):t===`warning`?Yy.warn(`Memory WARNING: ${n}MB RSS`):this.lastLevel!==`normal`&&Yy.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 Zy=new ai;function Qy(e,t){return Zy.run(e,async()=>{try{return await t()}finally{}})}M(`tool-timeout`);const $y=new Set([`onboard`,`reindex`,`produce_knowledge`,`analyze`,`codemod`,`audit`]);var eb=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 tb(e){return $y.has(e)?6e5:12e4}function nb(e,t,n){let r=new AbortController,i=r.signal;return new Promise((a,o)=>{let s=setTimeout(()=>{let e=new eb(n,t);i.aborted||r.abort(e),o(e)},t);s.unref();try{e(i).then(a,o).finally(()=>clearTimeout(s))}catch(e){clearTimeout(s),o(e instanceof Error?e:Error(String(e)))}})}const Q=M(`server`),rb=new Set([`status`,`list_tools`,`describe_tool`,`config`,`env`,`present`]);function ib(e,t=28){let n=e.replace(/\s+/g,` `).trim();return n.length<=t?n:`${n.slice(0,t-3)}...`}function ab(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 ob(e,t,n,r){let i=[];if(n){let t=await sb(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=>`"${ib(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-C4z3H1li.js`),o=e(await a(r,n.stateStore,void 0,t.l0CardDir),500);o.lines.length>0&&i.push(o.lines.join(`
3076
3076
  `))}catch(e){Q.debug?.(`Periodic prelude injection failed`,{error:String(e)})}}return i.length===0?null:`\n${i.join(`
3077
3077
  `)}`}async function sb(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=gp(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(`
3078
3078
  `)}catch{return null}}function cb(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||rb.has(a))return s;try{r--,i++;let e=o[0],a=await ob(t,n,ab(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 lb(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 ub(e){return lm(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(`
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{r as e}from"./bin.js";import{n as t,t as n}from"./startup-maintenance-BPrX5-1U.js";import{t as r}from"./repair-json-D4mft_HA.js";import{createLogger as i,serializeError as a,setDetailedErrorLoggingEnabled as o}from"../../core/dist/index.js";const s=i(`server`);var c=class{buffer;append(e){this.buffer=this.buffer?Buffer.concat([this.buffer,e]):e}readMessage(){if(!this.buffer)return null;for(let e=0;e<this.buffer.length;e++){if(this.buffer[e]!==10)continue;let t=this.buffer.toString(`utf8`,0,e).replace(/\r$/,``),n=e+1;try{let e=JSON.parse(t);return this.buffer=this.buffer.subarray(n),e}catch{try{let e=r(t);return s.warn(`JSON parse failed on MCP message — repair succeeded`,{preview:t.slice(0,80)}),this.buffer=this.buffer.subarray(n),e}catch{}}}return null}clear(){this.buffer=void 0}};async function l(r){let[{loadConfig:i,reconfigureForWorkspace:l,resolveIndexMode:u},{createLazyServer:d},{checkForUpdates:f,autoUpgradeScaffold:p},{RootsListChangedNotificationSchema:m}]=await Promise.all([import(`./config-B4klhHVp.js`),import(`./server-B9RF008q.js`),import(`./version-check-CH5SIhnq.js`),import(`@modelcontextprotocol/sdk/types.js`)]),h=i();o(h.logging?.errorDetails===!0),h.configError&&s.warn(`Config load failure`,{error:h.configError}),s.info(`Config loaded`,{sourceCount:h.sources.length,storePath:h.store.path}),p(),setInterval(f,1440*60*1e3).unref();let g=u(h),_=d(h,g),{server:v,startInit:y,ready:b,runInitialIndex:x}=_,{StdioServerTransport:S}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),C=new S;if(typeof C._readBuffer?.readMessage!=`function`)throw Error(`Cannot install JSON repair: StdioServerTransport._readBuffer has unexpected shape`);C._readBuffer=new c,s.debug(`JSON repair installed on stdio transport`),await v.connect(C),s.debug(`MCP server started`,{transport:`stdio`}),await e({config:h,indexMode:g,log:s,rootsChangedNotificationSchema:m,reconfigureForWorkspace:l,runInitialIndex:x,server:v,startInit:y,version:r});let w=null,T=null,E=!1,D=async e=>{E||(E=!0,s.info(`Shutdown signal received`,{signal:e}),w&&=(clearTimeout(w),null),T?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await C.close().catch(()=>void 0),await v.close().catch(()=>void 0),_.aikit&&await Promise.all([_.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),_.aikit.graphStore.close().catch(()=>{}),_.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),_.aikit.store.close().catch(()=>{})]),process.exit(0))},O=()=>{w&&clearTimeout(w),w=setTimeout(async()=>{s.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=_.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){s.warn(`Resource release failed during shutdown`,a(e))}},18e5),w.unref&&w.unref()};O(),process.stdin.on(`data`,()=>O()),process.stdin.on(`end`,()=>void D(`stdin-end`)),process.stdin.on(`close`,()=>void D(`stdin-close`)),process.stdin.on(`error`,()=>void D(`stdin-error`)),process.on(`SIGINT`,()=>void D(`SIGINT`)),process.on(`SIGTERM`,()=>void D(`SIGTERM`)),b.catch(e=>{s.error(`Initialization failed — server will continue with limited tools`,t(r,e))}),g===`smart`?b.then(async()=>{try{if(!_.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(_.aikit.indexer,h,_.aikit.store);T=t;let n=_.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),_.setSmartScheduler(t),s.debug(`Smart index scheduler started (stdio mode)`)}catch(e){s.error(`Failed to start smart index scheduler`,t(r,e))}}).catch(e=>s.error(`AI Kit init failed for smart scheduler`,t(r,e))):s.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:g}),n(b,()=>_.aikit?{curated:_.aikit.curated,stateStore:_.aikit.stateStore}:null,r)}export{l as startStdioMode};
2
+ import{r as e}from"./bin.js";import{n as t,t as n}from"./startup-maintenance-BPrX5-1U.js";import{t as r}from"./repair-json-D4mft_HA.js";import{createLogger as i,serializeError as a,setDetailedErrorLoggingEnabled as o}from"../../core/dist/index.js";const s=i(`server`);var c=class{buffer;append(e){this.buffer=this.buffer?Buffer.concat([this.buffer,e]):e}readMessage(){if(!this.buffer)return null;for(let e=0;e<this.buffer.length;e++){if(this.buffer[e]!==10)continue;let t=this.buffer.toString(`utf8`,0,e).replace(/\r$/,``),n=e+1;try{let e=JSON.parse(t);return this.buffer=this.buffer.subarray(n),e}catch{try{let e=r(t);return s.warn(`JSON parse failed on MCP message — repair succeeded`,{preview:t.slice(0,80)}),this.buffer=this.buffer.subarray(n),e}catch{}}}return null}clear(){this.buffer=void 0}};async function l(r){let[{loadConfig:i,reconfigureForWorkspace:l,resolveIndexMode:u},{createLazyServer:d},{checkForUpdates:f,autoUpgradeScaffold:p},{RootsListChangedNotificationSchema:m}]=await Promise.all([import(`./config-B4klhHVp.js`),import(`./server-D2a5Rjgk.js`),import(`./version-check-CH5SIhnq.js`),import(`@modelcontextprotocol/sdk/types.js`)]),h=i();o(h.logging?.errorDetails===!0),h.configError&&s.warn(`Config load failure`,{error:h.configError}),s.info(`Config loaded`,{sourceCount:h.sources.length,storePath:h.store.path}),p(),setInterval(f,1440*60*1e3).unref();let g=u(h),_=d(h,g),{server:v,startInit:y,ready:b,runInitialIndex:x}=_,{StdioServerTransport:S}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),C=new S;if(typeof C._readBuffer?.readMessage!=`function`)throw Error(`Cannot install JSON repair: StdioServerTransport._readBuffer has unexpected shape`);C._readBuffer=new c,s.debug(`JSON repair installed on stdio transport`),await v.connect(C),s.debug(`MCP server started`,{transport:`stdio`}),await e({config:h,indexMode:g,log:s,rootsChangedNotificationSchema:m,reconfigureForWorkspace:l,runInitialIndex:x,server:v,startInit:y,version:r});let w=null,T=null,E=!1,D=async e=>{E||(E=!0,s.info(`Shutdown signal received`,{signal:e}),w&&=(clearTimeout(w),null),T?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await C.close().catch(()=>void 0),await v.close().catch(()=>void 0),_.aikit&&await Promise.all([_.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),_.aikit.graphStore.close().catch(()=>{}),_.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),_.aikit.store.close().catch(()=>{})]),process.exit(0))},O=()=>{w&&clearTimeout(w),w=setTimeout(async()=>{s.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=_.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){s.warn(`Resource release failed during shutdown`,a(e))}},18e5),w.unref&&w.unref()};O(),process.stdin.on(`data`,()=>O()),process.stdin.on(`end`,()=>void D(`stdin-end`)),process.stdin.on(`close`,()=>void D(`stdin-close`)),process.stdin.on(`error`,()=>void D(`stdin-error`)),process.on(`SIGINT`,()=>void D(`SIGINT`)),process.on(`SIGTERM`,()=>void D(`SIGTERM`)),b.catch(e=>{s.error(`Initialization failed — server will continue with limited tools`,t(r,e))}),g===`smart`?b.then(async()=>{try{if(!_.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(_.aikit.indexer,h,_.aikit.store);T=t;let n=_.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),_.setSmartScheduler(t),s.debug(`Smart index scheduler started (stdio mode)`)}catch(e){s.error(`Failed to start smart index scheduler`,t(r,e))}}).catch(e=>s.error(`AI Kit init failed for smart scheduler`,t(r,e))):s.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:g}),n(b,()=>_.aikit?{curated:_.aikit.curated,stateStore:_.aikit.stateStore}:null,r)}export{l as startStdioMode};
@@ -1 +1 @@
1
- import{n as e}from"./workspace-bootstrap-DTnTU8p2.js";import{n as t,t as n}from"./startup-maintenance-CT6Z3734.js";import{t as r}from"./repair-json-B6Q_HRoP.js";import{createLogger as i,serializeError as a,setDetailedErrorLoggingEnabled as o}from"../../core/dist/index.js";const s=i(`server`);var c=class{buffer;append(e){this.buffer=this.buffer?Buffer.concat([this.buffer,e]):e}readMessage(){if(!this.buffer)return null;for(let e=0;e<this.buffer.length;e++){if(this.buffer[e]!==10)continue;let t=this.buffer.toString(`utf8`,0,e).replace(/\r$/,``),n=e+1;try{let e=JSON.parse(t);return this.buffer=this.buffer.subarray(n),e}catch{try{let e=r(t);return s.warn(`JSON parse failed on MCP message — repair succeeded`,{preview:t.slice(0,80)}),this.buffer=this.buffer.subarray(n),e}catch{}}}return null}clear(){this.buffer=void 0}};async function l(r){let[{loadConfig:i,reconfigureForWorkspace:l,resolveIndexMode:u},{createLazyServer:d},{checkForUpdates:f,autoUpgradeScaffold:p},{RootsListChangedNotificationSchema:m}]=await Promise.all([import(`./config-D3rRPB9X.js`),import(`./server-D3IS2SBd.js`),import(`./version-check-C7xqQr9o.js`),import(`@modelcontextprotocol/sdk/types.js`)]),h=i();o(h.logging?.errorDetails===!0),h.configError&&s.warn(`Config load failure`,{error:h.configError}),s.info(`Config loaded`,{sourceCount:h.sources.length,storePath:h.store.path}),p(),setInterval(f,1440*60*1e3).unref();let g=u(h),_=d(h,g),{server:v,startInit:y,ready:b,runInitialIndex:x}=_,{StdioServerTransport:S}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),C=new S;if(typeof C._readBuffer?.readMessage!=`function`)throw Error(`Cannot install JSON repair: StdioServerTransport._readBuffer has unexpected shape`);C._readBuffer=new c,s.debug(`JSON repair installed on stdio transport`),await v.connect(C),s.debug(`MCP server started`,{transport:`stdio`}),await e({config:h,indexMode:g,log:s,rootsChangedNotificationSchema:m,reconfigureForWorkspace:l,runInitialIndex:x,server:v,startInit:y,version:r});let w=null,T=null,E=!1,D=async e=>{E||(E=!0,s.info(`Shutdown signal received`,{signal:e}),w&&=(clearTimeout(w),null),T?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await C.close().catch(()=>void 0),await v.close().catch(()=>void 0),_.aikit&&await Promise.all([_.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),_.aikit.graphStore.close().catch(()=>{}),_.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),_.aikit.store.close().catch(()=>{})]),process.exit(0))},O=()=>{w&&clearTimeout(w),w=setTimeout(async()=>{s.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=_.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){s.warn(`Resource release failed during shutdown`,a(e))}},18e5),w.unref&&w.unref()};O(),process.stdin.on(`data`,()=>O()),process.stdin.on(`end`,()=>void D(`stdin-end`)),process.stdin.on(`close`,()=>void D(`stdin-close`)),process.stdin.on(`error`,()=>void D(`stdin-error`)),process.on(`SIGINT`,()=>void D(`SIGINT`)),process.on(`SIGTERM`,()=>void D(`SIGTERM`)),b.catch(e=>{s.error(`Initialization failed — server will continue with limited tools`,t(r,e))}),g===`smart`?b.then(async()=>{try{if(!_.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(_.aikit.indexer,h,_.aikit.store);T=t;let n=_.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),_.setSmartScheduler(t),s.debug(`Smart index scheduler started (stdio mode)`)}catch(e){s.error(`Failed to start smart index scheduler`,t(r,e))}}).catch(e=>s.error(`AI Kit init failed for smart scheduler`,t(r,e))):s.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:g}),n(b,()=>_.aikit?{curated:_.aikit.curated,stateStore:_.aikit.stateStore}:null,r)}export{l as startStdioMode};
1
+ import{n as e}from"./workspace-bootstrap-DTnTU8p2.js";import{n as t,t as n}from"./startup-maintenance-CT6Z3734.js";import{t as r}from"./repair-json-B6Q_HRoP.js";import{createLogger as i,serializeError as a,setDetailedErrorLoggingEnabled as o}from"../../core/dist/index.js";const s=i(`server`);var c=class{buffer;append(e){this.buffer=this.buffer?Buffer.concat([this.buffer,e]):e}readMessage(){if(!this.buffer)return null;for(let e=0;e<this.buffer.length;e++){if(this.buffer[e]!==10)continue;let t=this.buffer.toString(`utf8`,0,e).replace(/\r$/,``),n=e+1;try{let e=JSON.parse(t);return this.buffer=this.buffer.subarray(n),e}catch{try{let e=r(t);return s.warn(`JSON parse failed on MCP message — repair succeeded`,{preview:t.slice(0,80)}),this.buffer=this.buffer.subarray(n),e}catch{}}}return null}clear(){this.buffer=void 0}};async function l(r){let[{loadConfig:i,reconfigureForWorkspace:l,resolveIndexMode:u},{createLazyServer:d},{checkForUpdates:f,autoUpgradeScaffold:p},{RootsListChangedNotificationSchema:m}]=await Promise.all([import(`./config-D3rRPB9X.js`),import(`./server-jZ_r6xLb.js`),import(`./version-check-C7xqQr9o.js`),import(`@modelcontextprotocol/sdk/types.js`)]),h=i();o(h.logging?.errorDetails===!0),h.configError&&s.warn(`Config load failure`,{error:h.configError}),s.info(`Config loaded`,{sourceCount:h.sources.length,storePath:h.store.path}),p(),setInterval(f,1440*60*1e3).unref();let g=u(h),_=d(h,g),{server:v,startInit:y,ready:b,runInitialIndex:x}=_,{StdioServerTransport:S}=await import(`@modelcontextprotocol/sdk/server/stdio.js`),C=new S;if(typeof C._readBuffer?.readMessage!=`function`)throw Error(`Cannot install JSON repair: StdioServerTransport._readBuffer has unexpected shape`);C._readBuffer=new c,s.debug(`JSON repair installed on stdio transport`),await v.connect(C),s.debug(`MCP server started`,{transport:`stdio`}),await e({config:h,indexMode:g,log:s,rootsChangedNotificationSchema:m,reconfigureForWorkspace:l,runInitialIndex:x,server:v,startInit:y,version:r});let w=null,T=null,E=!1,D=async e=>{E||(E=!0,s.info(`Shutdown signal received`,{signal:e}),w&&=(clearTimeout(w),null),T?.stop(),await import(`../../tools/dist/index.js`).then(({processStopAll:e})=>e()).catch(()=>{}),await C.close().catch(()=>void 0),await v.close().catch(()=>void 0),_.aikit&&await Promise.all([_.aikit.embedder.shutdown?.().catch(()=>{})??Promise.resolve(),_.aikit.graphStore.close().catch(()=>{}),_.aikit.closeStateStore?.().catch(()=>{})??Promise.resolve(),_.aikit.store.close().catch(()=>{})]),process.exit(0))},O=()=>{w&&clearTimeout(w),w=setTimeout(async()=>{s.info(`Auto-shutdown: no activity for 30 minutes — releasing resources`);try{let e=_.aikit;e&&(e.embedder.shutdown?.().catch(()=>{}),e.store.releaseMemory?.(),e.graphStore.releaseMemory?.())}catch(e){s.warn(`Resource release failed during shutdown`,a(e))}},18e5),w.unref&&w.unref()};O(),process.stdin.on(`data`,()=>O()),process.stdin.on(`end`,()=>void D(`stdin-end`)),process.stdin.on(`close`,()=>void D(`stdin-close`)),process.stdin.on(`error`,()=>void D(`stdin-error`)),process.on(`SIGINT`,()=>void D(`SIGINT`)),process.on(`SIGTERM`,()=>void D(`SIGTERM`)),b.catch(e=>{s.error(`Initialization failed — server will continue with limited tools`,t(r,e))}),g===`smart`?b.then(async()=>{try{if(!_.aikit)throw Error(`AI Kit components are not available after initialization`);let{SmartIndexScheduler:e}=await import(`../../indexer/dist/index.js`),t=new e(_.aikit.indexer,h,_.aikit.store);T=t;let n=_.aikit.store;t.start(),n.onBeforeClose&&n.onBeforeClose(()=>t.stop()),_.setSmartScheduler(t),s.debug(`Smart index scheduler started (stdio mode)`)}catch(e){s.error(`Failed to start smart index scheduler`,t(r,e))}}).catch(e=>s.error(`AI Kit init failed for smart scheduler`,t(r,e))):s.warn(`Initial full indexing skipped; use aikit_reindex to index manually`,{indexMode:g}),n(b,()=>_.aikit?{curated:_.aikit.curated,stateStore:_.aikit.stateStore}:null,r)}export{l as startStdioMode};
@@ -1,8 +1,8 @@
1
- import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{SERVER_NAME as r}from"../definitions/mcp.mjs";import{getPlatformPrimaryModelMap as i}from"../definitions/models.mjs";import{PLATFORM_HOOK_CAPABILITIES as a}from"../definitions/platform-capabilities.mjs";import{PROMPTS as o}from"../definitions/prompts.mjs";import{AIKIT_INSTALL_HINT_SECTION as s,PLATFORM_OUTPUT_RULES_SECTION as c,PROTOCOLS as l}from"../definitions/protocols.mjs";import{CLAUDE_CODE_TOOL_MAP as u,IDE_CAPABILITIES as d}from"../definitions/tools.mjs";import{buildAgentTable as f,buildCompactAgentTable as p,buildFlowSection as m,buildHooksSection as h,buildSkillsSection as g,injectOrchestratorDirective as _,lowerFirst as v}from"./_shared.mjs";const y=m({flowTool:`flow`,isLifecycleOwner:!0}),b=m({flowTool:`flow`,isLifecycleOwner:!1});function x(e){return e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).replace(/[^a-zA-Z0-9]+/g,`-`).replace(/^-+|-+$/g,``).toLowerCase()}function S(e){return`"${String(e).replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`}function C(e){let t=(d[e]||[]).flatMap(e=>u[e]||[]);return[...new Set([...t])].sort((e,t)=>e.localeCompare(t))}function w(e,t){let n=[];return n.push(`# ${r} ${e}`),n.push(``),t.description&&(n.push(`> ${t.description}`),n.push(``)),n.push(t.content.trim()),n.push(``),n.join(`
2
- `)}function T(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function E(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&l[e.sharedBase]&&t.push(l[e.sharedBase]);for(let n of e.sharedProtocols||[])l[n]&&t.push(l[n]);return t}function D(){let t=[];for(let[n,r]of Object.entries(e)){if(r.variants){for(let[e,i]of Object.entries(r.variants))t.push({name:`${n}-${e}`,description:i.description||r.description});continue}t.push({name:n,description:r.description})}return t}function O(e){return D().map(({name:t,description:n})=>`- \`${e}/${t}.md\` — ${n}`).join(`
3
- `)}function k(t=f(e,i(`claude-code`))){return[`# ${r} — Claude Code Agents`,``,c,``,s,``,`## MCP Server`,``,`Server name: \`${r}\``,"Configured in `.mcp.json` (project) and `~/.claude.json` (user-global — `claude mcp add --scope user` format).","Default agent: `Orchestrator` in `~/.claude/settings.json` — every conversation starts as Orchestrator automatically.",``,`## Agents`,``,t,``,`## Agent Files`,``,O(`.claude/agents`),``,`## Commands`,``,"Slash commands live under `.claude/commands/`.",``,`## Session Protocol`,``,h(n,a[`claude-code`]),``].join(`
4
- `)}function A(){return _([`# ${r} — Claude Code Instructions`,``,"Detailed workspace instructions live in `AGENTS.md`.","Full sub-agent instructions live in `.claude/agents/`.","Slash commands live in `.claude/commands/`.","MCP server config lives in `.mcp.json` (project) and `~/.claude.json` (user-global — written by `claude mcp add --scope user`).","Default agent set to `Orchestrator` in `~/.claude/settings.json` — every conversation starts as Orchestrator, no `/agent` command needed.",``,"Start with `AGENTS.md`, then open the specific sub-agent file you want to use.",``,c,``,s,``]).join(`
5
- `)}function j(e,t,n,i,a){let o=C(t.toolRole),s=E(t),c=g(t.skills),l=e===`Orchestrator`?[y]:[b],u=[n,...s,t.bodyAddendum,c,...l].filter(Boolean).join(`
1
+ import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{SERVER_NAME as r}from"../definitions/mcp.mjs";import{getPlatformPrimaryModelMap as i}from"../definitions/models.mjs";import{PLATFORM_HOOK_CAPABILITIES as a}from"../definitions/platform-capabilities.mjs";import{PROMPTS as o}from"../definitions/prompts.mjs";import{AIKIT_INSTALL_HINT_SECTION as s,PLATFORM_OUTPUT_RULES_SECTION as c,PROTOCOLS as l}from"../definitions/protocols.mjs";import{AIKIT_TOOLS as u,CLAUDE_CODE_TOOL_MAP as d,IDE_CAPABILITIES as f}from"../definitions/tools.mjs";import{buildAgentTable as p,buildCompactAgentTable as m,buildFlowSection as h,buildHooksSection as g,buildSkillsSection as _,injectOrchestratorDirective as v,lowerFirst as y}from"./_shared.mjs";const b=h({flowTool:`flow`,isLifecycleOwner:!0}),x=h({flowTool:`flow`,isLifecycleOwner:!1});function S(e){return e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).replace(/[^a-zA-Z0-9]+/g,`-`).replace(/^-+|-+$/g,``).toLowerCase()}function C(e){return`"${String(e).replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`}function w(e){let t=(f[e]||[]).flatMap(e=>d[e]||[]),n=u.map(e=>`mcp__${r.toLowerCase().replace(/[^a-z0-9]/g,``)}__${e}`);return[...new Set([...t,...n])].sort((e,t)=>e.localeCompare(t))}function T(e,t){let n=[];return n.push(`# ${r} ${e}`),n.push(``),t.description&&(n.push(`> ${t.description}`),n.push(``)),n.push(t.content.trim()),n.push(``),n.join(`
2
+ `)}function E(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function D(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&l[e.sharedBase]&&t.push(l[e.sharedBase]);for(let n of e.sharedProtocols||[])l[n]&&t.push(l[n]);return t}function O(){let t=[];for(let[n,r]of Object.entries(e)){if(r.variants){for(let[e,i]of Object.entries(r.variants))t.push({name:`${n}-${e}`,description:i.description||r.description});continue}t.push({name:n,description:r.description})}return t}function k(e){return O().map(({name:t,description:n})=>`- \`${e}/${t}.md\` — ${n}`).join(`
3
+ `)}function A(t=p(e,i(`claude-code`))){return[`# ${r} — Claude Code Agents`,``,c,``,s,``,`## MCP Server`,``,`Server name: \`${r}\``,"Configured in `.mcp.json` (project) and `~/.claude.json` (user-global — `claude mcp add --scope user` format).","Default agent: `Orchestrator` in `~/.claude/settings.json` — every conversation starts as Orchestrator automatically.",``,`## Agents`,``,t,``,`## Agent Files`,``,k(`.claude/agents`),``,`## Commands`,``,"Slash commands live under `.claude/commands/`.",``,`## Session Protocol`,``,g(n,a[`claude-code`]),``].join(`
4
+ `)}function j(){return v([`# ${r} — Claude Code Instructions`,``,"Detailed workspace instructions live in `AGENTS.md`.","Full sub-agent instructions live in `.claude/agents/`.","Slash commands live in `.claude/commands/`.","MCP server config lives in `.mcp.json` (project) and `~/.claude.json` (user-global — written by `claude mcp add --scope user`).","Default agent set to `Orchestrator` in `~/.claude/settings.json` — every conversation starts as Orchestrator, no `/agent` command needed.",``,"Start with `AGENTS.md`, then open the specific sub-agent file you want to use.",``,c,``,s,``]).join(`
5
+ `)}function M(e,t,n,i,a){let o=w(t.toolRole),s=D(t),c=_(t.skills),l=e===`Orchestrator`?[b]:[x],u=[n,...s,t.bodyAddendum,c,...l].filter(Boolean).join(`
6
6
 
7
- `).trim(),d=t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${v(t.description)}.`,f=a?.[e],p=o.length>0?`tools: [${o.join(`, `)}]`:null,m=t.skills?.length>0?`skills: [${t.skills.map(([e])=>e).join(`, `)}]`:null,h=[`---`,`name: ${x(e)}`,`description: ${S(t.description)}`,...f?[`model: ${S(f)}`]:[],...p?[p]:[],`mcpServers:`,` - ${r}`,...m?[m]:[],`---`,``,`# ${e} - ${t.title||e}`,``,d];return u&&h.push(``,u),h.push(``),h.join(`
8
- `)}function M(){let t=[],n=i(`claude-code`),r=f(e,n),a=p(e);t.push({path:`CLAUDE.md`,content:A()}),t.push({path:`AGENTS.md`,content:k(r)});for(let[e,n]of Object.entries(o))t.push({path:`.claude/commands/aikit-${e}.md`,content:w(e,n)});for(let[i,o]of Object.entries(e)){let e=T(i,a);if(o.variants){for(let[a,s]of Object.entries(o.variants)){let c=`${i}-${a}`;t.push({path:`.claude/agents/${c}.md`,content:j(c,{...o,description:s.description||o.description,identity:s.identity,bodyAddendum:s.bodyAddendum},e,r,n)})}continue}t.push({path:`.claude/agents/${i}.md`,content:j(i,o,e,r,n)})}return t}export{y as CLAUDE_FLOWS_SECTION,M as generateClaudeCode};
7
+ `).trim(),d=t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${y(t.description)}.`,f=a?.[e],p=o.length>0?`tools: [${o.join(`, `)}]`:null,m=t.skills?.length>0?`skills: [${t.skills.map(([e])=>e).join(`, `)}]`:null,h=[`---`,`name: ${S(e)}`,`description: ${C(t.description)}`,...f?[`model: ${C(f)}`]:[],...p?[p]:[],`mcpServers:`,` - ${r}`,...m?[m]:[],`---`,``,`# ${e} - ${t.title||e}`,``,d];return u&&h.push(``,u),h.push(``),h.join(`
8
+ `)}function N(){let t=[],n=i(`claude-code`),r=p(e,n),a=m(e);t.push({path:`CLAUDE.md`,content:j()}),t.push({path:`AGENTS.md`,content:A(r)});for(let[e,n]of Object.entries(o))t.push({path:`.claude/commands/aikit-${e}.md`,content:T(e,n)});for(let[i,o]of Object.entries(e)){let e=E(i,a);if(o.variants){for(let[a,s]of Object.entries(o.variants)){let c=`${i}-${a}`;t.push({path:`.claude/agents/${c}.md`,content:M(c,{...o,description:s.description||o.description,identity:s.identity,bodyAddendum:s.bodyAddendum},e,r,n)})}continue}t.push({path:`.claude/agents/${i}.md`,content:M(i,o,e,r,n)})}return t}export{b as CLAUDE_FLOWS_SECTION,N as generateClaudeCode};
@@ -2,6 +2,16 @@ import{AGENTS as e}from"./agents.mjs";import{postTaskLesson as t,preTaskKnowledg
2
2
  ${t.map((e,t)=>` ${t+1}. ${e}`).join(`
3
3
  `)}`}const a={Orchestrator:e=>`You orchestrate full lifecycle: planning -> implementation -> review -> recovery -> commit. Own contract: what, order, owner. No source-code edits; delegate all implementation.
4
4
 
5
+ ## MANDATORY FIRST ACTIONS
6
+
7
+ Execute these MCP calls at session start, before ANY other work:
8
+
9
+ 1. \`mcp__aikit__flow({ action: 'status' })\` — Check active flow state.
10
+ 2. \`mcp__aikit__status({ includePrelude: true })\` — Load L0 workspace context (compact summary).
11
+ 3. If workspaceCore is null → \`mcp__aikit__onboard({ path: "." })\` first, then status again.
12
+
13
+ **Failure to execute these before any other action is a protocol violation.**
14
+
5
15
  ## Prime Contract
6
16
  1. Plan work.
7
17
  2. Dispatch specialists.
@@ -1 +1 @@
1
- const e=[`copilot`,`claude`,`copilotCli`,`hermes`],t={SessionStart:{copilot:`SessionStart`,claude:`SessionStart`,copilotCli:`sessionStart`,hermes:`SessionStart`},PreToolUse:{copilot:`PreToolUse`,claude:`PreToolUse`,copilotCli:`preToolUse`,hermes:`PreToolUse`},PostToolUse:{copilot:`PostToolUse`,claude:`PostToolUse`,copilotCli:`postToolUse`,hermes:`PostToolUse`},SubagentStart:{copilot:`SubagentStart`,claude:`SubagentStart`,copilotCli:`subagentStart`,hermes:`SubagentStart`},PreCompact:{copilot:`PreCompact`,claude:`PreCompact`,copilotCli:`preCompact`,hermes:`PreCompact`},Stop:{copilot:`Stop`,claude:`Stop`,copilotCli:`stop`,hermes:`Stop`}},n={fileRead:{copilot:[`read_file`,`readFile`],claude:[`Read`],copilotCli:[`read_file`],hermes:[`read_file`]},fileWrite:{copilot:[`editFiles`,`replace_string_in_file`,`create_file`],claude:[`Edit`,`Write`,`MultiEdit`],copilotCli:[`editFiles`,`replace_string_in_file`],hermes:[`write_file`,`patch`]},fileSearch:{copilot:[`grep_search`,`semantic_search`,`find`],claude:[`Bash`],copilotCli:[`grep_search`],hermes:[`search_files`]}},r={"privacy-guard":{id:`privacy-guard`,event:`PreToolUse`,category:`guard`,description:`Deny reads of secret-bearing files: .env, .pem, .key, .ssh/*, credentials, tokens, .netrc.`,llmBenefit:`Prevents accidental leakage of API keys, tokens, and credentials into conversation context.`,script:`privacy-guard.mjs`,matcher:[`fileRead`],outputBudgetLines:0,executionModel:`child-process`,scope:`user`,failurePolicy:`deny-closed`,supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Reject via agent instruction — no native hook runtime available`,evidenceRequirements:`Hook script tested against known secret patterns`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`},"scout-guard":{id:`scout-guard`,event:`PreToolUse`,category:`guard`,description:`Deny reads inside generated/dependency directories: node_modules/, dist/, .git/objects/, vendor/, build/.`,llmBenefit:`Keeps context clean by preventing reads of irrelevant generated or vendored files.`,script:`scout-guard.mjs`,matcher:[`fileRead`,`fileSearch`],outputBudgetLines:0,executionModel:`child-process`,scope:`user`,failurePolicy:`deny-closed`,supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Reject via agent instruction — no native hook runtime available`,evidenceRequirements:`Hook script tested against known generated directory patterns`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`},"freshness-signal":{id:`freshness-signal`,event:`SessionStart`,category:`signal`,description:`Check workspace state freshness at session start: onboard staleness, active flow, scaffold drift.`,llmBenefit:`Avoids working with stale onboard data or drifting scaffold state.`,script:`freshness-signal.mjs`,outputBudgetLines:5,executionModel:`child-process`,scope:`user`,silentWhenHealthy:!0,failurePolicy:`allow-open`,matcher:[],supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Skip — no native hook runtime on this platform`,evidenceRequirements:`None (signal-only, no enforcement)`,rollbackBehavior:`Remove from settings.json hooks block`},"scope-guard":{id:`scope-guard`,event:`PostToolUse`,category:`signal`,description:`After file writes, detect edit drift: files changed outside flow scope, too many files, scaffold source/dist mismatch.`,llmBenefit:`Prevents accidental scope creep, over-editing, and scaffold drift during a session.`,script:`scope-guard.mjs`,matcher:[`fileWrite`],outputBudgetLines:5,executionModel:`child-process`,scope:`user`,silentWhenHealthy:!0,failurePolicy:`allow-open`,supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Skip — no native hook runtime on this platform`,evidenceRequirements:`None (signal-only, no enforcement)`,rollbackBehavior:`Remove from settings.json hooks block`},"session-reminder":{id:`session-reminder`,event:`SessionStart`,category:`signal`,description:`Inject orchestrator skill protocol ("Delegate, never implement") at every session start as additionalContext.`,llmBenefit:`Reinforces the delegation protocol at the start of every Orchestrator session — harder for the model to skip than CLAUDE.md or agent instructions alone.`,script:`session-reminder.mjs`,outputBudgetLines:50,executionModel:`child-process`,scope:`user`,silentWhenHealthy:!1,failurePolicy:`allow-open`,matcher:[],supportedPlatforms:[`claude`],unsupportedBehavior:`Skip — only meaningful on Claude Code with its hooks runtime`,evidenceRequirements:`None (signal-only, no enforcement)`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`}},i=[`id`,`event`,`category`,`script`,`description`],a=[`matcher`,`llmBenefit`,`executionModel`,`scope`,`failurePolicy`,`outputBudgetLines`,`supportedPlatforms`,`unsupportedBehavior`],o=[`evidenceRequirements`,`rollbackBehavior`],s=[`silentWhenHealthy`];function c(){let e=new Set(Object.keys(t)),n=[`child-process`,`eventbus-subscriber`],c=[`deny-closed`,`allow-open`];for(let[t,l]of Object.entries(r)){for(let e of i){if(!(e in l)||l[e]===void 0||l[e]===null)throw Error(`EXEC_HOOKS["${t}"] is missing or null Tier 1 field "${e}". Add it to the "${t}" entry in exec-hooks.mjs.`);if(typeof l[e]==`string`&&l[e].trim()===``)throw Error(`EXEC_HOOKS["${t}"] has empty string for Tier 1 field "${e}". Provide a non-empty value.`)}for(let e of a)(!(e in l)||l[e]===void 0||l[e]===null)&&console.warn(`EXEC_HOOKS["${t}"] is missing Tier 2 field "${e}". Add it when the field values are actionable.`);if(l.category===`guard`)for(let e of o)(!(e in l)||l[e]===void 0||l[e]===null)&&console.warn(`EXEC_HOOKS["${t}"] (guard) is missing guard field "${e}". Add it when guard lifecycle tooling exists.`);if(l.category===`signal`)for(let e of s)(!(e in l)||l[e]===void 0||l[e]===null)&&console.warn(`EXEC_HOOKS["${t}"] (signal) is missing signal field "${e}". Add it when signal lifecycle tooling exists.`);if(l.id!==t)throw Error(`EXEC_HOOKS["${t}"] has id="${l.id}" which doesn't match its object key. Set id to "${t}".`);if(!e.has(l.event))throw Error(`EXEC_HOOKS["${t}"] has unrecognized event "${l.event}". Valid: ${[...e].join(`, `)}.`);if(![`guard`,`signal`].includes(l.category))throw Error(`EXEC_HOOKS["${t}"] has invalid category "${l.category}". Must be "guard" or "signal".`);[`user`,`workspace`].includes(l.scope)||console.warn(`EXEC_HOOKS["${t}"] has invalid scope "${l.scope}". Must be "user" or "workspace".`),l.executionModel&&!n.includes(l.executionModel)&&console.warn(`EXEC_HOOKS["${t}"] has unrecognized executionModel "${l.executionModel}". Valid: ${n.join(`, `)}.`),l.failurePolicy&&!c.includes(l.failurePolicy)&&console.warn(`EXEC_HOOKS["${t}"] has unrecognized failurePolicy "${l.failurePolicy}". Valid: ${c.join(`, `)}.`)}}function l(r){let i=[{name:`HOOK_EVENTS`,entries:Object.values(t)},{name:`HOOK_TOOL_MATCHERS`,entries:Object.values(n)}];for(let t of e){for(let e of i)for(let n of e.entries)if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e.name} (entry has keys: ${Object.keys(n).join(`, `)}). Add a "${t}" key to all entries in ${e.name} in exec-hooks.mjs.`);if(r){for(let[e,n]of Object.entries(r))if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e} (has keys: ${Object.keys(n).join(`, `)}). Add "${t}: '...'" to ${e}.`)}}}function u(e){let t=[];if(!e||typeof e!=`object`)return t.push(`Generated hook must be a non-null object`),t;for(let n of[`id`,`event`,`category`,`description`])(!e[n]||typeof e[n]!=`string`)&&t.push(`Generated hook missing or invalid "${n}" (must be a non-empty string)`);e.category&&![`guard`,`signal`].includes(e.category)&&t.push(`Generated hook has invalid category "${e.category}". Must be "guard" or "signal".`);let n=[`candidate`,`evaluated`,`promoted`,`rejected`,`disabled`];return e.promotionState&&!n.includes(e.promotionState)&&t.push(`Generated hook has invalid promotionState "${e.promotionState}". Valid: ${n.join(`, `)}.`),e.confidence!==void 0&&(typeof e.confidence!=`number`||e.confidence<0||e.confidence>1)&&t.push(`Generated hook confidence must be a number between 0 and 1, got "${e.confidence}"`),e.originToolNames!==void 0&&!Array.isArray(e.originToolNames)&&t.push(`Generated hook originToolNames must be an array of strings`),e.promotionState===`promoted`&&!e.createdAt&&t.push(`Generated hook promoted but missing createdAt timestamp`),t}export{r as EXEC_HOOKS,t as HOOK_EVENTS,n as HOOK_TOOL_MATCHERS,e as SUPPORTED_PLATFORMS,l as validateAllPlatformRegistries,u as validateGeneratedHookDef,c as validateHookDefinitions};
1
+ const e=[`copilot`,`claude`,`copilotCli`,`hermes`],t={SessionStart:{copilot:`SessionStart`,claude:`SessionStart`,copilotCli:`sessionStart`,hermes:`SessionStart`},PreToolUse:{copilot:`PreToolUse`,claude:`PreToolUse`,copilotCli:`preToolUse`,hermes:`PreToolUse`},PostToolUse:{copilot:`PostToolUse`,claude:`PostToolUse`,copilotCli:`postToolUse`,hermes:`PostToolUse`},SubagentStart:{copilot:`SubagentStart`,claude:`SubagentStart`,copilotCli:`subagentStart`,hermes:`SubagentStart`},PreCompact:{copilot:`PreCompact`,claude:`PreCompact`,copilotCli:`preCompact`,hermes:`PreCompact`},Stop:{copilot:`Stop`,claude:`Stop`,copilotCli:`stop`,hermes:`Stop`}},n={fileRead:{copilot:[`read_file`,`readFile`],claude:[`Read`],copilotCli:[`read_file`],hermes:[`read_file`]},fileWrite:{copilot:[`editFiles`,`replace_string_in_file`,`create_file`],claude:[`Edit`,`Write`,`MultiEdit`],copilotCli:[`editFiles`,`replace_string_in_file`],hermes:[`write_file`,`patch`]},fileSearch:{copilot:[`grep_search`,`semantic_search`,`find`],claude:[`Bash`],copilotCli:[`grep_search`],hermes:[`search_files`]}},r={"privacy-guard":{id:`privacy-guard`,event:`PreToolUse`,category:`guard`,description:`Deny reads of secret-bearing files: .env, .pem, .key, .ssh/*, credentials, tokens, .netrc.`,llmBenefit:`Prevents accidental leakage of API keys, tokens, and credentials into conversation context.`,script:`privacy-guard.mjs`,matcher:[`fileRead`],outputBudgetLines:0,executionModel:`child-process`,scope:`user`,failurePolicy:`deny-closed`,supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Reject via agent instruction — no native hook runtime available`,evidenceRequirements:`Hook script tested against known secret patterns`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`},"scout-guard":{id:`scout-guard`,event:`PreToolUse`,category:`guard`,description:`Deny reads inside generated/dependency directories: node_modules/, dist/, .git/objects/, vendor/, build/.`,llmBenefit:`Keeps context clean by preventing reads of irrelevant generated or vendored files.`,script:`scout-guard.mjs`,matcher:[`fileRead`,`fileSearch`],outputBudgetLines:0,executionModel:`child-process`,scope:`user`,failurePolicy:`deny-closed`,supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Reject via agent instruction — no native hook runtime available`,evidenceRequirements:`Hook script tested against known generated directory patterns`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`},"bash-guard":{id:`bash-guard`,event:`PreToolUse`,category:`guard`,description:`Deny grep/find/cat/ls/rg in Bash tool; redirect to MCP search, find, file_summary.`,llmBenefit:`Prevents context waste from raw shell code exploration. Pushes agent toward token-efficient MCP tools.`,script:`bash-guard.mjs`,matcher:[`fileSearch`],outputBudgetLines:0,executionModel:`child-process`,scope:`user`,failurePolicy:`deny-closed`,supportedPlatforms:[`claude`],unsupportedBehavior:`Skip — only meaningful on Claude Code with its Bash tool`,evidenceRequirements:`Hook script tested against grep/find/cat/ls/rg command patterns`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`},"read-size-guard":{id:`read-size-guard`,event:`PreToolUse`,category:`guard`,description:`Deny Read tool on files exceeding 100 lines; redirect to mcp__aikit__file_summary for compressed context.`,llmBenefit:`Prevents wasting context budget on reading large files directly. file_summary provides compressed, structured views.`,script:`read-size-guard.mjs`,matcher:[`fileRead`],outputBudgetLines:0,executionModel:`child-process`,scope:`user`,failurePolicy:`deny-closed`,supportedPlatforms:[`claude`],unsupportedBehavior:`Skip — only meaningful on Claude Code with aikit MCP tools`,evidenceRequirements:`Hook script tested against large-file read patterns`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`},"freshness-signal":{id:`freshness-signal`,event:`SessionStart`,category:`signal`,description:`Check workspace state freshness at session start: onboard staleness, active flow, scaffold drift.`,llmBenefit:`Avoids working with stale onboard data or drifting scaffold state.`,script:`freshness-signal.mjs`,outputBudgetLines:5,executionModel:`child-process`,scope:`user`,silentWhenHealthy:!0,failurePolicy:`allow-open`,matcher:[],supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Skip — no native hook runtime on this platform`,evidenceRequirements:`None (signal-only, no enforcement)`,rollbackBehavior:`Remove from settings.json hooks block`},"scope-guard":{id:`scope-guard`,event:`PostToolUse`,category:`signal`,description:`After file writes, detect edit drift: files changed outside flow scope, too many files, scaffold source/dist mismatch.`,llmBenefit:`Prevents accidental scope creep, over-editing, and scaffold drift during a session.`,script:`scope-guard.mjs`,matcher:[`fileWrite`],outputBudgetLines:5,executionModel:`child-process`,scope:`user`,silentWhenHealthy:!0,failurePolicy:`allow-open`,supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Skip — no native hook runtime on this platform`,evidenceRequirements:`None (signal-only, no enforcement)`,rollbackBehavior:`Remove from settings.json hooks block`},"session-reminder":{id:`session-reminder`,event:`SessionStart`,category:`signal`,description:`Inject FORBIDDEN tool substitutions, mandatory first actions, orchestrator delegation protocol, and AI Kit tool routing at every session start as additionalContext.`,llmBenefit:`Reinforces tool routing discipline (grep→search, read→file_summary) and session-start protocol (flow status, onboard check) at the start of every session — harder for the model to skip than CLAUDE.md or agent instructions alone.`,script:`session-reminder.mjs`,outputBudgetLines:50,executionModel:`child-process`,scope:`user`,silentWhenHealthy:!1,failurePolicy:`allow-open`,matcher:[],supportedPlatforms:[`claude`],unsupportedBehavior:`Skip — only meaningful on Claude Code with its hooks runtime`,evidenceRequirements:`None (signal-only, no enforcement)`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`}},i=[`id`,`event`,`category`,`script`,`description`],a=[`matcher`,`llmBenefit`,`executionModel`,`scope`,`failurePolicy`,`outputBudgetLines`,`supportedPlatforms`,`unsupportedBehavior`],o=[`evidenceRequirements`,`rollbackBehavior`],s=[`silentWhenHealthy`];function c(){let e=new Set(Object.keys(t)),n=[`child-process`,`eventbus-subscriber`],c=[`deny-closed`,`allow-open`];for(let[t,l]of Object.entries(r)){for(let e of i){if(!(e in l)||l[e]===void 0||l[e]===null)throw Error(`EXEC_HOOKS["${t}"] is missing or null Tier 1 field "${e}". Add it to the "${t}" entry in exec-hooks.mjs.`);if(typeof l[e]==`string`&&l[e].trim()===``)throw Error(`EXEC_HOOKS["${t}"] has empty string for Tier 1 field "${e}". Provide a non-empty value.`)}for(let e of a)(!(e in l)||l[e]===void 0||l[e]===null)&&console.warn(`EXEC_HOOKS["${t}"] is missing Tier 2 field "${e}". Add it when the field values are actionable.`);if(l.category===`guard`)for(let e of o)(!(e in l)||l[e]===void 0||l[e]===null)&&console.warn(`EXEC_HOOKS["${t}"] (guard) is missing guard field "${e}". Add it when guard lifecycle tooling exists.`);if(l.category===`signal`)for(let e of s)(!(e in l)||l[e]===void 0||l[e]===null)&&console.warn(`EXEC_HOOKS["${t}"] (signal) is missing signal field "${e}". Add it when signal lifecycle tooling exists.`);if(l.id!==t)throw Error(`EXEC_HOOKS["${t}"] has id="${l.id}" which doesn't match its object key. Set id to "${t}".`);if(!e.has(l.event))throw Error(`EXEC_HOOKS["${t}"] has unrecognized event "${l.event}". Valid: ${[...e].join(`, `)}.`);if(![`guard`,`signal`].includes(l.category))throw Error(`EXEC_HOOKS["${t}"] has invalid category "${l.category}". Must be "guard" or "signal".`);[`user`,`workspace`].includes(l.scope)||console.warn(`EXEC_HOOKS["${t}"] has invalid scope "${l.scope}". Must be "user" or "workspace".`),l.executionModel&&!n.includes(l.executionModel)&&console.warn(`EXEC_HOOKS["${t}"] has unrecognized executionModel "${l.executionModel}". Valid: ${n.join(`, `)}.`),l.failurePolicy&&!c.includes(l.failurePolicy)&&console.warn(`EXEC_HOOKS["${t}"] has unrecognized failurePolicy "${l.failurePolicy}". Valid: ${c.join(`, `)}.`)}}function l(r){let i=[{name:`HOOK_EVENTS`,entries:Object.values(t)},{name:`HOOK_TOOL_MATCHERS`,entries:Object.values(n)}];for(let t of e){for(let e of i)for(let n of e.entries)if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e.name} (entry has keys: ${Object.keys(n).join(`, `)}). Add a "${t}" key to all entries in ${e.name} in exec-hooks.mjs.`);if(r){for(let[e,n]of Object.entries(r))if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e} (has keys: ${Object.keys(n).join(`, `)}). Add "${t}: '...'" to ${e}.`)}}}function u(e){let t=[];if(!e||typeof e!=`object`)return t.push(`Generated hook must be a non-null object`),t;for(let n of[`id`,`event`,`category`,`description`])(!e[n]||typeof e[n]!=`string`)&&t.push(`Generated hook missing or invalid "${n}" (must be a non-empty string)`);e.category&&![`guard`,`signal`].includes(e.category)&&t.push(`Generated hook has invalid category "${e.category}". Must be "guard" or "signal".`);let n=[`candidate`,`evaluated`,`promoted`,`rejected`,`disabled`];return e.promotionState&&!n.includes(e.promotionState)&&t.push(`Generated hook has invalid promotionState "${e.promotionState}". Valid: ${n.join(`, `)}.`),e.confidence!==void 0&&(typeof e.confidence!=`number`||e.confidence<0||e.confidence>1)&&t.push(`Generated hook confidence must be a number between 0 and 1, got "${e.confidence}"`),e.originToolNames!==void 0&&!Array.isArray(e.originToolNames)&&t.push(`Generated hook originToolNames must be an array of strings`),e.promotionState===`promoted`&&!e.createdAt&&t.push(`Generated hook promoted but missing createdAt timestamp`),t}export{r as EXEC_HOOKS,t as HOOK_EVENTS,n as HOOK_TOOL_MATCHERS,e as SUPPORTED_PLATFORMS,l as validateAllPlatformRegistries,u as validateGeneratedHookDef,c as validateHookDefinitions};
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * bash-guard — PreToolUse guard against low-value Bash commands.
4
+ *
5
+ * Detects grep, find, cat, ls, rg patterns in Bash tool invocations
6
+ * and blocks them with a redirect to the appropriate AI Kit MCP tool
7
+ * (search, find, file_summary). All agents now have mcp__aikit__* tools
8
+ * in their tools: frontmatter alongside native tools.
9
+ *
10
+ * Only fires when the command STARTS with one of these patterns —
11
+ * mid-pipe uses (e.g., `git log | grep fix`) are allowed.
12
+ *
13
+ * @category guard
14
+ * @event PreToolUse
15
+ */
16
+
17
+ import { createHook } from './_runtime.mjs';
18
+
19
+ const BASH_TOOLS = new Set(['Bash', 'bash', 'execute_command', 'terminal']);
20
+
21
+ /**
22
+ * Patterns that map to MCP tools instead of raw shell.
23
+ * Only matches when the command STARTS with the pattern (after optional whitespace).
24
+ */
25
+ const REDIRECT_PATTERNS = [
26
+ {
27
+ re: /^\s*grep(\s|$)/m,
28
+ tool: 'mcp__aikit__search or mcp__aikit__find',
29
+ reason: 'grep for code search',
30
+ },
31
+ { re: /^\s*find(\s|$)/m, tool: 'mcp__aikit__find({ glob })', reason: 'find for file search' },
32
+ { re: /^\s*cat(\s|$)/m, tool: 'mcp__aikit__file_summary', reason: 'cat for reading files' },
33
+ {
34
+ re: /^\s*ls(\s|$)/m,
35
+ tool: 'mcp__aikit__find({ glob }) or mcp__aikit__search',
36
+ reason: 'ls for exploration',
37
+ },
38
+ {
39
+ re: /^\s*rg(\s|$)/m,
40
+ tool: 'mcp__aikit__search or mcp__aikit__find',
41
+ reason: 'rg (ripgrep) for search',
42
+ },
43
+ {
44
+ re: /^\s*dir(\s|$)/m,
45
+ tool: 'mcp__aikit__find({ glob }) or mcp__aikit__search',
46
+ reason: 'dir for exploration',
47
+ },
48
+ ];
49
+
50
+ /** Check if the command starts with a blocked pattern. */
51
+ const handler = async (context) => {
52
+ if (!BASH_TOOLS.has(context.toolName)) return { decision: 'allow' };
53
+
54
+ const command = String(
55
+ context.toolInput?.command ??
56
+ context.toolInput?.cmd ??
57
+ context.toolInput?.input ??
58
+ context.toolInput?.script ??
59
+ '',
60
+ );
61
+
62
+ if (!command.trim()) return { decision: 'allow' };
63
+
64
+ for (const { re, tool, reason } of REDIRECT_PATTERNS) {
65
+ if (re.test(command)) {
66
+ return {
67
+ decision: 'deny',
68
+ reason: `${reason}: use ${tool} instead. Bash is for builds, installs, git, scripts, network, and processes, not codebase exploration.`,
69
+ };
70
+ }
71
+ }
72
+
73
+ return { decision: 'allow' };
74
+ };
75
+
76
+ createHook(handler, { event: 'PreToolUse', category: 'guard' });
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * read-size-guard — PreToolUse guard against reading large files for understanding.
4
+ *
5
+ * Blocks Read tool on files exceeding MAX_LINES when the purpose appears to be
6
+ * understanding (not editing). Redirects to mcp__aikit__file_summary which
7
+ * provides compressed, relevant context at lower token cost.
8
+ *
9
+ * Editing goes through the Edit/MultiEdit tools, not Read — so this guard
10
+ * only affects context-wasting full-file reads.
11
+ *
12
+ * @category guard
13
+ * @event PreToolUse
14
+ */
15
+
16
+ import fs from 'node:fs';
17
+ import { createHook } from './_runtime.mjs';
18
+
19
+ const READ_TOOLS = new Set(['Read', 'read_file', 'readFile']);
20
+ const MAX_LINES = 100;
21
+
22
+ /** Count lines efficiently by reading the first 64KB (covers most files). */
23
+ function countLines(filePath) {
24
+ try {
25
+ const fd = fs.openSync(filePath, 'r');
26
+ try {
27
+ const buf = Buffer.alloc(65536);
28
+ const bytesRead = fs.readSync(fd, buf, 0, buf.length, 0);
29
+ if (bytesRead === 0) return 0;
30
+ const firstChunk = buf.toString('utf-8', 0, bytesRead);
31
+ const lines = firstChunk.split('\n').length;
32
+ // If we read less than the buffer, we have the whole file
33
+ if (bytesRead < buf.length) return lines;
34
+ // File is >64KB — likely over MAX_LINES
35
+ return MAX_LINES + 1;
36
+ } finally {
37
+ fs.closeSync(fd);
38
+ }
39
+ } catch {
40
+ return 0; // Can't read — allow the tool call
41
+ }
42
+ }
43
+
44
+ const handler = async (context) => {
45
+ if (!READ_TOOLS.has(context.toolName)) return { decision: 'allow' };
46
+
47
+ for (const filePath of context.filePaths) {
48
+ if (!filePath) continue;
49
+ const lineCount = countLines(filePath);
50
+ if (lineCount > MAX_LINES) {
51
+ return {
52
+ decision: 'deny',
53
+ reason: `File has ~${lineCount}+ lines (max ${MAX_LINES} for Read). Use mcp__aikit__file_summary({ files: ["${filePath.replace(/\\/g, '\\\\')}"], tier: 'T2', query: "<what you need>" }) for compressed context instead. Read is only for small files (< ${MAX_LINES} lines) or exact edit lines.`,
54
+ };
55
+ }
56
+ }
57
+
58
+ return { decision: 'allow' };
59
+ };
60
+
61
+ createHook(handler, { event: 'PreToolUse', category: 'guard' });