adam-agent-server 1.6.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App-ZRCRM7WR.js +13 -0
- package/dist/{adam-automator-skills-UFW5TXCC.js → adam-automator-skills-EZGBICHT.js} +1 -1
- package/dist/adam-tools-V5LPU47X.js +1 -0
- package/dist/{approval-handler-HQO62WK2.js → approval-handler-PB7PSLUS.js} +1 -1
- package/dist/audit-manager-BSBBDUER.js +1 -0
- package/dist/bree-engine-7S33CWS7.js +1 -0
- package/dist/channels-SITUUC4J.js +1 -0
- package/dist/{channels-J4STJ4X2.js → channels-ULFUCUUZ.js} +1 -1
- package/dist/{chunk-7446ZS6D.js → chunk-2L2347UQ.js} +1 -1
- package/dist/{chunk-FXQAUQTI.js → chunk-2YTDCR6A.js} +1 -1
- package/dist/chunk-4PQHGLZH.js +99 -0
- package/dist/{chunk-NCFVJCNQ.js → chunk-5EPG2US5.js} +2 -2
- package/dist/{chunk-2H7UOW4P.js → chunk-5QZXYKMS.js} +1 -1
- package/dist/chunk-5XOTPEAK.js +6 -0
- package/dist/{chunk-MDBVKBC7.js → chunk-6KF7OO2B.js} +1 -1
- package/dist/{chunk-TSPQ44HT.js → chunk-A5OCDYTW.js} +1 -1
- package/dist/{chunk-DWRYIN5N.js → chunk-AQ3ASS4B.js} +1 -1
- package/dist/{chunk-GMMWA5EG.js → chunk-B6LOT5CG.js} +1 -1
- package/dist/{chunk-MJSSCKMB.js → chunk-BCH2HAIM.js} +2 -2
- package/dist/{chunk-4C5ITATX.js → chunk-BQ3ZAYHC.js} +1 -1
- package/dist/{chunk-YHVYX3F4.js → chunk-DVN3BFPP.js} +1 -1
- package/dist/{chunk-P5ZXNBNV.js → chunk-EQZFOBAJ.js} +1 -1
- package/dist/{chunk-G5ESQEXN.js → chunk-FPZEZYUB.js} +1 -1
- package/dist/{chunk-YXYIA24D.js → chunk-GSFLLRS7.js} +1 -1
- package/dist/{chunk-7ZGSJCX5.js → chunk-HQRUJQN7.js} +1 -1
- package/dist/{chunk-52PR7XTN.js → chunk-IKPYPZ64.js} +1 -1
- package/dist/{chunk-FZCNYKNT.js → chunk-JJH2RCVC.js} +1 -1
- package/dist/chunk-K4C43YDD.js +7 -0
- package/dist/{chunk-V32YF3J5.js → chunk-M4YI4WVX.js} +1 -1
- package/dist/{chunk-WAG3MNMC.js → chunk-NASJH4NT.js} +1 -1
- package/dist/{chunk-TNL2LZB7.js → chunk-NUITL62I.js} +1 -1
- package/dist/{chunk-3LY6PD6A.js → chunk-NWMOV23A.js} +1 -1
- package/dist/chunk-PHT24MOV.js +1 -0
- package/dist/{chunk-ZL5JXLAX.js → chunk-QGYDGZSC.js} +1 -1
- package/dist/{chunk-VVSZZK5T.js → chunk-RI3V72RP.js} +2 -2
- package/dist/{chunk-RLJYEEQC.js → chunk-RZ7LCZVK.js} +1 -1
- package/dist/{chunk-5OQZPUBV.js → chunk-TAF2DBBC.js} +8 -8
- package/dist/{chunk-HWLSHTVX.js → chunk-ULTK7RD6.js} +3 -3
- package/dist/{chunk-DBP7GPWG.js → chunk-WMB7P64J.js} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{config-KFPS7IEH.js → config-HBQPBIWL.js} +1 -1
- package/dist/{db-PZ2V7UCK.js → db-QEWTZGU3.js} +1 -1
- package/dist/{delivery-log-ACNJ66RD.js → delivery-log-AC476GX7.js} +1 -1
- package/dist/engine-6K4RG644.js +1 -0
- package/dist/{evolution-audit-OQDGPKYI.js → evolution-audit-XMBDUN3T.js} +1 -1
- package/dist/index.js +13 -10
- package/dist/{learner-QCD6BH2J.js → learner-VCS3Q7BR.js} +1 -1
- package/dist/{memories-QGMRSBJJ.js → memories-VMOGFVPU.js} +1 -1
- package/dist/{memory-extractor-3MRK43A2.js → memory-extractor-4WJNHYWR.js} +2 -2
- package/dist/memory-service-ZS6MBUIC.js +1 -0
- package/dist/outbound-gateway-H7RFG6D2.js +1 -0
- package/dist/role-presets-XAEOYEAW.js +1 -0
- package/dist/role-workspace-NKGAH6J6.js +1 -0
- package/dist/{roles-KYXNMO5H.js → roles-ZYCFQMAY.js} +1 -1
- package/dist/{session-manager-LZ77OT7A.js → session-manager-COLCNIB7.js} +1 -1
- package/dist/task-templates-4KCZOUN5.js +1 -0
- package/dist/workflow-executor-Z7JFMR56.js +1 -0
- package/package.json +25 -25
- package/web/dist/assets/{ChannelDetail-DHT8fW0C.js → ChannelDetail-DnL0_h8q.js} +1 -1
- package/web/dist/assets/{Channels-YHGNXcRu.js → Channels-dod8Q4oq.js} +1 -1
- package/web/dist/assets/{Dashboard-DsHC5W4C.js → Dashboard-Dl0vA6Ky.js} +1 -1
- package/web/dist/assets/{EnvVarEditor-Dxy1Kz1Z.js → EnvVarEditor-C-gErAzC.js} +1 -1
- package/web/dist/assets/{EventDefDetail-CwprP2ch.js → EventDefDetail-BhJZGNlX.js} +1 -1
- package/web/dist/assets/{Events-B19a8cEG.js → Events-DnNZ9-BN.js} +1 -1
- package/web/dist/assets/{Evolution-DT6iZvil.js → Evolution-BBWmrrnr.js} +1 -1
- package/web/dist/assets/{GoalDetail-BALsnPQl.js → GoalDetail-uqWQCOj3.js} +1 -1
- package/web/dist/assets/{Goals-BJIsKgfH.js → Goals-CylKmR9j.js} +1 -1
- package/web/dist/assets/{Logs-Cv15aV3l.js → Logs-6rf0KT0z.js} +1 -1
- package/web/dist/assets/{Memories-CKAXhAso.js → Memories-CrBTujU7.js} +1 -1
- package/web/dist/assets/{Plugins-NO0S2spH.js → Plugins-VKUSUcSE.js} +1 -1
- package/web/dist/assets/{RoleDetail-1FNyCD4u.js → RoleDetail-DJc4CWFN.js} +1 -1
- package/web/dist/assets/{Roles-grfjw2zy.js → Roles-6pmjn04G.js} +1 -1
- package/web/dist/assets/{Settings-9LRLfa_4.js → Settings-DW1jmrNj.js} +1 -1
- package/web/dist/assets/{Strategies-BMyd_7_5.js → Strategies-Bmke6qZo.js} +1 -1
- package/web/dist/assets/{Switch-CULsD-kC.js → Switch-CfTpXW9_.js} +1 -1
- package/web/dist/assets/{TaskDetail-C2yXy8gE.js → TaskDetail-CwJ_UKgt.js} +1 -1
- package/web/dist/assets/Work-DVdWNBEm.js +1 -0
- package/web/dist/assets/{index-qYKJGoIB.js → index-DYsO5Awn.js} +2 -2
- package/web/dist/index.html +1 -1
- package/dist/App-WJMHK5EO.js +0 -13
- package/dist/adam-tools-IAZSLWYB.js +0 -1
- package/dist/audit-manager-LC5EQXCI.js +0 -1
- package/dist/bree-engine-M5CZ6A62.js +0 -1
- package/dist/channels-5TFYQN5Z.js +0 -1
- package/dist/chunk-FIN36WAP.js +0 -99
- package/dist/chunk-GGIHDFRW.js +0 -6
- package/dist/chunk-I7ZZKPHE.js +0 -7
- package/dist/chunk-YDVTWPNA.js +0 -1
- package/dist/engine-5DHYHDAP.js +0 -1
- package/dist/memory-service-M5ADGITG.js +0 -1
- package/dist/outbound-gateway-QRL36F7K.js +0 -1
- package/dist/role-presets-DLO3XS54.js +0 -1
- package/dist/role-workspace-URSOBCDH.js +0 -1
- package/dist/task-templates-YPNWJOVV.js +0 -1
- package/dist/workflow-executor-3WMS2WV3.js +0 -1
- package/web/dist/assets/Work-dftf35Me.js +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{a as
|
|
2
|
-
`),s=0;for(let t of e){let n=t.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7).trim());let a=n.indexOf("=");if(a===-1)continue;let i=n.slice(0,a).trim();if(!i)continue;let c=n.slice(a+1).trim();(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'"))&&(c=c.slice(1,-1)),c=c.replace(/\$\{(\w+)\}|\$(\w+)/g,(p,d,u)=>{let h=d??u;return process.env[h]??""}),(i.startsWith("ANTHROPIC_")||process.env[i]===void 0)&&(process.env[i]=c,s++)}return s}xe();qe();ws();import{existsSync as dn}from"fs";import pn from"path";import Ca from"fastify";import Aa from"@fastify/cors";import Ea from"@fastify/static";import Pa from"@fastify/websocket";import Oa from"@fastify/swagger";import Da from"@fastify/swagger-ui";import{timingSafeEqual as Fa}from"crypto";function un(o,r){let e=Ca({logger:!1});if(e.register(Oa,{openapi:{info:{title:"Adam API",description:"Agent orchestration server built on Claude Agent SDK. Multi-agent system with parallel task execution, intelligent agent routing, self-evolving personas, and REST/WebSocket API.",version:Le()},servers:[{url:"http://localhost:7100"}],tags:[{name:"Tasks",description:"Task lifecycle management"},{name:"Roles",description:"Role CRUD and workspace management"},{name:"Skills",description:"Skill CRUD and permissions"},{name:"Memories",description:"Agent memory search and retrieval"},{name:"Goals",description:"Goal-driven task management"},{name:"Strategies",description:"Thompson Sampling strategy engine"},{name:"Templates",description:"Task template CRUD and triggers"},{name:"Webhooks",description:"External system integration"},{name:"Config",description:"Runtime configuration management"},{name:"Evolution",description:"Agent evolution audit log"},{name:"Health",description:"Server health checks"}],components:{securitySchemes:{apiKey:{type:"apiKey",in:"header",name:"x-api-key",description:"API key for webhook endpoints"}}}}}),e.register(Da,{routePrefix:"/docs"}),e.register(Aa,{origin:!0}),e.register(Pa,{options:{maxPayload:1024*1024*16}}),r){let t=Buffer.from(r);e.addHook("onRequest",async(n,a)=>{let i=n.url;if(i==="/healthz"||i==="/readyz"||i.startsWith("/docs")||i.startsWith("/ui"))return;let c=n.headers["x-api-key"];if(c&&ln(c,t))return;let p=n.query,d=p.api_key||p["x-api-key"];if(!(d&&ln(d,t)))return a.status(401).send({code:"UNAUTHORIZED",message:"Invalid or missing API key"})})}let s=pn.join(_s,"web/dist");return dn(s)&&(e.register(Ea,{root:s,prefix:"/ui/",wildcard:!0}),e.get("/ui",async(t,n)=>n.sendFile("index.html",s))),e.setErrorHandler((t,n,a)=>{if(t.validation){let c=t.validation.map(p=>{let d=p.instancePath||p.params?.missingProperty||"";return d?`${d}: ${p.message}`:p.message});return a.status(400).send({code:"VALIDATION_ERROR",message:c.join("; ")})}let i=t.statusCode??500;return a.status(i).send({code:"INTERNAL_ERROR",message:t.message})}),e.setNotFoundHandler((t,n)=>{let a=t.url.split("?")[0];return t.url.startsWith("/ui")&&dn(s)&&!pn.extname(a)?n.sendFile("index.html",s):n.status(404).send({code:"NOT_FOUND",message:"Route not found"})}),e}function ln(o,r){try{let e=Buffer.from(o);return e.length!==r.length?!1:Fa(e,r)}catch{return!1}}import{z as g}from"zod/v4";var xa=o=>({...o,nullable:!0}),S={type:"object",properties:{code:{type:"string"},message:{type:"string"}}},ja={type:"object",additionalProperties:!0,properties:{id:{type:"string"},prompt:{type:"string"},dependsOn:{type:"array",items:{type:"string"}},outputAs:{type:"string"},roleId:{type:"string"},autoSelectRole:{type:"boolean"},requirements:{type:"object",additionalProperties:!0}}},Na={type:"object",additionalProperties:!0,properties:{type:{type:"string"},cron:{type:"string"},event:{type:"string"}}},mn={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},description:{type:"string"},trigger:Na,steps:{type:"array",items:ja},agentPreference:{type:"string"},config:{type:"object",additionalProperties:!0},tags:{type:"array",items:{type:"string"}},enabled:{type:"boolean"},createdAt:{type:"number"},updatedAt:{type:"number"}}},qa={type:"object",properties:{input:{type:"number"},output:{type:"number"}}},fn={type:"object",additionalProperties:!0,properties:{path:{type:"string"},access:{type:"string",enum:["ro","rw"]}}},Lt={type:"object",additionalProperties:!0,properties:{id:{type:"string"},targets:{type:"array",items:{type:"string"}}}},La={type:"object",additionalProperties:!0,properties:{tools:{type:"array",items:{type:"string"}},paths:{type:"array",items:fn},osCapabilities:{type:"array",items:Lt},network:{type:"boolean"},plugins:{type:"array",items:{type:"string"}}}},Ma={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},status:{type:"string"},allowedTools:{type:"array",items:{type:"string"}},disallowedTools:{type:"array",items:{type:"string"}},approvalRequired:{type:"array",items:{type:"string"}},osCapabilities:{type:"array",items:Lt},additionalDirectories:{type:"array",items:{type:"object",additionalProperties:!0}},cagPrompt:{type:"string"},learnedRules:{type:"array",items:{type:"string"}},performanceScore:{type:"number"},model:{type:"string"},executionMode:{type:"string"}}},Ua={type:"object",additionalProperties:!0,properties:{model:{type:"string"},maxTurns:{type:"integer"},maxBudgetUsd:{type:"number"},timeout:{type:"integer"},effort:{type:"string"},requirements:La,executionProfile:Ma}},yn={type:"object",additionalProperties:!0,properties:{tools:{type:"array",items:{type:"string"}},paths:{type:"array",items:fn},osCapabilities:{type:"array",items:Lt},plugins:{type:"array",items:{type:"string"}},network:{type:"boolean"}}},Ba={type:"object",additionalProperties:!0,properties:{roleId:{type:"string"},name:{type:"string"},fitScore:{type:"number"},missing:yn}},Wa={type:"object",additionalProperties:!0,properties:{code:{type:"string",enum:["ROLE_NOT_FOUND","ROLE_TOOL_MISMATCH","ROLE_PATH_SCOPE_MISMATCH","ROLE_OS_CAPABILITY_MISMATCH","ROLE_PLUGIN_MISMATCH","ROLE_NETWORK_MISMATCH","ROLE_SELECTION_AMBIGUOUS","REQUIREMENTS_MISSING","VALIDATION_ERROR"]},message:{type:"string"},missing:yn,candidates:{type:"array",items:Ba}}},gn={type:"object",additionalProperties:!0,properties:{id:{type:"string"},parentId:{type:"string"},status:{type:"string"},prompt:{type:"string"},originalPrompt:{type:"string"},config:Ua,result:{type:"string"},error:{type:"string"},sdkSessionId:{type:"string"},roleId:{type:"string"},templateId:{type:"string"},createdAt:{type:"number"},startedAt:{type:"number"},completedAt:{type:"number"},costUsd:{type:"number"},tokenUsage:qa,numTurns:{type:"number"},totalDurationMs:{type:"number"}}},Va={type:"object",additionalProperties:!0,properties:{model:{type:"string"},effort:{type:"string"},maxTurns:{type:"number"}}},Qe={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},source:{type:"string"},traits:{type:"array",items:{type:"string"}},background:{type:"string"},preferences:Va,learnedRules:{type:"array",items:{type:"string"}},memoryStreamId:{type:"string"},status:{type:"string"},createdAt:{type:"number"},lastActiveAt:{type:"number"},taskCount:{type:"number"},performanceScore:{type:"number"},role:{type:"string"},toolProfile:{type:"array",items:{type:"string"}},evaluationCriteria:{type:"object",additionalProperties:{type:"number"}},strategyPoolId:{type:"string"}}},Nt={type:"object",additionalProperties:!0,properties:{id:{type:"string"},roleId:{type:"string"},type:{type:"string"},content:{type:"string"},keywords:{type:"array",items:{type:"string"}},importance:{type:"number"},sourceType:{type:"string"},sourceTaskId:{type:"string"},evidence:{type:"array",items:{type:"string"}},createdAt:{type:"number"},lastAccessed:{type:"number"},retrievedCount:{type:"number"},score:{type:"number"}}},Ga={type:"object",additionalProperties:!0,properties:{id:{type:"string"},role:{type:"string"},taskType:{type:"string"},name:{type:"string"},promptTemplate:{type:"string"},alpha:{type:"number"},beta:{type:"number"},totalTrials:{type:"number"},avgReward:{type:"number"},toolProfile:{type:"array",items:{type:"string"}},createdAt:{type:"number"},updatedAt:{type:"number"}}},qt={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},description:{type:"string"},role:{type:"string"},metricType:{type:"string"},targetValue:{type:"number"},currentValue:{type:"number"},deadline:{type:"number"},budgetUsd:{type:"number"},status:{type:"string"},createdAt:{type:"number"},updatedAt:{type:"number"}}},$a={type:"object",additionalProperties:!0,properties:{name:{type:"string"},displayName:{type:"string"},description:{type:"string"},tags:{type:"array",items:{type:"string"}},trigger:{type:"string"}}},R={templateCreated:{201:{type:"object",properties:{templateId:{type:"string"}}},400:{type:"object",properties:{code:{type:"string"},message:{type:"string"},failingStepIds:{type:"array",items:{type:"string"}}}}},templateList:{200:{type:"object",properties:{templates:{type:"array",items:mn}}}},templateDetail:{200:{type:"object",properties:{template:mn}},404:S},templateUpdated:{200:{type:"object",properties:{templateId:{type:"string"}}},400:{type:"object",properties:{code:{type:"string"},message:{type:"string"},failingStepIds:{type:"array",items:{type:"string"}}}},404:S},templateDeleted:{200:{type:"object",properties:{templateId:{type:"string"},deleted:{type:"boolean"}}},404:S},templateRun:{200:{type:"object",properties:{executionId:{type:"string"},status:{type:"string"}}},404:S},taskCreated:{201:{type:"object",additionalProperties:!0,properties:{taskId:{type:"string"},roleId:{type:"string"},fitScore:{type:"number"}}},400:Wa},taskList:{200:{type:"object",properties:{tasks:{type:"array",items:gn}}}},taskDetail:{200:{type:"object",properties:{task:gn}},404:S},taskAction:{200:{type:"object",additionalProperties:!0,properties:{taskId:{type:"string"}}},400:S,404:S},approvalAction:{200:{type:"object",properties:{approvalId:{type:"string"},decision:{type:"string"}}},404:S},agentList:{200:{type:"object",properties:{roles:{type:"array",items:Qe}}}},agentDetail:{200:{type:"object",properties:{agent:Qe}},404:S},agentCreated:{201:{type:"object",properties:{agent:Qe}}},agentUpdated:{200:{type:"object",properties:{agent:Qe}},404:S},agentDeleted:{200:{type:"object",properties:{agentId:{type:"string"},deleted:{type:"boolean"}}},400:S,404:S},agentPersona:{200:{type:"object",properties:{persona:xa({type:"string"})}},404:S},memoryList:{200:{type:"object",properties:{memories:{type:"array",items:Nt},count:{type:"number"}}},404:S},memoryQuery:{200:{type:"object",properties:{memories:{type:"array",items:Nt},count:{type:"number"}}},404:S},memoryCreated:{201:{type:"object",properties:{memory:Nt}},400:S,404:S},memoryUpdated:{200:{type:"object",properties:{memoryId:{type:"string"},updated:{type:"boolean"},embeddingUpdated:{type:"boolean"}}},400:S,404:S},memoryDeleted:{200:{type:"object",properties:{memoryId:{type:"string"},deleted:{type:"boolean"}}},404:S},strategyList:{200:{type:"object",properties:{strategies:{type:"array",items:Ga}}}},strategyProbabilities:{200:{type:"object",additionalProperties:!0,properties:{role:{type:"string"},taskType:{type:"string"},stats:{type:"object",additionalProperties:!0},probabilities:{type:"object",additionalProperties:{type:"number"}}}}},goalList:{200:{type:"object",properties:{goals:{type:"array",items:qt}}}},goalDetail:{200:{type:"object",properties:{goal:qt}},404:S},goalCreated:{201:{type:"object",properties:{goal:qt}},400:{...S,additionalProperties:!0,properties:{...S.properties,errors:{type:"array",items:{type:"string"}},warnings:{type:"array",items:{type:"string"}}}}},webhookTriggered:{202:{type:"object",properties:{code:{type:"string"},message:{type:"string"},executionId:{type:"string"},templateId:{type:"string"}}},401:S,404:S,409:S,500:S},webhookList:{200:{type:"object",properties:{webhooks:{type:"array",items:$a},auth:{type:"string"}}}},configGet:{200:{type:"object",additionalProperties:!0,properties:{config:{type:"object",additionalProperties:{type:"object",additionalProperties:!0,properties:{value:{},mutable:{type:"boolean"}}}},mutable:{type:"array",items:{type:"string"}},restartRequired:{type:"array",items:{type:"string"}},sandbox:{type:"object",additionalProperties:!0,properties:{platform:{type:"string"},available:{type:"boolean"}}},osCapabilities:{type:"object",additionalProperties:!0,properties:{registry:{type:"array",items:{type:"object",additionalProperties:!0,properties:{id:{type:"string"},label:{type:"string"},description:{type:"string"},platform:{type:"string"},status:{type:"string"},availability:{type:"string"},editable:{type:"boolean"},supportsTargets:{type:"boolean"},disabledReason:{type:"string"},effectiveDisabledReason:{type:"string"}}}}}}}}},configPatch:{200:{type:"object",additionalProperties:!0,properties:{success:{type:"boolean"},updated:{type:"array",items:{type:"string"}},errors:{type:"array",items:{type:"string"}},message:{type:"string"}}}},healthz:{200:{type:"object",properties:{status:{type:"string"}}}},readyz:{200:{type:"object",properties:{status:{type:"string"},checks:{type:"object",additionalProperties:{type:"boolean"}}}},503:{type:"object",properties:{status:{type:"string"},checks:{type:"object",additionalProperties:{type:"boolean"}}}}}};var hn=g.union([g.object({type:g.literal("session"),sessionId:g.string()}),g.object({type:g.literal("channel"),channelId:g.string(),chatId:g.string().optional()})]),Ha=g.object({prompt:g.string().min(1,"prompt is required"),roleId:g.string().optional(),requirements:Ue.optional(),autoSelectRole:g.boolean().optional(),deliverTo:g.array(hn).optional(),reportTo:g.array(hn).optional(),config:g.object({allowedTools:g.array(g.string()).optional(),disallowedTools:g.array(g.string()).optional(),maxTurns:g.number().optional(),maxBudgetUsd:g.number().optional(),mcpServers:g.record(g.string(),g.unknown()).optional(),model:g.string().optional(),effort:g.enum(["low","medium","high","max"]).optional(),settingSources:g.array(g.string()).optional(),workspacePath:g.string().optional(),timeout:g.number().optional(),approvalRequired:g.array(g.string()).optional(),approvalTimeout:g.number().optional(),env:g.record(g.string(),g.string()).optional(),plugins:g.array(g.string()).optional()}).optional()}),de=g.object({id:g.string().uuid()}),za=["pending","queued","running","paused","completed","failed","cancelled"],Ka=g.object({status:g.enum(za).optional(),roleId:g.string().optional(),limit:g.coerce.number().min(1).max(100).default(100),offset:g.coerce.number().min(0).default(0)});async function bn(o){let r=new We;o.post("/tasks",{schema:{tags:["Tasks"],summary:"Create a task",description:"Create a new task with a prompt and optional agent/config overrides. The task enters 'pending' status and is picked up by the scheduler.",body:{type:"object",required:["prompt"],properties:{prompt:{type:"string",minLength:1,description:"Task prompt"},roleId:{type:"string",description:"Role to assign"},config:{type:"object",description:"Optional task configuration overrides",properties:{model:{type:"string"},maxTurns:{type:"integer"},maxBudgetUsd:{type:"number"},timeout:{type:"integer"},effort:{type:"string",enum:["low","medium","high","max"]}}}}},response:R.taskCreated}},async(n,a)=>{let i=Ha.safeParse(n.body);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)});let{prompt:c,roleId:p,requirements:d,autoSelectRole:u,config:h,deliverTo:w,reportTo:y}=i.data,f=await Ms({prompt:c,roleId:p,requirements:d,autoSelectRole:u,deliverTo:w,reportTo:y,config:h});return f.ok?a.status(201).send({taskId:f.taskId,roleId:f.roleId,fitScore:f.fitScore}):a.status(400).send({code:f.code,message:f.reason,missing:f.missing,candidates:f.candidates})}),o.get("/tasks",{schema:{tags:["Tasks"],summary:"List tasks",description:"List tasks with optional status filter and pagination.",querystring:{type:"object",properties:{status:{type:"string",enum:["pending","queued","running","paused","completed","failed","cancelled"]},limit:{type:"integer",minimum:1,maximum:100,default:100},offset:{type:"integer",minimum:0,default:0}}},response:R.taskList}},async(n,a)=>{let i=Ka.safeParse(n.query);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)});let{status:c,roleId:p,limit:d,offset:u}=i.data;return{tasks:G(c,d,u,p)}}),o.get("/tasks/:id",{schema:{tags:["Tasks"],summary:"Get task by ID",description:"Retrieve a single task by its UUID.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},response:R.taskDetail}},async(n,a)=>{let i=de.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)});let c=O(i.data.id);return c?{task:c}:a.status(404).send({code:"NOT_FOUND",message:"Task not found"})}),o.post("/tasks/:id/cancel",{schema:{tags:["Tasks"],summary:"Cancel a task",description:"Cancel a running, queued, pending, or paused task. Returns 400 if the task is in a terminal state.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},response:R.taskAction}},async(n,a)=>{let i=de.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)});let c=O(i.data.id);return c?c.status!=="running"&&c.status!=="queued"&&c.status!=="pending"&&c.status!=="paused"?a.status(400).send({code:"INVALID_STATE",message:`Cannot cancel task in status: ${c.status}`}):(r.cancelTask(c.id),{taskId:c.id,status:"cancelled"}):a.status(404).send({code:"NOT_FOUND",message:"Task not found"})});let e=g.object({taskIds:g.array(g.string()).min(1).max(500)});o.post("/tasks/batch-cancel",{schema:{tags:["Tasks"],summary:"Batch cancel tasks",description:"Cancel multiple tasks at once. Skips tasks that are already in terminal state. Returns count of cancelled tasks.",body:{type:"object",required:["taskIds"],properties:{taskIds:{type:"array",items:{type:"string"},minItems:1,maxItems:500}}}}},async(n,a)=>{let i=e.safeParse(n.body);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)});let c=new Set(["pending","queued","running","paused"]),p=0,d=[];for(let u of i.data.taskIds){let h=O(u);if(!h){d.push({taskId:u,reason:"not found"});continue}if(!c.has(h.status)){d.push({taskId:u,reason:`already ${h.status}`});continue}r.cancelTask(u),p++}return{cancelled:p,total:i.data.taskIds.length,errors:d.length>0?d:void 0}}),o.get("/tasks/:id/logs",{schema:{tags:["Tasks"],summary:"Get task step logs",description:"Returns execution step logs for a task (reasoning, tool calls, results).",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50},offset:{type:"integer",minimum:0,default:0}}}}},async(n,a)=>{let i=O(n.params.id);if(!i)return a.status(404).send({code:"NOT_FOUND",message:"Task not found"});let{limit:c=50,offset:p=0}=n.query;return{logs:ut(i.id,c,p)}});let s=g.object({approvalId:g.string().uuid(),reason:g.string().optional()});o.post("/tasks/:id/approve",{schema:{tags:["Tasks"],summary:"Approve a pending approval",description:"Approve a tool-use approval request for a paused task. The skill agent resumes execution with the approved tool call.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",required:["approvalId"],properties:{approvalId:{type:"string",format:"uuid"},reason:{type:"string"}}},response:R.approvalAction}},async(n,a)=>{let i=de.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)});let c=s.safeParse(n.body);return c.success?O(i.data.id)?r.resolveApproval(c.data.approvalId,"allow",c.data.reason)?{approvalId:c.data.approvalId,decision:"allow"}:a.status(404).send({code:"NOT_FOUND",message:"Approval not found or already resolved"}):a.status(404).send({code:"NOT_FOUND",message:"Task not found"}):a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(c.error)})}),o.post("/tasks/:id/reject",{schema:{tags:["Tasks"],summary:"Reject a pending approval",description:"Reject a tool-use approval request for a paused task. The skill agent skips the denied tool call.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",required:["approvalId"],properties:{approvalId:{type:"string",format:"uuid"},reason:{type:"string"}}},response:R.approvalAction}},async(n,a)=>{let i=de.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)});let c=s.safeParse(n.body);return c.success?O(i.data.id)?r.resolveApproval(c.data.approvalId,"deny",c.data.reason)?{approvalId:c.data.approvalId,decision:"deny"}:a.status(404).send({code:"NOT_FOUND",message:"Approval not found or already resolved"}):a.status(404).send({code:"NOT_FOUND",message:"Task not found"}):a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(c.error)})});let t=g.object({planId:g.string(),decision:g.enum(["allow","deny"]),approvalType:g.enum(["once","permanent"]).optional(),reason:g.string().optional()});o.post("/tasks/:id/approve-plan",{schema:{tags:["Tasks"],summary:"Approve or deny an execution plan",description:"Respond to a plan approval request. Allow once (single task), allow permanent (create rule for similar tasks), or deny.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",required:["planId","decision"],properties:{planId:{type:"string"},decision:{type:"string",enum:["allow","deny"]},approvalType:{type:"string",enum:["once","permanent"]},reason:{type:"string"}}}}},async(n,a)=>{let i=de.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)});let c=t.safeParse(n.body);if(!c.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(c.error)});if(!O(i.data.id))return a.status(404).send({code:"NOT_FOUND",message:"Task not found"});let{planId:d,decision:u,approvalType:h,reason:w}=c.data;return r.resolvePlanApproval(d,u,h,w)?{planId:d,decision:u,approvalType:h}:a.status(404).send({code:"NOT_FOUND",message:"Plan approval not found or already resolved"})}),o.get("/tasks/:id/plan",{schema:{tags:["Tasks"],summary:"Get execution plans for a task",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(n,a)=>{let i=de.safeParse(n.params);return i.success?O(i.data.id)?{plans:Ws(i.data.id)}:a.status(404).send({code:"NOT_FOUND",message:"Task not found"}):a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)})}),o.get("/tasks/:id/delivery-log",{schema:{tags:["Tasks"],summary:"Get delivery log for a task",description:"Returns delivery log entries for a task, including channel and webhook delivery attempts.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50}}}}},async(n,a)=>{let i=de.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(i.error)});let c=O(i.data.id);if(!c)return a.status(404).send({code:"NOT_FOUND",message:"Task not found"});let{limit:p=50}=n.query;return{logs:Us(c.id,p)}})}xe();qe();async function vn(o,r){o.get("/healthz",{schema:{tags:["Health"],summary:"Health check",description:"Basic liveness probe. Returns 200 if the server process is running.",response:R.healthz}},async(e,s)=>({status:"ok"})),o.get("/readyz",{schema:{tags:["Health"],summary:"Readiness check",description:"Readiness probe that checks database, roles, config, embedding model, and task hub. Returns 503 if any check fails.",response:R.readyz}},async(e,s)=>{let t={database:!1,manager:!1,config:!1};try{V().prepare("SELECT 1").get(),t.database=!0}catch{t.database=!1}t.manager=!0,t.config=!!r.server;try{let a=Ie(void 0,1,0);t.agents=a.length>0}catch{t.agents=!1}return t.embedding=Vs(),t.taskHub=!0,Object.values(t).every(a=>a)?{status:"ready",checks:t}:s.status(503).send({status:"not_ready",checks:t})}),o.get("/stats",{schema:{tags:["Health"],summary:"Runtime statistics",description:"Returns execution pool status, active/pending task counts, and cost summary."}},async(e,s)=>{let n=D().execution?.maxConcurrent??5,a=G("running"),i=G("pending"),c=hs(Gs());return{executionPool:{active:a.length,max:n,queued:i.length},totalCostToday:c}}),o.get("/version",{schema:{tags:["Health"],summary:"Server version",description:"Returns the server version from package.json.",response:{200:{type:"object",properties:{name:{type:"string"},version:{type:"string"}}}}}},async(e,s)=>({name:Cs(),version:Le()}))}import{timingSafeEqual as In}from"crypto";import{z as kn}from"zod/v4";var Mt=class{connections=new Map;eventBuffers=new Map;eventIndices=new Map;addConnection(r,e){this.connections.has(r)||this.connections.set(r,new Set),this.connections.get(r).add(e);let s=this.getBufferedEvents(r);for(let t of s)e.readyState===1&&e.send(JSON.stringify(t));e.on("close",()=>{this.removeConnection(r,e)})}removeConnection(r,e){let s=this.connections.get(r);s&&(s.delete(e),s.size===0&&this.connections.delete(r))}broadcast(r,e){this.addToBuffer(r,e);let s=this.connections.get(r);if(!s||s.size===0)return;let t=JSON.stringify(e);for(let n of s)n.readyState===1&&n.send(t)}addToBuffer(r,e){let s=this.eventBuffers.get(r);s||(s=[],this.eventBuffers.set(r,s)),s.push(e),s.length>100&&s.shift(),this.eventIndices.set(r,e.index)}getBufferedEvents(r){return this.eventBuffers.get(r)??[]}getNextIndex(r){let s=(this.eventIndices.get(r)??0)+1;return this.eventIndices.set(r,s),s}},Rn=new Mt;var Qa=kn.object({id:kn.string().uuid()});async function Tn(o,r){o.get("/tasks/:id/stream",{websocket:!0},(e,s)=>{if(r&&!Ya(s,r)){e.close(4401,"Unauthorized");return}let t=Qa.safeParse(s.params);if(!t.success){e.close(1008,"Invalid task ID");return}let{id:n}=t.data;if(!O(n)){e.close(1008,"Task not found");return}Rn.addConnection(n,e)})}function Ya(o,r){let e=o.headers["x-api-key"];if(e)try{let n=Buffer.from(e),a=Buffer.from(r);if(n.length===a.length&&In(n,a))return!0}catch{}let s=o.query,t=s.api_key||s["x-api-key"];if(t)try{let n=Buffer.from(t),a=Buffer.from(r);if(n.length===a.length&&In(n,a))return!0}catch{}return!1}import{timingSafeEqual as wn}from"crypto";Q();var Xa=N("ws"),Ye=new Set;function Sn(o,r){o.get("/events",{websocket:!0},(e,s)=>{if(r&&!Za(s,r)){e.close(4401,"Unauthorized");return}Ye.add(e),e.on("close",()=>{Ye.delete(e)}),e.on("error",t=>{Xa.error({error:t},"WebSocket error"),Ye.delete(e)})}),b.on("task_status_change",e=>{U(e)}),b.on("approval_request",e=>{U(e)}),b.on("stats_update",e=>{U(e)}),b.on("log_event",e=>{U(e)}),b.on("config_changed",e=>{U(e)}),b.on("plan_approval_request",e=>{(()=>{try{let t=Hs(e.taskId);if(!t)return!1;let n=zs(t.sessionId);return n?n.source.type==="channel"&&!!n.source.channelId:!1}catch{return!1}})()||U(e)}),b.on("plan_approval_decision",e=>{U(e)}),b.on("task_created",e=>{U(e)}),b.on("execution_slot_change",e=>{U(e)}),b.on("execution_task_start",e=>{U(e)}),b.on("execution_task_end",e=>{U(e)}),b.on("delivery_status_change",e=>{U(e)}),b.on("workflow_status_change",e=>{U(e)})}function U(o){let r=JSON.stringify(o);for(let e of Ye)e.readyState===1&&e.send(r)}function Za(o,r){let e=o.headers["x-api-key"];if(e)try{let n=Buffer.from(e),a=Buffer.from(r);if(n.length===a.length&&wn(n,a))return!0}catch{}let s=o.query,t=s.api_key||s["x-api-key"];if(t)try{let n=Buffer.from(t),a=Buffer.from(r);if(n.length===a.length&&wn(n,a))return!0}catch{}return!1}xe();function Ja(o){return{id:o.id,sdkSessionId:o.sdk_session_id??void 0,userTaskSessionId:o.user_task_session_id??void 0,workspacePath:o.workspace_path??void 0,toolsFingerprint:o.tools_fingerprint??void 0,createdAt:o.created_at,lastActiveAt:o.last_active_at??void 0}}function Ut(){let o=V(),r=o.prepare("SELECT * FROM server_state WHERE id = 1").get();if(r)return Ja(r);let e=Date.now();return o.prepare("INSERT INTO server_state (id, created_at) VALUES (1, ?)").run(e),{id:1,createdAt:e}}function we(o){let r=V(),e=[],s=[];"sdkSessionId"in o&&(e.push("sdk_session_id = ?"),s.push(o.sdkSessionId??null)),"userTaskSessionId"in o&&(e.push("user_task_session_id = ?"),s.push(o.userTaskSessionId??null)),"workspacePath"in o&&(e.push("workspace_path = ?"),s.push(o.workspacePath??null)),"lastActiveAt"in o&&(e.push("last_active_at = ?"),s.push(o.lastActiveAt??null)),"toolsFingerprint"in o&&(e.push("tools_fingerprint = ?"),s.push(o.toolsFingerprint??null)),e.length!==0&&(Ut(),s.push(1),r.prepare(`UPDATE server_state SET ${e.join(", ")} WHERE id = ?`).run(...s))}function Xe(o){we({sdkSessionId:o,lastActiveAt:Date.now()})}function _n(){we({sdkSessionId:void 0,lastActiveAt:Date.now()})}function Cn(o){we({workspacePath:o})}Is();qe();ws();import{z as l}from"zod/v4";import{v4 as An}from"uuid";Ds();Ta();import{rmSync as eo,existsSync as Bt}from"fs";var En=l.object({model:l.string().optional(),effort:l.enum(["low","medium","high","max"]).optional(),maxTurns:l.number().optional()}),Pn=l.object({path:l.string(),mode:l.enum(["ro","rw"]).default("rw"),inheritPlugins:l.boolean().optional(),inheritMcp:l.boolean().optional(),inheritPermissions:l.boolean().optional()}),to=l.string().max(256).regex(/^[A-Za-z_][A-Za-z0-9_]*$/,"Env var key must match POSIX format: [A-Za-z_][A-Za-z0-9_]*").check(l.refine(o=>!o.startsWith("ANTHROPIC_"),"ANTHROPIC_* keys are managed globally in Settings")),On=l.record(to,l.string().max(4096)).optional().check(l.refine(o=>!o||Object.keys(o).length<=100,"Maximum 100 environment variables per role")),Dn=l.object({id:l.string().min(1),targets:l.array(l.string().min(1)).optional()}),so=l.object({name:l.string().min(1,"name is required").regex(/^[\p{L}\p{N}_-]+$/u,"name must contain only letters, numbers, underscores, or hyphens"),cagPrompt:l.string().optional(),learnedRules:l.array(l.string()).optional(),allowedTools:l.array(l.string()).optional(),disallowedTools:l.array(l.string()).optional(),evaluationCriteria:l.record(l.string(),l.number()).optional(),executionMode:l.enum(["isolated","inline"]).optional(),model:l.string().optional(),maxBudgetUsd:l.number().optional(),approvalRequired:l.array(l.string()).optional(),preferences:En.optional(),additionalDirectories:l.array(Pn).optional(),allowedChannels:l.array(l.string()).optional(),inheritUserSettings:l.boolean().optional(),envVars:On,osCapabilities:l.array(Dn).optional()}),ro=l.object({name:l.string().min(1).optional(),cagPrompt:l.string().optional(),learnedRules:l.array(l.string()).optional(),status:l.enum(["active","inactive","retired"]).optional(),allowedTools:l.array(l.string()).optional(),disallowedTools:l.array(l.string()).optional(),evaluationCriteria:l.record(l.string(),l.number()).optional(),executionMode:l.enum(["isolated","inline"]).optional(),model:l.string().optional(),maxBudgetUsd:l.number().optional(),approvalRequired:l.array(l.string()).optional(),preferences:En.optional(),additionalDirectories:l.array(Pn).optional(),permissionMode:l.enum(["default","acceptEdits","dontAsk","bypassPermissions","plan","auto"]).optional(),allowedBashPatterns:l.array(l.string()).optional(),deniedBashPatterns:l.array(l.string()).optional(),allowedChannels:l.array(l.string()).nullable().optional(),inheritUserSettings:l.boolean().optional(),envVars:On,osCapabilities:l.array(Dn).optional()}),Ze=l.object({id:l.string().min(1)}),no=l.object({status:l.enum(["active","inactive","retired"]).optional(),limit:l.coerce.number().min(1).max(1e3).optional(),offset:l.coerce.number().min(0).default(0)}),ao=l.object({path:l.string().min(1)});async function Fn(o){o.get("/roles",{schema:{tags:["Roles"],summary:"List all roles",description:"List all roles with optional status filter and pagination.",querystring:{type:"object",properties:{status:{type:"string",enum:["active","inactive","retired"]},limit:{type:"integer",minimum:1,maximum:1e3},offset:{type:"integer",minimum:0,default:0}}}}},async(r,e)=>{let s=no.safeParse(r.query);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:l.prettifyError(s.error)});let{status:t,limit:n,offset:a}=s.data;return{roles:Ie(t,n,a).map(c=>({...c,workspacePath:ie(c.name)}))}}),o.post("/roles",{schema:{tags:["Roles"],summary:"Create a role",description:"Create a new role with a name, CAG prompt, and optional preferences.",body:{type:"object",required:["name"],properties:{name:{type:"string",minLength:1},cagPrompt:{type:"string"},preferences:{type:"object",properties:{model:{type:"string"},effort:{type:"string",enum:["low","medium","high","max"]},maxTurns:{type:"number"}}}}}}},async(r,e)=>{let s=so.safeParse(r.body);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:l.prettifyError(s.error)});let{name:t,cagPrompt:n,learnedRules:a,allowedTools:i,disallowedTools:c,evaluationCriteria:p,executionMode:d,model:u,maxBudgetUsd:h,approvalRequired:w,preferences:y,additionalDirectories:f,allowedChannels:A,inheritUserSettings:$,envVars:le,osCapabilities:te}=s.data;if(ft(t))return e.status(409).send({code:"CONFLICT",message:`Role with name '${t}' already exists`});let se;try{se=mt(te)}catch(K){return e.status(400).send({code:"VALIDATION_ERROR",message:K instanceof Error?K.message:String(K)})}let T={id:`role-${An().slice(0,8)}`,name:t,cagPrompt:n??"",learnedRules:a??[],memoryStreamId:`mem-${An().slice(0,8)}`,status:"active",preferences:y??{},allowedTools:i,disallowedTools:c,evaluationCriteria:p,executionMode:d,model:u,maxBudgetUsd:h,approvalRequired:w,additionalDirectories:f,allowedChannels:A,inheritUserSettings:$,envVars:le,osCapabilities:se,createdAt:Date.now()};return gt(T),bt(T),e.status(201).send({role:T})}),o.get("/roles/:id",{schema:{tags:["Roles"],summary:"Get role by ID",description:"Retrieve a single role with its project-scope plugins.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=Ze.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:l.prettifyError(s.error)});let t=M(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let n=ie(t.name),a=Me({scope:"project",projectPath:n});return{role:t,projectPlugins:a,workspacePath:n}}),o.get("/roles/:id/scores",{schema:{tags:["Roles"],summary:"Get role quality scores",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:100,default:20}}}}},async(r,e)=>{let s=l.object({id:l.string().min(1)}).safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:l.prettifyError(s.error)});let t=M(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let n=r.query.limit??20,a=Qs(t.id,n),i=Ys(t.id);return{scores:a,latestEma:i??null}}),o.patch("/roles/:id",{schema:{tags:["Roles"],summary:"Update a role",description:"Partially update a role's CAG prompt, learned rules, status, or preferences.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",properties:{name:{type:"string",minLength:1},cagPrompt:{type:"string"},learnedRules:{type:"array",items:{type:"string"}},status:{type:"string",enum:["active","inactive","retired"]},permissionMode:{type:"string",enum:["default","acceptEdits","dontAsk","bypassPermissions","plan","auto"]},allowedBashPatterns:{type:"array",items:{type:"string"}},deniedBashPatterns:{type:"array",items:{type:"string"}},preferences:{type:"object",properties:{model:{type:"string"},effort:{type:"string",enum:["low","medium","high","max"]},maxTurns:{type:"number"}}}}}}},async(r,e)=>{let s=Ze.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:l.prettifyError(s.error)});let t=ro.safeParse(r.body);if(!t.success)return e.status(400).send({code:"VALIDATION_ERROR",message:l.prettifyError(t.error)});if(!M(s.data.id))return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let{allowedChannels:a,osCapabilities:i,...c}=t.data,p={...c,updatedAt:Date.now()};if(a!==void 0&&(p.allowedChannels=a??void 0),i!==void 0)try{p.osCapabilities=mt(i)}catch(u){return e.status(400).send({code:"VALIDATION_ERROR",message:u instanceof Error?u.message:String(u)})}if(Ne(s.data.id,p),t.data.cagPrompt!==void 0||t.data.learnedRules!==void 0){let u=M(s.data.id);if(u){let h=ie(u.name);Bt(h)&&vt(h,u)}}let d=M(s.data.id);if(d&&(t.data.allowedTools!==void 0||t.data.disallowedTools!==void 0)){let u=ie(d.name);Bt(u)&&Rt(d.id,d.allowedTools,u)}return{role:d}}),o.delete("/roles/:id",{schema:{tags:["Roles"],summary:"Delete a role",description:"Delete a role and its workspace.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=Ze.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:l.prettifyError(s.error)});let t=M(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});if(t.id===Ss)return e.status(403).send({code:"FORBIDDEN",message:"System role 'chat-manager' cannot be deleted"});let n=ie(t.name);if(Bt(n))try{eo(n,{recursive:!0,force:!0})}catch{}return yt(s.data.id),{roleId:s.data.id,deleted:!0}}),o.post("/roles/:id/scan-directory",{schema:{tags:["Roles"],summary:"Scan directory for plugin/permission configuration",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",required:["path"],properties:{path:{type:"string",minLength:1}}}}},async(r,e)=>{let s=Ze.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:l.prettifyError(s.error)});let t=ao.safeParse(r.body);if(!t.success)return e.status(400).send({code:"VALIDATION_ERROR",message:l.prettifyError(t.error)});if(!M(s.data.id))return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let a=Os(t.data.path);return{path:t.data.path,enabledPlugins:a.enabledPlugins,mcpServers:a.mcpServers,allowedTools:a.allowedTools,disallowedTools:a.disallowedTools}}),o.get("/roles/:id/env-diff",{schema:{tags:["Roles"],summary:"Get role env diff",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=M(r.params.id);return s?{diffs:ks(s.name,s.envVars),envFileExists:ht(s.name)!==null}:e.status(404).send({code:"NOT_FOUND",message:"Role not found"})}),o.post("/roles/:id/sync-to-env",{schema:{tags:["Roles"],summary:"Sync role env to .env file",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=M(r.params.id);return s?{success:!0,changed:Ts(s.name,s.envVars)}:e.status(404).send({code:"NOT_FOUND",message:"Role not found"})}),o.post("/roles/:id/load-from-env",{schema:{tags:["Roles"],summary:"Load role env from .env file",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=M(r.params.id);if(!s)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let t=ht(s.name);if(!t)return e.status(400).send({code:"NOT_FOUND",message:".env file not found in role workspace"});let n={};for(let[a,i]of Object.entries(t))a.startsWith("ANTHROPIC_")||(n[a]=i);return Ne(s.id,{envVars:Object.keys(n).length>0?n:void 0,updatedAt:Date.now()}),{success:!0,updated:Object.keys(n).length}})}ve();import{z as xn}from"zod/v4";import{readdirSync as oo,existsSync as io}from"fs";import{join as Wt,resolve as jn,sep as qn}from"path";import{homedir as co}from"os";var po=20,lo=xn.object({prefix:xn.string()});function Ln(o){return o.startsWith("~/")?Wt(co(),o.slice(2)):o}function Nn(o){let r=jn(o);for(let e of is){let s=Ln(e),t=jn(s);if(r===t||r.startsWith(t+qn))return!0}return!1}async function Mn(o){o.get("/fs/suggest-dirs",{schema:{tags:["FS"],summary:"Suggest directory completions",description:"Return directory suggestions matching a given path prefix.",querystring:{type:"object",required:["prefix"],properties:{prefix:{type:"string"}}}}},async(r,e)=>{let s=lo.safeParse(r.query);if(!s.success)return{suggestions:[]};let{prefix:t}=s.data;if(!t.startsWith("/")&&!t.startsWith("~/"))return{suggestions:[]};if(Nn(t))return{suggestions:[]};let n=Ln(t),a,i;if(t.endsWith("/"))a=n,i="";else{let f=Math.max(n.lastIndexOf("/"),n.lastIndexOf(qn));if(f<0)return{suggestions:[]};a=n.slice(0,f+1),i=n.slice(f+1)}if(!io(a))return{suggestions:[]};let c;try{c=oo(a,{withFileTypes:!0}).filter(f=>f.isDirectory()).map(f=>f.name)}catch{return{suggestions:[]}}let p=i.toLowerCase(),d=c.filter(f=>f.toLowerCase().startsWith(p)),w=(i.startsWith(".")?d:d.filter(f=>!f.startsWith("."))).filter(f=>!Nn(Wt(a,f)));return w.sort((f,A)=>f.localeCompare(A,void 0,{sensitivity:"base"})),{suggestions:w.slice(0,po).map(f=>Wt(a,f))}})}import{z as _}from"zod/v4";qe();import{v4 as uo}from"uuid";var mo=_.object({roleId:_.string().min(1)}),go=_.object({roleId:_.string().min(1),prompt:_.string().min(1),topK:_.number().min(1).max(50).default(10)}),fo=_.object({limit:_.coerce.number().min(1).max(200).default(50),offset:_.coerce.number().min(0).default(0)});function Vt(o){return M(o)!==void 0}async function Un(o){o.get("/memories/:roleId",{schema:{tags:["Memories"],summary:"List role memories",description:"List all memories for a specific role with pagination. Embeddings are stripped from the response.",params:{type:"object",required:["roleId"],properties:{roleId:{type:"string"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50},offset:{type:"integer",minimum:0,default:0}}},response:R.memoryList}},async(s,t)=>{let n=mo.safeParse(s.params);if(!n.success)return t.status(400).send({code:"VALIDATION_ERROR",message:_.prettifyError(n.error)});let a=n.data.roleId;if(!Vt(a))return t.status(404).send({code:"NOT_FOUND",message:"Role or agent not found"});let i=fo.safeParse(s.query),{limit:c,offset:p}=i.success?i.data:{limit:50,offset:0},u=Js(a,c,p).map(({embedding:h,...w})=>w);return{memories:u,count:u.length}}),o.post("/memories/query",{schema:{tags:["Memories"],summary:"Query role memories",description:"Query a role's memories using hybrid search (FTS5 + vector similarity) with Smallville-style scoring (recency, importance, relevance).",body:{type:"object",required:["roleId","prompt"],properties:{roleId:{type:"string",minLength:1,description:"The role whose memories to query"},prompt:{type:"string",minLength:1,description:"The search query"},topK:{type:"integer",minimum:1,maximum:50,default:10,description:"Number of results to return"}}},response:R.memoryQuery}},async(s,t)=>{let n=go.safeParse(s.body);if(!n.success)return t.status(400).send({code:"VALIDATION_ERROR",message:_.prettifyError(n.error)});let{roleId:a,prompt:i,topK:c}=n.data;if(!Vt(a))return t.status(404).send({code:"NOT_FOUND",message:"Role or agent not found"});let d=(await wt(a,i,{topK:c})).map(({embedding:u,...h})=>h);return{memories:d,count:d.length}});let r=_.object({roleId:_.string().min(1),content:_.string().min(1),type:_.enum(["event","thought","reflection"]).default("thought"),keywords:_.array(_.string()).default([]),importance:_.number().min(1).max(5).default(3),tier:_.enum(["working","episodic","semantic"]).default("episodic")});o.post("/memories",{schema:{tags:["Memories"],summary:"Create memory",description:"Create a new memory for a role. Embedding is auto-generated from content.",body:{type:"object",required:["roleId","content"],properties:{roleId:{type:"string",minLength:1},content:{type:"string",minLength:1},type:{type:"string",enum:["event","thought","reflection"],default:"thought"},keywords:{type:"array",items:{type:"string"},default:[]},importance:{type:"integer",minimum:1,maximum:5,default:3},tier:{type:"string",enum:["working","episodic","semantic"],default:"episodic"}}},response:R.memoryCreated}},async(s,t)=>{let n=r.safeParse(s.body);if(!n.success)return t.status(400).send({code:"VALIDATION_ERROR",message:_.prettifyError(n.error)});let{roleId:a,content:i,type:c,keywords:p,importance:d,tier:u}=n.data;if(!Vt(a))return t.status(404).send({code:"NOT_FOUND",message:"Role or agent not found"});let h;try{h=await kt(i)}catch{}let w=`mem-${uo().slice(0,8)}`,y=Date.now();Xs({id:w,roleId:a,type:c,content:i,embedding:h,keywords:p,importance:d,sourceType:"manual",createdAt:y,lastAccessed:y,retrievedCount:0,tier:u??"episodic"});let f=Ve(w),{embedding:A,...$}=f;return t.status(201).send({memory:$})});let e=_.object({content:_.string().min(1).optional(),type:_.enum(["event","thought","reflection"]).optional(),keywords:_.array(_.string()).optional(),importance:_.number().min(1).max(5).optional()});o.patch("/memories/:id",{schema:{tags:["Memories"],summary:"Update memory",description:"Update a memory's content, type, keywords, or importance. Embedding is regenerated if content changes.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",properties:{content:{type:"string",minLength:1},type:{type:"string",enum:["event","thought","reflection"]},keywords:{type:"array",items:{type:"string"}},importance:{type:"integer",minimum:1,maximum:5}}},response:R.memoryUpdated}},async(s,t)=>{let{id:n}=s.params;if(!Ve(n))return t.status(404).send({code:"NOT_FOUND",message:"Memory not found"});let i=e.safeParse(s.body);if(!i.success)return t.status(400).send({code:"VALIDATION_ERROR",message:_.prettifyError(i.error)});let c=i.data,p,d=!0;if(c.content)try{p=await kt(c.content)}catch{d=!1}let u=Zs(n,{content:c.content,embedding:p,keywords:c.keywords,importance:c.importance,type:c.type});return{memoryId:n,updated:u,embeddingUpdated:d}}),o.delete("/memories/:id",{schema:{tags:["Memories"],summary:"Delete memory",description:"Delete a memory by ID.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},response:R.memoryDeleted}},async(s,t)=>{let{id:n}=s.params;return Ve(n)?(er(n),{memoryId:n,deleted:!0}):t.status(404).send({code:"NOT_FOUND",message:"Memory not found"})})}import{query as vo}from"@anthropic-ai/claude-agent-sdk";import{v4 as pe}from"uuid";function yo(){try{return D().defaults.maxBudgetUsd}catch{return 5}}function Gt(o){return`# ChatManager \u2014 User Interface Agent
|
|
1
|
+
import{A as Dt,a as Ve,b as Cr,c as Ar,d as Er,e as Pr,f as Or,g as Dr,h as Fr,i as xr,j as ge,k as Mr,l as Ur,m as ee,n as Qe,o as Br,p as Wr,q as Vr,r as $r,s as Gr,t as Te,u as Et,v as Hr,w as Pt,x as Ot}from"./chunk-TAF2DBBC.js";import{b as Ke,c as Rr,d as V,e as Ir,f as kr,g as Tr,h as At,i as J,j as wr,n as Sr,o as _r}from"./chunk-M4YI4WVX.js";import{a as Ys,b as Xs,c as Ft,d as xt,e as Xr,f as Zr,g as Jr,h as en,i as tn,k as sn,l as rn,n as nn,o as jt}from"./chunk-4PQHGLZH.js";import{d as Kr,e as zr}from"./chunk-AQ3ASS4B.js";import{b as Qr,c as Yr}from"./chunk-A5OCDYTW.js";import{c as Vs}from"./chunk-NUITL62I.js";import{c as an,d as on}from"./chunk-EQZFOBAJ.js";import{a as jr,b as ze,c as Nr,d as qr,e as Lr}from"./chunk-5QZXYKMS.js";import{b as zs,c as Qs}from"./chunk-2YTDCR6A.js";import"./chunk-BQ3ZAYHC.js";import{a as wt,c as sr}from"./chunk-IKPYPZ64.js";import{a as kt,b as $s}from"./chunk-SWP2JC54.js";import{a as ir,b as cr,c as dr,e as pr}from"./chunk-JJH2RCVC.js";import{a as X,b as Tt,c as Hs,e as Ks}from"./chunk-B6LOT5CG.js";import{a as hr,b as br,d as vr}from"./chunk-QGYDGZSC.js";import{a as He,b as Ct,c as fr,d as yr}from"./chunk-ULTK7RD6.js";import{a as Be,g as xs,h as js,j as ie,k as We,l as Ns,m as qs,p as Ms,q as Us}from"./chunk-6KF7OO2B.js";import{a as Ls}from"./chunk-IZNEOYRP.js";import{f as ur,g as mr,h as gr}from"./chunk-N4ES7TCL.js";import{a as It,b as Es,c as Ue,d as Ps,e as Os,f as Ds,h as Fs}from"./chunk-NWMOV23A.js";import{b as ut}from"./chunk-2L2347UQ.js";import{b as D,c as re,d as H,e as Re,f as bs}from"./chunk-K4C43YDD.js";import{b as lr}from"./chunk-RI3V72RP.js";import{b as or,d as ke,f as me}from"./chunk-GSFLLRS7.js";import{a as _s}from"./chunk-BCH2HAIM.js";import{a as ht,b as Ts,c as ws,d as wa,e as oe,f as bt,g as vt,h as Rt,j as Ss}from"./chunk-WMB7P64J.js";import{a as y}from"./chunk-L7JP7DUO.js";import{h as Bs,i as Ws}from"./chunk-RZ7LCZVK.js";import{a as Zs,b as $e,c as Js,g as er,j as tr}from"./chunk-DVN3BFPP.js";import{a as Cs,b as Me,c as As,d as cn}from"./chunk-NASJH4NT.js";import{b as Gs}from"./chunk-T33BLZV2.js";import{a as St,c as rr,d as Z,e as nr,f as Ge,i as _t,j as ar}from"./chunk-5XOTPEAK.js";import{b as fs,c as ys,e as hs}from"./chunk-PG6LMSX6.js";import{a as ds}from"./chunk-UQJZU3R5.js";import{a as pt,b as ps,c as ls,d as us,e as ms}from"./chunk-7IFLU3CY.js";import{a as De,b as ct,c as as,d as F,e as Fe,i as os,j as is,k as dt}from"./chunk-GSMC3VUM.js";import{f as Is,g as mt,i as ks,k as gt,l as U,m as ft,n as qe,o as Ie,p as yt,r as Le}from"./chunk-HQRUJQN7.js";import{b as ue,c as Ne,d as vs,g as Rs}from"./chunk-FPZEZYUB.js";import{b as G,c as lt,d as je}from"./chunk-5EPG2US5.js";import{c as cs,d as x,h as ve}from"./chunk-WBAPIPST.js";import{a as gs,c as q,d as xe,h as Y}from"./chunk-MRTJFYPR.js";import"./chunk-FCV2DPZQ.js";import{writeFileSync as ya,mkdirSync as ha,unlinkSync as ni}from"fs";import{join as it}from"path";ve();import{readFileSync as Sa,existsSync as _a}from"fs";import{resolve as Nt}from"path";function dn(o=x){let r=[],e=[],s=process.env.ADAM_ENV_FILE;s&&e.push(Nt(o,s)),e.push(Nt(o,".env.local")),e.push(Nt(o,".env"));for(let t of e){if(!_a(t))continue;Ca(t)>0&&r.push(t)}return r}function Ca(o){let e=Sa(o,"utf-8").split(`
|
|
2
|
+
`),s=0;for(let t of e){let n=t.trim();if(!n||n.startsWith("#"))continue;n.startsWith("export ")&&(n=n.slice(7).trim());let a=n.indexOf("=");if(a===-1)continue;let i=n.slice(0,a).trim();if(!i)continue;let c=n.slice(a+1).trim();(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'"))&&(c=c.slice(1,-1)),c=c.replace(/\$\{(\w+)\}|\$(\w+)/g,(p,d,l)=>{let g=d??l;return process.env[g]??""}),(i.startsWith("ANTHROPIC_")||process.env[i]===void 0)&&(process.env[i]=c,s++)}return s}je();Le();Ss();import{existsSync as pn}from"fs";import ln from"path";import Aa from"fastify";import Ea from"@fastify/cors";import Pa from"@fastify/static";import Oa from"@fastify/websocket";import Da from"@fastify/swagger";import Fa from"@fastify/swagger-ui";import{timingSafeEqual as xa}from"crypto";function mn(o,r){let e=Aa({logger:!1});if(e.register(Da,{openapi:{info:{title:"Adam API",description:"Agent orchestration server built on Claude Agent SDK. Multi-agent system with parallel task execution, intelligent agent routing, self-evolving personas, and REST/WebSocket API.",version:Me()},servers:[{url:"http://localhost:7100"}],tags:[{name:"Tasks",description:"Task lifecycle management"},{name:"Roles",description:"Role CRUD and workspace management"},{name:"Skills",description:"Skill CRUD and permissions"},{name:"Memories",description:"Agent memory search and retrieval"},{name:"Goals",description:"Goal-driven task management"},{name:"Strategies",description:"Thompson Sampling strategy engine"},{name:"Templates",description:"Task template CRUD and triggers"},{name:"Webhooks",description:"External system integration"},{name:"Config",description:"Runtime configuration management"},{name:"Evolution",description:"Agent evolution audit log"},{name:"Health",description:"Server health checks"}],components:{securitySchemes:{apiKey:{type:"apiKey",in:"header",name:"x-api-key",description:"API key for webhook endpoints"}}}}}),e.register(Fa,{routePrefix:"/docs"}),e.register(Ea,{origin:!0}),e.register(Oa,{options:{maxPayload:1024*1024*16}}),r){let t=Buffer.from(r);e.addHook("onRequest",async(n,a)=>{let i=n.url;if(i==="/healthz"||i==="/readyz"||i.startsWith("/docs")||i.startsWith("/ui"))return;let c=n.headers["x-api-key"];if(c&&un(c,t))return;let p=n.query,d=p.api_key||p["x-api-key"];if(!(d&&un(d,t)))return a.status(401).send({code:"UNAUTHORIZED",message:"Invalid or missing API key"})})}let s=ln.join(Cs,"web/dist");return pn(s)&&(e.register(Pa,{root:s,prefix:"/ui/",wildcard:!0}),e.get("/ui",async(t,n)=>n.sendFile("index.html",s))),e.setErrorHandler((t,n,a)=>{if(t.validation){let c=t.validation.map(p=>{let d=p.instancePath||p.params?.missingProperty||"";return d?`${d}: ${p.message}`:p.message});return a.status(400).send({code:"VALIDATION_ERROR",message:c.join("; ")})}let i=t.statusCode??500;return a.status(i).send({code:"INTERNAL_ERROR",message:t.message})}),e.setNotFoundHandler((t,n)=>{let a=t.url.split("?")[0];return t.url.startsWith("/ui")&&pn(s)&&!ln.extname(a)?n.sendFile("index.html",s):n.status(404).send({code:"NOT_FOUND",message:"Route not found"})}),e}function un(o,r){try{let e=Buffer.from(o);return e.length!==r.length?!1:xa(e,r)}catch{return!1}}import{z as f}from"zod/v4";var ja=o=>({...o,nullable:!0}),_={type:"object",properties:{code:{type:"string"},message:{type:"string"}}},Na={type:"object",additionalProperties:!0,properties:{id:{type:"string"},prompt:{type:"string"},dependsOn:{type:"array",items:{type:"string"}},outputAs:{type:"string"},roleId:{type:"string"},autoSelectRole:{type:"boolean"},requirements:{type:"object",additionalProperties:!0}}},qa={type:"object",additionalProperties:!0,properties:{type:{type:"string"},cron:{type:"string"},event:{type:"string"}}},gn={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},description:{type:"string"},trigger:qa,steps:{type:"array",items:Na},agentPreference:{type:"string"},config:{type:"object",additionalProperties:!0},tags:{type:"array",items:{type:"string"}},enabled:{type:"boolean"},createdAt:{type:"number"},updatedAt:{type:"number"}}},La={type:"object",properties:{input:{type:"number"},output:{type:"number"}}},yn={type:"object",additionalProperties:!0,properties:{path:{type:"string"},access:{type:"string",enum:["ro","rw"]}}},Mt={type:"object",additionalProperties:!0,properties:{id:{type:"string"},targets:{type:"array",items:{type:"string"}}}},Ma={type:"object",additionalProperties:!0,properties:{tools:{type:"array",items:{type:"string"}},paths:{type:"array",items:yn},osCapabilities:{type:"array",items:Mt},network:{type:"boolean"},plugins:{type:"array",items:{type:"string"}}}},Ua={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},status:{type:"string"},allowedTools:{type:"array",items:{type:"string"}},disallowedTools:{type:"array",items:{type:"string"}},approvalRequired:{type:"array",items:{type:"string"}},osCapabilities:{type:"array",items:Mt},additionalDirectories:{type:"array",items:{type:"object",additionalProperties:!0}},cagPrompt:{type:"string"},learnedRules:{type:"array",items:{type:"string"}},performanceScore:{type:"number"},model:{type:"string"},executionMode:{type:"string"}}},Ba={type:"object",additionalProperties:!0,properties:{model:{type:"string"},maxTurns:{type:"integer"},maxBudgetUsd:{type:"number"},timeout:{type:"integer"},effort:{type:"string"},requirements:Ma,executionProfile:Ua}},hn={type:"object",additionalProperties:!0,properties:{tools:{type:"array",items:{type:"string"}},paths:{type:"array",items:yn},osCapabilities:{type:"array",items:Mt},plugins:{type:"array",items:{type:"string"}},network:{type:"boolean"}}},Wa={type:"object",additionalProperties:!0,properties:{roleId:{type:"string"},name:{type:"string"},fitScore:{type:"number"},missing:hn}},Va={type:"object",additionalProperties:!0,properties:{code:{type:"string",enum:["ROLE_NOT_FOUND","ROLE_TOOL_MISMATCH","ROLE_PATH_SCOPE_MISMATCH","ROLE_OS_CAPABILITY_MISMATCH","ROLE_PLUGIN_MISMATCH","ROLE_NETWORK_MISMATCH","ROLE_SELECTION_AMBIGUOUS","REQUIREMENTS_MISSING","VALIDATION_ERROR"]},message:{type:"string"},missing:hn,candidates:{type:"array",items:Wa}}},fn={type:"object",additionalProperties:!0,properties:{id:{type:"string"},parentId:{type:"string"},status:{type:"string"},prompt:{type:"string"},originalPrompt:{type:"string"},config:Ba,result:{type:"string"},error:{type:"string"},sdkSessionId:{type:"string"},roleId:{type:"string"},templateId:{type:"string"},createdAt:{type:"number"},startedAt:{type:"number"},completedAt:{type:"number"},costUsd:{type:"number"},tokenUsage:La,numTurns:{type:"number"},totalDurationMs:{type:"number"}}},$a={type:"object",additionalProperties:!0,properties:{model:{type:"string"},effort:{type:"string"},maxTurns:{type:"number"}}},Ye={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},source:{type:"string"},traits:{type:"array",items:{type:"string"}},background:{type:"string"},preferences:$a,learnedRules:{type:"array",items:{type:"string"}},memoryStreamId:{type:"string"},status:{type:"string"},createdAt:{type:"number"},lastActiveAt:{type:"number"},taskCount:{type:"number"},performanceScore:{type:"number"},role:{type:"string"},toolProfile:{type:"array",items:{type:"string"}},evaluationCriteria:{type:"object",additionalProperties:{type:"number"}},strategyPoolId:{type:"string"}}},qt={type:"object",additionalProperties:!0,properties:{id:{type:"string"},roleId:{type:"string"},type:{type:"string"},content:{type:"string"},keywords:{type:"array",items:{type:"string"}},importance:{type:"number"},sourceType:{type:"string"},sourceTaskId:{type:"string"},evidence:{type:"array",items:{type:"string"}},createdAt:{type:"number"},lastAccessed:{type:"number"},retrievedCount:{type:"number"},score:{type:"number"}}},Ga={type:"object",additionalProperties:!0,properties:{id:{type:"string"},role:{type:"string"},taskType:{type:"string"},name:{type:"string"},promptTemplate:{type:"string"},alpha:{type:"number"},beta:{type:"number"},totalTrials:{type:"number"},avgReward:{type:"number"},toolProfile:{type:"array",items:{type:"string"}},createdAt:{type:"number"},updatedAt:{type:"number"}}},Lt={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},description:{type:"string"},role:{type:"string"},metricType:{type:"string"},targetValue:{type:"number"},currentValue:{type:"number"},deadline:{type:"number"},budgetUsd:{type:"number"},status:{type:"string"},createdAt:{type:"number"},updatedAt:{type:"number"}}},Ha={type:"object",additionalProperties:!0,properties:{name:{type:"string"},displayName:{type:"string"},description:{type:"string"},tags:{type:"array",items:{type:"string"}},trigger:{type:"string"}}},R={templateCreated:{201:{type:"object",properties:{templateId:{type:"string"}}},400:{type:"object",properties:{code:{type:"string"},message:{type:"string"},failingStepIds:{type:"array",items:{type:"string"}}}}},templateList:{200:{type:"object",properties:{templates:{type:"array",items:gn}}}},templateDetail:{200:{type:"object",properties:{template:gn}},404:_},templateUpdated:{200:{type:"object",properties:{templateId:{type:"string"}}},400:{type:"object",properties:{code:{type:"string"},message:{type:"string"},failingStepIds:{type:"array",items:{type:"string"}}}},404:_},templateDeleted:{200:{type:"object",properties:{templateId:{type:"string"},deleted:{type:"boolean"},mode:{type:"string",enum:["template_only","with_tasks"]},deletedCounts:{type:"object",properties:{template:{type:"number"},workflowExecutions:{type:"number"},tasks:{type:"number"}}}}},404:_,409:_},templateRun:{200:{type:"object",properties:{executionId:{type:"string"},status:{type:"string"}}},404:_},taskCreated:{201:{type:"object",additionalProperties:!0,properties:{taskId:{type:"string"},roleId:{type:"string"},fitScore:{type:"number"}}},400:Va},taskList:{200:{type:"object",properties:{tasks:{type:"array",items:fn}}}},taskDetail:{200:{type:"object",properties:{task:fn}},404:_},taskAction:{200:{type:"object",additionalProperties:!0,properties:{taskId:{type:"string"}}},400:_,404:_},approvalAction:{200:{type:"object",properties:{approvalId:{type:"string"},decision:{type:"string"}}},404:_},agentList:{200:{type:"object",properties:{roles:{type:"array",items:Ye}}}},agentDetail:{200:{type:"object",properties:{agent:Ye}},404:_},agentCreated:{201:{type:"object",properties:{agent:Ye}}},agentUpdated:{200:{type:"object",properties:{agent:Ye}},404:_},agentDeleted:{200:{type:"object",properties:{agentId:{type:"string"},deleted:{type:"boolean"}}},400:_,404:_},agentPersona:{200:{type:"object",properties:{persona:ja({type:"string"})}},404:_},memoryList:{200:{type:"object",properties:{memories:{type:"array",items:qt},count:{type:"number"}}},404:_},memoryQuery:{200:{type:"object",properties:{memories:{type:"array",items:qt},count:{type:"number"}}},404:_},memoryCreated:{201:{type:"object",properties:{memory:qt}},400:_,404:_},memoryUpdated:{200:{type:"object",properties:{memoryId:{type:"string"},updated:{type:"boolean"},embeddingUpdated:{type:"boolean"}}},400:_,404:_},memoryDeleted:{200:{type:"object",properties:{memoryId:{type:"string"},deleted:{type:"boolean"}}},404:_},strategyList:{200:{type:"object",properties:{strategies:{type:"array",items:Ga}}}},strategyProbabilities:{200:{type:"object",additionalProperties:!0,properties:{role:{type:"string"},taskType:{type:"string"},stats:{type:"object",additionalProperties:!0},probabilities:{type:"object",additionalProperties:{type:"number"}}}}},goalList:{200:{type:"object",properties:{goals:{type:"array",items:Lt}}}},goalDetail:{200:{type:"object",properties:{goal:Lt}},404:_},goalCreated:{201:{type:"object",properties:{goal:Lt}},400:{..._,additionalProperties:!0,properties:{..._.properties,errors:{type:"array",items:{type:"string"}},warnings:{type:"array",items:{type:"string"}}}}},webhookTriggered:{202:{type:"object",properties:{code:{type:"string"},message:{type:"string"},executionId:{type:"string"},templateId:{type:"string"}}},401:_,404:_,409:_,500:_},webhookList:{200:{type:"object",properties:{webhooks:{type:"array",items:Ha},auth:{type:"string"}}}},configGet:{200:{type:"object",additionalProperties:!0,properties:{config:{type:"object",additionalProperties:{type:"object",additionalProperties:!0,properties:{value:{},mutable:{type:"boolean"}}}},mutable:{type:"array",items:{type:"string"}},restartRequired:{type:"array",items:{type:"string"}},sandbox:{type:"object",additionalProperties:!0,properties:{platform:{type:"string"},available:{type:"boolean"}}},osCapabilities:{type:"object",additionalProperties:!0,properties:{registry:{type:"array",items:{type:"object",additionalProperties:!0,properties:{id:{type:"string"},label:{type:"string"},description:{type:"string"},platform:{type:"string"},status:{type:"string"},availability:{type:"string"},editable:{type:"boolean"},supportsTargets:{type:"boolean"},disabledReason:{type:"string"},effectiveDisabledReason:{type:"string"}}}}}}}}},configPatch:{200:{type:"object",additionalProperties:!0,properties:{success:{type:"boolean"},updated:{type:"array",items:{type:"string"}},errors:{type:"array",items:{type:"string"}},message:{type:"string"}}}},healthz:{200:{type:"object",properties:{status:{type:"string"}}}},readyz:{200:{type:"object",properties:{status:{type:"string"},checks:{type:"object",additionalProperties:{type:"boolean"}}}},503:{type:"object",properties:{status:{type:"string"},checks:{type:"object",additionalProperties:{type:"boolean"}}}}}};var bn=f.union([f.object({type:f.literal("session"),sessionId:f.string()}),f.object({type:f.literal("channel"),channelId:f.string(),chatId:f.string().optional()})]),Ka=f.object({prompt:f.string().min(1,"prompt is required"),roleId:f.string().optional(),requirements:Be.optional(),autoSelectRole:f.boolean().optional(),deliverTo:f.array(bn).optional(),reportTo:f.array(bn).optional(),config:f.object({allowedTools:f.array(f.string()).optional(),disallowedTools:f.array(f.string()).optional(),maxTurns:f.number().optional(),maxBudgetUsd:f.number().optional(),mcpServers:f.record(f.string(),f.unknown()).optional(),model:f.string().optional(),effort:f.enum(["low","medium","high","max"]).optional(),settingSources:f.array(f.string()).optional(),workspacePath:f.string().optional(),timeout:f.number().optional(),approvalRequired:f.array(f.string()).optional(),approvalTimeout:f.number().optional(),env:f.record(f.string(),f.string()).optional(),plugins:f.array(f.string()).optional()}).optional()}),ce=f.object({id:f.string().uuid()}),za=["pending","queued","running","paused","completed","failed","cancelled","blocked"],Qa=f.object({status:f.enum(za).optional(),roleId:f.string().optional(),limit:f.coerce.number().min(1).max(100).default(100),offset:f.coerce.number().min(0).default(0)});async function vn(o){let r=new Ve;o.post("/tasks",{schema:{tags:["Tasks"],summary:"Create a task",description:"Create a new task with a prompt and optional agent/config overrides. The task enters 'pending' status and is picked up by the scheduler.",body:{type:"object",required:["prompt"],properties:{prompt:{type:"string",minLength:1,description:"Task prompt"},roleId:{type:"string",description:"Role to assign"},config:{type:"object",description:"Optional task configuration overrides",properties:{model:{type:"string"},maxTurns:{type:"integer"},maxBudgetUsd:{type:"number"},timeout:{type:"integer"},effort:{type:"string",enum:["low","medium","high","max"]}}}}},response:R.taskCreated}},async(n,a)=>{let i=Ka.safeParse(n.body);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)});let{prompt:c,roleId:p,requirements:d,autoSelectRole:l,config:g,deliverTo:b,reportTo:E}=i.data,v=await Us({prompt:c,roleId:p,requirements:d,autoSelectRole:l,deliverTo:b,reportTo:E,config:g});return v.ok?a.status(201).send({taskId:v.taskId,roleId:v.roleId,fitScore:v.fitScore}):a.status(400).send({code:v.code,message:v.reason,missing:v.missing,candidates:v.candidates})}),o.get("/tasks",{schema:{tags:["Tasks"],summary:"List tasks",description:"List tasks with optional status filter and pagination.",querystring:{type:"object",properties:{status:{type:"string",enum:["pending","queued","running","paused","completed","failed","cancelled","blocked"]},limit:{type:"integer",minimum:1,maximum:100,default:100},offset:{type:"integer",minimum:0,default:0}}},response:R.taskList}},async(n,a)=>{let i=Qa.safeParse(n.query);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)});let{status:c,roleId:p,limit:d,offset:l}=i.data;return{tasks:H(c,d,l,p)}}),o.get("/tasks/:id",{schema:{tags:["Tasks"],summary:"Get task by ID",description:"Retrieve a single task by its UUID.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},response:R.taskDetail}},async(n,a)=>{let i=ce.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)});let c=D(i.data.id);return c?{task:c}:a.status(404).send({code:"NOT_FOUND",message:"Task not found"})}),o.post("/tasks/:id/cancel",{schema:{tags:["Tasks"],summary:"Cancel a task",description:"Cancel a running, queued, pending, or paused task. Returns 400 if the task is in a terminal state.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},response:R.taskAction}},async(n,a)=>{let i=ce.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)});let c=D(i.data.id);return c?c.status!=="running"&&c.status!=="queued"&&c.status!=="pending"&&c.status!=="paused"?a.status(400).send({code:"INVALID_STATE",message:`Cannot cancel task in status: ${c.status}`}):(r.cancelTask(c.id),{taskId:c.id,status:"cancelled"}):a.status(404).send({code:"NOT_FOUND",message:"Task not found"})});let e=f.object({taskIds:f.array(f.string()).min(1).max(500)});o.post("/tasks/batch-cancel",{schema:{tags:["Tasks"],summary:"Batch cancel tasks",description:"Cancel multiple tasks at once. Skips tasks that are already in terminal state. Returns count of cancelled tasks.",body:{type:"object",required:["taskIds"],properties:{taskIds:{type:"array",items:{type:"string"},minItems:1,maxItems:500}}}}},async(n,a)=>{let i=e.safeParse(n.body);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)});let c=new Set(["pending","queued","running","paused"]),p=0,d=[];for(let l of i.data.taskIds){let g=D(l);if(!g){d.push({taskId:l,reason:"not found"});continue}if(!c.has(g.status)){d.push({taskId:l,reason:`already ${g.status}`});continue}r.cancelTask(l),p++}return{cancelled:p,total:i.data.taskIds.length,errors:d.length>0?d:void 0}}),o.get("/tasks/:id/logs",{schema:{tags:["Tasks"],summary:"Get task step logs",description:"Returns execution step logs for a task (reasoning, tool calls, results).",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50},offset:{type:"integer",minimum:0,default:0}}}}},async(n,a)=>{let i=D(n.params.id);if(!i)return a.status(404).send({code:"NOT_FOUND",message:"Task not found"});let{limit:c=50,offset:p=0}=n.query;return{logs:ut(i.id,c,p)}});let s=f.object({approvalId:f.string().uuid(),reason:f.string().optional()});o.post("/tasks/:id/approve",{schema:{tags:["Tasks"],summary:"Approve a pending approval",description:"Approve a tool-use approval request for a paused task. The skill agent resumes execution with the approved tool call.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",required:["approvalId"],properties:{approvalId:{type:"string",format:"uuid"},reason:{type:"string"}}},response:R.approvalAction}},async(n,a)=>{let i=ce.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)});let c=s.safeParse(n.body);return c.success?D(i.data.id)?r.resolveApproval(c.data.approvalId,"allow",c.data.reason)?{approvalId:c.data.approvalId,decision:"allow"}:a.status(404).send({code:"NOT_FOUND",message:"Approval not found or already resolved"}):a.status(404).send({code:"NOT_FOUND",message:"Task not found"}):a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(c.error)})}),o.post("/tasks/:id/reject",{schema:{tags:["Tasks"],summary:"Reject a pending approval",description:"Reject a tool-use approval request for a paused task. The skill agent skips the denied tool call.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",required:["approvalId"],properties:{approvalId:{type:"string",format:"uuid"},reason:{type:"string"}}},response:R.approvalAction}},async(n,a)=>{let i=ce.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)});let c=s.safeParse(n.body);return c.success?D(i.data.id)?r.resolveApproval(c.data.approvalId,"deny",c.data.reason)?{approvalId:c.data.approvalId,decision:"deny"}:a.status(404).send({code:"NOT_FOUND",message:"Approval not found or already resolved"}):a.status(404).send({code:"NOT_FOUND",message:"Task not found"}):a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(c.error)})});let t=f.object({planId:f.string(),decision:f.enum(["allow","deny"]),approvalType:f.enum(["once","permanent"]).optional(),reason:f.string().optional()});o.post("/tasks/:id/approve-plan",{schema:{tags:["Tasks"],summary:"Approve or deny an execution plan",description:"Respond to a plan approval request. Allow once (single task), allow permanent (create rule for similar tasks), or deny.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",required:["planId","decision"],properties:{planId:{type:"string"},decision:{type:"string",enum:["allow","deny"]},approvalType:{type:"string",enum:["once","permanent"]},reason:{type:"string"}}}}},async(n,a)=>{let i=ce.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)});let c=t.safeParse(n.body);if(!c.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(c.error)});if(!D(i.data.id))return a.status(404).send({code:"NOT_FOUND",message:"Task not found"});let{planId:d,decision:l,approvalType:g,reason:b}=c.data;return r.resolvePlanApproval(d,l,g,b)?{planId:d,decision:l,approvalType:g}:a.status(404).send({code:"NOT_FOUND",message:"Plan approval not found or already resolved"})}),o.get("/tasks/:id/plan",{schema:{tags:["Tasks"],summary:"Get execution plans for a task",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(n,a)=>{let i=ce.safeParse(n.params);return i.success?D(i.data.id)?{plans:Vs(i.data.id)}:a.status(404).send({code:"NOT_FOUND",message:"Task not found"}):a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)})}),o.get("/tasks/:id/delivery-log",{schema:{tags:["Tasks"],summary:"Get delivery log for a task",description:"Returns delivery log entries for a task, including channel and webhook delivery attempts.",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50}}}}},async(n,a)=>{let i=ce.safeParse(n.params);if(!i.success)return a.status(400).send({code:"VALIDATION_ERROR",message:f.prettifyError(i.error)});let c=D(i.data.id);if(!c)return a.status(404).send({code:"NOT_FOUND",message:"Task not found"});let{limit:p=50}=n.query;return{logs:Bs(c.id,p)}})}je();Le();async function Rn(o,r){o.get("/healthz",{schema:{tags:["Health"],summary:"Health check",description:"Basic liveness probe. Returns 200 if the server process is running.",response:R.healthz}},async(e,s)=>({status:"ok"})),o.get("/readyz",{schema:{tags:["Health"],summary:"Readiness check",description:"Readiness probe that checks database, roles, config, embedding model, and task hub. Returns 503 if any check fails.",response:R.readyz}},async(e,s)=>{let t={database:!1,manager:!1,config:!1};try{G().prepare("SELECT 1").get(),t.database=!0}catch{t.database=!1}t.manager=!0,t.config=!!r.server;try{let a=Ie(void 0,1,0);t.agents=a.length>0}catch{t.agents=!1}return t.embedding=$s(),t.taskHub=!0,Object.values(t).every(a=>a)?{status:"ready",checks:t}:s.status(503).send({status:"not_ready",checks:t})}),o.get("/stats",{schema:{tags:["Health"],summary:"Runtime statistics",description:"Returns execution pool status, active/pending task counts, and cost summary."}},async(e,s)=>{let n=F().execution?.maxConcurrent??5,a=H("running"),i=H("pending"),c=bs(Gs());return{executionPool:{active:a.length,max:n,queued:i.length},totalCostToday:c}}),o.get("/version",{schema:{tags:["Health"],summary:"Server version",description:"Returns the server version from package.json.",response:{200:{type:"object",properties:{name:{type:"string"},version:{type:"string"}}}}}},async(e,s)=>({name:As(),version:Me()}))}import{timingSafeEqual as kn}from"crypto";import{z as Tn}from"zod/v4";var Ut=class{connections=new Map;eventBuffers=new Map;eventIndices=new Map;addConnection(r,e){this.connections.has(r)||this.connections.set(r,new Set),this.connections.get(r).add(e);let s=this.getBufferedEvents(r);for(let t of s)e.readyState===1&&e.send(JSON.stringify(t));e.on("close",()=>{this.removeConnection(r,e)})}removeConnection(r,e){let s=this.connections.get(r);s&&(s.delete(e),s.size===0&&this.connections.delete(r))}broadcast(r,e){this.addToBuffer(r,e);let s=this.connections.get(r);if(!s||s.size===0)return;let t=JSON.stringify(e);for(let n of s)n.readyState===1&&n.send(t)}addToBuffer(r,e){let s=this.eventBuffers.get(r);s||(s=[],this.eventBuffers.set(r,s)),s.push(e),s.length>100&&s.shift(),this.eventIndices.set(r,e.index)}getBufferedEvents(r){return this.eventBuffers.get(r)??[]}getNextIndex(r){let s=(this.eventIndices.get(r)??0)+1;return this.eventIndices.set(r,s),s}},In=new Ut;var Ya=Tn.object({id:Tn.string().uuid()});async function wn(o,r){o.get("/tasks/:id/stream",{websocket:!0},(e,s)=>{if(r&&!Xa(s,r)){e.close(4401,"Unauthorized");return}let t=Ya.safeParse(s.params);if(!t.success){e.close(1008,"Invalid task ID");return}let{id:n}=t.data;if(!D(n)){e.close(1008,"Task not found");return}In.addConnection(n,e)})}function Xa(o,r){let e=o.headers["x-api-key"];if(e)try{let n=Buffer.from(e),a=Buffer.from(r);if(n.length===a.length&&kn(n,a))return!0}catch{}let s=o.query,t=s.api_key||s["x-api-key"];if(t)try{let n=Buffer.from(t),a=Buffer.from(r);if(n.length===a.length&&kn(n,a))return!0}catch{}return!1}import{timingSafeEqual as Sn}from"crypto";Y();var Za=q("ws"),Xe=new Set;function _n(o,r){o.get("/events",{websocket:!0},(e,s)=>{if(r&&!Ja(s,r)){e.close(4401,"Unauthorized");return}Xe.add(e),e.on("close",()=>{Xe.delete(e)}),e.on("error",t=>{Za.error({error:t},"WebSocket error"),Xe.delete(e)})}),y.on("task_status_change",e=>{B(e)}),y.on("approval_request",e=>{B(e)}),y.on("stats_update",e=>{B(e)}),y.on("log_event",e=>{B(e)}),y.on("config_changed",e=>{B(e)}),y.on("plan_approval_request",e=>{(()=>{try{let t=Ks(e.taskId);if(!t)return!1;let n=zs(t.sessionId);return n?n.source.type==="channel"&&!!n.source.channelId:!1}catch{return!1}})()||B(e)}),y.on("plan_approval_decision",e=>{B(e)}),y.on("task_created",e=>{B(e)}),y.on("execution_slot_change",e=>{B(e)}),y.on("execution_task_start",e=>{B(e)}),y.on("execution_task_end",e=>{B(e)}),y.on("delivery_status_change",e=>{B(e)}),y.on("workflow_status_change",e=>{B(e)})}function B(o){let r=JSON.stringify(o);for(let e of Xe)e.readyState===1&&e.send(r)}function Ja(o,r){let e=o.headers["x-api-key"];if(e)try{let n=Buffer.from(e),a=Buffer.from(r);if(n.length===a.length&&Sn(n,a))return!0}catch{}let s=o.query,t=s.api_key||s["x-api-key"];if(t)try{let n=Buffer.from(t),a=Buffer.from(r);if(n.length===a.length&&Sn(n,a))return!0}catch{}return!1}je();function eo(o){return{id:o.id,sdkSessionId:o.sdk_session_id??void 0,userTaskSessionId:o.user_task_session_id??void 0,workspacePath:o.workspace_path??void 0,toolsFingerprint:o.tools_fingerprint??void 0,createdAt:o.created_at,lastActiveAt:o.last_active_at??void 0}}function Bt(){let o=G(),r=o.prepare("SELECT * FROM server_state WHERE id = 1").get();if(r)return eo(r);let e=Date.now();return o.prepare("INSERT INTO server_state (id, created_at) VALUES (1, ?)").run(e),{id:1,createdAt:e}}function we(o){let r=G(),e=[],s=[];"sdkSessionId"in o&&(e.push("sdk_session_id = ?"),s.push(o.sdkSessionId??null)),"userTaskSessionId"in o&&(e.push("user_task_session_id = ?"),s.push(o.userTaskSessionId??null)),"workspacePath"in o&&(e.push("workspace_path = ?"),s.push(o.workspacePath??null)),"lastActiveAt"in o&&(e.push("last_active_at = ?"),s.push(o.lastActiveAt??null)),"toolsFingerprint"in o&&(e.push("tools_fingerprint = ?"),s.push(o.toolsFingerprint??null)),e.length!==0&&(Bt(),s.push(1),r.prepare(`UPDATE server_state SET ${e.join(", ")} WHERE id = ?`).run(...s))}function Ze(o){we({sdkSessionId:o,lastActiveAt:Date.now()})}function Cn(){we({sdkSessionId:void 0,lastActiveAt:Date.now()})}function An(o){we({workspacePath:o})}ks();Le();Ss();import{z as u}from"zod/v4";import{v4 as En}from"uuid";Fs();wa();import{rmSync as to,existsSync as Wt}from"fs";var Pn=u.object({model:u.string().optional(),effort:u.enum(["low","medium","high","max"]).optional(),maxTurns:u.number().optional()}),On=u.object({path:u.string(),mode:u.enum(["ro","rw"]).default("rw"),inheritPlugins:u.boolean().optional(),inheritMcp:u.boolean().optional(),inheritPermissions:u.boolean().optional()}),so=u.string().max(256).regex(/^[A-Za-z_][A-Za-z0-9_]*$/,"Env var key must match POSIX format: [A-Za-z_][A-Za-z0-9_]*").check(u.refine(o=>!o.startsWith("ANTHROPIC_"),"ANTHROPIC_* keys are managed globally in Settings")),Dn=u.record(so,u.string().max(4096)).optional().check(u.refine(o=>!o||Object.keys(o).length<=100,"Maximum 100 environment variables per role")),Fn=u.object({id:u.string().min(1),targets:u.array(u.string().min(1)).optional()}),ro=u.object({name:u.string().min(1,"name is required").regex(/^[\p{L}\p{N}_-]+$/u,"name must contain only letters, numbers, underscores, or hyphens"),cagPrompt:u.string().optional(),learnedRules:u.array(u.string()).optional(),allowedTools:u.array(u.string()).optional(),disallowedTools:u.array(u.string()).optional(),evaluationCriteria:u.record(u.string(),u.number()).optional(),executionMode:u.enum(["isolated","inline"]).optional(),model:u.string().optional(),maxBudgetUsd:u.number().optional(),approvalRequired:u.array(u.string()).optional(),preferences:Pn.optional(),additionalDirectories:u.array(On).optional(),allowedChannels:u.array(u.string()).optional(),inheritUserSettings:u.boolean().optional(),envVars:Dn,osCapabilities:u.array(Fn).optional()}),no=u.object({name:u.string().min(1).optional(),cagPrompt:u.string().optional(),learnedRules:u.array(u.string()).optional(),status:u.enum(["active","inactive","retired"]).optional(),allowedTools:u.array(u.string()).optional(),disallowedTools:u.array(u.string()).optional(),evaluationCriteria:u.record(u.string(),u.number()).optional(),executionMode:u.enum(["isolated","inline"]).optional(),model:u.string().optional(),maxBudgetUsd:u.number().optional(),approvalRequired:u.array(u.string()).optional(),preferences:Pn.optional(),additionalDirectories:u.array(On).optional(),permissionMode:u.enum(["default","acceptEdits","dontAsk","bypassPermissions","plan","auto"]).optional(),allowedBashPatterns:u.array(u.string()).optional(),deniedBashPatterns:u.array(u.string()).optional(),allowedChannels:u.array(u.string()).nullable().optional(),inheritUserSettings:u.boolean().optional(),envVars:Dn,osCapabilities:u.array(Fn).optional()}),Je=u.object({id:u.string().min(1)}),ao=u.object({status:u.enum(["active","inactive","retired"]).optional(),limit:u.coerce.number().min(1).max(1e3).optional(),offset:u.coerce.number().min(0).default(0)}),oo=u.object({path:u.string().min(1)});async function xn(o){o.get("/roles",{schema:{tags:["Roles"],summary:"List all roles",description:"List all roles with optional status filter and pagination.",querystring:{type:"object",properties:{status:{type:"string",enum:["active","inactive","retired"]},limit:{type:"integer",minimum:1,maximum:1e3},offset:{type:"integer",minimum:0,default:0}}}}},async(r,e)=>{let s=ao.safeParse(r.query);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(s.error)});let{status:t,limit:n,offset:a}=s.data;return{roles:Ie(t,n,a).map(c=>({...c,workspacePath:oe(c.name)}))}}),o.post("/roles",{schema:{tags:["Roles"],summary:"Create a role",description:"Create a new role with a name, CAG prompt, and optional preferences.",body:{type:"object",required:["name"],properties:{name:{type:"string",minLength:1},cagPrompt:{type:"string"},preferences:{type:"object",properties:{model:{type:"string"},effort:{type:"string",enum:["low","medium","high","max"]},maxTurns:{type:"number"}}}}}}},async(r,e)=>{let s=ro.safeParse(r.body);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(s.error)});let{name:t,cagPrompt:n,learnedRules:a,allowedTools:i,disallowedTools:c,evaluationCriteria:p,executionMode:d,model:l,maxBudgetUsd:g,approvalRequired:b,preferences:E,additionalDirectories:v,allowedChannels:T,inheritUserSettings:w,envVars:W,osCapabilities:pe}=s.data;if(ft(t))return e.status(409).send({code:"CONFLICT",message:`Role with name '${t}' already exists`});let le;try{le=mt(pe)}catch(Q){return e.status(400).send({code:"VALIDATION_ERROR",message:Q instanceof Error?Q.message:String(Q)})}let S={id:`role-${En().slice(0,8)}`,name:t,cagPrompt:n??"",learnedRules:a??[],memoryStreamId:`mem-${En().slice(0,8)}`,status:"active",preferences:E??{},allowedTools:i,disallowedTools:c,evaluationCriteria:p,executionMode:d,model:l,maxBudgetUsd:g,approvalRequired:b,additionalDirectories:v,allowedChannels:T,inheritUserSettings:w,envVars:W,osCapabilities:le,createdAt:Date.now()};return gt(S),bt(S),e.status(201).send({role:S})}),o.get("/roles/:id",{schema:{tags:["Roles"],summary:"Get role by ID",description:"Retrieve a single role with its project-scope plugins.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=Je.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(s.error)});let t=U(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let n=oe(t.name),a=Ue({scope:"project",projectPath:n});return{role:t,projectPlugins:a,workspacePath:n}}),o.get("/roles/:id/scores",{schema:{tags:["Roles"],summary:"Get role quality scores",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:100,default:20}}}}},async(r,e)=>{let s=u.object({id:u.string().min(1)}).safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(s.error)});let t=U(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let n=r.query.limit??20,a=Ys(t.id,n),i=Xs(t.id);return{scores:a,latestEma:i??null}}),o.patch("/roles/:id",{schema:{tags:["Roles"],summary:"Update a role",description:"Partially update a role's CAG prompt, learned rules, status, or preferences.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",properties:{name:{type:"string",minLength:1},cagPrompt:{type:"string"},learnedRules:{type:"array",items:{type:"string"}},status:{type:"string",enum:["active","inactive","retired"]},permissionMode:{type:"string",enum:["default","acceptEdits","dontAsk","bypassPermissions","plan","auto"]},allowedBashPatterns:{type:"array",items:{type:"string"}},deniedBashPatterns:{type:"array",items:{type:"string"}},preferences:{type:"object",properties:{model:{type:"string"},effort:{type:"string",enum:["low","medium","high","max"]},maxTurns:{type:"number"}}}}}}},async(r,e)=>{let s=Je.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(s.error)});let t=no.safeParse(r.body);if(!t.success)return e.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(t.error)});if(!U(s.data.id))return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let{allowedChannels:a,osCapabilities:i,...c}=t.data,p={...c,updatedAt:Date.now()};if(a!==void 0&&(p.allowedChannels=a??void 0),i!==void 0)try{p.osCapabilities=mt(i)}catch(l){return e.status(400).send({code:"VALIDATION_ERROR",message:l instanceof Error?l.message:String(l)})}if(qe(s.data.id,p),t.data.cagPrompt!==void 0||t.data.learnedRules!==void 0){let l=U(s.data.id);if(l){let g=oe(l.name);Wt(g)&&vt(g,l)}}let d=U(s.data.id);if(d&&(t.data.allowedTools!==void 0||t.data.disallowedTools!==void 0)){let l=oe(d.name);Wt(l)&&Rt(d.id,d.allowedTools,l)}return{role:d}}),o.delete("/roles/:id",{schema:{tags:["Roles"],summary:"Delete a role",description:"Delete a role and its workspace.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=Je.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(s.error)});let t=U(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});if(t.id===_s)return e.status(403).send({code:"FORBIDDEN",message:"System role 'chat-manager' cannot be deleted"});let n=oe(t.name);if(Wt(n))try{to(n,{recursive:!0,force:!0})}catch{}return yt(s.data.id),{roleId:s.data.id,deleted:!0}}),o.post("/roles/:id/scan-directory",{schema:{tags:["Roles"],summary:"Scan directory for plugin/permission configuration",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",required:["path"],properties:{path:{type:"string",minLength:1}}}}},async(r,e)=>{let s=Je.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(s.error)});let t=oo.safeParse(r.body);if(!t.success)return e.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(t.error)});if(!U(s.data.id))return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let a=Ds(t.data.path);return{path:t.data.path,enabledPlugins:a.enabledPlugins,mcpServers:a.mcpServers,allowedTools:a.allowedTools,disallowedTools:a.disallowedTools}}),o.get("/roles/:id/env-diff",{schema:{tags:["Roles"],summary:"Get role env diff",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=U(r.params.id);return s?{diffs:Ts(s.name,s.envVars),envFileExists:ht(s.name)!==null}:e.status(404).send({code:"NOT_FOUND",message:"Role not found"})}),o.post("/roles/:id/sync-to-env",{schema:{tags:["Roles"],summary:"Sync role env to .env file",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=U(r.params.id);return s?{success:!0,changed:ws(s.name,s.envVars)}:e.status(404).send({code:"NOT_FOUND",message:"Role not found"})}),o.post("/roles/:id/load-from-env",{schema:{tags:["Roles"],summary:"Load role env from .env file",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=U(r.params.id);if(!s)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let t=ht(s.name);if(!t)return e.status(400).send({code:"NOT_FOUND",message:".env file not found in role workspace"});let n={};for(let[a,i]of Object.entries(t))a.startsWith("ANTHROPIC_")||(n[a]=i);return qe(s.id,{envVars:Object.keys(n).length>0?n:void 0,updatedAt:Date.now()}),{success:!0,updated:Object.keys(n).length}})}ve();import{z as jn}from"zod/v4";import{readdirSync as io,existsSync as co}from"fs";import{join as Vt,resolve as Nn,sep as Ln}from"path";import{homedir as po}from"os";var lo=20,uo=jn.object({prefix:jn.string()});function Mn(o){return o.startsWith("~/")?Vt(po(),o.slice(2)):o}function qn(o){let r=Nn(o);for(let e of cs){let s=Mn(e),t=Nn(s);if(r===t||r.startsWith(t+Ln))return!0}return!1}async function Un(o){o.get("/fs/suggest-dirs",{schema:{tags:["FS"],summary:"Suggest directory completions",description:"Return directory suggestions matching a given path prefix.",querystring:{type:"object",required:["prefix"],properties:{prefix:{type:"string"}}}}},async(r,e)=>{let s=uo.safeParse(r.query);if(!s.success)return{suggestions:[]};let{prefix:t}=s.data;if(!t.startsWith("/")&&!t.startsWith("~/"))return{suggestions:[]};if(qn(t))return{suggestions:[]};let n=Mn(t),a,i;if(t.endsWith("/"))a=n,i="";else{let v=Math.max(n.lastIndexOf("/"),n.lastIndexOf(Ln));if(v<0)return{suggestions:[]};a=n.slice(0,v+1),i=n.slice(v+1)}if(!co(a))return{suggestions:[]};let c;try{c=io(a,{withFileTypes:!0}).filter(v=>v.isDirectory()).map(v=>v.name)}catch{return{suggestions:[]}}let p=i.toLowerCase(),d=c.filter(v=>v.toLowerCase().startsWith(p)),b=(i.startsWith(".")?d:d.filter(v=>!v.startsWith("."))).filter(v=>!qn(Vt(a,v)));return b.sort((v,T)=>v.localeCompare(T,void 0,{sensitivity:"base"})),{suggestions:b.slice(0,lo).map(v=>Vt(a,v))}})}import{z as C}from"zod/v4";Le();import{v4 as mo}from"uuid";var go=C.object({roleId:C.string().min(1)}),fo=C.object({roleId:C.string().min(1),prompt:C.string().min(1),topK:C.number().min(1).max(50).default(10)}),yo=C.object({limit:C.coerce.number().min(1).max(200).default(50),offset:C.coerce.number().min(0).default(0)});function $t(o){return U(o)!==void 0}async function Bn(o){o.get("/memories/:roleId",{schema:{tags:["Memories"],summary:"List role memories",description:"List all memories for a specific role with pagination. Embeddings are stripped from the response.",params:{type:"object",required:["roleId"],properties:{roleId:{type:"string"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50},offset:{type:"integer",minimum:0,default:0}}},response:R.memoryList}},async(s,t)=>{let n=go.safeParse(s.params);if(!n.success)return t.status(400).send({code:"VALIDATION_ERROR",message:C.prettifyError(n.error)});let a=n.data.roleId;if(!$t(a))return t.status(404).send({code:"NOT_FOUND",message:"Role or agent not found"});let i=yo.safeParse(s.query),{limit:c,offset:p}=i.success?i.data:{limit:50,offset:0},l=er(a,c,p).map(({embedding:g,...b})=>b);return{memories:l,count:l.length}}),o.post("/memories/query",{schema:{tags:["Memories"],summary:"Query role memories",description:"Query a role's memories using hybrid search (FTS5 + vector similarity) with Smallville-style scoring (recency, importance, relevance).",body:{type:"object",required:["roleId","prompt"],properties:{roleId:{type:"string",minLength:1,description:"The role whose memories to query"},prompt:{type:"string",minLength:1,description:"The search query"},topK:{type:"integer",minimum:1,maximum:50,default:10,description:"Number of results to return"}}},response:R.memoryQuery}},async(s,t)=>{let n=fo.safeParse(s.body);if(!n.success)return t.status(400).send({code:"VALIDATION_ERROR",message:C.prettifyError(n.error)});let{roleId:a,prompt:i,topK:c}=n.data;if(!$t(a))return t.status(404).send({code:"NOT_FOUND",message:"Role or agent not found"});let d=(await wt(a,i,{topK:c})).map(({embedding:l,...g})=>g);return{memories:d,count:d.length}});let r=C.object({roleId:C.string().min(1),content:C.string().min(1),type:C.enum(["event","thought","reflection"]).default("thought"),keywords:C.array(C.string()).default([]),importance:C.number().min(1).max(5).default(3),tier:C.enum(["working","episodic","semantic"]).default("episodic")});o.post("/memories",{schema:{tags:["Memories"],summary:"Create memory",description:"Create a new memory for a role. Embedding is auto-generated from content.",body:{type:"object",required:["roleId","content"],properties:{roleId:{type:"string",minLength:1},content:{type:"string",minLength:1},type:{type:"string",enum:["event","thought","reflection"],default:"thought"},keywords:{type:"array",items:{type:"string"},default:[]},importance:{type:"integer",minimum:1,maximum:5,default:3},tier:{type:"string",enum:["working","episodic","semantic"],default:"episodic"}}},response:R.memoryCreated}},async(s,t)=>{let n=r.safeParse(s.body);if(!n.success)return t.status(400).send({code:"VALIDATION_ERROR",message:C.prettifyError(n.error)});let{roleId:a,content:i,type:c,keywords:p,importance:d,tier:l}=n.data;if(!$t(a))return t.status(404).send({code:"NOT_FOUND",message:"Role or agent not found"});let g;try{g=await kt(i)}catch{}let b=`mem-${mo().slice(0,8)}`,E=Date.now();Zs({id:b,roleId:a,type:c,content:i,embedding:g,keywords:p,importance:d,sourceType:"manual",createdAt:E,lastAccessed:E,retrievedCount:0,tier:l??"episodic"});let v=$e(b),{embedding:T,...w}=v;return t.status(201).send({memory:w})});let e=C.object({content:C.string().min(1).optional(),type:C.enum(["event","thought","reflection"]).optional(),keywords:C.array(C.string()).optional(),importance:C.number().min(1).max(5).optional()});o.patch("/memories/:id",{schema:{tags:["Memories"],summary:"Update memory",description:"Update a memory's content, type, keywords, or importance. Embedding is regenerated if content changes.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",properties:{content:{type:"string",minLength:1},type:{type:"string",enum:["event","thought","reflection"]},keywords:{type:"array",items:{type:"string"}},importance:{type:"integer",minimum:1,maximum:5}}},response:R.memoryUpdated}},async(s,t)=>{let{id:n}=s.params;if(!$e(n))return t.status(404).send({code:"NOT_FOUND",message:"Memory not found"});let i=e.safeParse(s.body);if(!i.success)return t.status(400).send({code:"VALIDATION_ERROR",message:C.prettifyError(i.error)});let c=i.data,p,d=!0;if(c.content)try{p=await kt(c.content)}catch{d=!1}let l=Js(n,{content:c.content,embedding:p,keywords:c.keywords,importance:c.importance,type:c.type});return{memoryId:n,updated:l,embeddingUpdated:d}}),o.delete("/memories/:id",{schema:{tags:["Memories"],summary:"Delete memory",description:"Delete a memory by ID.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},response:R.memoryDeleted}},async(s,t)=>{let{id:n}=s.params;return $e(n)?(tr(n),{memoryId:n,deleted:!0}):t.status(404).send({code:"NOT_FOUND",message:"Memory not found"})})}import{query as Ro}from"@anthropic-ai/claude-agent-sdk";import{v4 as de}from"uuid";function ho(){try{return F().defaults.maxBudgetUsd}catch{return 5}}function Gt(o){return`# ChatManager \u2014 User Interface Agent
|
|
3
3
|
|
|
4
4
|
You are the primary interface between the user and the goal-driven autonomous system.
|
|
5
5
|
You have access to a persistent conversation session and the adam-tools MCP server.
|
|
@@ -30,7 +30,7 @@ When the user asks what you can do or asks for help, call **get_capabilities** t
|
|
|
30
30
|
|
|
31
31
|
## Current Context
|
|
32
32
|
- Time: ${new Date(o.currentTime).toISOString()}
|
|
33
|
-
- Platform budget per task: $${
|
|
33
|
+
- Platform budget per task: $${ho()} (change via update_config with key "defaults.maxBudgetUsd")
|
|
34
34
|
- All config is stored in the database. adam.config.yaml is deprecated and NOT loaded at runtime.
|
|
35
35
|
- Role budget: if a Role has maxBudgetUsd set (> 0), the effective budget is min(role budget, platform budget). If 0 or unset, the platform budget applies.
|
|
36
36
|
|
|
@@ -79,20 +79,23 @@ conflict, treat the [Session context] as authoritative (it reflects the latest D
|
|
|
79
79
|
- **Task completion delivery is automatic**: When a task completes, the platform automatically delivers reportTo (status) and deliverTo (result) messages to the configured targets. The originating channel receives a status notification by default. Do NOT call send_to_channel to deliver task results \u2014 this causes duplicate messages. Only use send_to_channel for ad-hoc messages unrelated to task completion.
|
|
80
80
|
- Check goal/task progress \u2192 list_goals / read_task_status
|
|
81
81
|
- **Create new role**: When the user asks to create a role with specific capabilities (e.g., "\u80FD\u8BBF\u95EE\u7F51\u7EDC"), pass the required tools in allowedTools (e.g., ["WebSearch", "WebFetch"]). Without allowedTools, the role has no tool permissions and cannot execute tasks that need those tools.
|
|
82
|
+
- If the user explicitly names a delivery target (e.g., "\u53D1\u5230 iPad \u5FAE\u4FE1", "send to email", "\u901A\u8FC7\u98DE\u4E66\u544A\u8BC9\u6211"), MUST populate deliverTo with [{type:"channel", channelName:"<extracted keyword>"}]. The platform resolves the keyword via case-insensitive substring match against channel names. Only omit deliverTo when no target is mentioned (origin channel is the default).
|
|
82
83
|
|
|
83
84
|
## Conversation Coherence
|
|
84
85
|
When task completion notifications arrive, incorporate the results naturally into your conversation.
|
|
85
86
|
For example, if the user asked "run a report" and Task xyz completed, summarize the result for the user.
|
|
86
|
-
`}function
|
|
87
|
-
`)}function
|
|
88
|
-
`)}async function
|
|
87
|
+
`}function bo(o){return o.map(r=>`${r.role==="user"?"User":"Assistant"}: ${r.content}`).join(`
|
|
88
|
+
`)}function vo(o){return o.map(r=>`Memory [${r.tier??"episodic"}]: ${r.content} (importance: ${r.importance})`).join(`
|
|
89
|
+
`)}async function Wn(o,r){let e=hs(),s=Hs(o,e.maxSessionTurns),t=bo(s),n="";try{let i=await sr(void 0,r,["semantic","working"],{topK:5});i.length>0&&(n=vo(i))}catch{}let a=[];return t&&a.push(`[Session context \u2014 last ${e.maxSessionTurns} turns]
|
|
89
90
|
${t}`),n&&a.push(`[Relevant memories \u2014 from Memory system]
|
|
90
91
|
${n}`),a.push(`[Current message]
|
|
91
92
|
User: ${r}`),a.join(`
|
|
92
93
|
|
|
93
|
-
`)}ve();
|
|
94
|
+
`)}ve();Y();var j=q("chat-manager"),Io=x,Se=class{sessionId;adamToolsInstance=null;running=!1;processing=!1;messageQueue=[];lastActivityAt=Date.now();consecutiveStaleCount=0;subscribed=!1;activeChatSessionId;activeChatSource;taskOriginMap=new Map;constructor(r){this.sessionId=r}async start(){this.running||(this.running=!0,this.subscribeToEvents(),j.info("ChatManager started"))}stop(){this.running=!1,j.info("ChatManager stopped")}async handleMessage(r,e,s){return new Promise((t,n)=>{let a=e,i=s;this.messageQueue.push({content:r,chatSessionId:a,source:i,resolve:c=>{this.activeChatSessionId=void 0,this.activeChatSource=void 0,t(c)},reject:c=>{this.activeChatSessionId=void 0,this.activeChatSource=void 0,n(c)}}),this.processQueue()})}async processQueue(){if(this.processing||!this.running)return;let r=this.messageQueue.shift();if(r){this.activeChatSessionId=r.chatSessionId,this.activeChatSource=r.source,this.processing=!0;try{let e=await this.runQuery(r.content,r.chatSessionId);r.resolve(e)}catch(e){let s=e instanceof Error?e.message:String(e);if(s.includes("Prompt is too long")||s.includes("prompt is too long")){j.warn("Prompt too long \u2014 resetting session and retrying"),this.sessionId=void 0,Ze(void 0);try{let t=await this.runQuery(r.content,r.chatSessionId);r.resolve(t)}catch(t){r.reject(t instanceof Error?t:new Error(String(t)))}}else r.reject(e instanceof Error?e:new Error(s))}finally{this.processing=!1,this.processQueue()}}}async runQuery(r,e){let s=Gt({currentTime:Date.now()}),t=r;if(e)try{let d=await Wn(e,r);d&&d!==r&&(t=d)}catch(d){j.debug({error:d},"Session context enrichment failed, using raw message")}this.adamToolsInstance||(this.adamToolsInstance=Dt());let n=xt({currentTaskId:void 0,roleId:"role-chat-manager"}),a=Ft(d=>({disallowedTools:["WebSearch","WebFetch","Bash","Edit","Write","NotebookEdit"]}));j.debug({hasApiKey:!!process.env.ANTHROPIC_API_KEY,hasResume:!!this.sessionId},"ChatManager SDK query starting");let i=["WebSearch","WebFetch","Bash","Edit","Write","NotebookEdit"],c=Ro({prompt:t,options:{cwd:Io,additionalDirectories:[process.cwd()],systemPrompt:s,resume:this.sessionId,maxTurns:50,maxBudgetUsd:F().defaults.maxBudgetUsd,disallowedTools:i,settingSources:["project"],mcpServers:{"adam-tools":this.adamToolsInstance},hooks:n,canUseTool:a,env:{...os(),ANTHROPIC_SMALL_FAST_MODEL:F().anthropic?.smallFastModel||process.env.ANTHROPIC_MODEL||""},stderr:d=>{d.trim()&&j.debug({stderr:d.trim().slice(0,500)},"ChatManager SDK stderr")}}}),p="";for await(let d of c){let l=d;j.debug({eventType:l.type,subtype:l.subtype},"ChatManager SDK event"),this.lastActivityAt=Date.now(),this.consecutiveStaleCount=0,l.session_id&&typeof l.session_id=="string"&&(this.sessionId=l.session_id,Ze(this.sessionId)),l.type==="result"&&typeof l.result=="string"&&(p=l.result)}return p}subscribeToEvents(){this.subscribed||(this.subscribed=!0,y.on("task_created",r=>{this.activeChatSessionId&&this.activeChatSource&&(re(r.taskId,{sourceSessionId:this.activeChatSessionId}),this.taskOriginMap.set(r.taskId,{chatSessionId:this.activeChatSessionId,source:this.activeChatSource,createdAt:Date.now()}),j.debug({taskId:r.taskId,chatSessionId:this.activeChatSessionId},"Tracked task origin for result delivery"));let e=D(r.taskId);if(e?.parentId){let s=this.taskOriginMap.get(e.parentId),t=s?void 0:D(e.parentId),n=s?.chatSessionId??t?.sourceSessionId;n&&(re(r.taskId,{sourceSessionId:n}),s&&this.taskOriginMap.set(r.taskId,{...s}))}}),y.on("task_complete_event",r=>{this.handleTaskCompletion(r.taskId,r.result,r.error)}),y.on("task_status_change",r=>{let e=this.taskOriginMap.get(r.taskId);e&&r.newStatus==="running"&&this.handleTaskStatusReport(r.taskId,r.newStatus,e)}),y.on("plan_approval_request",r=>{let e=this.taskOriginMap.get(r.taskId);e&&this.handleTaskStatusReport(r.taskId,"approval_requested",e)}),setInterval(()=>{let r=Date.now()-864e5;for(let[e,s]of this.taskOriginMap)s.createdAt<r&&this.taskOriginMap.delete(e)},3600*1e3))}async handleTaskStatusReport(r,e,s){let t=D(r),a=(t?.roleId?await this.getRoleName(t.roleId):void 0)??r.slice(0,8),i=t?.prompt?.slice(0,1e3)??"",c;switch(e){case"running":c=`[System] Task "${a}" has started execution. Task prompt: "${i}". Compose a brief, natural status message for the user (1-2 sentences in the user's language). Do NOT call any tools \u2014 just output the message text.`;break;case"approval_requested":c=`[System] Task "${a}" needs user approval (privilege escalation). The approval request has been sent separately. Compose a brief notice for the user (1 sentence). Do NOT call any tools.`;break;default:return}let p={running:`\u4EFB\u52A1 ${a} \u5DF2\u542F\u52A8`,approval_requested:`\u4EFB\u52A1 ${a} \u9700\u8981\u6388\u6743`},d=!1,l=setTimeout(()=>{if(d)return;d=!0;let g=p[e]??`\u4EFB\u52A1 ${a}: ${e}`;this.deliverReport(s,r,g)},3e4);this.messageQueue.push({content:c,resolve:g=>{if(d)return;d=!0,clearTimeout(l);let b=g?.trim()||(p[e]??`\u4EFB\u52A1 ${a}: ${e}`);this.deliverReport(s,r,b)},reject:()=>{if(d)return;d=!0,clearTimeout(l);let g=p[e]??`\u4EFB\u52A1 ${a}: ${e}`;this.deliverReport(s,r,g)}}),this.processQueue()}deliverReport(r,e,s,t){let n={id:de(),sessionId:r.chatSessionId,role:"assistant",content:s,source:r.source,taskId:e,createdAt:Date.now()};X(n),y.emit({type:"chat_message",sessionId:r.chatSessionId,message:n}),J(r.chatSessionId),r.source.type==="channel"&&r.source.channelId&&r.source.chatId&&this.deliverToChannel(r.source.channelId,r.source.chatId,s,"report",t)}async handleTaskCompletion(r,e,s){let t=D(r),n=t,a=t?.status==="blocked",i=this.taskOriginMap.get(r);if(!i&&n?.sourceSessionId){let d=V(n.sourceSessionId);d&&(i={chatSessionId:d.id,source:d.source,createdAt:n.createdAt})}let c=s?`\u4EFB\u52A1\u5931\u8D25: ${s}`:e??"",p=async(d,l)=>{try{let g=V(d);if(!g)return;X({id:de(),sessionId:d,role:"assistant",content:l,source:g.source,taskId:r,createdAt:Date.now()}),J(d),y.emit({type:"chat_message",sessionId:d,message:{id:de(),sessionId:d,role:"assistant",content:l,source:g.source,createdAt:Date.now()}})}catch(g){j.error({error:g,taskId:r,targetSession:d},"Failed to deliver to session")}};if(a){let d=t.blockReason,l=`\u{1F7E1} \u4EFB\u52A1\u5361\u4F4F: ${d?.reason??"unknown"}
|
|
95
|
+
`+(d?.missingPrereqs?.length?`\u7F3A\u5C11: ${d.missingPrereqs.join(", ")}
|
|
96
|
+
`:"")+(d?.resumeHint?`\u89E3\u51B3\u65B9\u6CD5: ${d.resumeHint}`:"");if(i&&this.deliverReport(i,r,l,r),t?.reportTo?.length)for(let g of t.reportTo)g.type==="channel"&&g.channelId&&g.chatId?this.deliverToChannel(g.channelId,g.chatId,l,"report",r):g.type==="session"&&g.sessionId&&await p(g.sessionId,l);if(t?.deliverTo?.length)for(let g of t.deliverTo)g.type==="channel"&&g.channelId&&g.chatId?this.deliverToChannel(g.channelId,g.chatId,l,"deliver",r):g.type==="session"&&g.sessionId&&await p(g.sessionId,l);else i?.source.type==="channel"&&i.source.channelId&&i.source.chatId&&this.deliverToChannel(i.source.channelId,i.source.chatId,l,"deliver",r);i&&this.taskOriginMap.delete(r)}else{let d=t?.roleId?await this.getRoleName(t.roleId):void 0,l=d?`${d}`:r.slice(0,8),g=s?`[System] Task "${l}" failed. Error: ${s.slice(0,1500)}. Compose a brief failure report for the user (2-3 sentences). Do NOT call any tools.`:`[System] Task "${l}" completed successfully. Result summary: ${(e??"").slice(0,4e3)}. Compose a brief completion report for the user (2-3 sentences, highlight key outcomes). Do NOT call any tools.`,b={success:`\u4EFB\u52A1\u5B8C\u6210 (${l})`,error:`\u4EFB\u52A1\u5931\u8D25 (${l})`},E=!1,v=setTimeout(()=>{if(E)return;E=!0;let T=s?b.error:b.success;if(i&&this.deliverReport(i,r,T,r),t?.reportTo&&t.reportTo.length>0)for(let w of t.reportTo)w.type==="channel"&&w.channelId&&w.chatId?this.deliverToChannel(w.channelId,w.chatId,T,"report",r):w.type==="session"&&w.sessionId&&p(w.sessionId,T)},3e4);if(this.messageQueue.push({content:g,resolve:T=>{if(E)return;E=!0,clearTimeout(v);let w=T?.trim()||(s?b.error:b.success);if(i&&this.deliverReport(i,r,w,r),t?.reportTo&&t.reportTo.length>0)for(let W of t.reportTo)W.type==="channel"&&W.channelId&&W.chatId?this.deliverToChannel(W.channelId,W.chatId,w,"report",r):W.type==="session"&&W.sessionId&&p(W.sessionId,w);i&&this.taskOriginMap.delete(r)},reject:()=>{if(E)return;E=!0,clearTimeout(v);let T=s?b.error:b.success;if(i&&this.deliverReport(i,r,T,r),t?.reportTo&&t.reportTo.length>0)for(let w of t.reportTo)w.type==="channel"&&w.channelId&&w.chatId?this.deliverToChannel(w.channelId,w.chatId,T,"report",r):w.type==="session"&&w.sessionId&&p(w.sessionId,T);i&&this.taskOriginMap.delete(r)}}),this.processQueue(),i||j.debug({taskId:r},"Task completed but no chat session origin tracked (may be API-created or template-triggered)"),t?.deliverTo&&t.deliverTo.length>0)for(let T of t.deliverTo)T.type==="channel"&&T.channelId&&T.chatId?this.deliverToChannel(T.channelId,T.chatId,c,"deliver",r):T.type==="session"&&T.sessionId&&await p(T.sessionId,c);else if(i?.source.type==="channel"&&i.source.channelId&&i.source.chatId){let w=c.length>4e3?c.slice(0,4e3)+`
|
|
94
97
|
|
|
95
|
-
... \u67E5\u770B\u5B8C\u6574\u7ED3\u679C\u8BF7\u8BBF\u95EE Web UI`:
|
|
98
|
+
... \u67E5\u770B\u5B8C\u6574\u7ED3\u679C\u8BF7\u8BBF\u95EE Web UI`:c;this.deliverToChannel(i.source.channelId,i.source.chatId,w,"deliver",r)}}if(t?.parentId){let d=ie(t.parentId);if(d){let l=Re(t.parentId);if(l.every(b=>b.status==="completed"||b.status==="failed"||b.status==="blocked")){let b=l.some(T=>T.status==="failed"||T.status==="blocked"),E=b?"failed":"completed";We(t.parentId,{status:E,updatedAt:Date.now()}),j.info({goalId:t.parentId,goalName:d.name,finalStatus:E},"Goal completed");let v=`${b?"\u274C":"\u2705"} \u76EE\u6807\u5B8C\u6210: ${d.name}
|
|
96
99
|
|
|
97
|
-
${
|
|
98
|
-
`);try{let n=(await qs(s,"You are a concise title generator. Reply with only the title, max 50 characters.")).trim().slice(0,50);n.length>0&&Ks(o,{title:n})}catch{}}var zt=null;function $n(o){zt=o}async function Je(o,r,e,s){let t;s&&(t=B(s)),t||(t=vr(r)),t||(t=He(r,e));let n=$t(),a={id:n,sessionId:t.id,role:"user",content:o,source:r,createdAt:Date.now()};if(Y(a),b.emit({type:"chat_message",sessionId:t.id,message:a}),t.messageCount===0&&Gn(Io(t.id,o)),X(t.id),Ct(t.id),zt){let i=t.id,c=t.source,p=(async()=>{try{let d=await zt.handleMessage(o,i,r),u={id:$t(),sessionId:i,role:"assistant",content:d,source:r,createdAt:Date.now()};Y(u),b.emit({type:"chat_message",sessionId:i,message:u}),X(i),Ct(i),c.type==="channel"&&c.channelId&&c.chatId&&(Ht.info({sessionId:i,sourceType:c.type,hasChannelId:!!c.channelId,hasResponse:!!d},"Chat response ready, checking channel delivery"),await ko(c.channelId,c.chatId,d))}catch(d){(await import("./logger-WEXZORHP.js")).getLogger("message-handler").error({error:d,sessionId:i},"ChatManager response failed");let h={id:$t(),sessionId:i,role:"assistant",content:`\u26A0\uFE0F \u5904\u7406\u5931\u8D25: ${d instanceof Error?d.message:String(d)}`,source:r,createdAt:Date.now()};Y(h),b.emit({type:"chat_message",sessionId:i,message:h}),X(i)}})();Gn(p)}return{sessionId:t.id,messageId:n}}async function ko(o,r,e){Ht.info({channelId:o,chatId:r.slice(0,12)},"Delivering chat response to channel");try{let{getOutboundGateway:s}=await import("./outbound-gateway-QRL36F7K.js");await s().send({channelId:o,chatId:r,content:e,messageType:"reply"})}catch(s){Ht.error({error:s,channelId:o,chatId:r.slice(0,12)},"Channel delivery failed (non-fatal)")}}import{z as m}from"zod/v4";import{v4 as To}from"uuid";var Hn=m.union([m.object({type:m.literal("session"),sessionId:m.string()}),m.object({type:m.literal("channel"),channelId:m.string(),chatId:m.string().optional()})]),wo=m.object({id:m.string(),prompt:m.string(),dependsOn:m.array(m.string()).optional(),outputAs:m.string().optional(),roleId:m.string().optional(),autoSelectRole:m.boolean().optional(),requirements:Ue.optional(),config:m.object({timeout:m.number().optional(),maxTurns:m.number().optional()}).optional()}),So=m.discriminatedUnion("type",[m.object({type:m.literal("cron"),cron:m.string().min(1),event:m.undefined(),runAt:m.undefined(),eventDefId:m.undefined()}),m.object({type:m.literal("manual"),cron:m.undefined(),event:m.undefined(),runAt:m.undefined(),eventDefId:m.undefined()}),m.object({type:m.literal("once"),cron:m.undefined(),event:m.undefined(),runAt:m.string().min(1),eventDefId:m.undefined()}),m.object({type:m.literal("template_complete"),cron:m.undefined(),event:m.string().regex(/^template_complete:[\w-]+$/),runAt:m.undefined(),eventDefId:m.undefined()}),m.object({type:m.literal("workflow_complete"),cron:m.undefined(),event:m.string().regex(/^workflow_complete:[\w-]+$/),runAt:m.undefined(),eventDefId:m.undefined()}),m.object({type:m.literal("event"),cron:m.undefined(),event:m.undefined(),runAt:m.undefined(),eventDefId:m.string().uuid()})]),Kt=m.object({name:m.string().min(1),description:m.string().optional(),trigger:So,steps:m.array(wo).min(1),rolePreference:m.string().optional(),config:m.record(m.string(),m.unknown()).optional(),enabled:m.boolean().default(!0),goalIds:m.array(m.string()).optional(),deliverTo:m.array(Hn).optional(),reportTo:m.array(Hn).optional()}),Dd=Kt.transform(o=>({...o,deliverTo:o.deliverTo,reportTo:o.reportTo})),_o=Kt.partial().transform(o=>({...o,deliverTo:o.deliverTo,reportTo:o.reportTo})),et=m.object({id:m.string().min(1)});async function zn(o,r){o.post("/task-templates",{schema:{tags:["Templates"],summary:"Create a task template",description:"Create a new task template with trigger (cron/manual/once/template_complete/workflow_complete) and execution steps. Cron-triggered templates are automatically scheduled.",body:{type:"object",required:["name","trigger","steps"],properties:{name:{type:"string",minLength:1},description:{type:"string"},trigger:{type:"object",required:["type"],properties:{type:{type:"string",enum:["cron","manual","once","template_complete","workflow_complete","event"]},cron:{type:"string",description:"Cron expression (required when type is cron)"},event:{type:"string",description:"Required when type is template_complete or workflow_complete; format 'type:<targetId>'"},eventDefId:{type:"string",description:"Event def ID (required when type is event)"},runAt:{type:"string",description:"ISO 8601 timestamp (required when type is once)"}}},steps:{type:"array",minItems:1,items:{type:"object",required:["id","prompt"],properties:{id:{type:"string"},prompt:{type:"string"},dependsOn:{type:"array",items:{type:"string"}},outputAs:{type:"string"},roleId:{type:"string",description:"Role ID for this step (overrides template rolePreference)"},autoSelectRole:{type:"boolean",description:"If true, Adam picks the best-fit role at dispatch time; mutually exclusive with roleId."},requirements:{type:"object",additionalProperties:!0,description:"Task requirements object (tools, paths, osCapabilities, network, plugins). Required when autoSelectRole is true."},config:{type:"object",properties:{timeout:{type:"number",description:"Step-level timeout override (seconds)"},maxTurns:{type:"number",description:"Step-level maxTurns override"}}}}}},rolePreference:{type:"string"},config:{type:"object",additionalProperties:!0},enabled:{type:"boolean",default:!0},goalIds:{type:"array",items:{type:"string"}},deliverTo:{type:"array",items:{type:"object"}},reportTo:{type:"array",items:{type:"object"}}}},response:R.templateCreated}},async(e,s)=>{let t=Kt.safeParse(e.body);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)});let n={id:To(),...t.data,createdAt:Date.now()};try{sr(n)}catch(a){if(a instanceof St)return s.status(400).send({code:a.code,message:a.message,failingStepIds:a.failingStepIds});throw a}return n.enabled&&n.trigger.type==="cron"&&n.trigger.cron?await r.scheduleJob(n.id):n.enabled&&n.trigger.type==="once"&&n.trigger.runAt&&r.scheduleOnceJob(n.id),s.status(201).send({templateId:n.id})}),o.get("/task-templates",{schema:{tags:["Templates"],summary:"List task templates",description:"List all task templates, optionally filtering to enabled-only.",querystring:{type:"object",properties:{enabled:{type:"string",enum:["true","false"],description:"Filter to enabled templates only when 'true'"}}},response:R.templateList}},async e=>{let t=e.query.enabled==="true";return{templates:Ge(t)}}),o.get("/task-templates/:id",{schema:{tags:["Templates"],summary:"Get task template by ID",description:"Retrieve a single task template by its ID.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},response:R.templateDetail}},async(e,s)=>{let t=et.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)});let n=ne(t.data.id);return n?{template:n}:s.status(404).send({code:"NOT_FOUND",message:"Template not found"})}),o.patch("/task-templates/:id",{schema:{tags:["Templates"],summary:"Update a task template",description:"Partially update a task template. Cron schedules are automatically rescheduled if the trigger changes.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",properties:{name:{type:"string",minLength:1},description:{type:"string"},trigger:{type:"object",properties:{type:{type:"string",enum:["cron","manual","once","template_complete","workflow_complete"]},cron:{type:"string",description:"Cron expression (required when type is cron)"},event:{type:"string",description:"Event string: 'template_complete:<id>' or 'workflow_complete:<id>'"},runAt:{type:"string",description:"ISO 8601 timestamp (required when type is once)"}}},steps:{type:"array",items:{type:"object"}},rolePreference:{type:"string"},config:{type:"object",additionalProperties:!0},enabled:{type:"boolean"},goalIds:{type:"array",items:{type:"string"}},deliverTo:{type:"array",items:{type:"object"}},reportTo:{type:"array",items:{type:"object"}}}},response:R.templateUpdated}},async(e,s)=>{let t=et.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)});let n=_o.safeParse(e.body);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(n.error)});if(!ne(t.data.id))return s.status(404).send({code:"NOT_FOUND",message:"Template not found"});try{rr(t.data.id,n.data)}catch(c){if(c instanceof St)return s.status(400).send({code:c.code,message:c.message,failingStepIds:c.failingStepIds});throw c}await r.unscheduleJob(t.data.id);let i=ne(t.data.id);return i?.enabled&&i.trigger.type==="cron"&&i.trigger.cron?await r.scheduleJob(i.id):i?.enabled&&i.trigger.type==="once"&&i.trigger.runAt&&r.scheduleOnceJob(i.id),{templateId:t.data.id}}),o.delete("/task-templates/:id",{schema:{tags:["Templates"],summary:"Delete a task template",description:"Delete a task template by ID. Cron jobs are automatically unscheduled.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},response:R.templateDeleted}},async(e,s)=>{let t=et.safeParse(e.params);return t.success?ne(t.data.id)?(await r.unscheduleJob(t.data.id),nr(t.data.id),{templateId:t.data.id,deleted:!0}):s.status(404).send({code:"NOT_FOUND",message:"Template not found"}):s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)})}),o.post("/task-templates/:id/run",{schema:{tags:["Templates"],summary:"Run a task template",description:"Manually trigger execution of a task template regardless of its trigger type.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},response:R.templateRun}},async(e,s)=>{let t=et.safeParse(e.params);return t.success?ne(t.data.id)?{executionId:await r.runNow(t.data.id),status:"started"}:s.status(404).send({code:"NOT_FOUND",message:"Template not found"}):s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)})})}import{z as E}from"zod/v4";Ds();var Qt=E.object({id:E.string().min(1)}),Co=E.object({scope:E.enum(["user","project"]).optional(),cwd:E.string().optional()}),Ao=E.object({scope:E.enum(["user","project"]).optional(),cwd:E.string().optional()});async function Kn(o){o.get("/plugins",{schema:{tags:["Plugins"],summary:"List all installed plugins",querystring:{type:"object",properties:{scope:{type:"string",enum:["user","project","local"]}}}}},async e=>{let s=e.query,t=Me({scope:s.scope}),n=It();return{plugins:t.map(a=>({...a,globalEnabled:n[a.id]??a.enabled}))}}),o.get("/plugins/:id",{schema:{tags:["Plugins"],summary:"Get plugin by ID",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,s)=>{let t=Qt.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:E.prettifyError(t.error)});let n=Es(t.data.id);if(!n)return s.status(404).send({code:"NOT_FOUND",message:"Plugin not found"});let a=As(n.installPath),i=It();return{plugin:{...n,globalEnabled:i[n.id]??n.enabled,manifest:a}}}),o.post("/plugins/:id/enable",{schema:{tags:["Plugins"],summary:"Enable a plugin globally",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,s)=>{let t=Qt.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:E.prettifyError(t.error)});if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude CLI not found. Plugin enable/disable requires the Claude Agent SDK CLI."});try{return Dr(t.data.id),{pluginId:t.data.id,enabled:!0}}catch(n){return s.status(500).send({code:"CLI_ERROR",message:n instanceof Error?n.message:"Enable failed"})}}),o.post("/plugins/:id/disable",{schema:{tags:["Plugins"],summary:"Disable a plugin globally",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,s)=>{let t=Qt.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:E.prettifyError(t.error)});if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude CLI not found. Plugin enable/disable requires the Claude Agent SDK CLI."});try{return Fr(t.data.id),{pluginId:t.data.id,enabled:!1}}catch(n){return s.status(500).send({code:"CLI_ERROR",message:n instanceof Error?n.message:"Disable failed"})}}),o.get("/plugins/stats",{schema:{tags:["Plugins"],summary:"Get plugin usage statistics",querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50}}}}},async e=>{let s=e.query;return{stats:Xr(s.limit??50)}});let r=E.object({roleId:E.string().min(1)});o.get("/plugins/stats/role/:roleId",{schema:{tags:["Plugins"],summary:"Get plugin usage by role",params:{type:"object",required:["roleId"],properties:{roleId:{type:"string"}}}}},async(e,s)=>{let t=r.safeParse(e.params);return t.success?{roleId:t.data.roleId,stats:Yr(t.data.roleId)}:s.status(400).send({code:"VALIDATION_ERROR",message:E.prettifyError(t.error)})}),o.get("/plugins/marketplace",{schema:{tags:["Marketplace"],summary:"List available marketplace plugins"}},async(e,s)=>{if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found. Install Claude Code to use marketplace features."});try{let t=Er();return{available:t.available,installed:t.installed}}catch(t){return s.status(500).send({code:"CLI_ERROR",message:t instanceof Error?t.message:"CLI command failed"})}}),o.get("/plugins/marketplaces",{schema:{tags:["Marketplace"],summary:"List known marketplace sources"}},async()=>({sources:Ps()})),o.post("/plugins/install/:name",{schema:{tags:["Marketplace"],summary:"Install a plugin",params:{type:"object",required:["name"],properties:{name:{type:"string"}}},body:{type:"object",properties:{scope:{type:"string",enum:["user","project"]},cwd:{type:"string"}}}}},async(e,s)=>{let n=E.object({name:E.string().min(1)}).safeParse(e.params);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:E.prettifyError(n.error)});let a=Co.safeParse(e.body??{});if(!a.success)return s.status(400).send({code:"VALIDATION_ERROR",message:E.prettifyError(a.error)});if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found"});try{return Pr(n.data.name,a.data.scope??"user",a.data.cwd),{success:!0,pluginId:n.data.name}}catch(i){return s.status(500).send({code:"CLI_ERROR",message:i instanceof Error?i.message:"Install failed"})}}),o.post("/plugins/uninstall/:name",{schema:{tags:["Marketplace"],summary:"Uninstall a plugin",params:{type:"object",required:["name"],properties:{name:{type:"string"}}},body:{type:"object",properties:{scope:{type:"string",enum:["user","project"]},cwd:{type:"string"}}}}},async(e,s)=>{let n=E.object({name:E.string().min(1)}).safeParse(e.params);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:E.prettifyError(n.error)});let a=Ao.safeParse(e.body??{});if(!a.success)return s.status(400).send({code:"VALIDATION_ERROR",message:E.prettifyError(a.error)});if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found"});try{return Or(n.data.name,a.data.scope,a.data.cwd),{success:!0,pluginId:n.data.name}}catch(i){return s.status(500).send({code:"CLI_ERROR",message:i instanceof Error?i.message:"Uninstall failed"})}})}import{z as Yt}from"zod/v4";var Eo=Yt.object({name:Yt.string().min(1)}),Po="x-api-key";async function Qn(o,r,e){o.post("/webhooks/:name",{schema:{tags:["Webhooks"],summary:"Trigger a webhook",description:"Trigger a task template execution by name or ID. Requires X-API-Key header if API key is configured.",security:[{apiKey:[]}],params:{type:"object",required:["name"],properties:{name:{type:"string",description:"Template name or ID"}}},response:R.webhookTriggered}},async(s,t)=>{if(e&&s.headers[Po]!==e)return t.status(401).send({code:"UNAUTHORIZED",message:"Invalid or missing API key"});let n=Eo.safeParse(s.params);if(!n.success)return t.status(400).send({code:"VALIDATION_ERROR",message:Yt.prettifyError(n.error)});let{name:a}=n.data,i=ne(a);if(!i){let{listTaskTemplates:c}=await import("./task-templates-YPNWJOVV.js");i=c(!1).find(d=>d.name===a||d.id===a)}if(!i)return t.status(404).send({code:"NOT_FOUND",message:`Template '${a}' not found`});if(!i.enabled)return t.status(409).send({code:"DISABLED",message:`Template '${a}' is disabled`});try{let c=await r.runNow(i.id);return t.status(202).send({code:"ACCEPTED",message:`Template '${i.name}' triggered`,executionId:c,templateId:i.id})}catch(c){let p=c instanceof Error?c.message:String(c);return t.status(500).send({code:"EXECUTION_ERROR",message:p})}}),o.get("/webhooks",{schema:{tags:["Webhooks"],summary:"List available webhooks",description:"List all enabled task templates that can be triggered via webhook, along with auth requirements.",response:R.webhookList}},async()=>{let{listTaskTemplates:s}=await import("./task-templates-YPNWJOVV.js");return{webhooks:s(!0).map(n=>({name:n.id,displayName:n.name,description:n.description,tags:n.tags,trigger:`POST /webhooks/${n.id}`})),auth:e?"X-API-Key header required":"No auth configured"}})}import{z as Xt}from"zod/v4";import{z as H}from"zod/v4";var Oo=H.object({type:H.string().regex(/^[a-z0-9._]+$/,"type must be lowercase alphanumeric with dots or underscores").max(100),payload:H.record(H.string(),H.unknown()),dedup_key:H.string().max(200),occurred_at:H.string().datetime().optional(),schema_version:H.number().int().positive().optional(),confidence:H.number().min(0).max(1).optional()});function Yn(o,r){let e=Oo.safeParse(r);if(!e.success)throw new Error(`Invalid webhook envelope: ${H.prettifyError(e.error)}`);let s=e.data,t=new Date().toISOString(),n=Wr({eventDefId:o.id,type:s.type,source:`webhook-${o.id}`,dedupKey:s.dedup_key,payload:s.payload,occurredAt:s.occurred_at??t,confidence:s.confidence});return{duplicate:!n.inserted,eventId:n.id}}var Do=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Fo=Xt.object({event_def_id:Xt.string().regex(Do,"must be a valid UUID v4")});async function Xn(o){o.post("/webhooks/events/:event_def_id",{schema:{tags:["Webhooks","Events"],summary:"Fire an event via webhook",description:"Ingest an event from an external system. Returns 200 with duplicate=true if the event was already received (dedup key match).",params:{type:"object",required:["event_def_id"],properties:{event_def_id:{type:"string",format:"uuid",description:"Event definition ID"}}}}},async(r,e)=>{let s=Fo.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid event_def_id: ${Xt.prettifyError(s.error)}`});let{event_def_id:t}=s.data,n=Z(t);if(!n||!n.enabled)return e.status(404).send({code:"NOT_FOUND",message:`Event def '${t}' not found or disabled`});if(n.sourceType!=="webhook")return e.status(400).send({code:"WRONG_SOURCE",message:`Event def '${t}' has source type '${n.sourceType}', not 'webhook'`});try{let a=Yn(n,r.body),i=a.duplicate?200:201;return e.status(i).send({ok:!0,event_id:a.eventId,duplicate:a.duplicate})}catch(a){let i=a instanceof Error?a.message:String(a);return e.status(400).send({code:"INVALID_ENVELOPE",message:i})}})}import{z as P}from"zod/v4";import{v4 as xo}from"uuid";var fe=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,jo=P.object({name:P.string().min(1).max(100),sourceType:P.enum(Et()),sourceConfig:P.record(P.string(),P.unknown()),enabled:P.boolean().optional().default(!0),description:P.string().max(500).optional()}),No=P.object({name:P.string().min(1).max(100).optional(),sourceType:P.enum(Et()).optional(),sourceConfig:P.record(P.string(),P.unknown()).optional(),enabled:P.boolean().optional(),description:P.string().max(500).optional()}),qo=P.object({payload:P.record(P.string(),P.unknown()).optional()});async function Zn(o){o.get("/event-defs",async(r,e)=>{let{sourceType:s,enabled:t}=r.query,n=Ke({sourceType:s,enabled:t!==void 0?t==="true":void 0});return e.send(n)}),o.post("/event-defs",async(r,e)=>{let s=jo.safeParse(r.body);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid event def: ${P.prettifyError(s.error)}`});let t=s.data,n=Pt(t.sourceType,t.sourceConfig);if(!n.ok){let i=n.error;return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid source config: ${i}`})}if(t.sourceType==="cron"){let{CronExpressionParser:i}=await import("cron-parser");try{i.parse(t.sourceConfig.cron)}catch{return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid cron expression: ${t.sourceConfig.cron}`})}}let a=Mr({id:xo(),name:t.name,sourceType:t.sourceType,sourceConfig:t.sourceConfig,enabled:t.enabled??!0,description:t.description});return Te(a),e.status(201).send(a)}),o.get("/event-defs/:id",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});let t=Z(s);return t?e.send(t):e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`})}),o.patch("/event-defs/:id",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});let t=Z(s);if(!t)return e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`});let n=No.safeParse(r.body);if(!n.success)return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid update: ${P.prettifyError(n.error)}`});let a=n.data;if(a.sourceType!==void 0||a.sourceConfig!==void 0){let p=Pt(a.sourceType??t.sourceType,a.sourceConfig??t.sourceConfig);if(!p.ok){let d=p.error;return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid source config: ${d}`})}}let i=a.enabled!==void 0&&a.enabled!==t.enabled;i&&t.enabled&&At(s,t.sourceType);let c=Ur(s,{name:a.name,sourceType:a.sourceType,sourceConfig:a.sourceConfig,enabled:a.enabled,description:a.description});return i&&c&&c.enabled&&Te(c),e.send(c)}),o.delete("/event-defs/:id",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});let t=Z(s);return t?(At(s,t.sourceType),Br(s),e.status(204).send()):e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`})}),o.post("/event-defs/:id/fire",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});let t=Z(s);if(!t)return e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`});let{test:n}=r.query,a=n==="true";if(t.sourceType!=="manual"&&!a)return e.status(400).send({code:"WRONG_SOURCE",message:`Can only fire manual event defs directly; this def has source type '${t.sourceType}'. Use ?test=true to dry-run.`});let i=qo.safeParse(r.body),c=i.success?i.data.payload:void 0;try{let p=a?Gr(t,c):Vr(t,c);return e.status(201).send({event_id:p.eventId,test:a})}catch(p){let d=p instanceof Error?p.message:String(p);return e.status(400).send({code:"ERROR",message:d})}}),o.get("/event-defs/:id/firings",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});if(!Z(s))return e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`});let{since:n,limit:a}=r.query,i=Lr({eventDefId:s,since:n??void 0,limit:a?Math.min(parseInt(a,10),500):50});return e.send(i)}),o.get("/event-defs/:id/dispatches",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});if(!Z(s))return e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`});let{limit:n,offset:a}=r.query,i=fr(s,n?Math.min(parseInt(n,10),200):20,a?Math.max(parseInt(a,10),0):0);return e.send(i)})}import{z as I}from"zod/v4";var Lo=I.object({status:I.string().optional(),limit:I.coerce.number().min(1).max(100).default(20),offset:I.coerce.number().min(0).default(0)}),tt=I.union([I.object({type:I.literal("session"),sessionId:I.string()}),I.object({type:I.literal("channel"),channelId:I.string(),chatId:I.string().optional()})]),Mo=I.object({input:I.string().min(1,"goal input is required"),deliverTo:I.array(tt).optional(),reportTo:I.array(tt).optional()}),Jn=I.object({id:I.string().min(1)}),Uo=I.object({name:I.string().min(1).optional(),description:I.string().optional(),status:I.enum(["active","paused","completed","failed"]).optional(),currentValue:I.number().optional(),budgetUsd:I.number().min(0).optional(),deliverTo:I.array(tt).optional(),reportTo:I.array(tt).optional()});async function ea(o){o.get("/goals",{schema:{tags:["Goals"],summary:"List goals",description:"List goals with optional status filter and pagination.",querystring:{type:"object",properties:{status:{type:"string",description:"Filter by goal status"},limit:{type:"integer",minimum:1,maximum:100,default:20},offset:{type:"integer",minimum:0,default:0}}},response:R.goalList}},async(r,e)=>{let s=Lo.safeParse(r.query);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(s.error)});let{status:t,limit:n,offset:a}=s.data;return{goals:js(t,n,a)}}),o.get("/goals/:id",{schema:{tags:["Goals"],summary:"Get goal by ID",description:"Retrieve a single goal by its ID, including metric tree and progress.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},response:R.goalDetail}},async(r,e)=>{let s=ce(r.params.id);return s?{goal:s}:e.status(404).send({code:"NOT_FOUND",message:"Goal not found"})}),o.post("/goals",{schema:{tags:["Goals"],summary:"Create a goal",description:"Create a new goal from a natural language input. The input is parsed, validated, and a metric tree is built.",body:{type:"object",required:["input"],properties:{input:{type:"string",minLength:1,description:"Natural language goal description"},deliverTo:{type:"array",items:{type:"object"},description:"Delivery targets (result output)"},reportTo:{type:"array",items:{type:"object"},description:"Report targets (status notifications)"}}},response:R.goalCreated}},async(r,e)=>{let s=Mo.safeParse(r.body);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(s.error)});let t=await _r(s.data.input);if(!t.validationResult.isValid)return e.status(400).send({code:"INVALID_GOAL",errors:t.validationResult.errors,warnings:t.validationResult.warnings});let n=Cr(t.goalState,s.data.deliverTo,s.data.reportTo);return Ar(n.id,n.metricType),e.status(201).send({goal:n})}),o.patch("/goals/:id",{schema:{tags:["Goals"],summary:"Update a goal",description:"Partially update a goal's name, description, status, currentValue, or budgetUsd.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",properties:{name:{type:"string",minLength:1},description:{type:"string"},status:{type:"string"},currentValue:{type:"number"},budgetUsd:{type:"number",minimum:0},deliverTo:{type:"array",items:{type:"object"},description:"Delivery targets (result output)"},reportTo:{type:"array",items:{type:"object"},description:"Report targets (status notifications)"}}},response:R.goalDetail}},async(r,e)=>{let s=Jn.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(s.error)});let t=Uo.safeParse(r.body);return t.success?ce(s.data.id)?(Be(s.data.id,{...t.data,updatedAt:Date.now()}),{goal:ce(s.data.id)}):e.status(404).send({code:"NOT_FOUND",message:"Goal not found"}):e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(t.error)})}),o.delete("/goals/:id",{schema:{tags:["Goals"],summary:"Delete a goal",description:"Delete a goal by ID.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=Jn.safeParse(r.params);return s.success?ce(s.data.id)?(Ns(s.data.id),{goalId:s.data.id,deleted:!0}):e.status(404).send({code:"NOT_FOUND",message:"Goal not found"}):e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(s.error)})})}import{z as _e}from"zod/v4";var Bo=_e.object({role:_e.string().optional(),taskType:_e.string().optional(),limit:_e.coerce.number().min(1).max(100).default(50)});async function ta(o){o.get("/strategies",{schema:{tags:["Strategies"],summary:"List strategies",description:"List agent strategies with optional role/taskType filter. Returns evolutionary strategy entries used for agent routing.",querystring:{type:"object",properties:{role:{type:"string",description:"Filter by role ID"},taskType:{type:"string",description:"Filter by task type"},limit:{type:"integer",minimum:1,maximum:100,default:50}}},response:R.strategyList}},async(r,e)=>{let s=Bo.safeParse(r.query);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:_e.prettifyError(s.error)});let{role:t,taskType:n,limit:a}=s.data,i;return t&&n?i=Ls.getStrategies(t,n):t?i=xs(t):i=Fs(a),{strategies:i.slice(0,a)}})}vs();Q();Is();import{z as J}from"zod/v4";async function sa(o){o.get("/config",{schema:{tags:["Config"],summary:"Get current configuration",description:"Returns the current server configuration with runtime-mutable vs restart-required indication for each setting.",response:R.configGet}},async(e,s)=>{let t=D(),n=Hr(),a=await zr(),i=[...Oe,...ct],c={},p=new Set(["anthropic.apiKey","server.apiKey"]);for(let d of i){let u=dt(t,d),h=Oe.includes(d);p.has(d)&&typeof u=="string"&&u.length>0&&(u=u.slice(0,5)+"****"),c[d]={value:u??null,mutable:h}}return{config:c,mutable:[...Oe],restartRequired:[...ct],sandbox:{platform:n.platform,available:a},osCapabilities:{registry:Rs(n.platform,a)}}}),o.patch("/config",{schema:{tags:["Config"],summary:"Update runtime-mutable configuration",description:"Updates configuration values that can be changed at runtime. Restart-required settings are rejected but valid mutable changes are still applied (partial success).",response:R.configPatch}},async(e,s)=>{let t=e.body;if(!t||typeof t!="object")return s.status(400).send({success:!1,updated:[],errors:["Request body must be a JSON object with config key-value pairs"],message:"Validation error"});let n=os(t,ue);if(n.updated.includes("logging.level")){let a=t["logging.level"];typeof a=="string"&&Fe(a)}if(n.updated.length>0){let a=D(),i=n.updated.map(c=>({path:c,value:dt(a,c)}));b.emit({type:"config_changed",changes:i})}return{success:n.errors.length===0,updated:n.updated,errors:n.errors,message:n.errors.length===0?`Updated ${n.updated.length} configuration value(s)`:`Updated ${n.updated.length} value(s); ${n.errors.length} rejected (restart required)`}}),o.get("/config/env-diff",async()=>{let e=je();return{diffs:ls(e),envFileExists:ds()!==null}}),o.post("/config/sync-to-env",async()=>{let e=je();return{success:!0,changed:us(e)}}),o.post("/config/load-from-env",async()=>{let e=ps();if(!e)return{success:!1,error:".env file not found"};let s=0;for(let[n,a]of Object.entries(e)){let i=Object.entries(pt).find(([,c])=>c===n)?.[0];i&&(ue(i,a),s++)}let t={};for(let[n,a]of Object.entries(e))n in pt||n.startsWith("ANTHROPIC_")||n.startsWith("ADAM_")||(t[n]=a);return Object.keys(t).length>0&&(ue("defaults.env",t),D().defaults.env=t,s+=Object.keys(t).length),De(je),{success:!0,updated:s}});let r=J.string().max(256).regex(/^[A-Za-z_][A-Za-z0-9_]*$/,"Env var key must match POSIX format: [A-Za-z_][A-Za-z0-9_]*").check(J.refine(e=>!e.startsWith("ANTHROPIC_"),"ANTHROPIC_* keys are managed in the Anthropic config section"));o.get("/config/env",{schema:{tags:["Config"],summary:"Get custom environment variables",description:"Returns global custom env vars (defaults.env). Sensitive values are masked."}},async()=>({env:D().defaults?.env??{}})),o.put("/config/env",{schema:{tags:["Config"],summary:"Replace all custom environment variables",description:"Full replacement of defaults.env. ANTHROPIC_* keys are rejected."}},async(e,s)=>{let n=J.record(r,J.string().max(4096)).check(J.refine(i=>Object.keys(i).length<=100,"Maximum 100 environment variables")).safeParse(e.body);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:J.prettifyError(n.error)});let a=n.data;return ue("defaults.env",a),D().defaults.env=a,b.emit({type:"config_changed",changes:[{path:"defaults.env",value:a}]}),{success:!0,count:Object.keys(a).length}}),o.patch("/config/env",{schema:{tags:["Config"],summary:"Partially update custom environment variables",description:"Add/update keys (string value) or delete keys (null value). ANTHROPIC_* keys are rejected."}},async(e,s)=>{let n=J.record(r,J.string().max(4096).nullable()).safeParse(e.body);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:J.prettifyError(n.error)});let a={...D().defaults?.env??{}};for(let[i,c]of Object.entries(n.data))c===null?delete a[i]:a[i]=c;return Object.keys(a).length>100?s.status(400).send({code:"VALIDATION_ERROR",message:"Maximum 100 environment variables"}):(ue("defaults.env",a),D().defaults.env=a,b.emit({type:"config_changed",changes:[{path:"defaults.env",value:a}]}),{success:!0,count:Object.keys(a).length})})}async function ra(o){o.get("/audit/posture",async(r,e)=>{let s=await rn();return e.send(s)})}async function na(o){o.get("/evolution-audit",{schema:{tags:["Evolution"],summary:"List evolution audit records",description:"Returns evolution audit log entries with optional role filter.",querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:100,default:20},offset:{type:"integer",minimum:0,default:0},roleId:{type:"string"}}}}},async(r,e)=>{let{limit:s=20,offset:t=0,roleId:n}=r.query;return n?Qr(n,s,t):Kr(s,t)})}import{z as k}from"zod/v4";var Wo=["active","archived"],Vo=k.object({source:k.object({type:k.enum(["tui","web","api","channel"]),channelId:k.string().optional(),chatId:k.string().optional()}),roleId:k.string().optional()}),Ce=k.object({id:k.string().uuid()}),Go=k.object({status:k.enum(Wo).optional(),limit:k.coerce.number().min(1).max(100).default(100),offset:k.coerce.number().min(0).default(0)}),$o=k.object({limit:k.coerce.number().min(1).max(200).default(50),offset:k.coerce.number().min(0).default(0)});async function aa(o){o.post("/chat/sessions",{schema:{tags:["Chat"],summary:"Create a chat session",body:{type:"object",required:["source"],properties:{source:{type:"object",required:["type"],properties:{type:{type:"string",enum:["tui","web","api","channel"]},channelId:{type:"string"},chatId:{type:"string"}}},roleId:{type:"string"}}}}},async(e,s)=>{let t=Vo.safeParse(e.body);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let{source:n,roleId:a}=t.data,i=He(n,a);return s.status(201).send({session:i})}),o.get("/chat/sessions",{schema:{tags:["Chat"],summary:"List chat sessions",querystring:{type:"object",properties:{status:{type:"string",enum:["active","archived"]},limit:{type:"integer",minimum:1,maximum:100,default:100},offset:{type:"integer",minimum:0,default:0}}}}},async(e,s)=>{let t=Go.safeParse(e.query);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let{status:n}=t.data;return{sessions:Tr(n)}}),o.get("/chat/sessions/:id",{schema:{tags:["Chat"],summary:"Get chat session with messages",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(e,s)=>{let t=Ce.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=B(t.data.id);if(!n)return s.status(404).send({code:"NOT_FOUND",message:"Session not found"});let a=Tt(n.id);return{session:n,messages:a}}),o.post("/chat/sessions/:id/archive",{schema:{tags:["Chat"],summary:"Archive a chat session",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(e,s)=>{let t=Ce.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=B(t.data.id);return n?(Rr(n.id),{sessionId:n.id,status:"archived"}):s.status(404).send({code:"NOT_FOUND",message:"Session not found"})}),o.post("/chat/sessions/:id/restore",{schema:{tags:["Chat"],summary:"Restore an archived session",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(e,s)=>{let t=Ce.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=Ir(t.data.id);return n?{session:n}:s.status(404).send({code:"NOT_FOUND",message:"Session not found"})}),o.delete("/chat/sessions/:id",{schema:{tags:["Chat"],summary:"Delete a chat session",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(e,s)=>{let t=Ce.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=B(t.data.id);return n?(kr(n.id),s.status(204).send()):s.status(404).send({code:"NOT_FOUND",message:"Session not found"})}),o.get("/chat/sessions/:id/messages",{schema:{tags:["Chat"],summary:"Get messages for a session",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50},offset:{type:"integer",minimum:0,default:0}}}}},async(e,s)=>{let t=Ce.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=B(t.data.id);if(!n)return s.status(404).send({code:"NOT_FOUND",message:"Session not found"});let a=$o.safeParse(e.query),{limit:i=50,offset:c=0}=a.success?a.data:{};return{messages:Tt(n.id,i,c)}});let r=k.object({content:k.string().min(1,"content is required"),source:k.object({type:k.enum(["tui","web","api","channel"]),channelId:k.string().optional(),chatId:k.string().optional()}),roleId:k.string().optional(),sessionId:k.string().uuid().optional()});o.post("/chat/messages",{schema:{tags:["Chat"],summary:"Send a chat message",description:"Send a message. Creates a session if no active session exists for the source. Returns sessionId, messageId, and response.",body:{type:"object",required:["content","source"],properties:{content:{type:"string",minLength:1},source:{type:"object",required:["type"],properties:{type:{type:"string",enum:["tui","web","api","channel"]},channelId:{type:"string"},chatId:{type:"string"}}},roleId:{type:"string"},sessionId:{type:"string"}}}}},async(e,s)=>{let t=r.safeParse(e.body);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let{content:n,source:a,roleId:i,sessionId:c}=t.data,p=await Je(n,a,i,c);return s.status(201).send(p)})}Q();var Ho=N("ws"),st=new Set,rt=[],zo=50;function Ko(o){rt.push(o),rt.length>zo&&rt.shift()}function ye(o){Ko(o);let r=JSON.stringify(o);for(let e of st)e.readyState===1&&e.send(r)}function oa(o){o.get("/chat/stream",{websocket:!0},(r,e)=>{st.add(r);for(let s of rt)r.readyState===1&&r.send(JSON.stringify(s));r.on("close",()=>{st.delete(r)}),r.on("error",s=>{Ho.error({error:s},"Chat WebSocket error"),st.delete(r)})}),b.on("session_created",r=>ye(r)),b.on("session_archived",r=>ye(r)),b.on("session_restored",r=>ye(r)),b.on("session_deleted",r=>ye(r)),b.on("chat_message",r=>ye(r)),b.on("task_complete_event",r=>ye(r))}Q();var q=N("channels"),nt=class{adapters=new Map;rateLimits=new Map;healthInterval;rateLimitPerMinute;constructor(r){this.rateLimitPerMinute=r?.rateLimitPerMinute??60}async addChannel(r,e){this.adapters.set(r.id,e),e.onMessage(s=>{this.handleInbound(r.id,s)}),r.enabled&&await this.connectChannel(r.id)}async removeChannel(r){let e=this.adapters.get(r);if(e){try{await e.disconnect()}catch(s){q.error({channelId:r,error:s},"Error disconnecting channel")}this.adapters.delete(r),this.rateLimits.delete(r)}}async connectChannel(r){let e=this.adapters.get(r);if(!e)throw new Error(`No adapter registered for channel ${r}`);try{me(r,"connecting"),await e.connect(),me(r,"connected"),q.info({channelId:r,platform:e.platform},"Channel connected")}catch(s){throw me(r,"error"),q.error({channelId:r,error:s},"Failed to connect channel"),s}}async disconnectChannel(r){let e=this.adapters.get(r);if(e)try{await e.disconnect(),me(r,"disconnected"),q.info({channelId:r},"Channel disconnected")}catch(s){q.error({channelId:r,error:s},"Error disconnecting channel")}}getChannelStatus(r){let e=this.adapters.get(r);return e?e.getStatus():"disconnected"}getChannelStatuses(){let r=new Map;for(let[e,s]of this.adapters)r.set(e,s.getStatus());return r}hasAdapter(r){return this.adapters.has(r)}async sendMessage(r,e,s){let t=this.adapters.get(r);if(!t)return q.warn({channelId:r},"No adapter for outbound message"),null;if(!this.checkRateLimit(r))return q.warn({channelId:r},"Rate limit exceeded, dropping outbound message"),null;try{return await t.sendMessage(e,s)}catch(n){return q.error({channelId:r,chatId:e,error:n},"Failed to send outbound message"),null}}checkRateLimit(r){let e=Date.now(),s=this.rateLimits.get(r);return!s||e-s.windowStart>=6e4?(this.rateLimits.set(r,{count:1,windowStart:e}),!0):s.count>=this.rateLimitPerMinute?!1:(s.count++,!0)}async handleInbound(r,e){if(e.source==="system"){q.debug({channelId:r},"Skipping system message (anti-loop)");return}try{let{isRecentlySent:t}=await import("./outbound-gateway-QRL36F7K.js"),n=e.channelMessageId??e.raw?.MsgId??"";if(n&&t(String(n))){q.debug({channelId:r,messageId:n},"Skipping delivery-sent message (anti-loop)");return}}catch{}if(!this.checkRateLimit(r)){q.warn({channelId:r,senderId:e.senderId},"Rate limit exceeded for inbound message");return}try{let{handleInboundForApproval:t}=await import("./approval-handler-HQO62WK2.js");if(await t(r,e.chatId,e.content)){q.debug({channelId:r,chatId:e.chatId},"Inbound message consumed as approval reply");return}}catch{}let s=ar(r);if(s?.allowedChatIds&&!s.allowedChatIds.includes(e.chatId)){q.debug({channelId:r,chatId:e.chatId},"Chat not in allowlist, ignoring");return}try{let t=await Je(e.content,{type:"channel",channelId:r,chatId:e.chatId},s?.linkedRoleId);q.info({channelId:r,chatId:e.chatId,sessionId:t.sessionId},"Inbound message routed to session")}catch(t){q.error({channelId:r,chatId:e.chatId,error:t},"Failed to route inbound message")}}startHealthMonitor(r=3e4){this.stopHealthMonitor(),this.healthInterval=setInterval(()=>{this.checkHealth()},r)}stopHealthMonitor(){this.healthInterval&&(clearInterval(this.healthInterval),this.healthInterval=void 0)}checkHealth(){for(let[r,e]of this.adapters){let s=e.getStatus();try{me(r,s)}catch{}}}async startAll(){let r=ke(!0);for(let e of r){let s=this.adapters.get(e.id);if(s&&s.getStatus()!=="connected")try{await this.connectChannel(e.id)}catch{}}this.startHealthMonitor()}async stopAll(){this.stopHealthMonitor();for(let r of this.adapters.keys())await this.disconnectChannel(r);this.adapters.clear(),this.rateLimits.clear()}_getAdapterCount(){return this.adapters.size}_getRateLimitEntry(r){return this.rateLimits.get(r)}};xe();Q();var W=N("watchdog"),at=null;function ia(o,r,e,s){if(!o.enabled){W.info("Watchdog disabled");return}let t=o.intervalMinutes*6e4;W.info({intervalMinutes:o.intervalMinutes},"Watchdog started"),at=setInterval(()=>{Qo(o,r,e,s)},t)}function ca(){at&&(clearInterval(at),at=null,W.info("Watchdog stopped"))}function Qo(o,r,e,s){let{rules:t}=o;if(t.managerHealthCheck.enabled){let n=t.managerHealthCheck.staleDurationMinutes*6e4,a=r.getLastActivityAt();if(Date.now()-a>n){let i=`ChatManager session stale (no activity for ${t.managerHealthCheck.staleDurationMinutes} min)`;if(W.warn(i),t.managerHealthCheck.action==="restart"){let c=r.getConsecutiveStaleCount()>0;r.restartSession(),c&&(W.fatal("ChatManager unrecoverable after session restart \u2014 exiting for supervisor restart"),process.exit(1))}else t.managerHealthCheck.action==="notify"&&s(i)}}if(!e.isHealthy()){let n="ExecutionPool is not healthy (stopped unexpectedly)";W.warn(n),s(n)}if(t.staleTasks.enabled){let n=t.staleTasks.maxPendingMinutes*6e4,i=G("pending").filter(c=>Date.now()-c.createdAt>n);if(i.length>0){let c=`${i.length} stale task(s) pending > ${t.staleTasks.maxPendingMinutes} min`;W.warn({count:i.length},c),t.staleTasks.action==="notify"&&s(c)}}if(t.staleRunningTasks?.enabled){let n=t.staleRunningTasks.maxRunningMinutes*6e4,i=G("running").filter(c=>{if(!c.startedAt||Date.now()-c.startedAt<n)return!1;try{let h=V().prepare("SELECT MAX(timestamp) as latest FROM step_logs WHERE task_id = ?").get(c.id)?.latest??c.startedAt;return Date.now()-h>n}catch{return!0}});if(i.length>0){let c=`${i.length} task(s) running with no activity for > ${t.staleRunningTasks.maxRunningMinutes} min \u2014 marking as failed`;W.warn({count:i.length,taskIds:i.map(p=>p.id)},c);for(let p of i)re(p.id,{status:"failed",error:`Watchdog timeout: no activity for > ${t.staleRunningTasks.maxRunningMinutes} min`,completedAt:Date.now()}),b.emit({type:"task_status_change",taskId:p.id,oldStatus:"running",newStatus:"failed"}),e.releaseSlot(p.id);s(c)}}if(t.dbMaintenance.enabled)try{let a=V().pragma("wal_checkpoint(PASSIVE)");W.debug({walSize:a},"WAL checkpoint")}catch(n){W.error({error:n},"DB health check failed")}if(t.artifactCleanup?.enabled)try{let n=t.artifactCleanup.ttlDays*24*60*60*1e3,a=t.artifactCleanup.orphanGcMinAgeHours*60*60*1e3,i=Date.now()-n,c=en(i),p=0;for(let d of c){let u=new Set(Zr(d).map(w=>w.id));p+=mr(d,u,a);let h=Jr(d);for(let w of h)w.blobPath&&(lr(w.blobPath),p++);ur(d)}c.length>0&&W.info({executions:c.length,files:p},"Workflow artifacts cleaned")}catch(n){W.error({error:n},"Workflow artifact cleanup failed")}}Q();var Ae=N("event-dispatcher"),da=!1,Zt=1e4,Yo=300*1e3,ee=new Map;function Xo(o){let r=Date.now(),e=ee.get(o);if(e!==void 0&&e>r)return!1;if(ee.size>=Zt){for(let[s,t]of ee)if(t<=r&&ee.delete(s),ee.size<Zt)break;if(ee.size>=Zt){let s=ee.keys().next().value;s!==void 0&&ee.delete(s)}}return ee.set(o,r+Yo),!0}function pa(){da||(b.on("event_fired",async({eventDefId:o,eventId:r,payload:e})=>{if(!Xo(r)){Ae.debug({eventDefId:o,eventId:r},"event_fired: duplicate suppressed by LRU");return}let s=Ge(!0).filter(t=>t.trigger.type==="event"&&t.trigger.eventDefId===o);if(s.length===0){Ae.debug({eventDefId:o,eventId:r},"event_fired: no matching templates");return}Ae.info({eventDefId:o,eventId:r,matchedCount:s.length},"event_fired: dispatching templates");for(let t of s)yr(t,{triggerContext:{eventId:r,payload:e}}).catch(n=>{Ae.error({templateId:t.id,eventId:r,error:n},"template dispatch failed")})}),da=!0,Ae.info("EventDispatcher started"))}import{z as j}from"zod";import{v4 as Zo}from"uuid";var Jo=j.object({eventType:j.enum(["task_complete","task_error","plan_approval_request","*"]),matchCriteria:j.object({templateId:j.string().optional(),roleId:j.string().optional(),promptPattern:j.string().optional(),taskStatus:j.string().optional()}).optional().default({}),target:j.object({type:j.enum(["channel","webhook"]),channelId:j.string().optional(),chatId:j.string().optional(),webhookUrl:j.string().optional()}),formatTemplate:j.string().optional(),maxPerMinute:j.number().int().min(1).max(60).optional().default(5),skipOriginChannel:j.boolean().optional().default(!0),enabled:j.boolean().optional().default(!0)});async function Jt(o){o.get("/delivery-rules",async(r,e)=>jr()),o.post("/delivery-rules",async(r,e)=>{let s=Jo.safeParse(r.body);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:j.prettifyError(s.error)});let t=s.data,n={id:Zo(),eventType:t.eventType,matchCriteria:t.matchCriteria,target:t.target,formatTemplate:t.formatTemplate,maxPerMinute:t.maxPerMinute,skipOriginChannel:t.skipOriginChannel,enabled:t.enabled,createdAt:Date.now()};return xr(n),e.status(201).send(n)}),o.put("/delivery-rules/:id",async(r,e)=>{if(!ze(r.params.id))return e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"});let t=r.body;return Nr(r.params.id,t),{id:r.params.id,updated:!0}}),o.delete("/delivery-rules/:id",async(r,e)=>ze(r.params.id)?(qr(r.params.id),{id:r.params.id,deleted:!0}):e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"})),o.get("/delivery-rules/:id/log",async(r,e)=>Bs(r.params.id)),o.post("/delivery-rules/:id/test",async(r,e)=>{let s=ze(r.params.id);if(!s)return e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"});let{getDeliveryEngine:t}=await import("./engine-5DHYHDAP.js"),n=t();if(!n)return e.status(503).send({code:"ENGINE_NOT_READY",message:"DeliveryEngine not initialized"});let a=`[TEST] Delivery rule test at ${new Date().toISOString()}`,{createDeliveryLog:i}=await import("./delivery-log-ACNJ66RD.js"),{v4:c}=await import("uuid"),{TTL_MS:p}=await import("./delivery-log-ACNJ66RD.js"),d={id:c(),ruleId:s.id,status:"pending",target:s.target,content:a,attempts:0,createdAt:Date.now(),expiresAt:Date.now()+p};i(d);try{return await n.attemptDeliveryPublic(d,s),{id:d.id,ruleId:s.id,status:"sent",content:a}}catch(u){let h=u instanceof Error?u.message:String(u);return e.status(500).send({code:"DELIVERY_FAILED",message:h,logId:d.id})}})}import{z as ae}from"zod/v4";var la=new We,ua=ae.object({id:ae.string().min(1)}),ei=ae.object({id:ae.string().min(1),stepId:ae.string().min(1)});async function ma(o){o.get("/workflow-executions",{schema:{tags:["Workflows"],summary:"List workflow executions",description:"List recent workflow executions, optionally filtered by templateId.",querystring:{type:"object",properties:{templateId:{type:"string",description:"Filter by template ID"},limit:{type:"number",default:50},offset:{type:"number",default:0}}}}},async r=>{let e=r.query;return{executions:gr(e.templateId,e.limit??50,e.offset??0)}}),o.get("/workflow-executions/:id",{schema:{tags:["Workflows"],summary:"Get workflow execution",description:"Get details of a specific workflow execution including step statuses.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=ua.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:ae.prettifyError(s.error)});let t=$e(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Workflow execution not found"});let n=Re(s.data.id);return{execution:t,stepTasks:n}}),o.post("/workflow-executions/:id/cancel",{schema:{tags:["Workflows"],summary:"Cancel a workflow execution",description:"Cancel all running/pending step tasks in a workflow execution.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=ua.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:ae.prettifyError(s.error)});let t=$e(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Workflow execution not found"});if(t.status!=="running")return e.status(400).send({code:"INVALID_STATE",message:`Cannot cancel workflow in status: ${t.status}`});let n=Re(s.data.id),a=new Set(["pending","running","queued","paused"]),i=0,c={...t.stepStatuses};for(let p of n)a.has(p.status)&&(la.cancelTask(p.id),p.stepId&&(c[p.stepId]={taskId:p.id,status:"cancelled",roleId:p.roleId,error:"Workflow cancelled"}),i++);return _t(s.data.id,{status:"cancelled",stepStatuses:c,completedAt:Date.now()}),b.emit({type:"workflow_status_change",executionId:s.data.id,templateId:t.templateId,status:"cancelled"}),{executionId:s.data.id,cancelled:i,total:n.length}}),o.post("/workflow-executions/:id/steps/:stepId/skip",{schema:{tags:["Workflows"],summary:"Skip a workflow step",description:"Mark a pending step as skipped without cancelling the whole workflow. Dependents of the skipped step will also be skipped.",params:{type:"object",required:["id","stepId"],properties:{id:{type:"string"},stepId:{type:"string"}}}}},async(r,e)=>{let s=ei.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:ae.prettifyError(s.error)});let t=$e(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Workflow execution not found"});let n=t.stepStatuses[s.data.stepId];if(!n)return e.status(404).send({code:"NOT_FOUND",message:"Step not found in workflow"});if(n.taskId){let i=O(n.taskId);i&&["pending","running","queued","paused"].includes(i.status)&&la.cancelTask(n.taskId)}let a={...t.stepStatuses};return a[s.data.stepId]={...n,status:"skipped",error:"Manually skipped"},_t(s.data.id,{stepStatuses:a}),{executionId:s.data.id,stepId:s.data.stepId,status:"skipped"}})}Q();ve();ve();import{existsSync as ot,copyFileSync as ti,mkdirSync as es,cpSync as si}from"fs";import{join as z}from"path";function ts(){es(F,{recursive:!0}),es(z(F,"logs"),{recursive:!0}),es(z(F,".claude"),{recursive:!0})}function ga(o=process.cwd()){ts();let r=[],e=[{from:z(o,"data","adam.db"),to:z(F,"adam.db"),label:"database"},{from:z(o,"adam.config.yaml"),to:z(F,"adam.config.yaml"),label:"config"},{from:z(o,".env"),to:z(F,".env"),label:".env"}];for(let{from:n,to:a,label:i}of e)ot(n)&&!ot(a)&&(ti(n,a),r.push(i));let s=z(o,".claude","plugins"),t=z(F,".claude","plugins");return ot(s)&&!ot(t)&&(si(s,t,{recursive:!0}),r.push("plugins")),r}vs();var C=N("adam");function ni(o){let r={...o};if(r.defaults&&typeof r.defaults=="object"){let e={...r.defaults};if(e.env&&typeof e.env=="object"){let s={...e.env};for(let t of Object.keys(s))s[t]&&(s[t]=s[t].slice(0,4)+"****");e.env=s}r.defaults=e}if(r.server&&typeof r.server=="object"){let e={...r.server};e.apiKey&&typeof e.apiKey=="string"&&(e.apiKey=e.apiKey.slice(0,4)+"****"),r.server=e}return r}async function ai(){ts();let o=ga();o.length>0&&console.log(`[adam] Migrated to ~/.adam/: ${o.join(", ")}`);let r=cn();C.info("Starting Adam Agent Server"),r.length>0&&C.info({files:r},"Loaded env files");let e=gs();ns(e),D().anthropic?.apiKey||process.env.ANTHROPIC_API_KEY||C.warn("ANTHROPIC_API_KEY not set \u2014 configure via Settings UI or ~/.adam/.env"),process.env.ANTHROPIC_BASE_URL&&C.info({url:process.env.ANTHROPIC_BASE_URL},"Using custom API base URL");let t=e.defaults?.claudeCodePath;try{if(!t){let{createRequire:va}=await import("module"),{dirname:Ra,join:Ia}=await import("path"),ka=va(import.meta.url).resolve("@anthropic-ai/claude-agent-sdk");t=Ia(Ra(ka),"cli.js")}let{execSync:v}=await import("child_process"),{chmodSync:L,accessSync:oe,constants:be}=await import("fs");try{oe(t,be.X_OK)}catch{C.info({path:t},"CLI not executable, fixing permissions"),L(t,493)}let ba=v(`"${t}" --version`,{timeout:5e3,encoding:"utf-8"}).trim();C.info({path:t,version:ba},"Claude Code CLI detected")}catch(v){let L=v;L.code==="ENOENT"?C.warn({path:t},"Claude Code CLI not found. Task execution will fail. Install: npm i -g @anthropic-ai/claude-code"):C.warn({path:t,error:(L.stderr?.trim()||String(v)).slice(0,200)},"Claude Code CLI check failed")}let a=V().prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all();C.info({tables:a.map(v=>v.name).join(", ")},"Database initialized");let i=fs(),c=bs(i);c>0&&C.info({count:c},"Seeded config DB from .env");let{getAllConfig:p}=await import("./config-KFPS7IEH.js");De(p);let d=D();d.logging?.level&&Fe(d.logging.level),C.info({config:ni(d)},"Config loaded (DB + defaults)");let u=Ut(),{getToolsFingerprint:h}=await import("./adam-tools-IAZSLWYB.js"),w=h(),y=u.sdkSessionId;if(y&&u.toolsFingerprint!==w&&(C.info({old:u.toolsFingerprint?.slice(0,40),new:w.slice(0,40)},"MCP tools changed \u2014 invalidating old SDK session"),_n(),y=void 0),we({toolsFingerprint:w}),y){let v=process.cwd();u.workspacePath&&u.workspacePath!==v&&(C.warn({serverCwd:v,saved:u.workspacePath},"Workspace mismatch"),C.warn("SDK session may not resume correctly due to cwd mismatch")),C.info({sessionId:y.slice(0,8)},"Recovering manager SDK session")}else C.info("No previous manager SDK session found, starting fresh");u.userTaskSessionId&&C.info({sessionId:u.userTaskSessionId.slice(0,8)},"Recovering user task session"),Cn(process.cwd());let{initializeDefaultRoles:f}=await import("./role-presets-DLO3XS54.js"),A=f();C.info({count:A.length},"Roles initialized");let le=D().execution??{maxConcurrent:3,pollIntervalMs:3e4},te=new Se(y),se=new xt(le.maxConcurrent);$n(te),await te.start(),await se.start();let Ee=G("running");if(Ee.length>0){C.warn({count:Ee.length},"Found orphaned running tasks from previous session \u2014 marking as failed");for(let v of Ee)re(v.id,{status:"failed",error:"Server restarted while task was running",completedAt:Date.now()})}let T=un(e,e.server.apiKey);await T.register(v=>bn(v)),await T.register(v=>vn(v,e)),await T.register(v=>Tn(v,e.server.apiKey)),await T.register(Fn),await T.register(Un),await T.register(ea),await T.register(ta);let K=new hr;br(K),await K.start(),on(),await T.register(v=>zn(v,K)),await T.register(Kn),await T.register(v=>Qn(v,K,process.env.ADAM_WEBHOOK_API_KEY)),await T.register(Xn),await T.register(Zn),await T.register(sa),await T.register(ra),await T.register(na),await T.register(aa);let he=new nt;cr(he),await T.register(dr),await T.register(oa),await T.register(v=>Sn(v,e.server.apiKey)),await T.register(Mn),await T.register(Jt),await T.register(ma),wr(),nn(),pa();for(let v of Ke({enabled:!0}))Te(v);await tn(),he.startHealthMonitor();try{let v=ke();for(let L of v)if(L.platform==="wechat"){let oe=L.config;if(oe.botToken){let be=new or(L.id,oe);he.addChannel(L,be)}}}catch(v){C.error({error:v},"Failed to register WeChat adapters at startup")}try{let v=ke();for(let L of v)if(L.platform==="discord"){let oe=L.config;if(oe.botToken){let be=new ir(L.id,{botToken:oe.botToken});he.addChannel(L,be)}}}catch(v){C.error({error:v},"Failed to register Discord adapters at startup")}let{host:ss,port:Pe}=e.server;await T.listen({host:ss,port:Pe}),C.info({host:ss,port:Pe},"Server listening");let ha=e.watchdog??cs.watchdog;ia(ha,te,se,v=>{C.warn({alert:v},"Watchdog alert")}),ms(v=>{b.emit({type:"log_event",timestamp:v.time??Date.now(),level:v.level??"info",component:v.component??"adam",msg:v.msg??""})}),ya(F,{recursive:!0}),ya(it(F,"logs"),{recursive:!0}),fa(it(F,"adam.port"),String(Pe)),e.server.apiKey&&fa(it(F,"adam.key"),e.server.apiKey,{mode:384}),process.send?.({type:"ready",port:Pe});let rs=async()=>{C.info("Shutting down"),ca(),sn(),Sr(),an(),await he.stopAll(),te.stop(),se.stop(),await K.stop(),await $r(),await T.close(),lt();try{ri(it(F,"adam.key"))}catch{}process.exit(0)};process.on("SIGINT",()=>{rs()}),process.on("SIGTERM",()=>{rs()})}ai().catch(o=>{C.fatal(o,"Fatal error"),process.exit(1)});
|
|
100
|
+
${l.length} \u4E2A\u5B50\u4EFB\u52A1\u5168\u90E8\u5B8C\u6210`;await this.routeGoalNotification(d,v,t.parentId)}}}}async getRoleName(r){try{let{getRole:e}=await import("./roles-ZYCFQMAY.js");return e(r)?.name}catch{return}}async deliverToChannel(r,e,s,t="reply",n){if(!r||!e){j.warn({channelId:r,chatId:e},"Cannot deliver to channel: missing channelId or chatId");return}try{let i=await lr().send({taskId:n,channelId:r,chatId:e,content:s,messageType:t});i.success?j.info({channelId:r,chatId:e.slice(0,12),messageType:t,taskId:n?.slice(0,8),messageId:i.messageId},"Delivered notification to channel"):j.warn({channelId:r,chatId:e.slice(0,12),messageType:t,taskId:n?.slice(0,8),error:i.error},"Channel delivery failed")}catch(a){j.error({error:a,channelId:r,chatId:e.slice(0,12)},"Failed to deliver to channel")}}async routeGoalNotification(r,e,s){let t=r.deliverTo??[],n=r.sourceSessionId;if(!(t.length===0&&!n)){for(let a of t)if(a.type==="session")try{let i=V(a.sessionId);i&&(X({id:de(),sessionId:a.sessionId,role:"assistant",content:e,source:i.source,createdAt:Date.now()}),J(a.sessionId),y.emit({type:"chat_message",sessionId:a.sessionId,message:{id:de(),sessionId:a.sessionId,role:"assistant",content:e,source:i.source,createdAt:Date.now()}}))}catch(i){j.error({error:i,goalId:s,targetSession:a.sessionId},"Failed to deliver Goal notification to session")}else a.type==="channel"&&await this.deliverToChannel(a.channelId,a.chatId??"",e);if(n&&!t.some(a=>a.type==="session"&&a.sessionId===n))try{let a=V(n);a&&(X({id:de(),sessionId:n,role:"assistant",content:e,source:a.source,createdAt:Date.now()}),J(n),y.emit({type:"chat_message",sessionId:n,message:{id:de(),sessionId:n,role:"assistant",content:e,source:a.source,createdAt:Date.now()}}))}catch(a){j.error({error:a,goalId:s,sessionId:n},"Failed to deliver Goal notification to source session")}}}getLastActivityAt(){return this.lastActivityAt}getConsecutiveStaleCount(){return this.consecutiveStaleCount}isHealthy(){return this.running}async restartSession(){j.warn("Restarting ChatManager session (Watchdog triggered)"),this.consecutiveStaleCount++,this.sessionId=void 0,Ze(void 0)}};import{v4 as Ht}from"uuid";Y();var Kt=q("message-handler"),$n=new Set;function Gn(o){$n.add(o),o.finally(()=>{$n.delete(o)})}async function ko(o,r){if(!(await import("./config-ZBNGRASI.js").then(t=>t.getChatConfig())).autoTitle)return;let s=["Generate a very short title (max 50 characters) for a chat session that started with this message:",`"${r.slice(0,200)}"`,"Respond with only the title, no quotes or explanation."].join(`
|
|
101
|
+
`);try{let n=(await Ls(s,"You are a concise title generator. Reply with only the title, max 50 characters.")).trim().slice(0,50);n.length>0&&Qs(o,{title:n})}catch{}}var zt=null;function Hn(o){zt=o}async function et(o,r,e,s){let t;s&&(t=V(s)),t||(t=Rr(r)),t||(t=Ke(r,e));let n=Ht(),a={id:n,sessionId:t.id,role:"user",content:o,source:r,createdAt:Date.now()};if(X(a),y.emit({type:"chat_message",sessionId:t.id,message:a}),t.messageCount===0&&Gn(ko(t.id,o)),J(t.id),At(t.id),zt){let i=t.id,c=t.source,p=(async()=>{try{let d=await zt.handleMessage(o,i,r),l={id:Ht(),sessionId:i,role:"assistant",content:d,source:r,createdAt:Date.now()};X(l),y.emit({type:"chat_message",sessionId:i,message:l}),J(i),At(i),c.type==="channel"&&c.channelId&&c.chatId&&(Kt.info({sessionId:i,sourceType:c.type,hasChannelId:!!c.channelId,hasResponse:!!d},"Chat response ready, checking channel delivery"),await To(c.channelId,c.chatId,d))}catch(d){(await import("./logger-WEXZORHP.js")).getLogger("message-handler").error({error:d,sessionId:i},"ChatManager response failed");let g={id:Ht(),sessionId:i,role:"assistant",content:`\u26A0\uFE0F \u5904\u7406\u5931\u8D25: ${d instanceof Error?d.message:String(d)}`,source:r,createdAt:Date.now()};X(g),y.emit({type:"chat_message",sessionId:i,message:g}),J(i)}})();Gn(p)}return{sessionId:t.id,messageId:n}}async function To(o,r,e){Kt.info({channelId:o,chatId:r.slice(0,12)},"Delivering chat response to channel");try{let{getOutboundGateway:s}=await import("./outbound-gateway-H7RFG6D2.js");await s().send({channelId:o,chatId:r,content:e,messageType:"reply"})}catch(s){Kt.error({error:s,channelId:o,chatId:r.slice(0,12)},"Channel delivery failed (non-fatal)")}}import{z as m}from"zod/v4";import{v4 as wo}from"uuid";var Kn=m.union([m.object({type:m.literal("session"),sessionId:m.string()}),m.object({type:m.literal("channel"),channelId:m.string(),chatId:m.string().optional()})]),So=m.object({id:m.string(),prompt:m.string(),dependsOn:m.array(m.string()).optional(),outputAs:m.string().optional(),roleId:m.string().optional(),autoSelectRole:m.boolean().optional(),requirements:Be.optional(),config:m.object({timeout:m.number().optional(),maxTurns:m.number().optional()}).optional()}),_o=m.discriminatedUnion("type",[m.object({type:m.literal("cron"),cron:m.string().min(1),event:m.undefined(),runAt:m.undefined(),eventDefId:m.undefined()}),m.object({type:m.literal("manual"),cron:m.undefined(),event:m.undefined(),runAt:m.undefined(),eventDefId:m.undefined()}),m.object({type:m.literal("once"),cron:m.undefined(),event:m.undefined(),runAt:m.string().min(1),eventDefId:m.undefined()}),m.object({type:m.literal("template_complete"),cron:m.undefined(),event:m.string().regex(/^template_complete:[\w-]+$/),runAt:m.undefined(),eventDefId:m.undefined()}),m.object({type:m.literal("workflow_complete"),cron:m.undefined(),event:m.string().regex(/^workflow_complete:[\w-]+$/),runAt:m.undefined(),eventDefId:m.undefined()}),m.object({type:m.literal("event"),cron:m.undefined(),event:m.undefined(),runAt:m.undefined(),eventDefId:m.string().uuid()})]),Qt=m.object({name:m.string().min(1),description:m.string().optional(),trigger:_o,steps:m.array(So).min(1),rolePreference:m.string().optional(),config:m.record(m.string(),m.unknown()).optional(),enabled:m.boolean().default(!0),goalIds:m.array(m.string()).optional(),deliverTo:m.array(Kn).optional(),reportTo:m.array(Kn).optional()}),Fd=Qt.transform(o=>({...o,deliverTo:o.deliverTo,reportTo:o.reportTo})),Co=Qt.partial().transform(o=>({...o,deliverTo:o.deliverTo,reportTo:o.reportTo})),_e=m.object({id:m.string().min(1)});async function zn(o,r){o.post("/task-templates",{schema:{tags:["Templates"],summary:"Create a task template",description:"Create a new task template with trigger (cron/manual/once/template_complete/workflow_complete) and execution steps. Cron-triggered templates are automatically scheduled.",body:{type:"object",required:["name","trigger","steps"],properties:{name:{type:"string",minLength:1},description:{type:"string"},trigger:{type:"object",required:["type"],properties:{type:{type:"string",enum:["cron","manual","once","template_complete","workflow_complete","event"]},cron:{type:"string",description:"Cron expression (required when type is cron)"},event:{type:"string",description:"Required when type is template_complete or workflow_complete; format 'type:<targetId>'"},eventDefId:{type:"string",description:"Event def ID (required when type is event)"},runAt:{type:"string",description:"ISO 8601 timestamp (required when type is once)"}}},steps:{type:"array",minItems:1,items:{type:"object",required:["id","prompt"],properties:{id:{type:"string"},prompt:{type:"string"},dependsOn:{type:"array",items:{type:"string"}},outputAs:{type:"string"},roleId:{type:"string",description:"Role ID for this step (overrides template rolePreference)"},autoSelectRole:{type:"boolean",description:"If true, Adam picks the best-fit role at dispatch time; mutually exclusive with roleId."},requirements:{type:"object",additionalProperties:!0,description:"Task requirements object (tools, paths, osCapabilities, network, plugins). Required when autoSelectRole is true."},config:{type:"object",properties:{timeout:{type:"number",description:"Step-level timeout override (seconds)"},maxTurns:{type:"number",description:"Step-level maxTurns override"}}}}}},rolePreference:{type:"string"},config:{type:"object",additionalProperties:!0},enabled:{type:"boolean",default:!0},goalIds:{type:"array",items:{type:"string"}},deliverTo:{type:"array",items:{type:"object"}},reportTo:{type:"array",items:{type:"object"}}}},response:R.templateCreated}},async(e,s)=>{let t=Qt.safeParse(e.body);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)});let n={id:wo(),...t.data,createdAt:Date.now()};try{rr(n)}catch(a){if(a instanceof St)return s.status(400).send({code:a.code,message:a.message,failingStepIds:a.failingStepIds});throw a}return n.enabled&&n.trigger.type==="cron"&&n.trigger.cron?await r.scheduleJob(n.id):n.enabled&&n.trigger.type==="once"&&n.trigger.runAt&&r.scheduleOnceJob(n.id),s.status(201).send({templateId:n.id})}),o.get("/task-templates",{schema:{tags:["Templates"],summary:"List task templates",description:"List all task templates, optionally filtering to enabled-only.",querystring:{type:"object",properties:{enabled:{type:"string",enum:["true","false"],description:"Filter to enabled templates only when 'true'"}}},response:R.templateList}},async e=>{let t=e.query.enabled==="true";return{templates:Ge(t)}}),o.get("/task-templates/:id",{schema:{tags:["Templates"],summary:"Get task template by ID",description:"Retrieve a single task template by its ID.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},response:R.templateDetail}},async(e,s)=>{let t=_e.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)});let n=Z(t.data.id);return n?{template:n}:s.status(404).send({code:"NOT_FOUND",message:"Template not found"})}),o.get("/task-templates/:id/dependents",{schema:{tags:["Templates"],summary:"Get delete dependents for a task template",description:"Returns counts of workflow_executions and tasks that reference this template. Used by the UI to present delete mode choices (template_only vs with_tasks).",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,s)=>{let t=_e.safeParse(e.params);return t.success?Z(t.data.id)?{dependents:_t(t.data.id)}:s.status(404).send({code:"NOT_FOUND",message:"Template not found"}):s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)})}),o.patch("/task-templates/:id",{schema:{tags:["Templates"],summary:"Update a task template",description:"Partially update a task template. Cron schedules are automatically rescheduled if the trigger changes.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",properties:{name:{type:"string",minLength:1},description:{type:"string"},trigger:{type:"object",properties:{type:{type:"string",enum:["cron","manual","once","template_complete","workflow_complete"]},cron:{type:"string",description:"Cron expression (required when type is cron)"},event:{type:"string",description:"Event string: 'template_complete:<id>' or 'workflow_complete:<id>'"},runAt:{type:"string",description:"ISO 8601 timestamp (required when type is once)"}}},steps:{type:"array",items:{type:"object"}},rolePreference:{type:"string"},config:{type:"object",additionalProperties:!0},enabled:{type:"boolean"},goalIds:{type:"array",items:{type:"string"}},deliverTo:{type:"array",items:{type:"object"}},reportTo:{type:"array",items:{type:"object"}}}},response:R.templateUpdated}},async(e,s)=>{let t=_e.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)});let n=Co.safeParse(e.body);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(n.error)});if(!Z(t.data.id))return s.status(404).send({code:"NOT_FOUND",message:"Template not found"});try{nr(t.data.id,n.data)}catch(c){if(c instanceof St)return s.status(400).send({code:c.code,message:c.message,failingStepIds:c.failingStepIds});throw c}await r.unscheduleJob(t.data.id);let i=Z(t.data.id);return i?.enabled&&i.trigger.type==="cron"&&i.trigger.cron?await r.scheduleJob(i.id):i?.enabled&&i.trigger.type==="once"&&i.trigger.runAt&&r.scheduleOnceJob(i.id),{templateId:t.data.id}}),o.delete("/task-templates/:id",{schema:{tags:["Templates"],summary:"Delete a task template",description:"Delete a task template by ID. Cron jobs are automatically unscheduled. Use ?mode=template_only (default) to keep tasks as orphans, or ?mode=with_tasks to also delete all tasks created by this template (including their role_scores and manager_decisions; chat_messages.task_id is nulled). workflow_executions are always removed.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},querystring:{type:"object",properties:{mode:{type:"string",enum:["template_only","with_tasks"],default:"template_only"}}},response:R.templateDeleted}},async(e,s)=>{let t=_e.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)});let n=e.query.mode??"template_only";if(n!=="template_only"&&n!=="with_tasks")return s.status(400).send({code:"VALIDATION_ERROR",message:`mode must be 'template_only' or 'with_tasks' (got '${n}')`});let a=n;if(!Z(t.data.id))return s.status(404).send({code:"NOT_FOUND",message:"Template not found"});let c=_t(t.data.id);await r.unscheduleJob(t.data.id);try{ar(t.data.id,a)}catch(p){let d=p;if(d.code==="SQLITE_CONSTRAINT_FOREIGNKEY")return s.status(409).send({code:"FOREIGN_KEY_CONFLICT",message:`Cannot delete template: a referenced row blocks removal. Detail: ${d.message??"unknown"}`});throw p}return{templateId:t.data.id,deleted:!0,mode:a,deletedCounts:{template:1,workflowExecutions:c.executionCount,tasks:a==="with_tasks"?c.taskCount:0}}}),o.post("/task-templates/:id/run",{schema:{tags:["Templates"],summary:"Run a task template",description:"Manually trigger execution of a task template regardless of its trigger type.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},response:R.templateRun}},async(e,s)=>{let t=_e.safeParse(e.params);return t.success?Z(t.data.id)?{executionId:await r.runNow(t.data.id),status:"started"}:s.status(404).send({code:"NOT_FOUND",message:"Template not found"}):s.status(400).send({code:"VALIDATION_ERROR",message:m.prettifyError(t.error)})})}import{z as P}from"zod/v4";Fs();var Yt=P.object({id:P.string().min(1)}),Ao=P.object({scope:P.enum(["user","project"]).optional(),cwd:P.string().optional()}),Eo=P.object({scope:P.enum(["user","project"]).optional(),cwd:P.string().optional()});async function Qn(o){o.get("/plugins",{schema:{tags:["Plugins"],summary:"List all installed plugins",querystring:{type:"object",properties:{scope:{type:"string",enum:["user","project","local"]}}}}},async e=>{let s=e.query,t=Ue({scope:s.scope}),n=It();return{plugins:t.map(a=>({...a,globalEnabled:n[a.id]??a.enabled}))}}),o.get("/plugins/:id",{schema:{tags:["Plugins"],summary:"Get plugin by ID",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,s)=>{let t=Yt.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)});let n=Ps(t.data.id);if(!n)return s.status(404).send({code:"NOT_FOUND",message:"Plugin not found"});let a=Es(n.installPath),i=It();return{plugin:{...n,globalEnabled:i[n.id]??n.enabled,manifest:a}}}),o.post("/plugins/:id/enable",{schema:{tags:["Plugins"],summary:"Enable a plugin globally",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,s)=>{let t=Yt.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)});if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude CLI not found. Plugin enable/disable requires the Claude Agent SDK CLI."});try{return Fr(t.data.id),{pluginId:t.data.id,enabled:!0}}catch(n){return s.status(500).send({code:"CLI_ERROR",message:n instanceof Error?n.message:"Enable failed"})}}),o.post("/plugins/:id/disable",{schema:{tags:["Plugins"],summary:"Disable a plugin globally",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,s)=>{let t=Yt.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)});if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude CLI not found. Plugin enable/disable requires the Claude Agent SDK CLI."});try{return xr(t.data.id),{pluginId:t.data.id,enabled:!1}}catch(n){return s.status(500).send({code:"CLI_ERROR",message:n instanceof Error?n.message:"Disable failed"})}}),o.get("/plugins/stats",{schema:{tags:["Plugins"],summary:"Get plugin usage statistics",querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50}}}}},async e=>{let s=e.query;return{stats:Zr(s.limit??50)}});let r=P.object({roleId:P.string().min(1)});o.get("/plugins/stats/role/:roleId",{schema:{tags:["Plugins"],summary:"Get plugin usage by role",params:{type:"object",required:["roleId"],properties:{roleId:{type:"string"}}}}},async(e,s)=>{let t=r.safeParse(e.params);return t.success?{roleId:t.data.roleId,stats:Xr(t.data.roleId)}:s.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)})}),o.get("/plugins/marketplace",{schema:{tags:["Marketplace"],summary:"List available marketplace plugins"}},async(e,s)=>{if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found. Install Claude Code to use marketplace features."});try{let t=Pr();return{available:t.available,installed:t.installed}}catch(t){return s.status(500).send({code:"CLI_ERROR",message:t instanceof Error?t.message:"CLI command failed"})}}),o.get("/plugins/marketplaces",{schema:{tags:["Marketplace"],summary:"List known marketplace sources"}},async()=>({sources:Os()})),o.post("/plugins/install/:name",{schema:{tags:["Marketplace"],summary:"Install a plugin",params:{type:"object",required:["name"],properties:{name:{type:"string"}}},body:{type:"object",properties:{scope:{type:"string",enum:["user","project"]},cwd:{type:"string"}}}}},async(e,s)=>{let n=P.object({name:P.string().min(1)}).safeParse(e.params);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(n.error)});let a=Ao.safeParse(e.body??{});if(!a.success)return s.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(a.error)});if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found"});try{return Or(n.data.name,a.data.scope??"user",a.data.cwd),{success:!0,pluginId:n.data.name}}catch(i){return s.status(500).send({code:"CLI_ERROR",message:i instanceof Error?i.message:"Install failed"})}}),o.post("/plugins/uninstall/:name",{schema:{tags:["Marketplace"],summary:"Uninstall a plugin",params:{type:"object",required:["name"],properties:{name:{type:"string"}}},body:{type:"object",properties:{scope:{type:"string",enum:["user","project"]},cwd:{type:"string"}}}}},async(e,s)=>{let n=P.object({name:P.string().min(1)}).safeParse(e.params);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(n.error)});let a=Eo.safeParse(e.body??{});if(!a.success)return s.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(a.error)});if(!ge())return s.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found"});try{return Dr(n.data.name,a.data.scope,a.data.cwd),{success:!0,pluginId:n.data.name}}catch(i){return s.status(500).send({code:"CLI_ERROR",message:i instanceof Error?i.message:"Uninstall failed"})}})}import{z as Xt}from"zod/v4";var Po=Xt.object({name:Xt.string().min(1)}),Oo="x-api-key";async function Yn(o,r,e){o.post("/webhooks/:name",{schema:{tags:["Webhooks"],summary:"Trigger a webhook",description:"Trigger a task template execution by name or ID. Requires X-API-Key header if API key is configured.",security:[{apiKey:[]}],params:{type:"object",required:["name"],properties:{name:{type:"string",description:"Template name or ID"}}},response:R.webhookTriggered}},async(s,t)=>{if(e&&s.headers[Oo]!==e)return t.status(401).send({code:"UNAUTHORIZED",message:"Invalid or missing API key"});let n=Po.safeParse(s.params);if(!n.success)return t.status(400).send({code:"VALIDATION_ERROR",message:Xt.prettifyError(n.error)});let{name:a}=n.data,i=Z(a);if(!i){let{listTaskTemplates:c}=await import("./task-templates-4KCZOUN5.js");i=c(!1).find(d=>d.name===a||d.id===a)}if(!i)return t.status(404).send({code:"NOT_FOUND",message:`Template '${a}' not found`});if(!i.enabled)return t.status(409).send({code:"DISABLED",message:`Template '${a}' is disabled`});try{let c=await r.runNow(i.id);return t.status(202).send({code:"ACCEPTED",message:`Template '${i.name}' triggered`,executionId:c,templateId:i.id})}catch(c){let p=c instanceof Error?c.message:String(c);return t.status(500).send({code:"EXECUTION_ERROR",message:p})}}),o.get("/webhooks",{schema:{tags:["Webhooks"],summary:"List available webhooks",description:"List all enabled task templates that can be triggered via webhook, along with auth requirements.",response:R.webhookList}},async()=>{let{listTaskTemplates:s}=await import("./task-templates-4KCZOUN5.js");return{webhooks:s(!0).map(n=>({name:n.id,displayName:n.name,description:n.description,tags:n.tags,trigger:`POST /webhooks/${n.id}`})),auth:e?"X-API-Key header required":"No auth configured"}})}import{z as Zt}from"zod/v4";import{z as K}from"zod/v4";var Do=K.object({type:K.string().regex(/^[a-z0-9._]+$/,"type must be lowercase alphanumeric with dots or underscores").max(100),payload:K.record(K.string(),K.unknown()),dedup_key:K.string().max(200),occurred_at:K.string().datetime().optional(),schema_version:K.number().int().positive().optional(),confidence:K.number().min(0).max(1).optional()});function Xn(o,r){let e=Do.safeParse(r);if(!e.success)throw new Error(`Invalid webhook envelope: ${K.prettifyError(e.error)}`);let s=e.data,t=new Date().toISOString(),n=Vr({eventDefId:o.id,type:s.type,source:`webhook-${o.id}`,dedupKey:s.dedup_key,payload:s.payload,occurredAt:s.occurred_at??t,confidence:s.confidence});return{duplicate:!n.inserted,eventId:n.id}}var Fo=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,xo=Zt.object({event_def_id:Zt.string().regex(Fo,"must be a valid UUID v4")});async function Zn(o){o.post("/webhooks/events/:event_def_id",{schema:{tags:["Webhooks","Events"],summary:"Fire an event via webhook",description:"Ingest an event from an external system. Returns 200 with duplicate=true if the event was already received (dedup key match).",params:{type:"object",required:["event_def_id"],properties:{event_def_id:{type:"string",format:"uuid",description:"Event definition ID"}}}}},async(r,e)=>{let s=xo.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid event_def_id: ${Zt.prettifyError(s.error)}`});let{event_def_id:t}=s.data,n=ee(t);if(!n||!n.enabled)return e.status(404).send({code:"NOT_FOUND",message:`Event def '${t}' not found or disabled`});if(n.sourceType!=="webhook")return e.status(400).send({code:"WRONG_SOURCE",message:`Event def '${t}' has source type '${n.sourceType}', not 'webhook'`});try{let a=Xn(n,r.body),i=a.duplicate?200:201;return e.status(i).send({ok:!0,event_id:a.eventId,duplicate:a.duplicate})}catch(a){let i=a instanceof Error?a.message:String(a);return e.status(400).send({code:"INVALID_ENVELOPE",message:i})}})}import{z as O}from"zod/v4";import{v4 as jo}from"uuid";var fe=/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,No=O.object({name:O.string().min(1).max(100),sourceType:O.enum(Pt()),sourceConfig:O.record(O.string(),O.unknown()),enabled:O.boolean().optional().default(!0),description:O.string().max(500).optional()}),qo=O.object({name:O.string().min(1).max(100).optional(),sourceType:O.enum(Pt()).optional(),sourceConfig:O.record(O.string(),O.unknown()).optional(),enabled:O.boolean().optional(),description:O.string().max(500).optional()}),Lo=O.object({payload:O.record(O.string(),O.unknown()).optional()});async function Jn(o){o.get("/event-defs",async(r,e)=>{let{sourceType:s,enabled:t}=r.query,n=Qe({sourceType:s,enabled:t!==void 0?t==="true":void 0});return e.send(n)}),o.post("/event-defs",async(r,e)=>{let s=No.safeParse(r.body);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid event def: ${O.prettifyError(s.error)}`});let t=s.data,n=Ot(t.sourceType,t.sourceConfig);if(!n.ok){let i=n.error;return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid source config: ${i}`})}if(t.sourceType==="cron"){let{CronExpressionParser:i}=await import("cron-parser");try{i.parse(t.sourceConfig.cron)}catch{return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid cron expression: ${t.sourceConfig.cron}`})}}let a=Ur({id:jo(),name:t.name,sourceType:t.sourceType,sourceConfig:t.sourceConfig,enabled:t.enabled??!0,description:t.description});return Te(a),e.status(201).send(a)}),o.get("/event-defs/:id",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});let t=ee(s);return t?e.send(t):e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`})}),o.patch("/event-defs/:id",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});let t=ee(s);if(!t)return e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`});let n=qo.safeParse(r.body);if(!n.success)return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid update: ${O.prettifyError(n.error)}`});let a=n.data;if(a.sourceType!==void 0||a.sourceConfig!==void 0){let p=Ot(a.sourceType??t.sourceType,a.sourceConfig??t.sourceConfig);if(!p.ok){let d=p.error;return e.status(400).send({code:"VALIDATION_ERROR",message:`Invalid source config: ${d}`})}}let i=a.enabled!==void 0&&a.enabled!==t.enabled;i&&t.enabled&&Et(s,t.sourceType);let c=Br(s,{name:a.name,sourceType:a.sourceType,sourceConfig:a.sourceConfig,enabled:a.enabled,description:a.description});return i&&c&&c.enabled&&Te(c),e.send(c)}),o.delete("/event-defs/:id",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});let t=ee(s);return t?(Et(s,t.sourceType),Wr(s),e.status(204).send()):e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`})}),o.post("/event-defs/:id/fire",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});let t=ee(s);if(!t)return e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`});let{test:n}=r.query,a=n==="true";if(t.sourceType!=="manual"&&!a)return e.status(400).send({code:"WRONG_SOURCE",message:`Can only fire manual event defs directly; this def has source type '${t.sourceType}'. Use ?test=true to dry-run.`});let i=Lo.safeParse(r.body),c=i.success?i.data.payload:void 0;try{let p=a?Gr(t,c):$r(t,c);return e.status(201).send({event_id:p.eventId,test:a})}catch(p){let d=p instanceof Error?p.message:String(p);return e.status(400).send({code:"ERROR",message:d})}}),o.get("/event-defs/:id/firings",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});if(!ee(s))return e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`});let{since:n,limit:a}=r.query,i=Mr({eventDefId:s,since:n??void 0,limit:a?Math.min(parseInt(a,10),500):50});return e.send(i)}),o.get("/event-defs/:id/dispatches",async(r,e)=>{let{id:s}=r.params;if(!fe.test(s))return e.status(400).send({code:"VALIDATION_ERROR",message:"Invalid UUID"});if(!ee(s))return e.status(404).send({code:"NOT_FOUND",message:`Event def '${s}' not found`});let{limit:n,offset:a}=r.query,i=yr(s,n?Math.min(parseInt(n,10),200):20,a?Math.max(parseInt(a,10),0):0);return e.send(i)})}import{z as I}from"zod/v4";var Mo=I.object({status:I.string().optional(),limit:I.coerce.number().min(1).max(100).default(20),offset:I.coerce.number().min(0).default(0)}),tt=I.union([I.object({type:I.literal("session"),sessionId:I.string()}),I.object({type:I.literal("channel"),channelId:I.string(),chatId:I.string().optional()})]),Uo=I.object({input:I.string().min(1,"goal input is required"),deliverTo:I.array(tt).optional(),reportTo:I.array(tt).optional()}),ea=I.object({id:I.string().min(1)}),Bo=I.object({name:I.string().min(1).optional(),description:I.string().optional(),status:I.enum(["active","paused","completed","failed"]).optional(),currentValue:I.number().optional(),budgetUsd:I.number().min(0).optional(),deliverTo:I.array(tt).optional(),reportTo:I.array(tt).optional()});async function ta(o){o.get("/goals",{schema:{tags:["Goals"],summary:"List goals",description:"List goals with optional status filter and pagination.",querystring:{type:"object",properties:{status:{type:"string",description:"Filter by goal status"},limit:{type:"integer",minimum:1,maximum:100,default:20},offset:{type:"integer",minimum:0,default:0}}},response:R.goalList}},async(r,e)=>{let s=Mo.safeParse(r.query);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(s.error)});let{status:t,limit:n,offset:a}=s.data;return{goals:Ns(t,n,a)}}),o.get("/goals/:id",{schema:{tags:["Goals"],summary:"Get goal by ID",description:"Retrieve a single goal by its ID, including metric tree and progress.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},response:R.goalDetail}},async(r,e)=>{let s=ie(r.params.id);return s?{goal:s}:e.status(404).send({code:"NOT_FOUND",message:"Goal not found"})}),o.post("/goals",{schema:{tags:["Goals"],summary:"Create a goal",description:"Create a new goal from a natural language input. The input is parsed, validated, and a metric tree is built.",body:{type:"object",required:["input"],properties:{input:{type:"string",minLength:1,description:"Natural language goal description"},deliverTo:{type:"array",items:{type:"object"},description:"Delivery targets (result output)"},reportTo:{type:"array",items:{type:"object"},description:"Report targets (status notifications)"}}},response:R.goalCreated}},async(r,e)=>{let s=Uo.safeParse(r.body);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(s.error)});let t=await Cr(s.data.input);if(!t.validationResult.isValid)return e.status(400).send({code:"INVALID_GOAL",errors:t.validationResult.errors,warnings:t.validationResult.warnings});let n=Ar(t.goalState,s.data.deliverTo,s.data.reportTo);return Er(n.id,n.metricType),e.status(201).send({goal:n})}),o.patch("/goals/:id",{schema:{tags:["Goals"],summary:"Update a goal",description:"Partially update a goal's name, description, status, currentValue, or budgetUsd.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}},body:{type:"object",properties:{name:{type:"string",minLength:1},description:{type:"string"},status:{type:"string"},currentValue:{type:"number"},budgetUsd:{type:"number",minimum:0},deliverTo:{type:"array",items:{type:"object"},description:"Delivery targets (result output)"},reportTo:{type:"array",items:{type:"object"},description:"Report targets (status notifications)"}}},response:R.goalDetail}},async(r,e)=>{let s=ea.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(s.error)});let t=Bo.safeParse(r.body);return t.success?ie(s.data.id)?(We(s.data.id,{...t.data,updatedAt:Date.now()}),{goal:ie(s.data.id)}):e.status(404).send({code:"NOT_FOUND",message:"Goal not found"}):e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(t.error)})}),o.delete("/goals/:id",{schema:{tags:["Goals"],summary:"Delete a goal",description:"Delete a goal by ID.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=ea.safeParse(r.params);return s.success?ie(s.data.id)?(qs(s.data.id),{goalId:s.data.id,deleted:!0}):e.status(404).send({code:"NOT_FOUND",message:"Goal not found"}):e.status(400).send({code:"VALIDATION_ERROR",message:I.prettifyError(s.error)})})}import{z as Ce}from"zod/v4";var Wo=Ce.object({role:Ce.string().optional(),taskType:Ce.string().optional(),limit:Ce.coerce.number().min(1).max(100).default(50)});async function sa(o){o.get("/strategies",{schema:{tags:["Strategies"],summary:"List strategies",description:"List agent strategies with optional role/taskType filter. Returns evolutionary strategy entries used for agent routing.",querystring:{type:"object",properties:{role:{type:"string",description:"Filter by role ID"},taskType:{type:"string",description:"Filter by task type"},limit:{type:"integer",minimum:1,maximum:100,default:50}}},response:R.strategyList}},async(r,e)=>{let s=Wo.safeParse(r.query);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:Ce.prettifyError(s.error)});let{role:t,taskType:n,limit:a}=s.data,i;return t&&n?i=Ms.getStrategies(t,n):t?i=js(t):i=xs(a),{strategies:i.slice(0,a)}})}Rs();Y();ks();import{z as te}from"zod/v4";async function ra(o){o.get("/config",{schema:{tags:["Config"],summary:"Get current configuration",description:"Returns the current server configuration with runtime-mutable vs restart-required indication for each setting.",response:R.configGet}},async(e,s)=>{let t=F(),n=Kr(),a=await zr(),i=[...De,...ct],c={},p=new Set(["anthropic.apiKey","server.apiKey"]);for(let d of i){let l=dt(t,d),g=De.includes(d);p.has(d)&&typeof l=="string"&&l.length>0&&(l=l.slice(0,5)+"****"),c[d]={value:l??null,mutable:g}}return{config:c,mutable:[...De],restartRequired:[...ct],sandbox:{platform:n.platform,available:a},osCapabilities:{registry:Is(n.platform,a)}}}),o.patch("/config",{schema:{tags:["Config"],summary:"Update runtime-mutable configuration",description:"Updates configuration values that can be changed at runtime. Restart-required settings are rejected but valid mutable changes are still applied (partial success).",response:R.configPatch}},async(e,s)=>{let t=e.body;if(!t||typeof t!="object")return s.status(400).send({success:!1,updated:[],errors:["Request body must be a JSON object with config key-value pairs"],message:"Validation error"});let n=is(t,ue);if(n.updated.includes("logging.level")){let a=t["logging.level"];typeof a=="string"&&xe(a)}if(n.updated.length>0){let a=F(),i=n.updated.map(c=>({path:c,value:dt(a,c)}));y.emit({type:"config_changed",changes:i})}return{success:n.errors.length===0,updated:n.updated,errors:n.errors,message:n.errors.length===0?`Updated ${n.updated.length} configuration value(s)`:`Updated ${n.updated.length} value(s); ${n.errors.length} rejected (restart required)`}}),o.get("/config/env-diff",async()=>{let e=Ne();return{diffs:us(e),envFileExists:ps()!==null}}),o.post("/config/sync-to-env",async()=>{let e=Ne();return{success:!0,changed:ms(e)}}),o.post("/config/load-from-env",async()=>{let e=ls();if(!e)return{success:!1,error:".env file not found"};let s=0;for(let[n,a]of Object.entries(e)){let i=Object.entries(pt).find(([,c])=>c===n)?.[0];i&&(ue(i,a),s++)}let t={};for(let[n,a]of Object.entries(e))n in pt||n.startsWith("ANTHROPIC_")||n.startsWith("ADAM_")||(t[n]=a);return Object.keys(t).length>0&&(ue("defaults.env",t),F().defaults.env=t,s+=Object.keys(t).length),Fe(Ne),{success:!0,updated:s}});let r=te.string().max(256).regex(/^[A-Za-z_][A-Za-z0-9_]*$/,"Env var key must match POSIX format: [A-Za-z_][A-Za-z0-9_]*").check(te.refine(e=>!e.startsWith("ANTHROPIC_"),"ANTHROPIC_* keys are managed in the Anthropic config section"));o.get("/config/env",{schema:{tags:["Config"],summary:"Get custom environment variables",description:"Returns global custom env vars (defaults.env). Sensitive values are masked."}},async()=>({env:F().defaults?.env??{}})),o.put("/config/env",{schema:{tags:["Config"],summary:"Replace all custom environment variables",description:"Full replacement of defaults.env. ANTHROPIC_* keys are rejected."}},async(e,s)=>{let n=te.record(r,te.string().max(4096)).check(te.refine(i=>Object.keys(i).length<=100,"Maximum 100 environment variables")).safeParse(e.body);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:te.prettifyError(n.error)});let a=n.data;return ue("defaults.env",a),F().defaults.env=a,y.emit({type:"config_changed",changes:[{path:"defaults.env",value:a}]}),{success:!0,count:Object.keys(a).length}}),o.patch("/config/env",{schema:{tags:["Config"],summary:"Partially update custom environment variables",description:"Add/update keys (string value) or delete keys (null value). ANTHROPIC_* keys are rejected."}},async(e,s)=>{let n=te.record(r,te.string().max(4096).nullable()).safeParse(e.body);if(!n.success)return s.status(400).send({code:"VALIDATION_ERROR",message:te.prettifyError(n.error)});let a={...F().defaults?.env??{}};for(let[i,c]of Object.entries(n.data))c===null?delete a[i]:a[i]=c;return Object.keys(a).length>100?s.status(400).send({code:"VALIDATION_ERROR",message:"Maximum 100 environment variables"}):(ue("defaults.env",a),F().defaults.env=a,y.emit({type:"config_changed",changes:[{path:"defaults.env",value:a}]}),{success:!0,count:Object.keys(a).length})})}async function na(o){o.get("/audit/posture",async(r,e)=>{let s=await nn();return e.send(s)})}async function aa(o){o.get("/evolution-audit",{schema:{tags:["Evolution"],summary:"List evolution audit records",description:"Returns evolution audit log entries with optional role filter.",querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:100,default:20},offset:{type:"integer",minimum:0,default:0},roleId:{type:"string"}}}}},async(r,e)=>{let{limit:s=20,offset:t=0,roleId:n}=r.query;return n?Yr(n,s,t):Qr(s,t)})}import{z as k}from"zod/v4";var Vo=["active","archived"],$o=k.object({source:k.object({type:k.enum(["tui","web","api","channel"]),channelId:k.string().optional(),chatId:k.string().optional()}),roleId:k.string().optional()}),Ae=k.object({id:k.string().uuid()}),Go=k.object({status:k.enum(Vo).optional(),limit:k.coerce.number().min(1).max(100).default(100),offset:k.coerce.number().min(0).default(0)}),Ho=k.object({limit:k.coerce.number().min(1).max(200).default(50),offset:k.coerce.number().min(0).default(0)});async function oa(o){o.post("/chat/sessions",{schema:{tags:["Chat"],summary:"Create a chat session",body:{type:"object",required:["source"],properties:{source:{type:"object",required:["type"],properties:{type:{type:"string",enum:["tui","web","api","channel"]},channelId:{type:"string"},chatId:{type:"string"}}},roleId:{type:"string"}}}}},async(e,s)=>{let t=$o.safeParse(e.body);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let{source:n,roleId:a}=t.data,i=Ke(n,a);return s.status(201).send({session:i})}),o.get("/chat/sessions",{schema:{tags:["Chat"],summary:"List chat sessions",querystring:{type:"object",properties:{status:{type:"string",enum:["active","archived"]},limit:{type:"integer",minimum:1,maximum:100,default:100},offset:{type:"integer",minimum:0,default:0}}}}},async(e,s)=>{let t=Go.safeParse(e.query);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let{status:n}=t.data;return{sessions:wr(n)}}),o.get("/chat/sessions/:id",{schema:{tags:["Chat"],summary:"Get chat session with messages",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(e,s)=>{let t=Ae.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=V(t.data.id);if(!n)return s.status(404).send({code:"NOT_FOUND",message:"Session not found"});let a=Tt(n.id);return{session:n,messages:a}}),o.post("/chat/sessions/:id/archive",{schema:{tags:["Chat"],summary:"Archive a chat session",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(e,s)=>{let t=Ae.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=V(t.data.id);return n?(Ir(n.id),{sessionId:n.id,status:"archived"}):s.status(404).send({code:"NOT_FOUND",message:"Session not found"})}),o.post("/chat/sessions/:id/restore",{schema:{tags:["Chat"],summary:"Restore an archived session",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(e,s)=>{let t=Ae.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=kr(t.data.id);return n?{session:n}:s.status(404).send({code:"NOT_FOUND",message:"Session not found"})}),o.delete("/chat/sessions/:id",{schema:{tags:["Chat"],summary:"Delete a chat session",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(e,s)=>{let t=Ae.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=V(t.data.id);return n?(Tr(n.id),s.status(204).send()):s.status(404).send({code:"NOT_FOUND",message:"Session not found"})}),o.get("/chat/sessions/:id/messages",{schema:{tags:["Chat"],summary:"Get messages for a session",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},querystring:{type:"object",properties:{limit:{type:"integer",minimum:1,maximum:200,default:50},offset:{type:"integer",minimum:0,default:0}}}}},async(e,s)=>{let t=Ae.safeParse(e.params);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let n=V(t.data.id);if(!n)return s.status(404).send({code:"NOT_FOUND",message:"Session not found"});let a=Ho.safeParse(e.query),{limit:i=50,offset:c=0}=a.success?a.data:{};return{messages:Tt(n.id,i,c)}});let r=k.object({content:k.string().min(1,"content is required"),source:k.object({type:k.enum(["tui","web","api","channel"]),channelId:k.string().optional(),chatId:k.string().optional()}),roleId:k.string().optional(),sessionId:k.string().uuid().optional()});o.post("/chat/messages",{schema:{tags:["Chat"],summary:"Send a chat message",description:"Send a message. Creates a session if no active session exists for the source. Returns sessionId, messageId, and response.",body:{type:"object",required:["content","source"],properties:{content:{type:"string",minLength:1},source:{type:"object",required:["type"],properties:{type:{type:"string",enum:["tui","web","api","channel"]},channelId:{type:"string"},chatId:{type:"string"}}},roleId:{type:"string"},sessionId:{type:"string"}}}}},async(e,s)=>{let t=r.safeParse(e.body);if(!t.success)return s.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(t.error)});let{content:n,source:a,roleId:i,sessionId:c}=t.data,p=await et(n,a,i,c);return s.status(201).send(p)})}Y();var Ko=q("ws"),st=new Set,rt=[],zo=50;function Qo(o){rt.push(o),rt.length>zo&&rt.shift()}function ye(o){Qo(o);let r=JSON.stringify(o);for(let e of st)e.readyState===1&&e.send(r)}function ia(o){o.get("/chat/stream",{websocket:!0},(r,e)=>{st.add(r);for(let s of rt)r.readyState===1&&r.send(JSON.stringify(s));r.on("close",()=>{st.delete(r)}),r.on("error",s=>{Ko.error({error:s},"Chat WebSocket error"),st.delete(r)})}),y.on("session_created",r=>ye(r)),y.on("session_archived",r=>ye(r)),y.on("session_restored",r=>ye(r)),y.on("session_deleted",r=>ye(r)),y.on("chat_message",r=>ye(r)),y.on("task_complete_event",r=>ye(r))}Y();var L=q("channels"),nt=class{adapters=new Map;rateLimits=new Map;healthInterval;rateLimitPerMinute;constructor(r){this.rateLimitPerMinute=r?.rateLimitPerMinute??60}async addChannel(r,e){this.adapters.set(r.id,e),e.onMessage(s=>{this.handleInbound(r.id,s)}),r.enabled&&await this.connectChannel(r.id)}async removeChannel(r){let e=this.adapters.get(r);if(e){try{await e.disconnect()}catch(s){L.error({channelId:r,error:s},"Error disconnecting channel")}this.adapters.delete(r),this.rateLimits.delete(r)}}async connectChannel(r){let e=this.adapters.get(r);if(!e)throw new Error(`No adapter registered for channel ${r}`);try{me(r,"connecting"),await e.connect(),me(r,"connected"),L.info({channelId:r,platform:e.platform},"Channel connected")}catch(s){throw me(r,"error"),L.error({channelId:r,error:s},"Failed to connect channel"),s}}async disconnectChannel(r){let e=this.adapters.get(r);if(e)try{await e.disconnect(),me(r,"disconnected"),L.info({channelId:r},"Channel disconnected")}catch(s){L.error({channelId:r,error:s},"Error disconnecting channel")}}getChannelStatus(r){let e=this.adapters.get(r);return e?e.getStatus():"disconnected"}getChannelStatuses(){let r=new Map;for(let[e,s]of this.adapters)r.set(e,s.getStatus());return r}hasAdapter(r){return this.adapters.has(r)}async sendMessage(r,e,s){let t=this.adapters.get(r);if(!t)return L.warn({channelId:r},"No adapter for outbound message"),null;if(!this.checkRateLimit(r))return L.warn({channelId:r},"Rate limit exceeded, dropping outbound message"),null;try{return await t.sendMessage(e,s)}catch(n){return L.error({channelId:r,chatId:e,error:n},"Failed to send outbound message"),null}}checkRateLimit(r){let e=Date.now(),s=this.rateLimits.get(r);return!s||e-s.windowStart>=6e4?(this.rateLimits.set(r,{count:1,windowStart:e}),!0):s.count>=this.rateLimitPerMinute?!1:(s.count++,!0)}async handleInbound(r,e){if(e.source==="system"){L.debug({channelId:r},"Skipping system message (anti-loop)");return}try{let{isRecentlySent:t}=await import("./outbound-gateway-H7RFG6D2.js"),n=e.channelMessageId??e.raw?.MsgId??"";if(n&&t(String(n))){L.debug({channelId:r,messageId:n},"Skipping delivery-sent message (anti-loop)");return}}catch{}if(!this.checkRateLimit(r)){L.warn({channelId:r,senderId:e.senderId},"Rate limit exceeded for inbound message");return}try{let{handleInboundForApproval:t}=await import("./approval-handler-PB7PSLUS.js");if(await t(r,e.chatId,e.content)){L.debug({channelId:r,chatId:e.chatId},"Inbound message consumed as approval reply");return}}catch{}let s=or(r);if(s?.allowedChatIds&&!s.allowedChatIds.includes(e.chatId)){L.debug({channelId:r,chatId:e.chatId},"Chat not in allowlist, ignoring");return}try{let t=await et(e.content,{type:"channel",channelId:r,chatId:e.chatId},s?.linkedRoleId);L.info({channelId:r,chatId:e.chatId,sessionId:t.sessionId},"Inbound message routed to session")}catch(t){L.error({channelId:r,chatId:e.chatId,error:t},"Failed to route inbound message")}}startHealthMonitor(r=3e4){this.stopHealthMonitor(),this.healthInterval=setInterval(()=>{this.checkHealth()},r)}stopHealthMonitor(){this.healthInterval&&(clearInterval(this.healthInterval),this.healthInterval=void 0)}checkHealth(){for(let[r,e]of this.adapters){let s=e.getStatus();try{me(r,s)}catch{}}}async startAll(){let r=ke(!0);for(let e of r){let s=this.adapters.get(e.id);if(s&&s.getStatus()!=="connected")try{await this.connectChannel(e.id)}catch{}}this.startHealthMonitor()}async stopAll(){this.stopHealthMonitor();for(let r of this.adapters.keys())await this.disconnectChannel(r);this.adapters.clear(),this.rateLimits.clear()}_getAdapterCount(){return this.adapters.size}_getRateLimitEntry(r){return this.rateLimits.get(r)}};je();Y();var $=q("watchdog"),at=null;function ca(o,r,e,s){if(!o.enabled){$.info("Watchdog disabled");return}let t=o.intervalMinutes*6e4;$.info({intervalMinutes:o.intervalMinutes},"Watchdog started"),at=setInterval(()=>{Yo(o,r,e,s)},t)}function da(){at&&(clearInterval(at),at=null,$.info("Watchdog stopped"))}function Yo(o,r,e,s){let{rules:t}=o;if(t.managerHealthCheck.enabled){let n=t.managerHealthCheck.staleDurationMinutes*6e4,a=r.getLastActivityAt();if(Date.now()-a>n){let i=`ChatManager session stale (no activity for ${t.managerHealthCheck.staleDurationMinutes} min)`;if($.warn(i),t.managerHealthCheck.action==="restart"){let c=r.getConsecutiveStaleCount()>0;r.restartSession(),c&&($.fatal("ChatManager unrecoverable after session restart \u2014 exiting for supervisor restart"),process.exit(1))}else t.managerHealthCheck.action==="notify"&&s(i)}}if(!e.isHealthy()){let n="ExecutionPool is not healthy (stopped unexpectedly)";$.warn(n),s(n)}if(t.staleTasks.enabled){let n=t.staleTasks.maxPendingMinutes*6e4,i=H("pending").filter(c=>Date.now()-c.createdAt>n);if(i.length>0){let c=`${i.length} stale task(s) pending > ${t.staleTasks.maxPendingMinutes} min`;$.warn({count:i.length},c),t.staleTasks.action==="notify"&&s(c)}}if(t.staleRunningTasks?.enabled){let n=t.staleRunningTasks.maxRunningMinutes*6e4,i=H("running").filter(c=>{if(!c.startedAt||Date.now()-c.startedAt<n)return!1;try{let g=G().prepare("SELECT MAX(timestamp) as latest FROM step_logs WHERE task_id = ?").get(c.id)?.latest??c.startedAt;return Date.now()-g>n}catch{return!0}});if(i.length>0){let c=`${i.length} task(s) running with no activity for > ${t.staleRunningTasks.maxRunningMinutes} min \u2014 marking as failed`;$.warn({count:i.length,taskIds:i.map(p=>p.id)},c);for(let p of i)re(p.id,{status:"failed",error:`Watchdog timeout: no activity for > ${t.staleRunningTasks.maxRunningMinutes} min`,completedAt:Date.now()}),y.emit({type:"task_status_change",taskId:p.id,oldStatus:"running",newStatus:"failed"}),e.releaseSlot(p.id);s(c)}}if(t.dbMaintenance.enabled)try{let a=G().pragma("wal_checkpoint(PASSIVE)");$.debug({walSize:a},"WAL checkpoint")}catch(n){$.error({error:n},"DB health check failed")}if(t.artifactCleanup?.enabled)try{let n=t.artifactCleanup.ttlDays*24*60*60*1e3,a=t.artifactCleanup.orphanGcMinAgeHours*60*60*1e3,i=Date.now()-n,c=tn(i),p=0;for(let d of c){let l=new Set(Jr(d).map(b=>b.id));p+=gr(d,l,a);let g=en(d);for(let b of g)b.blobPath&&(ur(b.blobPath),p++);mr(d)}c.length>0&&$.info({executions:c.length,files:p},"Workflow artifacts cleaned")}catch(n){$.error({error:n},"Workflow artifact cleanup failed")}}Y();var Ee=q("event-dispatcher"),pa=!1,Jt=1e4,Xo=300*1e3,se=new Map;function Zo(o){let r=Date.now(),e=se.get(o);if(e!==void 0&&e>r)return!1;if(se.size>=Jt){for(let[s,t]of se)if(t<=r&&se.delete(s),se.size<Jt)break;if(se.size>=Jt){let s=se.keys().next().value;s!==void 0&&se.delete(s)}}return se.set(o,r+Xo),!0}function la(){pa||(y.on("event_fired",async({eventDefId:o,eventId:r,payload:e})=>{if(!Zo(r)){Ee.debug({eventDefId:o,eventId:r},"event_fired: duplicate suppressed by LRU");return}let s=Ge(!0).filter(t=>t.trigger.type==="event"&&t.trigger.eventDefId===o);if(s.length===0){Ee.debug({eventDefId:o,eventId:r},"event_fired: no matching templates");return}Ee.info({eventDefId:o,eventId:r,matchedCount:s.length},"event_fired: dispatching templates");for(let t of s)hr(t,{triggerContext:{eventId:r,payload:e}}).catch(n=>{Ee.error({templateId:t.id,eventId:r,error:n},"template dispatch failed")})}),pa=!0,Ee.info("EventDispatcher started"))}import{z as N}from"zod";import{v4 as Jo}from"uuid";var ei=N.object({eventType:N.enum(["task_complete","task_error","plan_approval_request","*"]),matchCriteria:N.object({templateId:N.string().optional(),roleId:N.string().optional(),promptPattern:N.string().optional(),taskStatus:N.string().optional()}).optional().default({}),target:N.object({type:N.enum(["channel","webhook"]),channelId:N.string().optional(),chatId:N.string().optional(),webhookUrl:N.string().optional()}),formatTemplate:N.string().optional(),maxPerMinute:N.number().int().min(1).max(60).optional().default(5),skipOriginChannel:N.boolean().optional().default(!0),enabled:N.boolean().optional().default(!0)});async function es(o){o.get("/delivery-rules",async(r,e)=>Nr()),o.post("/delivery-rules",async(r,e)=>{let s=ei.safeParse(r.body);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:N.prettifyError(s.error)});let t=s.data,n={id:Jo(),eventType:t.eventType,matchCriteria:t.matchCriteria,target:t.target,formatTemplate:t.formatTemplate,maxPerMinute:t.maxPerMinute,skipOriginChannel:t.skipOriginChannel,enabled:t.enabled,createdAt:Date.now()};return jr(n),e.status(201).send(n)}),o.put("/delivery-rules/:id",async(r,e)=>{if(!ze(r.params.id))return e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"});let t=r.body;return qr(r.params.id,t),{id:r.params.id,updated:!0}}),o.delete("/delivery-rules/:id",async(r,e)=>ze(r.params.id)?(Lr(r.params.id),{id:r.params.id,deleted:!0}):e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"})),o.get("/delivery-rules/:id/log",async(r,e)=>Ws(r.params.id)),o.post("/delivery-rules/:id/test",async(r,e)=>{let s=ze(r.params.id);if(!s)return e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"});let{getDeliveryEngine:t}=await import("./engine-6K4RG644.js"),n=t();if(!n)return e.status(503).send({code:"ENGINE_NOT_READY",message:"DeliveryEngine not initialized"});let a=`[TEST] Delivery rule test at ${new Date().toISOString()}`,{createDeliveryLog:i}=await import("./delivery-log-AC476GX7.js"),{v4:c}=await import("uuid"),{TTL_MS:p}=await import("./delivery-log-AC476GX7.js"),d={id:c(),ruleId:s.id,status:"pending",target:s.target,content:a,attempts:0,createdAt:Date.now(),expiresAt:Date.now()+p};i(d);try{return await n.attemptDeliveryPublic(d,s),{id:d.id,ruleId:s.id,status:"sent",content:a}}catch(l){let g=l instanceof Error?l.message:String(l);return e.status(500).send({code:"DELIVERY_FAILED",message:g,logId:d.id})}})}import{z as ne}from"zod/v4";var ua=new Ve,ma=ne.object({id:ne.string().min(1)}),ti=ne.object({id:ne.string().min(1),stepId:ne.string().min(1)});async function ga(o){o.get("/workflow-executions",{schema:{tags:["Workflows"],summary:"List workflow executions",description:"List recent workflow executions, optionally filtered by templateId.",querystring:{type:"object",properties:{templateId:{type:"string",description:"Filter by template ID"},limit:{type:"number",default:50},offset:{type:"number",default:0}}}}},async r=>{let e=r.query;return{executions:fr(e.templateId,e.limit??50,e.offset??0)}}),o.get("/workflow-executions/:id",{schema:{tags:["Workflows"],summary:"Get workflow execution",description:"Get details of a specific workflow execution including step statuses.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=ma.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:ne.prettifyError(s.error)});let t=He(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Workflow execution not found"});let n=Re(s.data.id);return{execution:t,stepTasks:n}}),o.post("/workflow-executions/:id/cancel",{schema:{tags:["Workflows"],summary:"Cancel a workflow execution",description:"Cancel all running/pending step tasks in a workflow execution.",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(r,e)=>{let s=ma.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:ne.prettifyError(s.error)});let t=He(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Workflow execution not found"});if(t.status!=="running")return e.status(400).send({code:"INVALID_STATE",message:`Cannot cancel workflow in status: ${t.status}`});let n=Re(s.data.id),a=new Set(["pending","running","queued","paused"]),i=0,c={...t.stepStatuses};for(let p of n)a.has(p.status)&&(ua.cancelTask(p.id),p.stepId&&(c[p.stepId]={taskId:p.id,status:"cancelled",roleId:p.roleId,error:"Workflow cancelled"}),i++);return Ct(s.data.id,{status:"cancelled",stepStatuses:c,completedAt:Date.now()}),y.emit({type:"workflow_status_change",executionId:s.data.id,templateId:t.templateId,status:"cancelled"}),{executionId:s.data.id,cancelled:i,total:n.length}}),o.post("/workflow-executions/:id/steps/:stepId/skip",{schema:{tags:["Workflows"],summary:"Skip a workflow step",description:"Mark a pending step as skipped without cancelling the whole workflow. Dependents of the skipped step will also be skipped.",params:{type:"object",required:["id","stepId"],properties:{id:{type:"string"},stepId:{type:"string"}}}}},async(r,e)=>{let s=ti.safeParse(r.params);if(!s.success)return e.status(400).send({code:"VALIDATION_ERROR",message:ne.prettifyError(s.error)});let t=He(s.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Workflow execution not found"});let n=t.stepStatuses[s.data.stepId];if(!n)return e.status(404).send({code:"NOT_FOUND",message:"Step not found in workflow"});if(n.taskId){let i=D(n.taskId);i&&["pending","running","queued","paused"].includes(i.status)&&ua.cancelTask(n.taskId)}let a={...t.stepStatuses};return a[s.data.stepId]={...n,status:"skipped",error:"Manually skipped"},Ct(s.data.id,{stepStatuses:a}),{executionId:s.data.id,stepId:s.data.stepId,status:"skipped"}})}Y();ve();ve();import{existsSync as ot,copyFileSync as si,mkdirSync as ts,cpSync as ri}from"fs";import{join as z}from"path";function ss(){ts(x,{recursive:!0}),ts(z(x,"logs"),{recursive:!0}),ts(z(x,".claude"),{recursive:!0})}function fa(o=process.cwd()){ss();let r=[],e=[{from:z(o,"data","adam.db"),to:z(x,"adam.db"),label:"database"},{from:z(o,"adam.config.yaml"),to:z(x,"adam.config.yaml"),label:"config"},{from:z(o,".env"),to:z(x,".env"),label:".env"}];for(let{from:n,to:a,label:i}of e)ot(n)&&!ot(a)&&(si(n,a),r.push(i));let s=z(o,".claude","plugins"),t=z(x,".claude","plugins");return ot(s)&&!ot(t)&&(ri(s,t,{recursive:!0}),r.push("plugins")),r}Rs();var A=q("adam");function ai(o){let r={...o};if(r.defaults&&typeof r.defaults=="object"){let e={...r.defaults};if(e.env&&typeof e.env=="object"){let s={...e.env};for(let t of Object.keys(s))s[t]&&(s[t]=s[t].slice(0,4)+"****");e.env=s}r.defaults=e}if(r.server&&typeof r.server=="object"){let e={...r.server};e.apiKey&&typeof e.apiKey=="string"&&(e.apiKey=e.apiKey.slice(0,4)+"****"),r.server=e}return r}async function oi(){ss();let o=fa();o.length>0&&console.log(`[adam] Migrated to ~/.adam/: ${o.join(", ")}`);let r=dn();A.info("Starting Adam Agent Server"),r.length>0&&A.info({files:r},"Loaded env files");let e=fs();as(e),F().anthropic?.apiKey||process.env.ANTHROPIC_API_KEY||A.warn("ANTHROPIC_API_KEY not set \u2014 configure via Settings UI or ~/.adam/.env"),process.env.ANTHROPIC_BASE_URL&&A.info({url:process.env.ANTHROPIC_BASE_URL},"Using custom API base URL");let t=e.defaults?.claudeCodePath;try{if(!t){let{createRequire:Ra}=await import("module"),{dirname:Ia,join:ka}=await import("path"),Ta=Ra(import.meta.url).resolve("@anthropic-ai/claude-agent-sdk");t=ka(Ia(Ta),"cli.js")}let{execSync:h}=await import("child_process"),{chmodSync:M,accessSync:ae,constants:be}=await import("fs");try{ae(t,be.X_OK)}catch{A.info({path:t},"CLI not executable, fixing permissions"),M(t,493)}let va=h(`"${t}" --version`,{timeout:5e3,encoding:"utf-8"}).trim();A.info({path:t,version:va},"Claude Code CLI detected")}catch(h){let M=h;M.code==="ENOENT"?A.warn({path:t},"Claude Code CLI not found. Task execution will fail. Install: npm i -g @anthropic-ai/claude-code"):A.warn({path:t,error:(M.stderr?.trim()||String(h)).slice(0,200)},"Claude Code CLI check failed")}let a=G().prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all();A.info({tables:a.map(h=>h.name).join(", ")},"Database initialized");let i=ys(),c=vs(i);c>0&&A.info({count:c},"Seeded config DB from .env");let{getAllConfig:p}=await import("./config-HBQPBIWL.js");Fe(p);let d=F();d.logging?.level&&xe(d.logging.level),A.info({config:ai(d)},"Config loaded (DB + defaults)");let l=Bt(),{getToolsFingerprint:g}=await import("./adam-tools-V5LPU47X.js"),b=g(),E=l.sdkSessionId;if(E&&l.toolsFingerprint!==b&&(A.info({old:l.toolsFingerprint?.slice(0,40),new:b.slice(0,40)},"MCP tools changed \u2014 invalidating old SDK session"),Cn(),E=void 0),we({toolsFingerprint:b}),E){let h=process.cwd();l.workspacePath&&l.workspacePath!==h&&(A.warn({serverCwd:h,saved:l.workspacePath},"Workspace mismatch"),A.warn("SDK session may not resume correctly due to cwd mismatch")),A.info({sessionId:E.slice(0,8)},"Recovering manager SDK session")}else A.info("No previous manager SDK session found, starting fresh");l.userTaskSessionId&&A.info({sessionId:l.userTaskSessionId.slice(0,8)},"Recovering user task session"),An(process.cwd());let{initializeDefaultRoles:v}=await import("./role-presets-XAEOYEAW.js"),T=v();A.info({count:T.length},"Roles initialized");let W=F().execution??{maxConcurrent:3,pollIntervalMs:3e4},pe=new Se(E),le=new jt(W.maxConcurrent);Hn(pe),await pe.start(),await le.start();let Pe=H("running");if(Pe.length>0){A.warn({count:Pe.length},"Found orphaned running tasks from previous session \u2014 marking as failed");for(let h of Pe)re(h.id,{status:"failed",error:"Server restarted while task was running",completedAt:Date.now()})}let S=mn(e,e.server.apiKey);await S.register(h=>vn(h)),await S.register(h=>Rn(h,e)),await S.register(h=>wn(h,e.server.apiKey)),await S.register(xn),await S.register(Bn),await S.register(ta),await S.register(sa);let Q=new br;vr(Q),await Q.start(),cn(),await S.register(h=>zn(h,Q)),await S.register(Qn),await S.register(h=>Yn(h,Q,process.env.ADAM_WEBHOOK_API_KEY)),await S.register(Zn),await S.register(Jn),await S.register(ra),await S.register(na),await S.register(aa),await S.register(oa);let he=new nt;dr(he),await S.register(pr),await S.register(ia),await S.register(h=>_n(h,e.server.apiKey)),await S.register(Un),await S.register(es),await S.register(ga),Sr(),an(),la();for(let h of Qe({enabled:!0}))Te(h);await sn(),he.startHealthMonitor();try{let h=ke();for(let M of h)if(M.platform==="wechat"){let ae=M.config;if(ae.botToken){let be=new ir(M.id,ae);he.addChannel(M,be)}}}catch(h){A.error({error:h},"Failed to register WeChat adapters at startup")}try{let h=ke();for(let M of h)if(M.platform==="discord"){let ae=M.config;if(ae.botToken){let be=new cr(M.id,{botToken:ae.botToken});he.addChannel(M,be)}}}catch(h){A.error({error:h},"Failed to register Discord adapters at startup")}let{host:rs,port:Oe}=e.server;await S.listen({host:rs,port:Oe}),A.info({host:rs,port:Oe},"Server listening");let ba=e.watchdog??ds.watchdog;ca(ba,pe,le,h=>{A.warn({alert:h},"Watchdog alert")}),gs(h=>{y.emit({type:"log_event",timestamp:h.time??Date.now(),level:h.level??"info",component:h.component??"adam",msg:h.msg??""})}),ha(x,{recursive:!0}),ha(it(x,"logs"),{recursive:!0}),ya(it(x,"adam.port"),String(Oe)),e.server.apiKey&&ya(it(x,"adam.key"),e.server.apiKey,{mode:384}),process.send?.({type:"ready",port:Oe});let ns=async()=>{A.info("Shutting down"),da(),rn(),_r(),on(),await he.stopAll(),pe.stop(),le.stop(),await Q.stop(),await Hr(),await S.close(),lt();try{ni(it(x,"adam.key"))}catch{}process.exit(0)};process.on("SIGINT",()=>{ns()}),process.on("SIGTERM",()=>{ns()})}oi().catch(o=>{A.fatal(o,"Fatal error"),process.exit(1)});
|