adam-agent-server 1.2.0 → 1.2.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/{adam-tools-SXOVOPS2.js → adam-tools-V22LRDCP.js} +1 -1
- package/dist/{chunk-XTGWQUO4.js → chunk-IZWULGUS.js} +1 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/web/dist/assets/{ChannelDetail-e6rVX_y8.js → ChannelDetail-DoQs1auJ.js} +1 -1
- package/web/dist/assets/{Channels-DJvZPKer.js → Channels-Dc6QduC1.js} +1 -1
- package/web/dist/assets/{Chat-hTZdEwyE.js → Chat-NrKA_MiZ.js} +1 -1
- package/web/dist/assets/{Dashboard-B4rL_ePs.js → Dashboard-C67v0x7e.js} +1 -1
- package/web/dist/assets/{EnvVarEditor-C8kRWejV.js → EnvVarEditor-DeCQryTm.js} +1 -1
- package/web/dist/assets/{Evolution-BGwFCo7X.js → Evolution-CbFOTN2o.js} +1 -1
- package/web/dist/assets/{GoalDetail-BH2ku-0t.js → GoalDetail-DYUbYJpT.js} +1 -1
- package/web/dist/assets/{Goals-DynDtpMC.js → Goals-7eD9_7Qo.js} +1 -1
- package/web/dist/assets/{Logs-CyJFouE6.js → Logs-CDFbfvQT.js} +1 -1
- package/web/dist/assets/{Memories-ClcFD7OG.js → Memories-D0J8Es-o.js} +1 -1
- package/web/dist/assets/{Plugins-SNOQNNcL.js → Plugins-CXCUhsEZ.js} +1 -1
- package/web/dist/assets/{RoleDetail-vlTPiYwY.js → RoleDetail-C2lXyAjt.js} +2 -2
- package/web/dist/assets/{Roles-CFcuHIvA.js → Roles-Bia_f3ml.js} +1 -1
- package/web/dist/assets/{Settings-C9Kuz-6D.js → Settings-CzgdtkLo.js} +1 -1
- package/web/dist/assets/{Strategies-DZWlQCHp.js → Strategies-CRdpzdUe.js} +1 -1
- package/web/dist/assets/{Switch-DOi0EFHj.js → Switch-B05Q1L98.js} +1 -1
- package/web/dist/assets/{TaskDetail-DjmmnldI.js → TaskDetail-4yYEVV6Z.js} +1 -1
- package/web/dist/assets/{Work-CvESHC3Y.js → Work-CE6TB6LG.js} +1 -1
- package/web/dist/assets/{index-BFmC20R2.js → index-oA-kWqT5.js} +2 -2
- package/web/dist/index.html +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as a,o as b}from"./chunk-
|
|
1
|
+
import{n as a,o as b}from"./chunk-IZWULGUS.js";import"./chunk-5V36ACKZ.js";import"./chunk-OEKM2W3K.js";import"./chunk-EJVUUIAV.js";import"./chunk-GMCIKDTC.js";import"./chunk-6YURWVQG.js";import"./chunk-CDVIT7L5.js";import"./chunk-W3554FQ7.js";import"./chunk-RPTHFQX7.js";import"./chunk-AJVN3KPM.js";import"./chunk-AR2IZMM2.js";import"./chunk-SWPXG2CY.js";import"./chunk-KLQOILIJ.js";import"./chunk-L7JP7DUO.js";import"./chunk-GUQAIWCQ.js";import"./chunk-2CMR5AG7.js";import"./chunk-4TCP2AT7.js";import"./chunk-6DXNXLYG.js";import"./chunk-SBX3HMDA.js";import"./chunk-ZM6YED5F.js";import"./chunk-7IFLU3CY.js";import"./chunk-6HD6NYIB.js";import"./chunk-B4WHT7DX.js";import"./chunk-7LBDLAUQ.js";import"./chunk-KVSO3KGZ.js";import"./chunk-WBAPIPST.js";import"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";export{b as createAdamTools,a as getToolsFingerprint};
|
|
@@ -65,7 +65,7 @@ Complete tasks with high quality.
|
|
|
65
65
|
4. Verify completion against requirements`}static mutateTemplate(t){let r=[this.addProcessEmphasis(),this.addQualityFocus(),this.addVerificationStep()],n=r[Math.floor(Math.random()*r.length)];return`${t}
|
|
66
66
|
|
|
67
67
|
## Evolution
|
|
68
|
-
${n}`}static addProcessEmphasis(){let t=["Break down complex tasks into smaller steps","Iterate on solutions, testing each component","Document your reasoning at each step"];return`**Process:** ${t[Math.floor(Math.random()*t.length)]}`}static addQualityFocus(){let t=["Double-check all outputs before completing","Consider edge cases and error conditions","Optimize for correctness over speed"];return`**Quality:** ${t[Math.floor(Math.random()*t.length)]}`}static addVerificationStep(){return"**Verification:** After completing, verify your work meets all requirements."}static async generateWithLLM(t,r,n){return{promptTemplate:this.generateBaselinePrompt(t,r),rationale:"Generated baseline - LLM integration in Phase 5"}}};C();Ae();import{v4 as y}from"uuid";import{spawnSync as tt}from"child_process";import{createRequire as Rt}from"module";import{dirname as _t,join as rt}from"path";import{openSync as Mt,readFileSync as xt,unlinkSync as Lt}from"fs";var Pt=3e4,nt=12e4;function ot(){let t=Rt(import.meta.url).resolve("@anthropic-ai/claude-agent-sdk");return rt(_t(t),"cli.js")}function G(e,t){let r=ot(),n=t?.timeout??Pt;if(t?.json){let i=rt("/tmp",`adam-cli-stdout-${process.pid}-${Date.now()}.txt`),s=Mt(i,"w");try{let l=tt("node",[r,...e],{cwd:t.cwd,timeout:n,stdio:["ignore",s,"pipe"],encoding:"utf-8"});if(l.status!==0)throw new Error(l.stderr?.trim()||`CLI exited with status ${l.status}`);return xt(i,"utf-8")}finally{try{Lt(i)}catch{}}}let o=tt("node",[r,...e],{cwd:t?.cwd,timeout:n,encoding:"utf-8"});if(o.status!==0)throw new Error(o.stderr?.trim()||`CLI exited with status ${o.status}`);return o.stdout}function at(){let e=G(["plugin","list","--available","--json"],{json:!0});return JSON.parse(e)}function we(e,t="user",r){return G(["plugin","install",e,"--scope",t],{cwd:r,timeout:nt})}function ve(e,t,r){return G(["plugin","uninstall",e],{cwd:r,timeout:nt})}function it(e,t){return G(["plugin","enable",e])}function st(e,t){return G(["plugin","disable",e])}function Sn(){try{return!!ot()}catch{return!1}}C();import*as lt from"crypto";var V=w("api"),B=class{cancelTask(t){let r=h(t);r&&(E(t,{status:"cancelled",completedAt:Date.now()}),me.emit({type:"task_status_change",taskId:t,oldStatus:r.status,newStatus:"cancelled"}),V.debug({taskId:t,oldStatus:r.status},"Task cancelled"))}resolveApproval(t,r,n){return V.debug({approvalId:t,action:r,reason:n},"Approval resolved (no-op in Pure C)"),!0}resolvePlanApproval(t,r,n,o){let i=_e(t);if(!i)return V.warn({planId:t},"Plan not found or already resolved"),!1;let s=h(i.taskId);return s?(Me(t,r==="allow"?"approved":"denied",n),r==="allow"&&n==="permanent"&&xe({id:lt.randomUUID(),roleId:i.roleId,taskPattern:s.prompt.slice(0,100).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),maxRiskLevel:i.plan.overallRisk,createdAt:Date.now(),createdByTaskId:s.id}),me.emit({type:"plan_approval_decision",taskId:s.id,planId:t,decision:r,approvalType:n,reason:o}),V.debug({planId:t,decision:r,approvalType:n},"Plan approval resolved"),!0):(V.warn({planId:t},"Task not found for plan"),!1)}};import{existsSync as At}from"fs";function ct(e,t){return t?{allowedTools:Et(t.allowedTools,e.allowedTools),disallowedTools:Ie(e.disallowedTools,t.disallowedTools),approvalRequired:Ie(e.approvalRequired,t.approvalRequired),maxBudgetUsd:t.maxBudgetUsd!==void 0&&t.maxBudgetUsd>0?Math.min(t.maxBudgetUsd,e.maxBudgetUsd):e.maxBudgetUsd,plugins:Ie(e.plugins??[],t.plugins)}:{allowedTools:e.allowedTools,disallowedTools:e.disallowedTools,approvalRequired:e.approvalRequired,maxBudgetUsd:e.maxBudgetUsd,plugins:e.plugins??[]}}function Et(e,t){if(e===void 0)return t;if(e.length===0)return[];if(t.length===0)return e;let r=new Set(t);return e.filter(n=>r.has(n))}function Ie(e,t){return t===void 0?e:[...new Set([...e,...t])]}var ie=w("manager");function c(e){return{content:[{type:"text",text:JSON.stringify(e)}]}}async function R(e){let{listChannels:t}=await import("./channels-WZOYE4O4.js"),r=t(),{listSessions:n}=await import("./session-manager-Z6MIYRD3.js"),o=[...n("active"),...n("archived")],i=[];for(let s of e)if(s.type==="session"&&s.sessionId)i.push({type:"session",sessionId:s.sessionId});else if(s.type==="channel"){let l=s.channelId,d=s.chatId;if(!l&&s.channelName){let u=r.find(m=>m.name.toLowerCase().includes(s.channelName.toLowerCase()));u&&(l=u.id)}if(l&&!d){let u=o.find(m=>m.source.type==="channel"&&m.source.channelId===l&&m.source.chatId);u?.source.chatId?d=u.source.chatId:d=r.find(g=>g.id===l)?.config?.userId}l&&d?i.push({type:"channel",channelId:l,chatId:d}):ie.warn({channelName:s.channelName,channelId:l,chatId:d},"Could not resolve channel notify target")}return i}async function Nt(e){let{listRoles:t}=await import("./roles-3UTFKSHI.js"),r=t(void 0,100,0);for(let n of r)if(n.name.toLowerCase().includes(e.toLowerCase()))return n.id}var Ut={goalId:a.string()},$t={goalId:a.string(),status:a.string().optional(),currentValue:a.number().optional(),budgetUsd:a.number().optional(),notes:a.string().optional()},jt={goalId:a.string(),goalDescription:a.string(),maxSubtasks:a.number().optional()},x=a.union([a.object({type:a.literal("session"),sessionId:a.string()}),a.object({type:a.literal("channel"),channelName:a.string()}),a.object({type:a.literal("channel"),channelId:a.string(),chatId:a.string().optional()})]),Ot={prompt:a.string(),roleId:a.string().describe("Role ID. Call list_roles first to find the best role for the task."),deliverTo:a.array(x).optional().describe("Where to deliver the task output (result full text). E.g., send result to a specific channel."),reportTo:a.array(x).optional().describe("Where to send status reports (completion summary). Defaults to the originating channel/session."),toolOverrides:a.object({allowedTools:a.array(a.string()).optional(),disallowedTools:a.array(a.string()).optional()}).optional()},Ft={taskId:a.string(),goalId:a.string().optional(),strategyId:a.string().optional()},Gt={roleId:a.string(),taskType:a.string(),name:a.string().optional()},Vt={status:a.string().optional(),limit:a.number().optional()},Bt={taskId:a.string(),roleId:a.string()},qt={taskId:a.string().optional(),status:a.string().optional(),limit:a.number().optional()},Wt={roleId:a.string(),allowedTools:a.array(a.string()).optional(),disallowedTools:a.array(a.string()).optional(),additionalDirectories:a.array(a.object({path:a.string(),mode:a.enum(["ro","rw"]).optional().describe("Read-only or read-write access. Default: rw. Enforced by OS sandbox."),inheritPlugins:a.boolean().optional(),inheritMcp:a.boolean().optional(),inheritPermissions:a.boolean().optional()})).optional(),allowedChannels:a.array(a.string()).optional(),inheritUserSettings:a.boolean().optional().describe("Enable/disable inheriting user-level settings (global plugins, MCP servers). Default: false (isolated).")},Jt={roleId:a.string().optional(),limit:a.number().optional()},Ht={name:a.string(),cagPrompt:a.string(),traits:a.array(a.string()).optional(),allowedTools:a.array(a.string()).optional(),disallowedTools:a.array(a.string()).optional(),additionalDirectories:a.array(a.object({path:a.string(),mode:a.enum(["ro","rw"]).optional().describe("Read-only or read-write access. Default: rw. Enforced by OS sandbox."),inheritPlugins:a.boolean().optional(),inheritMcp:a.boolean().optional(),inheritPermissions:a.boolean().optional()})).optional()},Yt={roleId:a.string(),reason:a.string().optional()},zt={name:a.string(),description:a.string().optional(),roleId:a.string().optional(),metric:a.string().optional(),targetValue:a.number().optional(),deadline:a.number().optional(),budgetUsd:a.number().optional(),deliverTo:a.array(x).optional().describe("Where to deliver goal completion notifications.")},Kt={name:a.string(),description:a.string().optional(),triggerType:a.enum(["cron","event"]),triggerCron:a.string().optional(),triggerEvent:a.string().optional(),prompt:a.string(),roleId:a.string().optional(),enabled:a.boolean().optional(),goalIds:a.array(a.string()).optional(),deliverTo:a.array(x).optional().describe("Where to deliver the task output (result full text)."),reportTo:a.array(x).optional().describe("Where to send status reports (completion summary).")},Qt={status:a.enum(["active","retired","probation"]).optional(),limit:a.number().optional()},Xt={enabled:a.boolean().optional()},Zt={},er={},tr={prompt:a.string().describe("The task prompt to execute after the delay"),delayMinutes:a.number().optional().describe("Minutes from now to execute (e.g., 30 for 'half an hour later')"),runAt:a.string().optional().describe("ISO 8601 timestamp to execute at (e.g., '2026-04-01T15:00:00+08:00')"),roleId:a.string().describe("Role ID to assign the task to. Call list_roles first."),deliverTo:a.array(x).optional().describe("Where to deliver the task output (result full text)."),reportTo:a.array(x).optional().describe("Where to send status reports (completion summary).")},rr={roleId:a.string().optional().describe("If provided, shows which plugins are installed in that role's workspace.")},nr={roleId:a.string().describe("Role ID to install the plugin under (project-scope)."),pluginId:a.string().describe("Plugin ID (e.g. 'github@anthropic'). Use list_available_plugins to discover available plugins.")},or={roleId:a.string().describe("Role ID to uninstall the plugin from."),pluginId:a.string().describe("Plugin ID to uninstall.")},ar={roleId:a.string().describe("Role ID to bind the MCP server to."),mcpName:a.string().describe("Name for this MCP server (e.g., 'github', 'filesystem')."),mcpConfig:a.record(a.string(),a.unknown()).describe("MCP server configuration object.")},ir={roleId:a.string().describe("Role ID to unbind the MCP server from."),mcpName:a.string().describe("Name of the MCP server to remove.")},sr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},lr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},cr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},dr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},ur={},pr={},mr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},gr={roleId:a.string().describe("Role ID to associate scanned plugins with."),path:a.string().describe("Directory path to scan for .claude/settings.json.")},fr={taskId:a.string().describe("Task ID to cancel.")},hr={taskId:a.string().describe("Task ID to get logs for."),limit:a.number().optional().describe("Max log entries (default 20).")},br={roleId:a.string().describe("Role ID to delete.")},yr={},wr={updates:a.record(a.string(),a.unknown()).describe("Config key-value pairs to update. Example: { 'defaults.maxTurns': 50, 'logging.level': 'debug' }")},vr={roleId:a.string().describe("Role ID to list memories for."),limit:a.number().optional().describe("Max results (default 20).")},Ir={templateId:a.string().describe("Template ID to update."),name:a.string().optional(),enabled:a.boolean().optional(),prompt:a.string().optional(),triggerCron:a.string().optional(),triggerEvent:a.string().optional(),roleId:a.string().optional()},Tr={templateId:a.string().describe("Template ID to delete.")},Sr={templateId:a.string().describe("Template ID to run immediately.")},kr={enabled:a.boolean().optional().describe("Filter by enabled status.")},Rr={eventType:a.string().describe("Event type that triggers this rule (e.g., 'task_complete')."),channelId:a.string().describe("Channel ID to deliver to."),format:a.string().optional().describe("Format template (e.g., 'summary', 'full'). Default: 'summary'."),matchCriteria:a.record(a.string(),a.unknown()).optional().describe("JSON match criteria for event fields."),enabled:a.boolean().optional().describe("Enable this rule immediately (default true).")},_r={ruleId:a.string().describe("Delivery rule ID to delete.")},Mr={roleId:a.string().optional().describe("Role ID to filter strategies by.")},dt=[p("read_goal_state","Read a single goal's detailed state: progress percentage, time remaining, budget spent, and current value. Use this for deep-dive on one goal; use list_goals for an overview of all goals.",Ut,async e=>{let t=k(e.goalId);if(!t)return c({error:"Goal not found"});let r=Date.now(),n=t.targetValue>0?t.currentValue/t.targetValue:0;return c({id:t.id,name:t.name,description:t.description,roleId:t.roleId,metricType:t.metricType,targetValue:t.targetValue,currentValue:t.currentValue,deadline:t.deadline,budgetUsd:t.budgetUsd,status:t.status,progress:n,timeRemainingMs:Math.max(0,t.deadline-r),budgetRemainingUsd:t.budgetUsd})}),p("update_goal_state","Update a goal's status, current value, or budget.",$t,async e=>{let t={};return e.status&&(t.status=e.status),e.currentValue!==void 0&&(t.currentValue=e.currentValue),e.budgetUsd!==void 0&&(t.budgetUsd=e.budgetUsd),Object.keys(t).length>0&&(t.updatedAt=Date.now(),X(e.goalId,t)),c({success:!0})}),p("decompose_goal","Decompose a goal into actionable subtasks using LLM reasoning.",jt,async e=>{let t=I(),r=Math.min(e.maxSubtasks??5,10);try{let{query:o}=await import("@anthropic-ai/claude-agent-sdk"),i=`Decompose this goal into ${r} actionable subtasks.
|
|
68
|
+
${n}`}static addProcessEmphasis(){let t=["Break down complex tasks into smaller steps","Iterate on solutions, testing each component","Document your reasoning at each step"];return`**Process:** ${t[Math.floor(Math.random()*t.length)]}`}static addQualityFocus(){let t=["Double-check all outputs before completing","Consider edge cases and error conditions","Optimize for correctness over speed"];return`**Quality:** ${t[Math.floor(Math.random()*t.length)]}`}static addVerificationStep(){return"**Verification:** After completing, verify your work meets all requirements."}static async generateWithLLM(t,r,n){return{promptTemplate:this.generateBaselinePrompt(t,r),rationale:"Generated baseline - LLM integration in Phase 5"}}};C();Ae();import{v4 as y}from"uuid";import{spawnSync as tt}from"child_process";import{createRequire as Rt}from"module";import{dirname as _t,join as rt}from"path";import{openSync as Mt,readFileSync as xt,unlinkSync as Lt}from"fs";var Pt=3e4,nt=12e4;function ot(){let t=Rt(import.meta.url).resolve("@anthropic-ai/claude-agent-sdk");return rt(_t(t),"cli.js")}function G(e,t){let r=ot(),n=t?.timeout??Pt;if(t?.json){let i=rt("/tmp",`adam-cli-stdout-${process.pid}-${Date.now()}.txt`),s=Mt(i,"w");try{let l=tt("node",[r,...e],{cwd:t.cwd,timeout:n,stdio:["ignore",s,"pipe"],encoding:"utf-8"});if(l.status!==0)throw new Error(l.stderr?.trim()||`CLI exited with status ${l.status}`);return xt(i,"utf-8")}finally{try{Lt(i)}catch{}}}let o=tt("node",[r,...e],{cwd:t?.cwd,timeout:n,encoding:"utf-8"});if(o.status!==0)throw new Error(o.stderr?.trim()||`CLI exited with status ${o.status}`);return o.stdout}function at(){let e=G(["plugin","list","--available","--json"],{json:!0});return JSON.parse(e)}function we(e,t="user",r){return G(["plugin","install",e,"--scope",t],{cwd:r,timeout:nt})}function ve(e,t,r){let n=["plugin","uninstall",e];return t&&n.push("--scope",t),G(n,{cwd:r,timeout:nt})}function it(e,t){return G(["plugin","enable",e])}function st(e,t){return G(["plugin","disable",e])}function Sn(){try{return!!ot()}catch{return!1}}C();import*as lt from"crypto";var V=w("api"),B=class{cancelTask(t){let r=h(t);r&&(E(t,{status:"cancelled",completedAt:Date.now()}),me.emit({type:"task_status_change",taskId:t,oldStatus:r.status,newStatus:"cancelled"}),V.debug({taskId:t,oldStatus:r.status},"Task cancelled"))}resolveApproval(t,r,n){return V.debug({approvalId:t,action:r,reason:n},"Approval resolved (no-op in Pure C)"),!0}resolvePlanApproval(t,r,n,o){let i=_e(t);if(!i)return V.warn({planId:t},"Plan not found or already resolved"),!1;let s=h(i.taskId);return s?(Me(t,r==="allow"?"approved":"denied",n),r==="allow"&&n==="permanent"&&xe({id:lt.randomUUID(),roleId:i.roleId,taskPattern:s.prompt.slice(0,100).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),maxRiskLevel:i.plan.overallRisk,createdAt:Date.now(),createdByTaskId:s.id}),me.emit({type:"plan_approval_decision",taskId:s.id,planId:t,decision:r,approvalType:n,reason:o}),V.debug({planId:t,decision:r,approvalType:n},"Plan approval resolved"),!0):(V.warn({planId:t},"Task not found for plan"),!1)}};import{existsSync as At}from"fs";function ct(e,t){return t?{allowedTools:Et(t.allowedTools,e.allowedTools),disallowedTools:Ie(e.disallowedTools,t.disallowedTools),approvalRequired:Ie(e.approvalRequired,t.approvalRequired),maxBudgetUsd:t.maxBudgetUsd!==void 0&&t.maxBudgetUsd>0?Math.min(t.maxBudgetUsd,e.maxBudgetUsd):e.maxBudgetUsd,plugins:Ie(e.plugins??[],t.plugins)}:{allowedTools:e.allowedTools,disallowedTools:e.disallowedTools,approvalRequired:e.approvalRequired,maxBudgetUsd:e.maxBudgetUsd,plugins:e.plugins??[]}}function Et(e,t){if(e===void 0)return t;if(e.length===0)return[];if(t.length===0)return e;let r=new Set(t);return e.filter(n=>r.has(n))}function Ie(e,t){return t===void 0?e:[...new Set([...e,...t])]}var ie=w("manager");function c(e){return{content:[{type:"text",text:JSON.stringify(e)}]}}async function R(e){let{listChannels:t}=await import("./channels-WZOYE4O4.js"),r=t(),{listSessions:n}=await import("./session-manager-Z6MIYRD3.js"),o=[...n("active"),...n("archived")],i=[];for(let s of e)if(s.type==="session"&&s.sessionId)i.push({type:"session",sessionId:s.sessionId});else if(s.type==="channel"){let l=s.channelId,d=s.chatId;if(!l&&s.channelName){let u=r.find(m=>m.name.toLowerCase().includes(s.channelName.toLowerCase()));u&&(l=u.id)}if(l&&!d){let u=o.find(m=>m.source.type==="channel"&&m.source.channelId===l&&m.source.chatId);u?.source.chatId?d=u.source.chatId:d=r.find(g=>g.id===l)?.config?.userId}l&&d?i.push({type:"channel",channelId:l,chatId:d}):ie.warn({channelName:s.channelName,channelId:l,chatId:d},"Could not resolve channel notify target")}return i}async function Nt(e){let{listRoles:t}=await import("./roles-3UTFKSHI.js"),r=t(void 0,100,0);for(let n of r)if(n.name.toLowerCase().includes(e.toLowerCase()))return n.id}var Ut={goalId:a.string()},$t={goalId:a.string(),status:a.string().optional(),currentValue:a.number().optional(),budgetUsd:a.number().optional(),notes:a.string().optional()},jt={goalId:a.string(),goalDescription:a.string(),maxSubtasks:a.number().optional()},x=a.union([a.object({type:a.literal("session"),sessionId:a.string()}),a.object({type:a.literal("channel"),channelName:a.string()}),a.object({type:a.literal("channel"),channelId:a.string(),chatId:a.string().optional()})]),Ot={prompt:a.string(),roleId:a.string().describe("Role ID. Call list_roles first to find the best role for the task."),deliverTo:a.array(x).optional().describe("Where to deliver the task output (result full text). E.g., send result to a specific channel."),reportTo:a.array(x).optional().describe("Where to send status reports (completion summary). Defaults to the originating channel/session."),toolOverrides:a.object({allowedTools:a.array(a.string()).optional(),disallowedTools:a.array(a.string()).optional()}).optional()},Ft={taskId:a.string(),goalId:a.string().optional(),strategyId:a.string().optional()},Gt={roleId:a.string(),taskType:a.string(),name:a.string().optional()},Vt={status:a.string().optional(),limit:a.number().optional()},Bt={taskId:a.string(),roleId:a.string()},qt={taskId:a.string().optional(),status:a.string().optional(),limit:a.number().optional()},Wt={roleId:a.string(),allowedTools:a.array(a.string()).optional(),disallowedTools:a.array(a.string()).optional(),additionalDirectories:a.array(a.object({path:a.string(),mode:a.enum(["ro","rw"]).optional().describe("Read-only or read-write access. Default: rw. Enforced by OS sandbox."),inheritPlugins:a.boolean().optional(),inheritMcp:a.boolean().optional(),inheritPermissions:a.boolean().optional()})).optional(),allowedChannels:a.array(a.string()).optional(),inheritUserSettings:a.boolean().optional().describe("Enable/disable inheriting user-level settings (global plugins, MCP servers). Default: false (isolated).")},Jt={roleId:a.string().optional(),limit:a.number().optional()},Ht={name:a.string(),cagPrompt:a.string(),traits:a.array(a.string()).optional(),allowedTools:a.array(a.string()).optional(),disallowedTools:a.array(a.string()).optional(),additionalDirectories:a.array(a.object({path:a.string(),mode:a.enum(["ro","rw"]).optional().describe("Read-only or read-write access. Default: rw. Enforced by OS sandbox."),inheritPlugins:a.boolean().optional(),inheritMcp:a.boolean().optional(),inheritPermissions:a.boolean().optional()})).optional()},Yt={roleId:a.string(),reason:a.string().optional()},zt={name:a.string(),description:a.string().optional(),roleId:a.string().optional(),metric:a.string().optional(),targetValue:a.number().optional(),deadline:a.number().optional(),budgetUsd:a.number().optional(),deliverTo:a.array(x).optional().describe("Where to deliver goal completion notifications.")},Kt={name:a.string(),description:a.string().optional(),triggerType:a.enum(["cron","event"]),triggerCron:a.string().optional(),triggerEvent:a.string().optional(),prompt:a.string(),roleId:a.string().optional(),enabled:a.boolean().optional(),goalIds:a.array(a.string()).optional(),deliverTo:a.array(x).optional().describe("Where to deliver the task output (result full text)."),reportTo:a.array(x).optional().describe("Where to send status reports (completion summary).")},Qt={status:a.enum(["active","retired","probation"]).optional(),limit:a.number().optional()},Xt={enabled:a.boolean().optional()},Zt={},er={},tr={prompt:a.string().describe("The task prompt to execute after the delay"),delayMinutes:a.number().optional().describe("Minutes from now to execute (e.g., 30 for 'half an hour later')"),runAt:a.string().optional().describe("ISO 8601 timestamp to execute at (e.g., '2026-04-01T15:00:00+08:00')"),roleId:a.string().describe("Role ID to assign the task to. Call list_roles first."),deliverTo:a.array(x).optional().describe("Where to deliver the task output (result full text)."),reportTo:a.array(x).optional().describe("Where to send status reports (completion summary).")},rr={roleId:a.string().optional().describe("If provided, shows which plugins are installed in that role's workspace.")},nr={roleId:a.string().describe("Role ID to install the plugin under (project-scope)."),pluginId:a.string().describe("Plugin ID (e.g. 'github@anthropic'). Use list_available_plugins to discover available plugins.")},or={roleId:a.string().describe("Role ID to uninstall the plugin from."),pluginId:a.string().describe("Plugin ID to uninstall.")},ar={roleId:a.string().describe("Role ID to bind the MCP server to."),mcpName:a.string().describe("Name for this MCP server (e.g., 'github', 'filesystem')."),mcpConfig:a.record(a.string(),a.unknown()).describe("MCP server configuration object.")},ir={roleId:a.string().describe("Role ID to unbind the MCP server from."),mcpName:a.string().describe("Name of the MCP server to remove.")},sr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},lr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},cr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},dr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},ur={},pr={},mr={pluginId:a.string().describe("Plugin ID (e.g., 'github@anthropic').")},gr={roleId:a.string().describe("Role ID to associate scanned plugins with."),path:a.string().describe("Directory path to scan for .claude/settings.json.")},fr={taskId:a.string().describe("Task ID to cancel.")},hr={taskId:a.string().describe("Task ID to get logs for."),limit:a.number().optional().describe("Max log entries (default 20).")},br={roleId:a.string().describe("Role ID to delete.")},yr={},wr={updates:a.record(a.string(),a.unknown()).describe("Config key-value pairs to update. Example: { 'defaults.maxTurns': 50, 'logging.level': 'debug' }")},vr={roleId:a.string().describe("Role ID to list memories for."),limit:a.number().optional().describe("Max results (default 20).")},Ir={templateId:a.string().describe("Template ID to update."),name:a.string().optional(),enabled:a.boolean().optional(),prompt:a.string().optional(),triggerCron:a.string().optional(),triggerEvent:a.string().optional(),roleId:a.string().optional()},Tr={templateId:a.string().describe("Template ID to delete.")},Sr={templateId:a.string().describe("Template ID to run immediately.")},kr={enabled:a.boolean().optional().describe("Filter by enabled status.")},Rr={eventType:a.string().describe("Event type that triggers this rule (e.g., 'task_complete')."),channelId:a.string().describe("Channel ID to deliver to."),format:a.string().optional().describe("Format template (e.g., 'summary', 'full'). Default: 'summary'."),matchCriteria:a.record(a.string(),a.unknown()).optional().describe("JSON match criteria for event fields."),enabled:a.boolean().optional().describe("Enable this rule immediately (default true).")},_r={ruleId:a.string().describe("Delivery rule ID to delete.")},Mr={roleId:a.string().optional().describe("Role ID to filter strategies by.")},dt=[p("read_goal_state","Read a single goal's detailed state: progress percentage, time remaining, budget spent, and current value. Use this for deep-dive on one goal; use list_goals for an overview of all goals.",Ut,async e=>{let t=k(e.goalId);if(!t)return c({error:"Goal not found"});let r=Date.now(),n=t.targetValue>0?t.currentValue/t.targetValue:0;return c({id:t.id,name:t.name,description:t.description,roleId:t.roleId,metricType:t.metricType,targetValue:t.targetValue,currentValue:t.currentValue,deadline:t.deadline,budgetUsd:t.budgetUsd,status:t.status,progress:n,timeRemainingMs:Math.max(0,t.deadline-r),budgetRemainingUsd:t.budgetUsd})}),p("update_goal_state","Update a goal's status, current value, or budget.",$t,async e=>{let t={};return e.status&&(t.status=e.status),e.currentValue!==void 0&&(t.currentValue=e.currentValue),e.budgetUsd!==void 0&&(t.budgetUsd=e.budgetUsd),Object.keys(t).length>0&&(t.updatedAt=Date.now(),X(e.goalId,t)),c({success:!0})}),p("decompose_goal","Decompose a goal into actionable subtasks using LLM reasoning.",jt,async e=>{let t=I(),r=Math.min(e.maxSubtasks??5,10);try{let{query:o}=await import("@anthropic-ai/claude-agent-sdk"),i=`Decompose this goal into ${r} actionable subtasks.
|
|
69
69
|
|
|
70
70
|
Goal: ${e.goalDescription}
|
|
71
71
|
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as fs,b as hs,c as mt,d as gt,e as mr,f as gr,g as yr,h as fr,j as hr,k as br,m as vr,n as yt}from"./chunk-ITUBFUJQ.js";import{c as Rr,d as Ir}from"./chunk-KKLZIXBN.js";import"./chunk-2HN2TSP6.js";import{a as xs,c as js}from"./chunk-JNRCXAW3.js";import{b as or,c as ir}from"./chunk-QN6BEJF5.js";import{a as cr,b as dr,c as lr,e as pr}from"./chunk-IHP7JV6J.js";import{b as ur}from"./chunk-EGS6U3V5.js";import{a as ds,b as $s,c as Hs,d as Ks,e as zs,f as Qs,g as Ys,h as Xs,i as Zs,j as Js,k as er,l as tr,m as ce,o as ut}from"./chunk-
|
|
1
|
+
import{a as fs,b as hs,c as mt,d as gt,e as mr,f as gr,g as yr,h as fr,j as hr,k as br,m as vr,n as yt}from"./chunk-ITUBFUJQ.js";import{c as Rr,d as Ir}from"./chunk-KKLZIXBN.js";import"./chunk-2HN2TSP6.js";import{a as xs,c as js}from"./chunk-JNRCXAW3.js";import{b as or,c as ir}from"./chunk-QN6BEJF5.js";import{a as cr,b as dr,c as lr,e as pr}from"./chunk-IHP7JV6J.js";import{b as ur}from"./chunk-EGS6U3V5.js";import{a as ds,b as $s,c as Hs,d as Ks,e as zs,f as Qs,g as Ys,h as Xs,i as Zs,j as Js,k as er,l as tr,m as ce,o as ut}from"./chunk-IZWULGUS.js";import{a as Gs}from"./chunk-5V36ACKZ.js";import{c as dt,d as bs,e as _e,f as vs,g as Rs,h as Is,j as ks}from"./chunk-OEKM2W3K.js";import{c as cs}from"./chunk-EJVUUIAV.js";import{b as Je}from"./chunk-GMCIKDTC.js";import{a as sr,b as De,c as rr,d as ar,e as nr}from"./chunk-6YURWVQG.js";import{b as se,c as Oe,d as Fs,e as Ds}from"./chunk-CDVIT7L5.js";import{a as Ze,b as F,c as X,d as W,e as Yt,f as Xt}from"./chunk-W3554FQ7.js";import{b as Fe,c as qs,d as M,e as Ls,f as Ms,g as Bs,h as pt,i as z,j as Us,n as Ws,o as Vs}from"./chunk-RPTHFQX7.js";import{b as gs,c as ys}from"./chunk-AJVN3KPM.js";import{a as K,b as ct,c as us,e as ms}from"./chunk-AR2IZMM2.js";import{b as Ns,d as ye,f as ie}from"./chunk-SWPXG2CY.js";import{a as rs}from"./chunk-BIIP363C.js";import{a as rt,b as es,c as ts,d as wa,e as te,f as at,g as nt,h as ot,j as ss}from"./chunk-KLQOILIJ.js";import{h as os,i as is}from"./chunk-OFOVSC72.js";import{a as f}from"./chunk-L7JP7DUO.js";import{a as lt,c as As}from"./chunk-GUQAIWCQ.js";import{a as it,b as ls}from"./chunk-2CMR5AG7.js";import{a as Ts,b as Ee,c as Ss,g as ws,j as Cs}from"./chunk-4TCP2AT7.js";import{a as as,b as Pe,c as ns,d as kr}from"./chunk-PMHNW5IL.js";import{b as ps}from"./chunk-Z5ET7WW2.js";import{a as Ps,b as Z,c as _s,d as Es,g as Os}from"./chunk-6DXNXLYG.js";import{b as Ht,c as Kt,d as zt,e as Qt}from"./chunk-SBX3HMDA.js";import{a as Bt}from"./chunk-ZM6YED5F.js";import{a as Ye,b as Ut,c as Wt,d as Vt,e as Gt}from"./chunk-7IFLU3CY.js";import{a as Ie,b as ze,c as Nt,d as E,e as ke,i as qt,j as Lt,k as Qe}from"./chunk-6HD6NYIB.js";import{d as et,e as L,f as tt,g as Ce,h as ge,i as st,k as Ae}from"./chunk-B4WHT7DX.js";import{b as oe,c as we,d as Zt,g as Jt}from"./chunk-7LBDLAUQ.js";import{b as U,c as Xe,d as Se}from"./chunk-KVSO3KGZ.js";import{c as Mt,d as O,h as me}from"./chunk-WBAPIPST.js";import{a as $t,c as q,d as Te,h as Y}from"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";import{writeFileSync as ha,mkdirSync as ba,unlinkSync as $n}from"fs";import{join as He}from"path";me();import{readFileSync as Ca,existsSync as Aa}from"fs";import{resolve as ft}from"path";function Tr(o=O){let s=[],e=[],r=process.env.ADAM_ENV_FILE;r&&e.push(ft(o,r)),e.push(ft(o,".env.local")),e.push(ft(o,".env"));for(let t of e){if(!Aa(t))continue;Pa(t)>0&&s.push(t)}return s}function Pa(o){let e=Ca(o,"utf-8").split(`
|
|
2
2
|
`),r=0;for(let t of e){let a=t.trim();if(!a||a.startsWith("#"))continue;a.startsWith("export ")&&(a=a.slice(7).trim());let n=a.indexOf("=");if(n===-1)continue;let i=a.slice(0,n).trim();if(!i)continue;let c=a.slice(n+1).trim();(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'"))&&(c=c.slice(1,-1)),c=c.replace(/\$\{(\w+)\}|\$(\w+)/g,(l,d,m)=>{let b=d??m;return process.env[b]??""}),(i.startsWith("ANTHROPIC_")||process.env[i]===void 0)&&(process.env[i]=c,r++)}return r}Se();Ae();ss();import{existsSync as Sr}from"fs";import wr from"path";import _a from"fastify";import Ea from"@fastify/cors";import Oa from"@fastify/static";import Fa from"@fastify/websocket";import Da from"@fastify/swagger";import xa from"@fastify/swagger-ui";import{timingSafeEqual as ja}from"crypto";function Ar(o,s){let e=_a({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:Pe()},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(xa,{routePrefix:"/docs"}),e.register(Ea,{origin:!0}),e.register(Fa,{options:{maxPayload:1024*1024*16}}),s){let t=Buffer.from(s);e.addHook("onRequest",async(a,n)=>{let i=a.url;if(i==="/healthz"||i==="/readyz"||i.startsWith("/docs")||i.startsWith("/ui"))return;let c=a.headers["x-api-key"];if(c&&Cr(c,t))return;let l=a.query,d=l.api_key||l["x-api-key"];if(!(d&&Cr(d,t)))return n.status(401).send({code:"UNAUTHORIZED",message:"Invalid or missing API key"})})}let r=wr.join(as,"web/dist");return Sr(r)&&(e.register(Oa,{root:r,prefix:"/ui/",wildcard:!0}),e.get("/ui",async(t,a)=>a.sendFile("index.html",r))),e.setErrorHandler((t,a,n)=>{if(t.validation){let c=t.validation.map(l=>{let d=l.instancePath||l.params?.missingProperty||"";return d?`${d}: ${l.message}`:l.message});return n.status(400).send({code:"VALIDATION_ERROR",message:c.join("; ")})}let i=t.statusCode??500;return n.status(i).send({code:"INTERNAL_ERROR",message:t.message})}),e.setNotFoundHandler((t,a)=>{let n=t.url.split("?")[0];return t.url.startsWith("/ui")&&Sr(r)&&!wr.extname(n)?a.sendFile("index.html",r):a.status(404).send({code:"NOT_FOUND",message:"Route not found"})}),e}function Cr(o,s){try{let e=Buffer.from(o);return e.length!==s.length?!1:ja(e,s)}catch{return!1}}import{z as u}from"zod/v4";import{v4 as Va}from"uuid";var Na=o=>({...o,nullable:!0}),S={type:"object",properties:{code:{type:"string"},message:{type:"string"}}},qa={type:"object",additionalProperties:!0,properties:{id:{type:"string"},prompt:{type:"string"},dependsOn:{type:"array",items:{type:"string"}},outputAs:{type:"string"}}},La={type:"object",additionalProperties:!0,properties:{type:{type:"string"},cron:{type:"string"},event:{type:"string"}}},Pr={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},description:{type:"string"},trigger:La,steps:{type:"array",items:qa},agentPreference:{type:"string"},config:{type:"object",additionalProperties:!0},tags:{type:"array",items:{type:"string"}},enabled:{type:"boolean"},createdAt:{type:"number"},updatedAt:{type:"number"}}},Ma={type:"object",properties:{input:{type:"number"},output:{type:"number"}}},_r={type:"object",additionalProperties:!0,properties:{id:{type:"string"},parentId:{type:"string"},status:{type:"string"},prompt:{type:"string"},originalPrompt:{type:"string"},config:{type:"object",additionalProperties:!0},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:Ma,numTurns:{type:"number"},totalDurationMs:{type:"number"}}},Ba={type:"object",additionalProperties:!0,properties:{model:{type:"string"},effort:{type:"string"},maxTurns:{type:"number"}}},xe={type:"object",additionalProperties:!0,properties:{id:{type:"string"},name:{type:"string"},source:{type:"string"},traits:{type:"array",items:{type:"string"}},background:{type:"string"},preferences:Ba,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"}}},ht={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"}}},Ua={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"}}},bt={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"}}},Wa={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"}}}},templateList:{200:{type:"object",properties:{templates:{type:"array",items:Pr}}}},templateDetail:{200:{type:"object",properties:{template:Pr}},404:S},templateUpdated:{200:{type:"object",properties:{templateId:{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",properties:{taskId:{type:"string"}}},400:S},taskList:{200:{type:"object",properties:{tasks:{type:"array",items:_r}}}},taskDetail:{200:{type:"object",properties:{task:_r}},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:xe}}}},agentDetail:{200:{type:"object",properties:{agent:xe}},404:S},agentCreated:{201:{type:"object",properties:{agent:xe}}},agentUpdated:{200:{type:"object",properties:{agent:xe}},404:S},agentDeleted:{200:{type:"object",properties:{agentId:{type:"string"},deleted:{type:"boolean"}}},400:S,404:S},agentPersona:{200:{type:"object",properties:{persona:Na({type:"string"})}},404:S},memoryList:{200:{type:"object",properties:{memories:{type:"array",items:ht},count:{type:"number"}}},404:S},memoryQuery:{200:{type:"object",properties:{memories:{type:"array",items:ht},count:{type:"number"}}},404:S},memoryCreated:{201:{type:"object",properties:{memory:ht}},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:Ua}}}},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:bt}}}},goalDetail:{200:{type:"object",properties:{goal:bt}},404:S},goalCreated:{201:{type:"object",properties:{goal:bt}},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:Wa},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"}}}}},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 Er=u.union([u.object({type:u.literal("session"),sessionId:u.string()}),u.object({type:u.literal("channel"),channelId:u.string(),chatId:u.string().optional()})]),Ga=u.object({prompt:u.string().min(1,"prompt is required"),roleId:u.string().optional(),deliverTo:u.array(Er).optional(),reportTo:u.array(Er).optional(),config:u.object({allowedTools:u.array(u.string()).optional(),disallowedTools:u.array(u.string()).optional(),maxTurns:u.number().optional(),maxBudgetUsd:u.number().optional(),mcpServers:u.record(u.string(),u.unknown()).optional(),model:u.string().optional(),effort:u.enum(["low","medium","high","max"]).optional(),settingSources:u.array(u.string()).optional(),workspacePath:u.string().optional(),timeout:u.number().optional(),approvalRequired:u.array(u.string()).optional(),approvalTimeout:u.number().optional(),env:u.record(u.string(),u.string()).optional(),plugins:u.array(u.string()).optional()}).optional()}),re=u.object({id:u.string().uuid()}),$a=["pending","queued","running","paused","completed","failed","cancelled"],Ha=u.object({status:u.enum($a).optional(),roleId:u.string().optional(),limit:u.coerce.number().min(1).max(100).default(100),offset:u.coerce.number().min(0).default(0)});async function Or(o){let s=new ds;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(a,n)=>{let i=Ga.safeParse(a.body);if(!i.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(i.error)});let{prompt:c,roleId:l,config:d,deliverTo:m,reportTo:b}=i.data,I=zt(),y={timeout:d?.timeout??I.timeout,approvalRequired:d?.approvalRequired??I.approvalRequired,approvalTimeout:d?.approvalTimeout??I.approvalTimeout,allowedTools:d?.allowedTools??I.allowedTools,disallowedTools:d?.disallowedTools??I.disallowedTools,maxTurns:d?.maxTurns??I.maxTurns,maxBudgetUsd:d?.maxBudgetUsd??I.maxBudgetUsd,mcpServers:d?.mcpServers,model:d?.model||I.model||void 0,effort:d?.effort??I.effort,settingSources:d?.settingSources??I.settingSources,workspacePath:d?.workspacePath,env:d?.env??I.env,claudeCodePath:I.claudeCodePath,plugins:d?.plugins},g={id:Va(),status:"pending",prompt:c,roleId:l,config:y,deliverTo:m,reportTo:b,createdAt:Date.now()};return Ze(g),f.emit({type:"task_created",taskId:g.id}),n.status(201).send({taskId:g.id})}),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(a,n)=>{let i=Ha.safeParse(a.query);if(!i.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(i.error)});let{status:c,roleId:l,limit:d,offset:m}=i.data;return{tasks:W(c,d,m,l)}}),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(a,n)=>{let i=re.safeParse(a.params);if(!i.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(i.error)});let c=F(i.data.id);return c?{task:c}:n.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(a,n)=>{let i=re.safeParse(a.params);if(!i.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(i.error)});let c=F(i.data.id);return c?c.status!=="running"&&c.status!=="queued"&&c.status!=="pending"&&c.status!=="paused"?n.status(400).send({code:"INVALID_STATE",message:`Cannot cancel task in status: ${c.status}`}):(s.cancelTask(c.id),{taskId:c.id,status:"cancelled"}):n.status(404).send({code:"NOT_FOUND",message:"Task not found"})});let e=u.object({taskIds:u.array(u.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(a,n)=>{let i=e.safeParse(a.body);if(!i.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(i.error)});let c=new Set(["pending","queued","running","paused"]),l=0,d=[];for(let m of i.data.taskIds){let b=F(m);if(!b){d.push({taskId:m,reason:"not found"});continue}if(!c.has(b.status)){d.push({taskId:m,reason:`already ${b.status}`});continue}s.cancelTask(m),l++}return{cancelled:l,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(a,n)=>{let i=F(a.params.id);if(!i)return n.status(404).send({code:"NOT_FOUND",message:"Task not found"});let{limit:c=50,offset:l=0}=a.query;return{logs:Je(i.id,c,l)}});let r=u.object({approvalId:u.string().uuid(),reason:u.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(a,n)=>{let i=re.safeParse(a.params);if(!i.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(i.error)});let c=r.safeParse(a.body);return c.success?F(i.data.id)?s.resolveApproval(c.data.approvalId,"allow",c.data.reason)?{approvalId:c.data.approvalId,decision:"allow"}:n.status(404).send({code:"NOT_FOUND",message:"Approval not found or already resolved"}):n.status(404).send({code:"NOT_FOUND",message:"Task not found"}):n.status(400).send({code:"VALIDATION_ERROR",message:u.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(a,n)=>{let i=re.safeParse(a.params);if(!i.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(i.error)});let c=r.safeParse(a.body);return c.success?F(i.data.id)?s.resolveApproval(c.data.approvalId,"deny",c.data.reason)?{approvalId:c.data.approvalId,decision:"deny"}:n.status(404).send({code:"NOT_FOUND",message:"Approval not found or already resolved"}):n.status(404).send({code:"NOT_FOUND",message:"Task not found"}):n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(c.error)})});let t=u.object({planId:u.string(),decision:u.enum(["allow","deny"]),approvalType:u.enum(["once","permanent"]).optional(),reason:u.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(a,n)=>{let i=re.safeParse(a.params);if(!i.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(i.error)});let c=t.safeParse(a.body);if(!c.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(c.error)});if(!F(i.data.id))return n.status(404).send({code:"NOT_FOUND",message:"Task not found"});let{planId:d,decision:m,approvalType:b,reason:I}=c.data;return s.resolvePlanApproval(d,m,b,I)?{planId:d,decision:m,approvalType:b}:n.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(a,n)=>{let i=re.safeParse(a.params);return i.success?F(i.data.id)?{plans:cs(i.data.id)}:n.status(404).send({code:"NOT_FOUND",message:"Task not found"}):n.status(400).send({code:"VALIDATION_ERROR",message:u.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(a,n)=>{let i=re.safeParse(a.params);if(!i.success)return n.status(400).send({code:"VALIDATION_ERROR",message:u.prettifyError(i.error)});let c=F(i.data.id);if(!c)return n.status(404).send({code:"NOT_FOUND",message:"Task not found"});let{limit:l=50}=a.query;return{logs:os(c.id,l)}})}Se();Ae();async function Fr(o,s){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,r)=>({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,r)=>{let t={database:!1,manager:!1,config:!1};try{U().prepare("SELECT 1").get(),t.database=!0}catch{t.database=!1}t.manager=!0,t.config=!!s.server;try{let n=ge(void 0,1,0);t.agents=n.length>0}catch{t.agents=!1}return t.embedding=ls(),t.taskHub=!0,Object.values(t).every(n=>n)?{status:"ready",checks:t}:r.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,r)=>{let a=E().execution?.maxConcurrent??5,n=W("running"),i=W("pending"),c=Xt(ps());return{executionPool:{active:n.length,max:a,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,r)=>({name:ns(),version:Pe()}))}import{timingSafeEqual as xr}from"crypto";import{z as jr}from"zod/v4";var vt=class{connections=new Map;eventBuffers=new Map;eventIndices=new Map;addConnection(s,e){this.connections.has(s)||this.connections.set(s,new Set),this.connections.get(s).add(e);let r=this.getBufferedEvents(s);for(let t of r)e.readyState===1&&e.send(JSON.stringify(t));e.on("close",()=>{this.removeConnection(s,e)})}removeConnection(s,e){let r=this.connections.get(s);r&&(r.delete(e),r.size===0&&this.connections.delete(s))}broadcast(s,e){this.addToBuffer(s,e);let r=this.connections.get(s);if(!r||r.size===0)return;let t=JSON.stringify(e);for(let a of r)a.readyState===1&&a.send(t)}addToBuffer(s,e){let r=this.eventBuffers.get(s);r||(r=[],this.eventBuffers.set(s,r)),r.push(e),r.length>100&&r.shift(),this.eventIndices.set(s,e.index)}getBufferedEvents(s){return this.eventBuffers.get(s)??[]}getNextIndex(s){let r=(this.eventIndices.get(s)??0)+1;return this.eventIndices.set(s,r),r}},Dr=new vt;var Ka=jr.object({id:jr.string().uuid()});async function Nr(o,s){o.get("/tasks/:id/stream",{websocket:!0},(e,r)=>{if(s&&!za(r,s)){e.close(4401,"Unauthorized");return}let t=Ka.safeParse(r.params);if(!t.success){e.close(1008,"Invalid task ID");return}let{id:a}=t.data;if(!F(a)){e.close(1008,"Task not found");return}Dr.addConnection(a,e)})}function za(o,s){let e=o.headers["x-api-key"];if(e)try{let a=Buffer.from(e),n=Buffer.from(s);if(a.length===n.length&&xr(a,n))return!0}catch{}let r=o.query,t=r.api_key||r["x-api-key"];if(t)try{let a=Buffer.from(t),n=Buffer.from(s);if(a.length===n.length&&xr(a,n))return!0}catch{}return!1}import{timingSafeEqual as qr}from"crypto";Y();var Qa=q("ws"),je=new Set;function Lr(o,s){o.get("/events",{websocket:!0},(e,r)=>{if(s&&!Ya(r,s)){e.close(4401,"Unauthorized");return}je.add(e),e.on("close",()=>{je.delete(e)}),e.on("error",t=>{Qa.error({error:t},"WebSocket error"),je.delete(e)})}),f.on("task_status_change",e=>{B(e)}),f.on("approval_request",e=>{B(e)}),f.on("stats_update",e=>{B(e)}),f.on("log_event",e=>{B(e)}),f.on("config_changed",e=>{B(e)}),f.on("plan_approval_request",e=>{(()=>{try{let t=ms(e.taskId);if(!t)return!1;let a=gs(t.sessionId);return a?a.source.type==="channel"&&!!a.source.channelId:!1}catch{return!1}})()||B(e)}),f.on("plan_approval_decision",e=>{B(e)}),f.on("task_created",e=>{B(e)}),f.on("execution_slot_change",e=>{B(e)}),f.on("execution_task_start",e=>{B(e)}),f.on("execution_task_end",e=>{B(e)}),f.on("delivery_status_change",e=>{B(e)})}function B(o){let s=JSON.stringify(o);for(let e of je)e.readyState===1&&e.send(s)}function Ya(o,s){let e=o.headers["x-api-key"];if(e)try{let a=Buffer.from(e),n=Buffer.from(s);if(a.length===n.length&&qr(a,n))return!0}catch{}let r=o.query,t=r.api_key||r["x-api-key"];if(t)try{let a=Buffer.from(t),n=Buffer.from(s);if(a.length===n.length&&qr(a,n))return!0}catch{}return!1}Se();function Xa(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 Rt(){let o=U(),s=o.prepare("SELECT * FROM server_state WHERE id = 1").get();if(s)return Xa(s);let e=Date.now();return o.prepare("INSERT INTO server_state (id, created_at) VALUES (1, ?)").run(e),{id:1,createdAt:e}}function fe(o){let s=U(),e=[],r=[];"sdkSessionId"in o&&(e.push("sdk_session_id = ?"),r.push(o.sdkSessionId??null)),"userTaskSessionId"in o&&(e.push("user_task_session_id = ?"),r.push(o.userTaskSessionId??null)),"workspacePath"in o&&(e.push("workspace_path = ?"),r.push(o.workspacePath??null)),"lastActiveAt"in o&&(e.push("last_active_at = ?"),r.push(o.lastActiveAt??null)),"toolsFingerprint"in o&&(e.push("tools_fingerprint = ?"),r.push(o.toolsFingerprint??null)),e.length!==0&&(Rt(),r.push(1),s.prepare(`UPDATE server_state SET ${e.join(", ")} WHERE id = ?`).run(...r))}function Ne(o){fe({sdkSessionId:o,lastActiveAt:Date.now()})}function Mr(){fe({sdkSessionId:void 0,lastActiveAt:Date.now()})}function Br(o){fe({workspacePath:o})}Ae();ss();import{z as p}from"zod/v4";import{v4 as Ur}from"uuid";ks();wa();import{rmSync as Za,existsSync as It}from"fs";var Wr=p.object({model:p.string().optional(),effort:p.enum(["low","medium","high","max"]).optional(),maxTurns:p.number().optional()}),Vr=p.object({path:p.string(),mode:p.enum(["ro","rw"]).default("rw"),inheritPlugins:p.boolean().optional(),inheritMcp:p.boolean().optional(),inheritPermissions:p.boolean().optional()}),Ja=p.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(p.refine(o=>!o.startsWith("ANTHROPIC_"),"ANTHROPIC_* keys are managed globally in Settings")),Gr=p.record(Ja,p.string().max(4096)).optional().check(p.refine(o=>!o||Object.keys(o).length<=100,"Maximum 100 environment variables per role")),en=p.object({name:p.string().min(1,"name is required").regex(/^[\p{L}\p{N}_-]+$/u,"name must contain only letters, numbers, underscores, or hyphens"),cagPrompt:p.string().optional(),learnedRules:p.array(p.string()).optional(),allowedTools:p.array(p.string()).optional(),disallowedTools:p.array(p.string()).optional(),evaluationCriteria:p.record(p.string(),p.number()).optional(),executionMode:p.enum(["isolated","inline"]).optional(),model:p.string().optional(),maxBudgetUsd:p.number().optional(),approvalRequired:p.array(p.string()).optional(),preferences:Wr.optional(),additionalDirectories:p.array(Vr).optional(),allowedChannels:p.array(p.string()).optional(),inheritUserSettings:p.boolean().optional(),envVars:Gr}),tn=p.object({name:p.string().min(1).optional(),cagPrompt:p.string().optional(),learnedRules:p.array(p.string()).optional(),status:p.enum(["active","inactive","retired"]).optional(),allowedTools:p.array(p.string()).optional(),disallowedTools:p.array(p.string()).optional(),evaluationCriteria:p.record(p.string(),p.number()).optional(),executionMode:p.enum(["isolated","inline"]).optional(),model:p.string().optional(),maxBudgetUsd:p.number().optional(),approvalRequired:p.array(p.string()).optional(),preferences:Wr.optional(),additionalDirectories:p.array(Vr).optional(),allowedChannels:p.array(p.string()).nullable().optional(),inheritUserSettings:p.boolean().optional(),envVars:Gr}),qe=p.object({id:p.string().min(1)}),sn=p.object({status:p.enum(["active","inactive","retired"]).optional(),limit:p.coerce.number().min(1).max(100).default(100),offset:p.coerce.number().min(0).default(0)}),rn=p.object({path:p.string().min(1)});async function $r(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:100,default:100},offset:{type:"integer",minimum:0,default:0}}}}},async(s,e)=>{let r=sn.safeParse(s.query);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:p.prettifyError(r.error)});let{status:t,limit:a,offset:n}=r.data;return{roles:ge(t,a,n).map(c=>({...c,workspacePath:te(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(s,e)=>{let r=en.safeParse(s.body);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:p.prettifyError(r.error)});let{name:t,cagPrompt:a,learnedRules:n,allowedTools:i,disallowedTools:c,evaluationCriteria:l,executionMode:d,model:m,maxBudgetUsd:b,approvalRequired:I,preferences:y,additionalDirectories:g,allowedChannels:A,inheritUserSettings:V,envVars:ne}=r.data;if(tt(t))return e.status(409).send({code:"CONFLICT",message:`Role with name '${t}' already exists`});let H={id:`role-${Ur().slice(0,8)}`,name:t,cagPrompt:a??"",learnedRules:n??[],memoryStreamId:`mem-${Ur().slice(0,8)}`,status:"active",preferences:y??{},allowedTools:i,disallowedTools:c,evaluationCriteria:l,executionMode:d,model:m,maxBudgetUsd:b,approvalRequired:I,additionalDirectories:g,allowedChannels:A,inheritUserSettings:V,envVars:ne,createdAt:Date.now()};return et(H),at(H),e.status(201).send({role:H})}),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(s,e)=>{let r=qe.safeParse(s.params);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:p.prettifyError(r.error)});let t=L(r.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let a=te(t.name),n=_e({scope:"project",projectPath:a});return{role:t,projectPlugins:n,workspacePath:a}}),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(s,e)=>{let r=p.object({id:p.string().min(1)}).safeParse(s.params);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:p.prettifyError(r.error)});let t=L(r.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let a=s.query.limit??20,n=fs(t.id,a),i=hs(t.id);return{scores:n,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"]},preferences:{type:"object",properties:{model:{type:"string"},effort:{type:"string",enum:["low","medium","high","max"]},maxTurns:{type:"number"}}}}}}},async(s,e)=>{let r=qe.safeParse(s.params);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:p.prettifyError(r.error)});let t=tn.safeParse(s.body);if(!t.success)return e.status(400).send({code:"VALIDATION_ERROR",message:p.prettifyError(t.error)});if(!L(r.data.id))return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let{allowedChannels:n,...i}=t.data,c={...i,updatedAt:Date.now()};if(n!==void 0&&(c.allowedChannels=n??void 0),Ce(r.data.id,c),t.data.cagPrompt!==void 0||t.data.learnedRules!==void 0){let d=L(r.data.id);if(d){let m=te(d.name);It(m)&&nt(m,d)}}let l=L(r.data.id);if(l&&(t.data.allowedTools!==void 0||t.data.disallowedTools!==void 0)){let d=te(l.name);It(d)&&ot(l.id,l.allowedTools,d)}return{role:l}}),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(s,e)=>{let r=qe.safeParse(s.params);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:p.prettifyError(r.error)});let t=L(r.data.id);if(!t)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});if(t.id===rs)return e.status(403).send({code:"FORBIDDEN",message:"System role 'chat-manager' cannot be deleted"});let a=te(t.name);if(It(a))try{Za(a,{recursive:!0,force:!0})}catch{}return st(r.data.id),{roleId:r.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(s,e)=>{let r=qe.safeParse(s.params);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:p.prettifyError(r.error)});let t=rn.safeParse(s.body);if(!t.success)return e.status(400).send({code:"VALIDATION_ERROR",message:p.prettifyError(t.error)});if(!L(r.data.id))return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let n=Is(t.data.path);return{path:t.data.path,enabledPlugins:n.enabledPlugins,mcpServers:n.mcpServers,allowedTools:n.allowedTools,disallowedTools:n.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(s,e)=>{let r=L(s.params.id);return r?{diffs:es(r.name,r.envVars),envFileExists:rt(r.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(s,e)=>{let r=L(s.params.id);return r?{success:!0,changed:ts(r.name,r.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(s,e)=>{let r=L(s.params.id);if(!r)return e.status(404).send({code:"NOT_FOUND",message:"Role not found"});let t=rt(r.name);if(!t)return e.status(400).send({code:"NOT_FOUND",message:".env file not found in role workspace"});let a={};for(let[n,i]of Object.entries(t))n.startsWith("ANTHROPIC_")||(a[n]=i);return Ce(r.id,{envVars:Object.keys(a).length>0?a:void 0,updatedAt:Date.now()}),{success:!0,updated:Object.keys(a).length}})}me();import{z as Hr}from"zod/v4";import{readdirSync as an,existsSync as nn}from"fs";import{join as kt,resolve as Kr,sep as Qr}from"path";import{homedir as on}from"os";var cn=20,dn=Hr.object({prefix:Hr.string()});function Yr(o){return o.startsWith("~/")?kt(on(),o.slice(2)):o}function zr(o){let s=Kr(o);for(let e of Mt){let r=Yr(e),t=Kr(r);if(s===t||s.startsWith(t+Qr))return!0}return!1}async function Xr(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(s,e)=>{let r=dn.safeParse(s.query);if(!r.success)return{suggestions:[]};let{prefix:t}=r.data;if(!t.startsWith("/")&&!t.startsWith("~/"))return{suggestions:[]};if(zr(t))return{suggestions:[]};let a=Yr(t),n,i;if(t.endsWith("/"))n=a,i="";else{let g=Math.max(a.lastIndexOf("/"),a.lastIndexOf(Qr));if(g<0)return{suggestions:[]};n=a.slice(0,g+1),i=a.slice(g+1)}if(!nn(n))return{suggestions:[]};let c;try{c=an(n,{withFileTypes:!0}).filter(g=>g.isDirectory()).map(g=>g.name)}catch{return{suggestions:[]}}let l=i.toLowerCase(),d=c.filter(g=>g.toLowerCase().startsWith(l)),I=(i.startsWith(".")?d:d.filter(g=>!g.startsWith("."))).filter(g=>!zr(kt(n,g)));return I.sort((g,A)=>g.localeCompare(A,void 0,{sensitivity:"base"})),{suggestions:I.slice(0,cn).map(g=>kt(n,g))}})}import{z as w}from"zod/v4";Ae();import{v4 as ln}from"uuid";var pn=w.object({roleId:w.string().min(1)}),un=w.object({roleId:w.string().min(1),prompt:w.string().min(1),topK:w.number().min(1).max(50).default(10)}),mn=w.object({limit:w.coerce.number().min(1).max(200).default(50),offset:w.coerce.number().min(0).default(0)});function Tt(o){return L(o)!==void 0}async function Zr(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(r,t)=>{let a=pn.safeParse(r.params);if(!a.success)return t.status(400).send({code:"VALIDATION_ERROR",message:w.prettifyError(a.error)});let n=a.data.roleId;if(!Tt(n))return t.status(404).send({code:"NOT_FOUND",message:"Role or agent not found"});let i=mn.safeParse(r.query),{limit:c,offset:l}=i.success?i.data:{limit:50,offset:0},m=ws(n,c,l).map(({embedding:b,...I})=>I);return{memories:m,count:m.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(r,t)=>{let a=un.safeParse(r.body);if(!a.success)return t.status(400).send({code:"VALIDATION_ERROR",message:w.prettifyError(a.error)});let{roleId:n,prompt:i,topK:c}=a.data;if(!Tt(n))return t.status(404).send({code:"NOT_FOUND",message:"Role or agent not found"});let d=(await lt(n,i,{topK:c})).map(({embedding:m,...b})=>b);return{memories:d,count:d.length}});let s=w.object({roleId:w.string().min(1),content:w.string().min(1),type:w.enum(["event","thought","reflection"]).default("thought"),keywords:w.array(w.string()).default([]),importance:w.number().min(1).max(5).default(3),tier:w.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(r,t)=>{let a=s.safeParse(r.body);if(!a.success)return t.status(400).send({code:"VALIDATION_ERROR",message:w.prettifyError(a.error)});let{roleId:n,content:i,type:c,keywords:l,importance:d,tier:m}=a.data;if(!Tt(n))return t.status(404).send({code:"NOT_FOUND",message:"Role or agent not found"});let b;try{b=await it(i)}catch{}let I=`mem-${ln().slice(0,8)}`,y=Date.now();Ts({id:I,roleId:n,type:c,content:i,embedding:b,keywords:l,importance:d,sourceType:"manual",createdAt:y,lastAccessed:y,retrievedCount:0,tier:m??"episodic"});let g=Ee(I),{embedding:A,...V}=g;return t.status(201).send({memory:V})});let e=w.object({content:w.string().min(1).optional(),type:w.enum(["event","thought","reflection"]).optional(),keywords:w.array(w.string()).optional(),importance:w.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(r,t)=>{let{id:a}=r.params;if(!Ee(a))return t.status(404).send({code:"NOT_FOUND",message:"Memory not found"});let i=e.safeParse(r.body);if(!i.success)return t.status(400).send({code:"VALIDATION_ERROR",message:w.prettifyError(i.error)});let c=i.data,l,d=!0;if(c.content)try{l=await it(c.content)}catch{d=!1}let m=Ss(a,{content:c.content,embedding:l,keywords:c.keywords,importance:c.importance,type:c.type});return{memoryId:a,updated:m,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(r,t)=>{let{id:a}=r.params;return Ee(a)?(Cs(a),{memoryId:a,deleted:!0}):t.status(404).send({code:"NOT_FOUND",message:"Memory not found"})})}import{query as hn}from"@anthropic-ai/claude-agent-sdk";import{v4 as ae}from"uuid";function gn(){try{return E().defaults.maxBudgetUsd}catch{return 5}}function St(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.
|
|
@@ -85,4 +85,4 @@ User: ${s}`),n.join(`
|
|
|
85
85
|
... \u67E5\u770B\u5B8C\u6574\u7ED3\u679C\u8BF7\u8BBF\u95EE Web UI`:n;this.deliverToChannel(a.source.channelId,a.source.chatId,g,"deliver",s)}if(t?.parentId){let y=se(t.parentId);if(y){let g=Yt(t.parentId);if(g.every(V=>V.status==="completed"||V.status==="failed")){let V=g.some(H=>H.status==="failed"),ne=V?"failed":"completed";Oe(t.parentId,{status:ne,updatedAt:Date.now()}),D.info({goalId:t.parentId,goalName:y.name,finalStatus:ne},"Goal completed");let J=`${V?"\u274C":"\u2705"} \u76EE\u6807\u5B8C\u6210: ${y.name}
|
|
86
86
|
|
|
87
87
|
${g.length} \u4E2A\u5B50\u4EFB\u52A1\u5168\u90E8\u5B8C\u6210`;await this.routeGoalNotification(y,J,t.parentId)}}}}async getRoleName(s){try{let{getRole:e}=await import("./roles-3UTFKSHI.js");return e(s)?.name}catch{return}}async deliverToChannel(s,e,r,t="reply",a){if(!s||!e){D.warn({channelId:s,chatId:e},"Cannot deliver to channel: missing channelId or chatId");return}try{let i=await ur().send({taskId:a,channelId:s,chatId:e,content:r,messageType:t});i.success?D.info({channelId:s,chatId:e.slice(0,12),messageType:t,taskId:a?.slice(0,8),messageId:i.messageId},"Delivered notification to channel"):D.warn({channelId:s,chatId:e.slice(0,12),messageType:t,taskId:a?.slice(0,8),error:i.error},"Channel delivery failed")}catch(n){D.error({error:n,channelId:s,chatId:e.slice(0,12)},"Failed to deliver to channel")}}async routeGoalNotification(s,e,r){let t=s.deliverTo??[],a=s.sourceSessionId;if(!(t.length===0&&!a)){for(let n of t)if(n.type==="session")try{let i=M(n.sessionId);i&&(K({id:ae(),sessionId:n.sessionId,role:"assistant",content:e,source:i.source,createdAt:Date.now()}),z(n.sessionId),f.emit({type:"chat_message",sessionId:n.sessionId,message:{id:ae(),sessionId:n.sessionId,role:"assistant",content:e,source:i.source,createdAt:Date.now()}}))}catch(i){D.error({error:i,goalId:r,targetSession:n.sessionId},"Failed to deliver Goal notification to session")}else n.type==="channel"&&await this.deliverToChannel(n.channelId,n.chatId??"",e);if(a&&!t.some(n=>n.type==="session"&&n.sessionId===a))try{let n=M(a);n&&(K({id:ae(),sessionId:a,role:"assistant",content:e,source:n.source,createdAt:Date.now()}),z(a),f.emit({type:"chat_message",sessionId:a,message:{id:ae(),sessionId:a,role:"assistant",content:e,source:n.source,createdAt:Date.now()}}))}catch(n){D.error({error:n,goalId:r,sessionId:a},"Failed to deliver Goal notification to source session")}}}getLastActivityAt(){return this.lastActivityAt}getConsecutiveStaleCount(){return this.consecutiveStaleCount}isHealthy(){return this.running}async restartSession(){D.warn("Restarting ChatManager session (Watchdog triggered)"),this.consecutiveStaleCount++,this.sessionId=void 0,Ne(void 0)}};import{v4 as wt}from"uuid";Y();var Ct=q("message-handler");async function vn(o,s){if(!(await import("./config-7HYICF5P.js").then(t=>t.getChatConfig())).autoTitle)return;let r=["Generate a very short title (max 50 characters) for a chat session that started with this message:",`"${s.slice(0,200)}"`,"Respond with only the title, no quotes or explanation."].join(`
|
|
88
|
-
`);try{let a=(await Gs(r,"You are a concise title generator. Reply with only the title, max 50 characters.")).trim().slice(0,50);a.length>0&&ys(o,{title:a})}catch{}}var At=null;function ta(o){At=o}async function Le(o,s,e,r){let t;r&&(t=M(r)),t||(t=qs(s)),t||(t=Fe(s,e));let a=wt(),n={id:a,sessionId:t.id,role:"user",content:o,source:s,createdAt:Date.now()};if(K(n),f.emit({type:"chat_message",sessionId:t.id,message:n}),t.messageCount===0&&vn(t.id,o),z(t.id),pt(t.id),At){let i=t.id,c=t.source;(async()=>{try{let l=await At.handleMessage(o,i,s),d={id:wt(),sessionId:i,role:"assistant",content:l,source:s,createdAt:Date.now()};K(d),f.emit({type:"chat_message",sessionId:i,message:d}),z(i),pt(i),c.type==="channel"&&c.channelId&&c.chatId&&(Ct.info({sessionId:i,sourceType:c.type,hasChannelId:!!c.channelId,hasResponse:!!l},"Chat response ready, checking channel delivery"),Rn(c.channelId,c.chatId,l))}catch(l){(await import("./logger-QCJUU7GV.js")).getLogger("message-handler").error({error:l,sessionId:i},"ChatManager response failed");let m={id:wt(),sessionId:i,role:"assistant",content:`\u26A0\uFE0F \u5904\u7406\u5931\u8D25: ${l instanceof Error?l.message:String(l)}`,source:s,createdAt:Date.now()};K(m),f.emit({type:"chat_message",sessionId:i,message:m}),z(i)}})()}return{sessionId:t.id,messageId:a}}async function Rn(o,s,e){Ct.info({channelId:o,chatId:s.slice(0,12)},"Delivering chat response to channel");try{let{getOutboundGateway:r}=await import("./outbound-gateway-6FQRWYFF.js");await r().send({channelId:o,chatId:s,content:e,messageType:"reply"})}catch(r){Ct.error({error:r,channelId:o,chatId:s.slice(0,12)},"Channel delivery failed (non-fatal)")}}import{z as h}from"zod/v4";import{v4 as In}from"uuid";var sa=h.union([h.object({type:h.literal("session"),sessionId:h.string()}),h.object({type:h.literal("channel"),channelId:h.string(),chatId:h.string().optional()})]),kn=h.object({id:h.string(),prompt:h.string(),dependsOn:h.array(h.string()).optional(),outputAs:h.string().optional()}),Tn=h.object({type:h.enum(["cron","manual","event","once"]),cron:h.string().optional(),event:h.string().optional(),runAt:h.string().optional()}),Pt=h.object({name:h.string().min(1),description:h.string().optional(),trigger:Tn,steps:h.array(kn).min(1),rolePreference:h.string().optional(),config:h.record(h.string(),h.unknown()).optional(),enabled:h.boolean().default(!0),goalIds:h.array(h.string()).optional(),deliverTo:h.array(sa).optional(),reportTo:h.array(sa).optional()}),vc=Pt.transform(o=>({...o,deliverTo:o.deliverTo,reportTo:o.reportTo})),Sn=Pt.partial().transform(o=>({...o,deliverTo:o.deliverTo,reportTo:o.reportTo})),Me=h.object({id:h.string().min(1)});async function ra(o,s){o.post("/task-templates",{schema:{tags:["Templates"],summary:"Create a task template",description:"Create a new task template with trigger (cron/manual/event) 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","event","once"]},cron:{type:"string",description:"Cron expression (required when type is cron)"},event:{type:"string",description:"Event name (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"}}}},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,r)=>{let t=Pt.safeParse(e.body);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(t.error)});let a={id:In(),...t.data,createdAt:Date.now()};return Ps(a),a.enabled&&a.trigger.type==="cron"&&a.trigger.cron?await s.scheduleJob(a.id):a.enabled&&a.trigger.type==="once"&&a.trigger.runAt&&s.scheduleOnceJob(a.id),r.status(201).send({templateId:a.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:Es(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,r)=>{let t=Me.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(t.error)});let a=Z(t.data.id);return a?{template:a}:r.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","event","once"]},cron:{type:"string"},event:{type:"string"},runAt:{type:"string"}}},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,r)=>{let t=Me.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(t.error)});let a=Sn.safeParse(e.body);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(a.error)});if(!Z(t.data.id))return r.status(404).send({code:"NOT_FOUND",message:"Template not found"});_s(t.data.id,a.data),await s.unscheduleJob(t.data.id);let i=Z(t.data.id);return i?.enabled&&i.trigger.type==="cron"&&i.trigger.cron?await s.scheduleJob(i.id):i?.enabled&&i.trigger.type==="once"&&i.trigger.runAt&&s.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,r)=>{let t=Me.safeParse(e.params);return t.success?Z(t.data.id)?(await s.unscheduleJob(t.data.id),Os(t.data.id),{templateId:t.data.id,deleted:!0}):r.status(404).send({code:"NOT_FOUND",message:"Template not found"}):r.status(400).send({code:"VALIDATION_ERROR",message:h.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,r)=>{let t=Me.safeParse(e.params);return t.success?Z(t.data.id)?{executionId:await s.runNow(t.data.id),status:"started"}:r.status(404).send({code:"NOT_FOUND",message:"Template not found"}):r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(t.error)})})}import{z as P}from"zod/v4";ks();var _t=P.object({id:P.string().min(1)}),wn=P.object({scope:P.enum(["user","project"]).optional(),cwd:P.string().optional()}),Cn=P.object({scope:P.enum(["user","project"]).optional(),cwd:P.string().optional()});async function aa(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 r=e.query,t=_e({scope:r.scope}),a=dt();return{plugins:t.map(n=>({...n,globalEnabled:a[n.id]??n.enabled}))}}),o.get("/plugins/:id",{schema:{tags:["Plugins"],summary:"Get plugin by ID",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,r)=>{let t=_t.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)});let a=vs(t.data.id);if(!a)return r.status(404).send({code:"NOT_FOUND",message:"Plugin not found"});let n=bs(a.installPath),i=dt();return{plugin:{...a,globalEnabled:i[a.id]??a.enabled,manifest:n}}}),o.post("/plugins/:id/enable",{schema:{tags:["Plugins"],summary:"Enable a plugin globally",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,r)=>{let t=_t.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)});if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude CLI not found. Plugin enable/disable requires the Claude Agent SDK CLI."});try{return er(t.data.id),{pluginId:t.data.id,enabled:!0}}catch(a){return r.status(500).send({code:"CLI_ERROR",message:a instanceof Error?a.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,r)=>{let t=_t.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)});if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude CLI not found. Plugin enable/disable requires the Claude Agent SDK CLI."});try{return tr(t.data.id),{pluginId:t.data.id,enabled:!1}}catch(a){return r.status(500).send({code:"CLI_ERROR",message:a instanceof Error?a.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 r=e.query;return{stats:fr(r.limit??50)}});let s=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,r)=>{let t=s.safeParse(e.params);return t.success?{roleId:t.data.roleId,stats:yr(t.data.roleId)}:r.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,r)=>{if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found. Install Claude Code to use marketplace features."});try{let t=Xs();return{available:t.available,installed:t.installed}}catch(t){return r.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:Rs()})),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,r)=>{let a=P.object({name:P.string().min(1)}).safeParse(e.params);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(a.error)});let n=wn.safeParse(e.body??{});if(!n.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(n.error)});if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found"});try{return Zs(a.data.name,n.data.scope??"user",n.data.cwd),{success:!0,pluginId:a.data.name}}catch(i){return r.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,r)=>{let a=P.object({name:P.string().min(1)}).safeParse(e.params);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(a.error)});let n=Cn.safeParse(e.body??{});if(!n.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(n.error)});if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found"});try{return Js(a.data.name,n.data.scope,n.data.cwd),{success:!0,pluginId:a.data.name}}catch(i){return r.status(500).send({code:"CLI_ERROR",message:i instanceof Error?i.message:"Uninstall failed"})}})}import{z as Et}from"zod/v4";var An=Et.object({name:Et.string().min(1)}),Pn="x-api-key";async function na(o,s,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(r,t)=>{if(e&&r.headers[Pn]!==e)return t.status(401).send({code:"UNAUTHORIZED",message:"Invalid or missing API key"});let a=An.safeParse(r.params);if(!a.success)return t.status(400).send({code:"VALIDATION_ERROR",message:Et.prettifyError(a.error)});let{name:n}=a.data,i=Z(n);if(!i){let{listTaskTemplates:c}=await import("./task-templates-PSP7GOJJ.js");i=c(!1).find(d=>d.name===n||d.id===n)}if(!i)return t.status(404).send({code:"NOT_FOUND",message:`Template '${n}' not found`});if(!i.enabled)return t.status(409).send({code:"DISABLED",message:`Template '${n}' is disabled`});try{let c=await s.runNow(i.id);return t.status(202).send({code:"ACCEPTED",message:`Template '${i.name}' triggered`,executionId:c,templateId:i.id})}catch(c){let l=c instanceof Error?c.message:String(c);return t.status(500).send({code:"EXECUTION_ERROR",message:l})}}),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:r}=await import("./task-templates-PSP7GOJJ.js");return{webhooks:r(!0).map(a=>({name:a.id,displayName:a.name,description:a.description,tags:a.tags,trigger:`POST /webhooks/${a.id}`})),auth:e?"X-API-Key header required":"No auth configured"}})}import{z as k}from"zod/v4";var _n=k.object({status:k.string().optional(),limit:k.coerce.number().min(1).max(100).default(20),offset:k.coerce.number().min(0).default(0)}),Be=k.union([k.object({type:k.literal("session"),sessionId:k.string()}),k.object({type:k.literal("channel"),channelId:k.string(),chatId:k.string().optional()})]),En=k.object({input:k.string().min(1,"goal input is required"),deliverTo:k.array(Be).optional(),reportTo:k.array(Be).optional()}),oa=k.object({id:k.string().min(1)}),On=k.object({name:k.string().min(1).optional(),description:k.string().optional(),status:k.enum(["active","paused","completed","failed"]).optional(),currentValue:k.number().optional(),budgetUsd:k.number().min(0).optional(),deliverTo:k.array(Be).optional(),reportTo:k.array(Be).optional()});async function ia(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(s,e)=>{let r=_n.safeParse(s.query);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(r.error)});let{status:t,limit:a,offset:n}=r.data;return{goals:Fs(t,a,n)}}),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(s,e)=>{let r=se(s.params.id);return r?{goal:r}: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(s,e)=>{let r=En.safeParse(s.body);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(r.error)});let t=await $s(r.data.input);if(!t.validationResult.isValid)return e.status(400).send({code:"INVALID_GOAL",errors:t.validationResult.errors,warnings:t.validationResult.warnings});let a=Hs(t.goalState,r.data.deliverTo,r.data.reportTo);return Ks(a.id,a.metricType),e.status(201).send({goal:a})}),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(s,e)=>{let r=oa.safeParse(s.params);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(r.error)});let t=On.safeParse(s.body);return t.success?se(r.data.id)?(Oe(r.data.id,{...t.data,updatedAt:Date.now()}),{goal:se(r.data.id)}):e.status(404).send({code:"NOT_FOUND",message:"Goal not found"}):e.status(400).send({code:"VALIDATION_ERROR",message:k.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(s,e)=>{let r=oa.safeParse(s.params);return r.success?se(r.data.id)?(Ds(r.data.id),{goalId:r.data.id,deleted:!0}):e.status(404).send({code:"NOT_FOUND",message:"Goal not found"}):e.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(r.error)})})}import{z as be}from"zod/v4";var Fn=be.object({role:be.string().optional(),taskType:be.string().optional(),limit:be.coerce.number().min(1).max(100).default(50)});async function ca(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(s,e)=>{let r=Fn.safeParse(s.query);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:be.prettifyError(r.error)});let{role:t,taskType:a,limit:n}=r.data,i;return t&&a?i=Ys.getStrategies(t,a):t?i=Qs(t):i=zs(n),{strategies:i.slice(0,n)}})}Jt();Y();import{z as Q}from"zod/v4";async function da(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,r)=>{let t=E(),a=mr(),n=[...Ie,...ze],i={},c=new Set(["anthropic.apiKey","server.apiKey"]);for(let l of n){let d=Qe(t,l),m=Ie.includes(l);c.has(l)&&typeof d=="string"&&d.length>0&&(d=d.slice(0,5)+"****"),i[l]={value:d??null,mutable:m}}return{config:i,mutable:[...Ie],restartRequired:[...ze],sandbox:{platform:a.platform,available:await gr()}}}),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,r)=>{let t=e.body;if(!t||typeof t!="object")return r.status(400).send({success:!1,updated:[],errors:["Request body must be a JSON object with config key-value pairs"],message:"Validation error"});let a=Lt(t,oe);if(a.updated.includes("logging.level")){let n=t["logging.level"];typeof n=="string"&&Te(n)}if(a.updated.length>0){let n=E(),i=a.updated.map(c=>({path:c,value:Qe(n,c)}));f.emit({type:"config_changed",changes:i})}return{success:a.errors.length===0,updated:a.updated,errors:a.errors,message:a.errors.length===0?`Updated ${a.updated.length} configuration value(s)`:`Updated ${a.updated.length} value(s); ${a.errors.length} rejected (restart required)`}}),o.get("/config/env-diff",async()=>{let e=we();return{diffs:Vt(e),envFileExists:Ut()!==null}}),o.post("/config/sync-to-env",async()=>{let e=we();return{success:!0,changed:Gt(e)}}),o.post("/config/load-from-env",async()=>{let e=Wt();if(!e)return{success:!1,error:".env file not found"};let r=0;for(let[a,n]of Object.entries(e)){let i=Object.entries(Ye).find(([,c])=>c===a)?.[0];i&&(oe(i,n),r++)}let t={};for(let[a,n]of Object.entries(e))a in Ye||a.startsWith("ANTHROPIC_")||a.startsWith("ADAM_")||(t[a]=n);return Object.keys(t).length>0&&(oe("defaults.env",t),E().defaults.env=t,r+=Object.keys(t).length),ke(we),{success:!0,updated:r}});let s=Q.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(Q.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:E().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,r)=>{let a=Q.record(s,Q.string().max(4096)).check(Q.refine(i=>Object.keys(i).length<=100,"Maximum 100 environment variables")).safeParse(e.body);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:Q.prettifyError(a.error)});let n=a.data;return oe("defaults.env",n),E().defaults.env=n,f.emit({type:"config_changed",changes:[{path:"defaults.env",value:n}]}),{success:!0,count:Object.keys(n).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,r)=>{let a=Q.record(s,Q.string().max(4096).nullable()).safeParse(e.body);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:Q.prettifyError(a.error)});let n={...E().defaults?.env??{}};for(let[i,c]of Object.entries(a.data))c===null?delete n[i]:n[i]=c;return Object.keys(n).length>100?r.status(400).send({code:"VALIDATION_ERROR",message:"Maximum 100 environment variables"}):(oe("defaults.env",n),E().defaults.env=n,f.emit({type:"config_changed",changes:[{path:"defaults.env",value:n}]}),{success:!0,count:Object.keys(n).length})})}async function la(o){o.get("/audit/posture",async(s,e)=>{let r=await vr();return e.send(r)})}async function pa(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(s,e)=>{let{limit:r=20,offset:t=0,roleId:a}=s.query;return a?ir(a,r,t):or(r,t)})}import{z as T}from"zod/v4";var Dn=["active","archived"],xn=T.object({source:T.object({type:T.enum(["tui","web","api","channel"]),channelId:T.string().optional(),chatId:T.string().optional()}),roleId:T.string().optional()}),ve=T.object({id:T.string().uuid()}),jn=T.object({status:T.enum(Dn).optional(),limit:T.coerce.number().min(1).max(100).default(100),offset:T.coerce.number().min(0).default(0)}),Nn=T.object({limit:T.coerce.number().min(1).max(200).default(50),offset:T.coerce.number().min(0).default(0)});async function ua(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,r)=>{let t=xn.safeParse(e.body);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let{source:a,roleId:n}=t.data,i=Fe(a,n);return r.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,r)=>{let t=jn.safeParse(e.query);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let{status:a}=t.data;return{sessions:Us(a)}}),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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=M(t.data.id);if(!a)return r.status(404).send({code:"NOT_FOUND",message:"Session not found"});let n=ct(a.id);return{session:a,messages:n}}),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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=M(t.data.id);return a?(Ls(a.id),{sessionId:a.id,status:"archived"}):r.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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=Ms(t.data.id);return a?{session:a}:r.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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=M(t.data.id);return a?(Bs(a.id),r.status(204).send()):r.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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=M(t.data.id);if(!a)return r.status(404).send({code:"NOT_FOUND",message:"Session not found"});let n=Nn.safeParse(e.query),{limit:i=50,offset:c=0}=n.success?n.data:{};return{messages:ct(a.id,i,c)}});let s=T.object({content:T.string().min(1,"content is required"),source:T.object({type:T.enum(["tui","web","api","channel"]),channelId:T.string().optional(),chatId:T.string().optional()}),roleId:T.string().optional(),sessionId:T.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,r)=>{let t=s.safeParse(e.body);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let{content:a,source:n,roleId:i,sessionId:c}=t.data,l=await Le(a,n,i,c);return r.status(201).send(l)})}Y();var qn=q("ws"),Ue=new Set,We=[],Ln=50;function Mn(o){We.push(o),We.length>Ln&&We.shift()}function de(o){Mn(o);let s=JSON.stringify(o);for(let e of Ue)e.readyState===1&&e.send(s)}function ma(o){o.get("/chat/stream",{websocket:!0},(s,e)=>{Ue.add(s);for(let r of We)s.readyState===1&&s.send(JSON.stringify(r));s.on("close",()=>{Ue.delete(s)}),s.on("error",r=>{qn.error({error:r},"Chat WebSocket error"),Ue.delete(s)})}),f.on("session_created",s=>de(s)),f.on("session_archived",s=>de(s)),f.on("session_restored",s=>de(s)),f.on("session_deleted",s=>de(s)),f.on("chat_message",s=>de(s)),f.on("task_complete_event",s=>de(s))}Y();var j=q("channels"),Ve=class{adapters=new Map;rateLimits=new Map;healthInterval;rateLimitPerMinute;constructor(s){this.rateLimitPerMinute=s?.rateLimitPerMinute??60}async addChannel(s,e){this.adapters.set(s.id,e),e.onMessage(r=>{this.handleInbound(s.id,r)}),s.enabled&&await this.connectChannel(s.id)}async removeChannel(s){let e=this.adapters.get(s);if(e){try{await e.disconnect()}catch(r){j.error({channelId:s,error:r},"Error disconnecting channel")}this.adapters.delete(s),this.rateLimits.delete(s)}}async connectChannel(s){let e=this.adapters.get(s);if(!e)throw new Error(`No adapter registered for channel ${s}`);try{ie(s,"connecting"),await e.connect(),ie(s,"connected"),j.info({channelId:s,platform:e.platform},"Channel connected")}catch(r){throw ie(s,"error"),j.error({channelId:s,error:r},"Failed to connect channel"),r}}async disconnectChannel(s){let e=this.adapters.get(s);if(e)try{await e.disconnect(),ie(s,"disconnected"),j.info({channelId:s},"Channel disconnected")}catch(r){j.error({channelId:s,error:r},"Error disconnecting channel")}}getChannelStatus(s){let e=this.adapters.get(s);return e?e.getStatus():"disconnected"}getChannelStatuses(){let s=new Map;for(let[e,r]of this.adapters)s.set(e,r.getStatus());return s}hasAdapter(s){return this.adapters.has(s)}async sendMessage(s,e,r){let t=this.adapters.get(s);if(!t)return j.warn({channelId:s},"No adapter for outbound message"),null;if(!this.checkRateLimit(s))return j.warn({channelId:s},"Rate limit exceeded, dropping outbound message"),null;try{return await t.sendMessage(e,r)}catch(a){return j.error({channelId:s,chatId:e,error:a},"Failed to send outbound message"),null}}checkRateLimit(s){let e=Date.now(),r=this.rateLimits.get(s);return!r||e-r.windowStart>=6e4?(this.rateLimits.set(s,{count:1,windowStart:e}),!0):r.count>=this.rateLimitPerMinute?!1:(r.count++,!0)}async handleInbound(s,e){if(e.source==="system"){j.debug({channelId:s},"Skipping system message (anti-loop)");return}try{let{isRecentlySent:t}=await import("./outbound-gateway-6FQRWYFF.js"),a=e.channelMessageId??e.raw?.MsgId??"";if(a&&t(String(a))){j.debug({channelId:s,messageId:a},"Skipping delivery-sent message (anti-loop)");return}}catch{}if(!this.checkRateLimit(s)){j.warn({channelId:s,senderId:e.senderId},"Rate limit exceeded for inbound message");return}try{let{handleInboundForApproval:t}=await import("./approval-handler-JYIS2PKQ.js");if(await t(s,e.chatId,e.content)){j.debug({channelId:s,chatId:e.chatId},"Inbound message consumed as approval reply");return}}catch{}let r=Ns(s);if(r?.allowedChatIds&&!r.allowedChatIds.includes(e.chatId)){j.debug({channelId:s,chatId:e.chatId},"Chat not in allowlist, ignoring");return}try{let t=await Le(e.content,{type:"channel",channelId:s,chatId:e.chatId},r?.linkedRoleId);j.info({channelId:s,chatId:e.chatId,sessionId:t.sessionId},"Inbound message routed to session")}catch(t){j.error({channelId:s,chatId:e.chatId,error:t},"Failed to route inbound message")}}startHealthMonitor(s=3e4){this.stopHealthMonitor(),this.healthInterval=setInterval(()=>{this.checkHealth()},s)}stopHealthMonitor(){this.healthInterval&&(clearInterval(this.healthInterval),this.healthInterval=void 0)}checkHealth(){for(let[s,e]of this.adapters){let r=e.getStatus();try{ie(s,r)}catch{}}}async startAll(){let s=ye(!0);for(let e of s){let r=this.adapters.get(e.id);if(r&&r.getStatus()!=="connected")try{await this.connectChannel(e.id)}catch{}}this.startHealthMonitor()}async stopAll(){this.stopHealthMonitor();for(let s of this.adapters.keys())await this.disconnectChannel(s);this.adapters.clear(),this.rateLimits.clear()}_getAdapterCount(){return this.adapters.size}_getRateLimitEntry(s){return this.rateLimits.get(s)}};Se();Y();var G=q("watchdog"),Ge=null;function ga(o,s,e,r){if(!o.enabled){G.info("Watchdog disabled");return}let t=o.intervalMinutes*6e4;G.info({intervalMinutes:o.intervalMinutes},"Watchdog started"),Ge=setInterval(()=>{Bn(o,s,e,r)},t)}function ya(){Ge&&(clearInterval(Ge),Ge=null,G.info("Watchdog stopped"))}function Bn(o,s,e,r){let{rules:t}=o;if(t.managerHealthCheck.enabled){let a=t.managerHealthCheck.staleDurationMinutes*6e4,n=s.getLastActivityAt();if(Date.now()-n>a){let i=`ChatManager session stale (no activity for ${t.managerHealthCheck.staleDurationMinutes} min)`;if(G.warn(i),t.managerHealthCheck.action==="restart"){let c=s.getConsecutiveStaleCount()>0;s.restartSession(),c&&(G.fatal("ChatManager unrecoverable after session restart \u2014 exiting for supervisor restart"),process.exit(1))}else t.managerHealthCheck.action==="notify"&&r(i)}}if(!e.isHealthy()){let a="ExecutionPool is not healthy (stopped unexpectedly)";G.warn(a),r(a)}if(t.staleTasks.enabled){let a=t.staleTasks.maxPendingMinutes*6e4,i=W("pending").filter(c=>Date.now()-c.createdAt>a);if(i.length>0){let c=`${i.length} stale task(s) pending > ${t.staleTasks.maxPendingMinutes} min`;G.warn({count:i.length},c),t.staleTasks.action==="notify"&&r(c)}}if(t.staleRunningTasks?.enabled){let a=t.staleRunningTasks.maxRunningMinutes*6e4,i=W("running").filter(c=>{if(!c.startedAt||Date.now()-c.startedAt<a)return!1;try{let b=U().prepare("SELECT MAX(timestamp) as latest FROM step_logs WHERE task_id = ?").get(c.id)?.latest??c.startedAt;return Date.now()-b>a}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`;G.warn({count:i.length,taskIds:i.map(l=>l.id)},c);for(let l of i)X(l.id,{status:"failed",error:`Watchdog timeout: no activity for > ${t.staleRunningTasks.maxRunningMinutes} min`,completedAt:Date.now()}),f.emit({type:"task_status_change",taskId:l.id,oldStatus:"running",newStatus:"failed"}),e.releaseSlot(l.id);r(c)}}if(t.dbMaintenance.enabled)try{let n=U().pragma("wal_checkpoint(PASSIVE)");G.debug({walSize:n},"WAL checkpoint")}catch(a){G.error({error:a},"DB health check failed")}}import{z as x}from"zod";import{v4 as Un}from"uuid";var Wn=x.object({eventType:x.enum(["task_complete","task_error","plan_approval_request","*"]),matchCriteria:x.object({templateId:x.string().optional(),roleId:x.string().optional(),promptPattern:x.string().optional(),taskStatus:x.string().optional()}).optional().default({}),target:x.object({type:x.enum(["channel","webhook"]),channelId:x.string().optional(),chatId:x.string().optional(),webhookUrl:x.string().optional()}),formatTemplate:x.string().optional(),maxPerMinute:x.number().int().min(1).max(60).optional().default(5),skipOriginChannel:x.boolean().optional().default(!0),enabled:x.boolean().optional().default(!0)});async function Ot(o){o.get("/delivery-rules",async(s,e)=>rr()),o.post("/delivery-rules",async(s,e)=>{let r=Wn.safeParse(s.body);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:x.prettifyError(r.error)});let t=r.data,a={id:Un(),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 sr(a),e.status(201).send(a)}),o.put("/delivery-rules/:id",async(s,e)=>{if(!De(s.params.id))return e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"});let t=s.body;return ar(s.params.id,t),{id:s.params.id,updated:!0}}),o.delete("/delivery-rules/:id",async(s,e)=>De(s.params.id)?(nr(s.params.id),{id:s.params.id,deleted:!0}):e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"})),o.get("/delivery-rules/:id/log",async(s,e)=>is(s.params.id)),o.post("/delivery-rules/:id/test",async(s,e)=>{let r=De(s.params.id);if(!r)return e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"});let{getDeliveryEngine:t}=await import("./engine-5RJ7NJSM.js"),a=t();if(!a)return e.status(503).send({code:"ENGINE_NOT_READY",message:"DeliveryEngine not initialized"});let n=`[TEST] Delivery rule test at ${new Date().toISOString()}`,{createDeliveryLog:i}=await import("./delivery-log-SC2ULFCK.js"),{v4:c}=await import("uuid"),{TTL_MS:l}=await import("./delivery-log-SC2ULFCK.js"),d={id:c(),ruleId:r.id,status:"pending",target:r.target,content:n,attempts:0,createdAt:Date.now(),expiresAt:Date.now()+l};i(d);try{return await a.attemptDeliveryPublic(d,r),{id:d.id,ruleId:r.id,status:"sent",content:n}}catch(m){let b=m instanceof Error?m.message:String(m);return e.status(500).send({code:"DELIVERY_FAILED",message:b,logId:d.id})}})}Y();me();me();import{existsSync as $e,copyFileSync as Vn,mkdirSync as Ft,cpSync as Gn}from"fs";import{join as $}from"path";function Dt(){Ft(O,{recursive:!0}),Ft($(O,"logs"),{recursive:!0}),Ft($(O,".claude"),{recursive:!0})}function fa(o=process.cwd()){Dt();let s=[],e=[{from:$(o,"data","adam.db"),to:$(O,"adam.db"),label:"database"},{from:$(o,"adam.config.yaml"),to:$(O,"adam.config.yaml"),label:"config"},{from:$(o,".env"),to:$(O,".env"),label:".env"}];for(let{from:a,to:n,label:i}of e)$e(a)&&!$e(n)&&(Vn(a,n),s.push(i));let r=$(o,".claude","plugins"),t=$(O,".claude","plugins");return $e(r)&&!$e(t)&&(Gn(r,t,{recursive:!0}),s.push("plugins")),s}Jt();var C=q("adam");function Hn(o){let s={...o};if(s.defaults&&typeof s.defaults=="object"){let e={...s.defaults};if(e.env&&typeof e.env=="object"){let r={...e.env};for(let t of Object.keys(r))r[t]&&(r[t]=r[t].slice(0,4)+"****");e.env=r}s.defaults=e}if(s.server&&typeof s.server=="object"){let e={...s.server};e.apiKey&&typeof e.apiKey=="string"&&(e.apiKey=e.apiKey.slice(0,4)+"****"),s.server=e}return s}async function Kn(){Dt();let o=fa();o.length>0&&console.log(`[adam] Migrated to ~/.adam/: ${o.join(", ")}`);let s=Tr();C.info("Starting Adam Agent Server"),s.length>0&&C.info({files:s},"Loaded env files");let e=Ht();Nt(e),E().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:Ia}=await import("module"),{dirname:ka,join:Ta}=await import("path"),Sa=Ia(import.meta.url).resolve("@anthropic-ai/claude-agent-sdk");t=Ta(ka(Sa),"cli.js")}let{execSync:v}=await import("child_process"),{chmodSync:N,accessSync:ee,constants:ue}=await import("fs");try{ee(t,ue.X_OK)}catch{C.info({path:t},"CLI not executable, fixing permissions"),N(t,493)}let Ra=v(`"${t}" --version`,{timeout:5e3,encoding:"utf-8"}).trim();C.info({path:t,version:Ra},"Claude Code CLI detected")}catch(v){let N=v;N.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:(N.stderr?.trim()||String(v)).slice(0,200)},"Claude Code CLI check failed")}let n=U().prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all();C.info({tables:n.map(v=>v.name).join(", ")},"Database initialized");let i=Kt(),c=Zt(i);c>0&&C.info({count:c},"Seeded config DB from .env");let{getAllConfig:l}=await import("./config-EI3SCA4W.js");ke(l);let d=E();d.logging?.level&&Te(d.logging.level),C.info({config:Hn(d)},"Config loaded (DB + defaults)");let m=Rt(),{getToolsFingerprint:b}=await import("./adam-tools-SXOVOPS2.js"),I=b(),y=m.sdkSessionId;if(y&&m.toolsFingerprint!==I&&(C.info({old:m.toolsFingerprint?.slice(0,40),new:I.slice(0,40)},"MCP tools changed \u2014 invalidating old SDK session"),Mr(),y=void 0),fe({toolsFingerprint:I}),y){let v=process.cwd();m.workspacePath&&m.workspacePath!==v&&(C.warn({serverCwd:v,saved:m.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");m.userTaskSessionId&&C.info({sessionId:m.userTaskSessionId.slice(0,8)},"Recovering user task session"),Br(process.cwd());let{initializeDefaultRoles:g}=await import("./role-presets-LRP6P5O2.js"),A=g();C.info({count:A.length},"Roles initialized");let ne=E().execution??{maxConcurrent:3,pollIntervalMs:3e4},J=new he(y),H=new yt(ne.maxConcurrent);ta(J),await J.start(),await H.start();let Ke=W("running");if(Ke.length>0){C.warn({count:Ke.length},"Found orphaned running tasks from previous session \u2014 marking as failed");for(let v of Ke)X(v.id,{status:"failed",error:"Server restarted while task was running",completedAt:Date.now()})}let _=Ar(e,e.server.apiKey);await _.register(v=>Or(v)),await _.register(v=>Fr(v,e)),await _.register(v=>Nr(v,e.server.apiKey)),await _.register($r),await _.register(Zr),await _.register(ia),await _.register(ca);let le=new xs;js(le),await le.start(),kr(),await _.register(v=>ra(v,le)),await _.register(aa),await _.register(v=>na(v,le,process.env.ADAM_WEBHOOK_API_KEY)),await _.register(da),await _.register(la),await _.register(pa),await _.register(ua);let pe=new Ve;lr(pe),await _.register(pr),await _.register(ma),await _.register(v=>Lr(v,e.server.apiKey)),await _.register(Xr),await _.register(Ot),Ws(),Rr(),await hr(),pe.startHealthMonitor();try{let v=ye();for(let N of v)if(N.platform==="wechat"){let ee=N.config;if(ee.botToken){let ue=new cr(N.id,ee);pe.addChannel(N,ue)}}}catch(v){C.error({error:v},"Failed to register WeChat adapters at startup")}try{let v=ye();for(let N of v)if(N.platform==="discord"){let ee=N.config;if(ee.botToken){let ue=new dr(N.id,{botToken:ee.botToken});pe.addChannel(N,ue)}}}catch(v){C.error({error:v},"Failed to register Discord adapters at startup")}let{host:xt,port:Re}=e.server;await _.listen({host:xt,port:Re}),C.info({host:xt,port:Re},"Server listening");let va=e.watchdog??Bt.watchdog;ga(va,J,H,v=>{C.warn({alert:v},"Watchdog alert")}),$t(v=>{f.emit({type:"log_event",timestamp:v.time??Date.now(),level:v.level??"info",component:v.component??"adam",msg:v.msg??""})}),ba(O,{recursive:!0}),ba(He(O,"logs"),{recursive:!0}),ha(He(O,"adam.port"),String(Re)),e.server.apiKey&&ha(He(O,"adam.key"),e.server.apiKey,{mode:384}),process.send?.({type:"ready",port:Re});let jt=async()=>{C.info("Shutting down"),ya(),br(),Vs(),Ir(),await pe.stopAll(),J.stop(),H.stop(),await le.stop(),await _.close(),Xe();try{$n(He(O,"adam.key"))}catch{}process.exit(0)};process.on("SIGINT",()=>{jt()}),process.on("SIGTERM",()=>{jt()})}Kn().catch(o=>{C.fatal(o,"Fatal error"),process.exit(1)});
|
|
88
|
+
`);try{let a=(await Gs(r,"You are a concise title generator. Reply with only the title, max 50 characters.")).trim().slice(0,50);a.length>0&&ys(o,{title:a})}catch{}}var At=null;function ta(o){At=o}async function Le(o,s,e,r){let t;r&&(t=M(r)),t||(t=qs(s)),t||(t=Fe(s,e));let a=wt(),n={id:a,sessionId:t.id,role:"user",content:o,source:s,createdAt:Date.now()};if(K(n),f.emit({type:"chat_message",sessionId:t.id,message:n}),t.messageCount===0&&vn(t.id,o),z(t.id),pt(t.id),At){let i=t.id,c=t.source;(async()=>{try{let l=await At.handleMessage(o,i,s),d={id:wt(),sessionId:i,role:"assistant",content:l,source:s,createdAt:Date.now()};K(d),f.emit({type:"chat_message",sessionId:i,message:d}),z(i),pt(i),c.type==="channel"&&c.channelId&&c.chatId&&(Ct.info({sessionId:i,sourceType:c.type,hasChannelId:!!c.channelId,hasResponse:!!l},"Chat response ready, checking channel delivery"),Rn(c.channelId,c.chatId,l))}catch(l){(await import("./logger-QCJUU7GV.js")).getLogger("message-handler").error({error:l,sessionId:i},"ChatManager response failed");let m={id:wt(),sessionId:i,role:"assistant",content:`\u26A0\uFE0F \u5904\u7406\u5931\u8D25: ${l instanceof Error?l.message:String(l)}`,source:s,createdAt:Date.now()};K(m),f.emit({type:"chat_message",sessionId:i,message:m}),z(i)}})()}return{sessionId:t.id,messageId:a}}async function Rn(o,s,e){Ct.info({channelId:o,chatId:s.slice(0,12)},"Delivering chat response to channel");try{let{getOutboundGateway:r}=await import("./outbound-gateway-6FQRWYFF.js");await r().send({channelId:o,chatId:s,content:e,messageType:"reply"})}catch(r){Ct.error({error:r,channelId:o,chatId:s.slice(0,12)},"Channel delivery failed (non-fatal)")}}import{z as h}from"zod/v4";import{v4 as In}from"uuid";var sa=h.union([h.object({type:h.literal("session"),sessionId:h.string()}),h.object({type:h.literal("channel"),channelId:h.string(),chatId:h.string().optional()})]),kn=h.object({id:h.string(),prompt:h.string(),dependsOn:h.array(h.string()).optional(),outputAs:h.string().optional()}),Tn=h.object({type:h.enum(["cron","manual","event","once"]),cron:h.string().optional(),event:h.string().optional(),runAt:h.string().optional()}),Pt=h.object({name:h.string().min(1),description:h.string().optional(),trigger:Tn,steps:h.array(kn).min(1),rolePreference:h.string().optional(),config:h.record(h.string(),h.unknown()).optional(),enabled:h.boolean().default(!0),goalIds:h.array(h.string()).optional(),deliverTo:h.array(sa).optional(),reportTo:h.array(sa).optional()}),vc=Pt.transform(o=>({...o,deliverTo:o.deliverTo,reportTo:o.reportTo})),Sn=Pt.partial().transform(o=>({...o,deliverTo:o.deliverTo,reportTo:o.reportTo})),Me=h.object({id:h.string().min(1)});async function ra(o,s){o.post("/task-templates",{schema:{tags:["Templates"],summary:"Create a task template",description:"Create a new task template with trigger (cron/manual/event) 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","event","once"]},cron:{type:"string",description:"Cron expression (required when type is cron)"},event:{type:"string",description:"Event name (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"}}}},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,r)=>{let t=Pt.safeParse(e.body);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(t.error)});let a={id:In(),...t.data,createdAt:Date.now()};return Ps(a),a.enabled&&a.trigger.type==="cron"&&a.trigger.cron?await s.scheduleJob(a.id):a.enabled&&a.trigger.type==="once"&&a.trigger.runAt&&s.scheduleOnceJob(a.id),r.status(201).send({templateId:a.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:Es(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,r)=>{let t=Me.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(t.error)});let a=Z(t.data.id);return a?{template:a}:r.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","event","once"]},cron:{type:"string"},event:{type:"string"},runAt:{type:"string"}}},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,r)=>{let t=Me.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(t.error)});let a=Sn.safeParse(e.body);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(a.error)});if(!Z(t.data.id))return r.status(404).send({code:"NOT_FOUND",message:"Template not found"});_s(t.data.id,a.data),await s.unscheduleJob(t.data.id);let i=Z(t.data.id);return i?.enabled&&i.trigger.type==="cron"&&i.trigger.cron?await s.scheduleJob(i.id):i?.enabled&&i.trigger.type==="once"&&i.trigger.runAt&&s.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,r)=>{let t=Me.safeParse(e.params);return t.success?Z(t.data.id)?(await s.unscheduleJob(t.data.id),Os(t.data.id),{templateId:t.data.id,deleted:!0}):r.status(404).send({code:"NOT_FOUND",message:"Template not found"}):r.status(400).send({code:"VALIDATION_ERROR",message:h.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,r)=>{let t=Me.safeParse(e.params);return t.success?Z(t.data.id)?{executionId:await s.runNow(t.data.id),status:"started"}:r.status(404).send({code:"NOT_FOUND",message:"Template not found"}):r.status(400).send({code:"VALIDATION_ERROR",message:h.prettifyError(t.error)})})}import{z as P}from"zod/v4";ks();var _t=P.object({id:P.string().min(1)}),wn=P.object({scope:P.enum(["user","project"]).optional(),cwd:P.string().optional()}),Cn=P.object({scope:P.enum(["user","project"]).optional(),cwd:P.string().optional()});async function aa(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 r=e.query,t=_e({scope:r.scope}),a=dt();return{plugins:t.map(n=>({...n,globalEnabled:a[n.id]??n.enabled}))}}),o.get("/plugins/:id",{schema:{tags:["Plugins"],summary:"Get plugin by ID",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,r)=>{let t=_t.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)});let a=vs(t.data.id);if(!a)return r.status(404).send({code:"NOT_FOUND",message:"Plugin not found"});let n=bs(a.installPath),i=dt();return{plugin:{...a,globalEnabled:i[a.id]??a.enabled,manifest:n}}}),o.post("/plugins/:id/enable",{schema:{tags:["Plugins"],summary:"Enable a plugin globally",params:{type:"object",required:["id"],properties:{id:{type:"string"}}}}},async(e,r)=>{let t=_t.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)});if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude CLI not found. Plugin enable/disable requires the Claude Agent SDK CLI."});try{return er(t.data.id),{pluginId:t.data.id,enabled:!0}}catch(a){return r.status(500).send({code:"CLI_ERROR",message:a instanceof Error?a.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,r)=>{let t=_t.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(t.error)});if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude CLI not found. Plugin enable/disable requires the Claude Agent SDK CLI."});try{return tr(t.data.id),{pluginId:t.data.id,enabled:!1}}catch(a){return r.status(500).send({code:"CLI_ERROR",message:a instanceof Error?a.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 r=e.query;return{stats:fr(r.limit??50)}});let s=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,r)=>{let t=s.safeParse(e.params);return t.success?{roleId:t.data.roleId,stats:yr(t.data.roleId)}:r.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,r)=>{if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found. Install Claude Code to use marketplace features."});try{let t=Xs();return{available:t.available,installed:t.installed}}catch(t){return r.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:Rs()})),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,r)=>{let a=P.object({name:P.string().min(1)}).safeParse(e.params);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(a.error)});let n=wn.safeParse(e.body??{});if(!n.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(n.error)});if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found"});try{return Zs(a.data.name,n.data.scope??"user",n.data.cwd),{success:!0,pluginId:a.data.name}}catch(i){return r.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,r)=>{let a=P.object({name:P.string().min(1)}).safeParse(e.params);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(a.error)});let n=Cn.safeParse(e.body??{});if(!n.success)return r.status(400).send({code:"VALIDATION_ERROR",message:P.prettifyError(n.error)});if(!ce())return r.status(503).send({code:"CLI_NOT_AVAILABLE",message:"Claude Code CLI not found"});try{return Js(a.data.name,n.data.scope,n.data.cwd),{success:!0,pluginId:a.data.name}}catch(i){return r.status(500).send({code:"CLI_ERROR",message:i instanceof Error?i.message:"Uninstall failed"})}})}import{z as Et}from"zod/v4";var An=Et.object({name:Et.string().min(1)}),Pn="x-api-key";async function na(o,s,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(r,t)=>{if(e&&r.headers[Pn]!==e)return t.status(401).send({code:"UNAUTHORIZED",message:"Invalid or missing API key"});let a=An.safeParse(r.params);if(!a.success)return t.status(400).send({code:"VALIDATION_ERROR",message:Et.prettifyError(a.error)});let{name:n}=a.data,i=Z(n);if(!i){let{listTaskTemplates:c}=await import("./task-templates-PSP7GOJJ.js");i=c(!1).find(d=>d.name===n||d.id===n)}if(!i)return t.status(404).send({code:"NOT_FOUND",message:`Template '${n}' not found`});if(!i.enabled)return t.status(409).send({code:"DISABLED",message:`Template '${n}' is disabled`});try{let c=await s.runNow(i.id);return t.status(202).send({code:"ACCEPTED",message:`Template '${i.name}' triggered`,executionId:c,templateId:i.id})}catch(c){let l=c instanceof Error?c.message:String(c);return t.status(500).send({code:"EXECUTION_ERROR",message:l})}}),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:r}=await import("./task-templates-PSP7GOJJ.js");return{webhooks:r(!0).map(a=>({name:a.id,displayName:a.name,description:a.description,tags:a.tags,trigger:`POST /webhooks/${a.id}`})),auth:e?"X-API-Key header required":"No auth configured"}})}import{z as k}from"zod/v4";var _n=k.object({status:k.string().optional(),limit:k.coerce.number().min(1).max(100).default(20),offset:k.coerce.number().min(0).default(0)}),Be=k.union([k.object({type:k.literal("session"),sessionId:k.string()}),k.object({type:k.literal("channel"),channelId:k.string(),chatId:k.string().optional()})]),En=k.object({input:k.string().min(1,"goal input is required"),deliverTo:k.array(Be).optional(),reportTo:k.array(Be).optional()}),oa=k.object({id:k.string().min(1)}),On=k.object({name:k.string().min(1).optional(),description:k.string().optional(),status:k.enum(["active","paused","completed","failed"]).optional(),currentValue:k.number().optional(),budgetUsd:k.number().min(0).optional(),deliverTo:k.array(Be).optional(),reportTo:k.array(Be).optional()});async function ia(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(s,e)=>{let r=_n.safeParse(s.query);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(r.error)});let{status:t,limit:a,offset:n}=r.data;return{goals:Fs(t,a,n)}}),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(s,e)=>{let r=se(s.params.id);return r?{goal:r}: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(s,e)=>{let r=En.safeParse(s.body);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(r.error)});let t=await $s(r.data.input);if(!t.validationResult.isValid)return e.status(400).send({code:"INVALID_GOAL",errors:t.validationResult.errors,warnings:t.validationResult.warnings});let a=Hs(t.goalState,r.data.deliverTo,r.data.reportTo);return Ks(a.id,a.metricType),e.status(201).send({goal:a})}),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(s,e)=>{let r=oa.safeParse(s.params);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(r.error)});let t=On.safeParse(s.body);return t.success?se(r.data.id)?(Oe(r.data.id,{...t.data,updatedAt:Date.now()}),{goal:se(r.data.id)}):e.status(404).send({code:"NOT_FOUND",message:"Goal not found"}):e.status(400).send({code:"VALIDATION_ERROR",message:k.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(s,e)=>{let r=oa.safeParse(s.params);return r.success?se(r.data.id)?(Ds(r.data.id),{goalId:r.data.id,deleted:!0}):e.status(404).send({code:"NOT_FOUND",message:"Goal not found"}):e.status(400).send({code:"VALIDATION_ERROR",message:k.prettifyError(r.error)})})}import{z as be}from"zod/v4";var Fn=be.object({role:be.string().optional(),taskType:be.string().optional(),limit:be.coerce.number().min(1).max(100).default(50)});async function ca(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(s,e)=>{let r=Fn.safeParse(s.query);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:be.prettifyError(r.error)});let{role:t,taskType:a,limit:n}=r.data,i;return t&&a?i=Ys.getStrategies(t,a):t?i=Qs(t):i=zs(n),{strategies:i.slice(0,n)}})}Jt();Y();import{z as Q}from"zod/v4";async function da(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,r)=>{let t=E(),a=mr(),n=[...Ie,...ze],i={},c=new Set(["anthropic.apiKey","server.apiKey"]);for(let l of n){let d=Qe(t,l),m=Ie.includes(l);c.has(l)&&typeof d=="string"&&d.length>0&&(d=d.slice(0,5)+"****"),i[l]={value:d??null,mutable:m}}return{config:i,mutable:[...Ie],restartRequired:[...ze],sandbox:{platform:a.platform,available:await gr()}}}),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,r)=>{let t=e.body;if(!t||typeof t!="object")return r.status(400).send({success:!1,updated:[],errors:["Request body must be a JSON object with config key-value pairs"],message:"Validation error"});let a=Lt(t,oe);if(a.updated.includes("logging.level")){let n=t["logging.level"];typeof n=="string"&&Te(n)}if(a.updated.length>0){let n=E(),i=a.updated.map(c=>({path:c,value:Qe(n,c)}));f.emit({type:"config_changed",changes:i})}return{success:a.errors.length===0,updated:a.updated,errors:a.errors,message:a.errors.length===0?`Updated ${a.updated.length} configuration value(s)`:`Updated ${a.updated.length} value(s); ${a.errors.length} rejected (restart required)`}}),o.get("/config/env-diff",async()=>{let e=we();return{diffs:Vt(e),envFileExists:Ut()!==null}}),o.post("/config/sync-to-env",async()=>{let e=we();return{success:!0,changed:Gt(e)}}),o.post("/config/load-from-env",async()=>{let e=Wt();if(!e)return{success:!1,error:".env file not found"};let r=0;for(let[a,n]of Object.entries(e)){let i=Object.entries(Ye).find(([,c])=>c===a)?.[0];i&&(oe(i,n),r++)}let t={};for(let[a,n]of Object.entries(e))a in Ye||a.startsWith("ANTHROPIC_")||a.startsWith("ADAM_")||(t[a]=n);return Object.keys(t).length>0&&(oe("defaults.env",t),E().defaults.env=t,r+=Object.keys(t).length),ke(we),{success:!0,updated:r}});let s=Q.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(Q.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:E().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,r)=>{let a=Q.record(s,Q.string().max(4096)).check(Q.refine(i=>Object.keys(i).length<=100,"Maximum 100 environment variables")).safeParse(e.body);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:Q.prettifyError(a.error)});let n=a.data;return oe("defaults.env",n),E().defaults.env=n,f.emit({type:"config_changed",changes:[{path:"defaults.env",value:n}]}),{success:!0,count:Object.keys(n).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,r)=>{let a=Q.record(s,Q.string().max(4096).nullable()).safeParse(e.body);if(!a.success)return r.status(400).send({code:"VALIDATION_ERROR",message:Q.prettifyError(a.error)});let n={...E().defaults?.env??{}};for(let[i,c]of Object.entries(a.data))c===null?delete n[i]:n[i]=c;return Object.keys(n).length>100?r.status(400).send({code:"VALIDATION_ERROR",message:"Maximum 100 environment variables"}):(oe("defaults.env",n),E().defaults.env=n,f.emit({type:"config_changed",changes:[{path:"defaults.env",value:n}]}),{success:!0,count:Object.keys(n).length})})}async function la(o){o.get("/audit/posture",async(s,e)=>{let r=await vr();return e.send(r)})}async function pa(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(s,e)=>{let{limit:r=20,offset:t=0,roleId:a}=s.query;return a?ir(a,r,t):or(r,t)})}import{z as T}from"zod/v4";var Dn=["active","archived"],xn=T.object({source:T.object({type:T.enum(["tui","web","api","channel"]),channelId:T.string().optional(),chatId:T.string().optional()}),roleId:T.string().optional()}),ve=T.object({id:T.string().uuid()}),jn=T.object({status:T.enum(Dn).optional(),limit:T.coerce.number().min(1).max(100).default(100),offset:T.coerce.number().min(0).default(0)}),Nn=T.object({limit:T.coerce.number().min(1).max(200).default(50),offset:T.coerce.number().min(0).default(0)});async function ua(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,r)=>{let t=xn.safeParse(e.body);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let{source:a,roleId:n}=t.data,i=Fe(a,n);return r.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,r)=>{let t=jn.safeParse(e.query);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let{status:a}=t.data;return{sessions:Us(a)}}),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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=M(t.data.id);if(!a)return r.status(404).send({code:"NOT_FOUND",message:"Session not found"});let n=ct(a.id);return{session:a,messages:n}}),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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=M(t.data.id);return a?(Ls(a.id),{sessionId:a.id,status:"archived"}):r.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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=Ms(t.data.id);return a?{session:a}:r.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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=M(t.data.id);return a?(Bs(a.id),r.status(204).send()):r.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,r)=>{let t=ve.safeParse(e.params);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let a=M(t.data.id);if(!a)return r.status(404).send({code:"NOT_FOUND",message:"Session not found"});let n=Nn.safeParse(e.query),{limit:i=50,offset:c=0}=n.success?n.data:{};return{messages:ct(a.id,i,c)}});let s=T.object({content:T.string().min(1,"content is required"),source:T.object({type:T.enum(["tui","web","api","channel"]),channelId:T.string().optional(),chatId:T.string().optional()}),roleId:T.string().optional(),sessionId:T.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,r)=>{let t=s.safeParse(e.body);if(!t.success)return r.status(400).send({code:"VALIDATION_ERROR",message:T.prettifyError(t.error)});let{content:a,source:n,roleId:i,sessionId:c}=t.data,l=await Le(a,n,i,c);return r.status(201).send(l)})}Y();var qn=q("ws"),Ue=new Set,We=[],Ln=50;function Mn(o){We.push(o),We.length>Ln&&We.shift()}function de(o){Mn(o);let s=JSON.stringify(o);for(let e of Ue)e.readyState===1&&e.send(s)}function ma(o){o.get("/chat/stream",{websocket:!0},(s,e)=>{Ue.add(s);for(let r of We)s.readyState===1&&s.send(JSON.stringify(r));s.on("close",()=>{Ue.delete(s)}),s.on("error",r=>{qn.error({error:r},"Chat WebSocket error"),Ue.delete(s)})}),f.on("session_created",s=>de(s)),f.on("session_archived",s=>de(s)),f.on("session_restored",s=>de(s)),f.on("session_deleted",s=>de(s)),f.on("chat_message",s=>de(s)),f.on("task_complete_event",s=>de(s))}Y();var j=q("channels"),Ve=class{adapters=new Map;rateLimits=new Map;healthInterval;rateLimitPerMinute;constructor(s){this.rateLimitPerMinute=s?.rateLimitPerMinute??60}async addChannel(s,e){this.adapters.set(s.id,e),e.onMessage(r=>{this.handleInbound(s.id,r)}),s.enabled&&await this.connectChannel(s.id)}async removeChannel(s){let e=this.adapters.get(s);if(e){try{await e.disconnect()}catch(r){j.error({channelId:s,error:r},"Error disconnecting channel")}this.adapters.delete(s),this.rateLimits.delete(s)}}async connectChannel(s){let e=this.adapters.get(s);if(!e)throw new Error(`No adapter registered for channel ${s}`);try{ie(s,"connecting"),await e.connect(),ie(s,"connected"),j.info({channelId:s,platform:e.platform},"Channel connected")}catch(r){throw ie(s,"error"),j.error({channelId:s,error:r},"Failed to connect channel"),r}}async disconnectChannel(s){let e=this.adapters.get(s);if(e)try{await e.disconnect(),ie(s,"disconnected"),j.info({channelId:s},"Channel disconnected")}catch(r){j.error({channelId:s,error:r},"Error disconnecting channel")}}getChannelStatus(s){let e=this.adapters.get(s);return e?e.getStatus():"disconnected"}getChannelStatuses(){let s=new Map;for(let[e,r]of this.adapters)s.set(e,r.getStatus());return s}hasAdapter(s){return this.adapters.has(s)}async sendMessage(s,e,r){let t=this.adapters.get(s);if(!t)return j.warn({channelId:s},"No adapter for outbound message"),null;if(!this.checkRateLimit(s))return j.warn({channelId:s},"Rate limit exceeded, dropping outbound message"),null;try{return await t.sendMessage(e,r)}catch(a){return j.error({channelId:s,chatId:e,error:a},"Failed to send outbound message"),null}}checkRateLimit(s){let e=Date.now(),r=this.rateLimits.get(s);return!r||e-r.windowStart>=6e4?(this.rateLimits.set(s,{count:1,windowStart:e}),!0):r.count>=this.rateLimitPerMinute?!1:(r.count++,!0)}async handleInbound(s,e){if(e.source==="system"){j.debug({channelId:s},"Skipping system message (anti-loop)");return}try{let{isRecentlySent:t}=await import("./outbound-gateway-6FQRWYFF.js"),a=e.channelMessageId??e.raw?.MsgId??"";if(a&&t(String(a))){j.debug({channelId:s,messageId:a},"Skipping delivery-sent message (anti-loop)");return}}catch{}if(!this.checkRateLimit(s)){j.warn({channelId:s,senderId:e.senderId},"Rate limit exceeded for inbound message");return}try{let{handleInboundForApproval:t}=await import("./approval-handler-JYIS2PKQ.js");if(await t(s,e.chatId,e.content)){j.debug({channelId:s,chatId:e.chatId},"Inbound message consumed as approval reply");return}}catch{}let r=Ns(s);if(r?.allowedChatIds&&!r.allowedChatIds.includes(e.chatId)){j.debug({channelId:s,chatId:e.chatId},"Chat not in allowlist, ignoring");return}try{let t=await Le(e.content,{type:"channel",channelId:s,chatId:e.chatId},r?.linkedRoleId);j.info({channelId:s,chatId:e.chatId,sessionId:t.sessionId},"Inbound message routed to session")}catch(t){j.error({channelId:s,chatId:e.chatId,error:t},"Failed to route inbound message")}}startHealthMonitor(s=3e4){this.stopHealthMonitor(),this.healthInterval=setInterval(()=>{this.checkHealth()},s)}stopHealthMonitor(){this.healthInterval&&(clearInterval(this.healthInterval),this.healthInterval=void 0)}checkHealth(){for(let[s,e]of this.adapters){let r=e.getStatus();try{ie(s,r)}catch{}}}async startAll(){let s=ye(!0);for(let e of s){let r=this.adapters.get(e.id);if(r&&r.getStatus()!=="connected")try{await this.connectChannel(e.id)}catch{}}this.startHealthMonitor()}async stopAll(){this.stopHealthMonitor();for(let s of this.adapters.keys())await this.disconnectChannel(s);this.adapters.clear(),this.rateLimits.clear()}_getAdapterCount(){return this.adapters.size}_getRateLimitEntry(s){return this.rateLimits.get(s)}};Se();Y();var G=q("watchdog"),Ge=null;function ga(o,s,e,r){if(!o.enabled){G.info("Watchdog disabled");return}let t=o.intervalMinutes*6e4;G.info({intervalMinutes:o.intervalMinutes},"Watchdog started"),Ge=setInterval(()=>{Bn(o,s,e,r)},t)}function ya(){Ge&&(clearInterval(Ge),Ge=null,G.info("Watchdog stopped"))}function Bn(o,s,e,r){let{rules:t}=o;if(t.managerHealthCheck.enabled){let a=t.managerHealthCheck.staleDurationMinutes*6e4,n=s.getLastActivityAt();if(Date.now()-n>a){let i=`ChatManager session stale (no activity for ${t.managerHealthCheck.staleDurationMinutes} min)`;if(G.warn(i),t.managerHealthCheck.action==="restart"){let c=s.getConsecutiveStaleCount()>0;s.restartSession(),c&&(G.fatal("ChatManager unrecoverable after session restart \u2014 exiting for supervisor restart"),process.exit(1))}else t.managerHealthCheck.action==="notify"&&r(i)}}if(!e.isHealthy()){let a="ExecutionPool is not healthy (stopped unexpectedly)";G.warn(a),r(a)}if(t.staleTasks.enabled){let a=t.staleTasks.maxPendingMinutes*6e4,i=W("pending").filter(c=>Date.now()-c.createdAt>a);if(i.length>0){let c=`${i.length} stale task(s) pending > ${t.staleTasks.maxPendingMinutes} min`;G.warn({count:i.length},c),t.staleTasks.action==="notify"&&r(c)}}if(t.staleRunningTasks?.enabled){let a=t.staleRunningTasks.maxRunningMinutes*6e4,i=W("running").filter(c=>{if(!c.startedAt||Date.now()-c.startedAt<a)return!1;try{let b=U().prepare("SELECT MAX(timestamp) as latest FROM step_logs WHERE task_id = ?").get(c.id)?.latest??c.startedAt;return Date.now()-b>a}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`;G.warn({count:i.length,taskIds:i.map(l=>l.id)},c);for(let l of i)X(l.id,{status:"failed",error:`Watchdog timeout: no activity for > ${t.staleRunningTasks.maxRunningMinutes} min`,completedAt:Date.now()}),f.emit({type:"task_status_change",taskId:l.id,oldStatus:"running",newStatus:"failed"}),e.releaseSlot(l.id);r(c)}}if(t.dbMaintenance.enabled)try{let n=U().pragma("wal_checkpoint(PASSIVE)");G.debug({walSize:n},"WAL checkpoint")}catch(a){G.error({error:a},"DB health check failed")}}import{z as x}from"zod";import{v4 as Un}from"uuid";var Wn=x.object({eventType:x.enum(["task_complete","task_error","plan_approval_request","*"]),matchCriteria:x.object({templateId:x.string().optional(),roleId:x.string().optional(),promptPattern:x.string().optional(),taskStatus:x.string().optional()}).optional().default({}),target:x.object({type:x.enum(["channel","webhook"]),channelId:x.string().optional(),chatId:x.string().optional(),webhookUrl:x.string().optional()}),formatTemplate:x.string().optional(),maxPerMinute:x.number().int().min(1).max(60).optional().default(5),skipOriginChannel:x.boolean().optional().default(!0),enabled:x.boolean().optional().default(!0)});async function Ot(o){o.get("/delivery-rules",async(s,e)=>rr()),o.post("/delivery-rules",async(s,e)=>{let r=Wn.safeParse(s.body);if(!r.success)return e.status(400).send({code:"VALIDATION_ERROR",message:x.prettifyError(r.error)});let t=r.data,a={id:Un(),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 sr(a),e.status(201).send(a)}),o.put("/delivery-rules/:id",async(s,e)=>{if(!De(s.params.id))return e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"});let t=s.body;return ar(s.params.id,t),{id:s.params.id,updated:!0}}),o.delete("/delivery-rules/:id",async(s,e)=>De(s.params.id)?(nr(s.params.id),{id:s.params.id,deleted:!0}):e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"})),o.get("/delivery-rules/:id/log",async(s,e)=>is(s.params.id)),o.post("/delivery-rules/:id/test",async(s,e)=>{let r=De(s.params.id);if(!r)return e.status(404).send({code:"NOT_FOUND",message:"Delivery rule not found"});let{getDeliveryEngine:t}=await import("./engine-5RJ7NJSM.js"),a=t();if(!a)return e.status(503).send({code:"ENGINE_NOT_READY",message:"DeliveryEngine not initialized"});let n=`[TEST] Delivery rule test at ${new Date().toISOString()}`,{createDeliveryLog:i}=await import("./delivery-log-SC2ULFCK.js"),{v4:c}=await import("uuid"),{TTL_MS:l}=await import("./delivery-log-SC2ULFCK.js"),d={id:c(),ruleId:r.id,status:"pending",target:r.target,content:n,attempts:0,createdAt:Date.now(),expiresAt:Date.now()+l};i(d);try{return await a.attemptDeliveryPublic(d,r),{id:d.id,ruleId:r.id,status:"sent",content:n}}catch(m){let b=m instanceof Error?m.message:String(m);return e.status(500).send({code:"DELIVERY_FAILED",message:b,logId:d.id})}})}Y();me();me();import{existsSync as $e,copyFileSync as Vn,mkdirSync as Ft,cpSync as Gn}from"fs";import{join as $}from"path";function Dt(){Ft(O,{recursive:!0}),Ft($(O,"logs"),{recursive:!0}),Ft($(O,".claude"),{recursive:!0})}function fa(o=process.cwd()){Dt();let s=[],e=[{from:$(o,"data","adam.db"),to:$(O,"adam.db"),label:"database"},{from:$(o,"adam.config.yaml"),to:$(O,"adam.config.yaml"),label:"config"},{from:$(o,".env"),to:$(O,".env"),label:".env"}];for(let{from:a,to:n,label:i}of e)$e(a)&&!$e(n)&&(Vn(a,n),s.push(i));let r=$(o,".claude","plugins"),t=$(O,".claude","plugins");return $e(r)&&!$e(t)&&(Gn(r,t,{recursive:!0}),s.push("plugins")),s}Jt();var C=q("adam");function Hn(o){let s={...o};if(s.defaults&&typeof s.defaults=="object"){let e={...s.defaults};if(e.env&&typeof e.env=="object"){let r={...e.env};for(let t of Object.keys(r))r[t]&&(r[t]=r[t].slice(0,4)+"****");e.env=r}s.defaults=e}if(s.server&&typeof s.server=="object"){let e={...s.server};e.apiKey&&typeof e.apiKey=="string"&&(e.apiKey=e.apiKey.slice(0,4)+"****"),s.server=e}return s}async function Kn(){Dt();let o=fa();o.length>0&&console.log(`[adam] Migrated to ~/.adam/: ${o.join(", ")}`);let s=Tr();C.info("Starting Adam Agent Server"),s.length>0&&C.info({files:s},"Loaded env files");let e=Ht();Nt(e),E().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:Ia}=await import("module"),{dirname:ka,join:Ta}=await import("path"),Sa=Ia(import.meta.url).resolve("@anthropic-ai/claude-agent-sdk");t=Ta(ka(Sa),"cli.js")}let{execSync:v}=await import("child_process"),{chmodSync:N,accessSync:ee,constants:ue}=await import("fs");try{ee(t,ue.X_OK)}catch{C.info({path:t},"CLI not executable, fixing permissions"),N(t,493)}let Ra=v(`"${t}" --version`,{timeout:5e3,encoding:"utf-8"}).trim();C.info({path:t,version:Ra},"Claude Code CLI detected")}catch(v){let N=v;N.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:(N.stderr?.trim()||String(v)).slice(0,200)},"Claude Code CLI check failed")}let n=U().prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name").all();C.info({tables:n.map(v=>v.name).join(", ")},"Database initialized");let i=Kt(),c=Zt(i);c>0&&C.info({count:c},"Seeded config DB from .env");let{getAllConfig:l}=await import("./config-EI3SCA4W.js");ke(l);let d=E();d.logging?.level&&Te(d.logging.level),C.info({config:Hn(d)},"Config loaded (DB + defaults)");let m=Rt(),{getToolsFingerprint:b}=await import("./adam-tools-V22LRDCP.js"),I=b(),y=m.sdkSessionId;if(y&&m.toolsFingerprint!==I&&(C.info({old:m.toolsFingerprint?.slice(0,40),new:I.slice(0,40)},"MCP tools changed \u2014 invalidating old SDK session"),Mr(),y=void 0),fe({toolsFingerprint:I}),y){let v=process.cwd();m.workspacePath&&m.workspacePath!==v&&(C.warn({serverCwd:v,saved:m.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");m.userTaskSessionId&&C.info({sessionId:m.userTaskSessionId.slice(0,8)},"Recovering user task session"),Br(process.cwd());let{initializeDefaultRoles:g}=await import("./role-presets-LRP6P5O2.js"),A=g();C.info({count:A.length},"Roles initialized");let ne=E().execution??{maxConcurrent:3,pollIntervalMs:3e4},J=new he(y),H=new yt(ne.maxConcurrent);ta(J),await J.start(),await H.start();let Ke=W("running");if(Ke.length>0){C.warn({count:Ke.length},"Found orphaned running tasks from previous session \u2014 marking as failed");for(let v of Ke)X(v.id,{status:"failed",error:"Server restarted while task was running",completedAt:Date.now()})}let _=Ar(e,e.server.apiKey);await _.register(v=>Or(v)),await _.register(v=>Fr(v,e)),await _.register(v=>Nr(v,e.server.apiKey)),await _.register($r),await _.register(Zr),await _.register(ia),await _.register(ca);let le=new xs;js(le),await le.start(),kr(),await _.register(v=>ra(v,le)),await _.register(aa),await _.register(v=>na(v,le,process.env.ADAM_WEBHOOK_API_KEY)),await _.register(da),await _.register(la),await _.register(pa),await _.register(ua);let pe=new Ve;lr(pe),await _.register(pr),await _.register(ma),await _.register(v=>Lr(v,e.server.apiKey)),await _.register(Xr),await _.register(Ot),Ws(),Rr(),await hr(),pe.startHealthMonitor();try{let v=ye();for(let N of v)if(N.platform==="wechat"){let ee=N.config;if(ee.botToken){let ue=new cr(N.id,ee);pe.addChannel(N,ue)}}}catch(v){C.error({error:v},"Failed to register WeChat adapters at startup")}try{let v=ye();for(let N of v)if(N.platform==="discord"){let ee=N.config;if(ee.botToken){let ue=new dr(N.id,{botToken:ee.botToken});pe.addChannel(N,ue)}}}catch(v){C.error({error:v},"Failed to register Discord adapters at startup")}let{host:xt,port:Re}=e.server;await _.listen({host:xt,port:Re}),C.info({host:xt,port:Re},"Server listening");let va=e.watchdog??Bt.watchdog;ga(va,J,H,v=>{C.warn({alert:v},"Watchdog alert")}),$t(v=>{f.emit({type:"log_event",timestamp:v.time??Date.now(),level:v.level??"info",component:v.component??"adam",msg:v.msg??""})}),ba(O,{recursive:!0}),ba(He(O,"logs"),{recursive:!0}),ha(He(O,"adam.port"),String(Re)),e.server.apiKey&&ha(He(O,"adam.key"),e.server.apiKey,{mode:384}),process.send?.({type:"ready",port:Re});let jt=async()=>{C.info("Shutting down"),ya(),br(),Vs(),Ir(),await pe.stopAll(),J.stop(),H.stop(),await le.stop(),await _.close(),Xe();try{$n(He(O,"adam.key"))}catch{}process.exit(0)};process.on("SIGINT",()=>{jt()}),process.on("SIGTERM",()=>{jt()})}Kn().catch(o=>{C.fatal(o,"Fatal error"),process.exit(1)});
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{$ as t,H as n,N as r,nt as i,w as a,y as o}from"./vendor-icons-CkI4-NxL.js";import{d as s,r as c,t as l}from"./vendor-react-DLRtONKt.js";import{r as u}from"./dist-HyCSN_hp.js";import{t as d}from"./index-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{$ as t,H as n,N as r,nt as i,w as a,y as o}from"./vendor-icons-CkI4-NxL.js";import{d as s,r as c,t as l}from"./vendor-react-DLRtONKt.js";import{r as u}from"./dist-HyCSN_hp.js";import{t as d}from"./index-oA-kWqT5.js";import{n as f,r as p,t as m}from"./Card-4mOZntHG.js";import{n as h}from"./format-DvtQjPZn.js";var g=e(i(),1),_=l();function v(){let{id:e}=s(),[i,l]=(0,g.useState)(null),[v,b]=(0,g.useState)([]),[x,S]=(0,g.useState)([]),[C,w]=(0,g.useState)(null);if((0,g.useEffect)(()=>{e&&((async()=>{try{l((await u(`/channels/${e}`)).channel),w(null)}catch(e){w(e instanceof Error?e.message:`Failed to load channel`)}})(),u(`/delivery-rules`).then(t=>b(t.filter(t=>t.target.type===`channel`&&t.target.channelId===e))).catch(()=>b([])),u(`/delivery-rules`).then(async t=>{let n=t.filter(t=>t.target.type===`channel`&&t.target.channelId===e),r=[];for(let e of n.slice(0,3))try{let t=await u(`/delivery-rules/${e.id}/log`);r.push(...t.log??[])}catch{}r.sort((e,t)=>t.createdAt-e.createdAt),S(r.slice(0,20))}).catch(()=>S([])))},[e]),C)return(0,_.jsxs)(`div`,{className:`space-y-4`,children:[(0,_.jsxs)(c,{to:`/channels`,className:`flex items-center gap-1.5 text-sm text-slate-400 hover:text-slate-200`,children:[(0,_.jsx)(t,{size:14}),` Back to Channels`]}),(0,_.jsx)(m,{className:`text-center text-red-400`,children:C})]});if(!i)return(0,_.jsxs)(`div`,{className:`space-y-4`,children:[(0,_.jsxs)(c,{to:`/channels`,className:`flex items-center gap-1.5 text-sm text-slate-400 hover:text-slate-200`,children:[(0,_.jsx)(t,{size:14}),` Back to Channels`]}),(0,_.jsx)(m,{className:`text-center text-slate-500`,children:`Loading...`})]});let T=e=>e===`connected`?`success`:e===`connecting`?`warning`:e===`error`?`destructive`:`secondary`,E=e=>{switch(e){case`wechat`:return`WeChat`;case`telegram`:return`Telegram`;case`slack`:return`Slack`;case`discord`:return`Discord`;default:return e.charAt(0).toUpperCase()+e.slice(1)}},D={...i.config};for(let e of[`botToken`,`apiKey`,`secret`,`password`,`token`])e in D&&(D[e]=`********`);return(0,_.jsxs)(`div`,{className:`space-y-4`,children:[(0,_.jsxs)(c,{to:`/channels`,className:`flex items-center gap-1.5 text-sm text-slate-400 hover:text-slate-200`,children:[(0,_.jsx)(t,{size:14}),` Back to Channels`]}),(0,_.jsx)(m,{children:(0,_.jsx)(`div`,{className:`flex items-start justify-between gap-4`,children:(0,_.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-2 mb-2`,children:[(0,_.jsx)(d,{variant:T(i.status),children:i.status}),(0,_.jsx)(d,{variant:`outline`,children:E(i.platform)}),i.enabled?(0,_.jsx)(d,{variant:`success`,children:`enabled`}):(0,_.jsx)(d,{variant:`secondary`,children:`disabled`}),(0,_.jsx)(`span`,{className:`font-mono text-xs text-slate-500`,children:i.id})]}),(0,_.jsx)(`h2`,{className:`text-lg font-semibold text-slate-200`,children:i.name})]})})}),(0,_.jsxs)(`div`,{className:`grid grid-cols-2 gap-3 lg:grid-cols-4`,children:[(0,_.jsx)(y,{icon:n,label:`Created`,value:h(i.createdAt),mono:!0}),(0,_.jsx)(y,{icon:a,label:`Messages`,value:String(i.messageCount),mono:!0}),i.lastMessageAt&&(0,_.jsx)(y,{icon:n,label:`Last Message`,value:h(i.lastMessageAt),mono:!0}),i.linkedRoleId&&(0,_.jsx)(y,{icon:o,label:`Linked Role`,value:i.linkedRoleId.slice(0,8)+`...`,mono:!0})]}),(0,_.jsxs)(m,{children:[(0,_.jsx)(f,{children:(0,_.jsx)(p,{children:`Configuration`})}),(0,_.jsx)(`pre`,{className:`max-h-64 overflow-auto whitespace-pre-wrap rounded-md bg-slate-800 p-3 font-mono text-xs text-slate-300`,children:JSON.stringify(D,null,2)})]}),v.length>0&&(0,_.jsxs)(m,{children:[(0,_.jsx)(f,{children:(0,_.jsxs)(p,{className:`flex items-center gap-2`,children:[(0,_.jsx)(r,{size:14}),` Delivery Rules (`,v.length,`)`]})}),(0,_.jsx)(`div`,{className:`space-y-2`,children:v.map(e=>(0,_.jsxs)(`div`,{className:`rounded-md border border-slate-700 bg-slate-800/50 p-2`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,_.jsx)(d,{variant:`outline`,children:e.eventType}),e.enabled?(0,_.jsx)(d,{variant:`success`,children:`active`}):(0,_.jsx)(d,{variant:`secondary`,children:`disabled`}),(0,_.jsxs)(`span`,{className:`text-xs text-slate-500`,children:[`max `,e.maxPerMinute,`/min`]})]}),(0,_.jsxs)(`p`,{className:`mt-1 text-xs text-slate-400 font-mono`,children:[`Rule: `,e.id]})]},e.id))})]}),x.length>0&&(0,_.jsxs)(m,{children:[(0,_.jsx)(f,{children:(0,_.jsxs)(p,{className:`flex items-center gap-2`,children:[(0,_.jsx)(a,{size:14}),` Delivery Log (`,x.length,`)`]})}),(0,_.jsx)(`div`,{className:`space-y-2`,children:x.slice(0,10).map(e=>(0,_.jsxs)(`div`,{className:`flex items-center justify-between rounded-md border border-slate-800 p-2`,children:[(0,_.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,_.jsx)(`span`,{className:`text-sm text-slate-300 font-mono`,children:e.taskId.slice(0,8)}),(0,_.jsx)(`span`,{className:`text-xs text-slate-500 ml-2`,children:h(e.createdAt)})]}),(0,_.jsx)(d,{variant:e.status===`delivered`?`default`:e.status===`failed`?`destructive`:`outline`,children:e.status})]},e.id))})]})]})}function y({icon:e,label:t,value:n,mono:r}){return(0,_.jsxs)(m,{className:`flex flex-col gap-1`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-1.5 text-slate-500`,children:[(0,_.jsx)(e,{size:12}),(0,_.jsx)(`span`,{className:`text-xs`,children:t})]}),(0,_.jsx)(`span`,{className:`text-sm text-slate-200 truncate ${r?`font-mono text-xs`:``}`,children:n})]})}export{v as ChannelDetail};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{S as t,b as n,g as r,nt as i,o as a,t as o,v as s,w as c,y as l}from"./vendor-icons-CkI4-NxL.js";import{t as u}from"./vendor-react-DLRtONKt.js";import{r as d}from"./dist-HyCSN_hp.js";import{f,t as p}from"./index-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{S as t,b as n,g as r,nt as i,o as a,t as o,v as s,w as c,y as l}from"./vendor-icons-CkI4-NxL.js";import{t as u}from"./vendor-react-DLRtONKt.js";import{r as d}from"./dist-HyCSN_hp.js";import{f,t as p}from"./index-oA-kWqT5.js";import{n as m,r as h,t as g}from"./Card-4mOZntHG.js";import{t as _}from"./EmptyState-BlgMMAr-.js";var v=e(i(),1),y=u(),b=[`telegram`,`slack`,`discord`,`openclaw`,`wechat`,`whatsapp`],x={telegram:`{
|
|
2
2
|
"botToken": ""
|
|
3
3
|
}`,slack:`{
|
|
4
4
|
"botToken": "",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{T as t,d as n,et as r,m as i,nt as a,o,v as s}from"./vendor-icons-CkI4-NxL.js";import{t as c}from"./vendor-react-DLRtONKt.js";import{a as l,r as u}from"./dist-HyCSN_hp.js";import{t as d}from"./vendor-state-B_-GdGNJ.js";import{f}from"./index-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-Dw2cE7zH.js";import{T as t,d as n,et as r,m as i,nt as a,o,v as s}from"./vendor-icons-CkI4-NxL.js";import{t as c}from"./vendor-react-DLRtONKt.js";import{a as l,r as u}from"./dist-HyCSN_hp.js";import{t as d}from"./vendor-state-B_-GdGNJ.js";import{f}from"./index-oA-kWqT5.js";import{a as p}from"./format-DvtQjPZn.js";var m=e(a(),1),h=d((e,t)=>({sessions:[],activeSessionId:null,messages:[],loading:!1,sending:!1,_chatWs:null,_chatWsReconnectDelay:1e3,fetchSessions:async()=>{try{e({sessions:(await u(`/chat/sessions`)).sessions})}catch{}},fetchMessages:async t=>{e({loading:!0});try{e({messages:(await u(`/chat/sessions/${t}`)).messages,loading:!1})}catch{e({messages:[],loading:!1})}},sendMessage:async n=>{if(t().sending)return null;e({sending:!0});try{let r=await u(`/chat/messages`,{method:`POST`,body:JSON.stringify({content:n,source:{type:`web`},sessionId:t().activeSessionId??void 0})});return e({activeSessionId:r.sessionId,sending:!1}),t().fetchSessions(),r}catch{return e({sending:!1}),null}},createSession:async()=>{try{let t=await u(`/chat/sessions`,{method:`POST`,body:JSON.stringify({source:{type:`web`}})});return e(e=>({sessions:[t.session,...e.sessions],activeSessionId:t.session.id,messages:[]})),t.session}catch{return null}},archiveSession:async t=>{try{await u(`/chat/sessions/${t}/archive`,{method:`POST`}),e(e=>({sessions:e.sessions.map(e=>e.id===t?{...e,status:`archived`}:e),activeSessionId:e.activeSessionId===t?null:e.activeSessionId,messages:e.activeSessionId===t?[]:e.messages}))}catch{}},restoreSession:async t=>{try{await u(`/chat/sessions/${t}/restore`,{method:`POST`}),e(e=>({sessions:e.sessions.map(e=>e.id===t?{...e,status:`active`}:e)}))}catch{}},deleteSession:async t=>{try{await u(`/chat/sessions/${t}`,{method:`DELETE`}),e(e=>({sessions:e.sessions.filter(e=>e.id!==t),activeSessionId:e.activeSessionId===t?null:e.activeSessionId,messages:e.activeSessionId===t?[]:e.messages}))}catch{}},setActiveSession:n=>{e({activeSessionId:n,messages:[]}),n&&t().fetchMessages(n)},connectChatStream:()=>{let n=t()._chatWs;if(n&&n.readyState<=1)return;let r=window.location.protocol===`https:`?`wss:`:`ws:`,i=localStorage.getItem(`adam_api_key`),a=new URL(`${r}//${window.location.host}/chat/stream`);i&&a.searchParams.set(`api_key`,i);let o=new WebSocket(a.toString());o.onopen=()=>{e({_chatWs:o,_chatWsReconnectDelay:1e3})},o.onclose=()=>{let n=t()._chatWsReconnectDelay;e({_chatWs:null,_chatWsReconnectDelay:Math.min(n*2,1e4)}),setTimeout(()=>{t().connectChatStream()},n)},o.onerror=()=>{o.close()},o.onmessage=n=>{try{let r=JSON.parse(n.data);if(r.type===`chat_message`&&r.message){let n=r.message,{activeSessionId:i,messages:a}=t();if(n.sessionId!==i||a.some(e=>e.id===n.id))return;e(e=>({messages:[...e.messages,n]}))}else r.type===`session_created`&&t().fetchSessions()}catch{}},e({_chatWs:o})},disconnectChatStream:()=>{let n=t()._chatWs;n&&(n.onclose=null,n.onerror=null,n.onmessage=null,n.close(),e({_chatWs:null}))}})),g=c();function _({message:e}){let t=e.role===`user`;return(0,g.jsx)(`div`,{className:l(`flex`,t?`justify-end`:`justify-start`),children:(0,g.jsxs)(`div`,{className:l(`max-w-[80%] rounded-lg px-3.5 py-2.5 text-sm leading-relaxed`,t?`bg-blue-600 text-white`:`border border-slate-700 bg-slate-800 text-slate-200`),children:[(0,g.jsx)(`div`,{className:`whitespace-pre-wrap break-words`,children:e.content}),(0,g.jsx)(`div`,{className:l(`mt-1.5 text-[10px]`,t?`text-blue-200/60`:`text-slate-500`),children:p(typeof e.createdAt==`number`?e.createdAt:new Date(e.createdAt).getTime())})]})})}function v({onSend:e,disabled:t,placeholder:r=`Type a message...`}){let[i,a]=(0,m.useState)(``),o=(0,m.useRef)(null),s=()=>{let n=i.trim();!n||t||(e(n),a(``),o.current&&(o.current.style.height=`auto`))},c=e=>{e.key===`Enter`&&!e.shiftKey&&(e.preventDefault(),s())},l=()=>{let e=o.current;e&&(e.style.height=`auto`,e.style.height=`${Math.min(e.scrollHeight,120)}px`)};return(0,g.jsxs)(`div`,{className:`flex items-end gap-2 border-t border-slate-800 bg-slate-950 px-4 py-3`,children:[(0,g.jsx)(`textarea`,{ref:o,value:i,onChange:e=>{a(e.target.value),l()},onKeyDown:c,placeholder:r,disabled:t,rows:1,className:`flex-1 resize-none rounded-md border border-slate-700 bg-slate-800 px-3 py-2 text-sm text-slate-200 placeholder:text-slate-500 focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 disabled:opacity-50`}),(0,g.jsx)(f,{onClick:s,disabled:t||!i.trim(),size:`default`,"aria-label":`Send message`,children:(0,g.jsx)(n,{size:16})})]})}function y(e){let t=Math.floor((Date.now()-e)/1e3);if(t<60)return`just now`;let n=Math.floor(t/60);if(n<60)return`${n}m ago`;let r=Math.floor(n/60);return r<24?`${r}h ago`:`${Math.floor(r/24)}d ago`}function b({session:e,isActive:t,onSelect:n,onArchive:a,onRestore:s,onDelete:c}){let u=e.status===`archived`;return(0,g.jsxs)(`button`,{onClick:n,className:l(`group flex w-full flex-col gap-1 rounded-md px-2.5 py-2 text-left transition-colors`,t?`bg-slate-800 text-slate-100`:`text-slate-400 hover:bg-slate-800/50 hover:text-slate-300`,u&&`opacity-60`),children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,g.jsx)(`span`,{className:`truncate text-xs font-medium`,children:e.title??e.id.slice(0,8)}),(0,g.jsxs)(`div`,{className:`flex gap-0.5 opacity-0 group-hover:opacity-100`,children:[u?(0,g.jsx)(`span`,{role:`button`,tabIndex:0,onClick:e=>{e.stopPropagation(),s()},onKeyDown:e=>{e.key===`Enter`&&(e.stopPropagation(),s())},className:`rounded p-0.5 text-slate-500 hover:text-emerald-400`,title:`Restore`,children:(0,g.jsx)(i,{size:12})}):(0,g.jsx)(`span`,{role:`button`,tabIndex:0,onClick:e=>{e.stopPropagation(),a()},onKeyDown:e=>{e.key===`Enter`&&(e.stopPropagation(),a())},className:`rounded p-0.5 text-slate-500 hover:text-amber-400`,title:`Archive`,children:(0,g.jsx)(r,{size:12})}),(0,g.jsx)(`span`,{role:`button`,tabIndex:0,onClick:e=>{e.stopPropagation(),c()},onKeyDown:e=>{e.key===`Enter`&&(e.stopPropagation(),c())},className:`rounded p-0.5 text-slate-500 hover:text-red-400`,title:`Delete`,children:(0,g.jsx)(o,{size:12})})]})]}),(0,g.jsxs)(`div`,{className:`flex items-center gap-2 text-[10px] text-slate-500`,children:[(0,g.jsxs)(`span`,{children:[e.messageCount,` turns`]}),(0,g.jsx)(`span`,{children:y(e.lastActiveAt)}),u&&(0,g.jsx)(`span`,{className:`rounded bg-slate-700 px-1 py-0.5 text-[9px]`,children:`archived`})]})]})}function x({sessions:e,activeSessionId:t,onSelectSession:n,onNewSession:r,onArchiveSession:i,onRestoreSession:a,onDeleteSession:o}){let c=e.filter(e=>e.status===`active`),l=e.filter(e=>e.status===`archived`);return(0,g.jsxs)(`div`,{className:`flex h-full flex-col`,children:[(0,g.jsxs)(`div`,{className:`flex items-center justify-between border-b border-slate-800 px-3 py-2.5`,children:[(0,g.jsx)(`span`,{className:`text-xs font-medium text-slate-400`,children:`Sessions`}),(0,g.jsx)(f,{variant:`ghost`,size:`sm`,onClick:r,children:(0,g.jsx)(s,{size:14})})]}),(0,g.jsxs)(`div`,{className:`flex-1 overflow-y-auto px-1.5 py-1.5`,children:[c.length===0&&l.length===0&&(0,g.jsx)(`div`,{className:`px-2 py-4 text-center text-xs text-slate-500`,children:`No sessions yet`}),c.length>0&&(0,g.jsx)(`div`,{className:`space-y-0.5`,children:c.map(e=>(0,g.jsx)(b,{session:e,isActive:e.id===t,onSelect:()=>n(e.id),onArchive:()=>i(e.id),onRestore:()=>a(e.id),onDelete:()=>o(e.id)},e.id))}),l.length>0&&(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(`div`,{className:`mt-3 mb-1 px-2 text-[10px] font-medium uppercase tracking-wider text-slate-600`,children:`Archived`}),(0,g.jsx)(`div`,{className:`space-y-0.5`,children:l.map(e=>(0,g.jsx)(b,{session:e,isActive:e.id===t,onSelect:()=>n(e.id),onArchive:()=>i(e.id),onRestore:()=>a(e.id),onDelete:()=>o(e.id)},e.id))})]})]})]})}function S(){let e=h(e=>e.sessions),n=h(e=>e.activeSessionId),r=h(e=>e.messages),i=h(e=>e.sending),a=h(e=>e.fetchSessions),o=h(e=>e.sendMessage),s=h(e=>e.createSession),c=h(e=>e.archiveSession),l=h(e=>e.restoreSession),u=h(e=>e.deleteSession),d=h(e=>e.setActiveSession),f=h(e=>e.connectChatStream),p=h(e=>e.disconnectChatStream),y=(0,m.useRef)(null);return(0,m.useEffect)(()=>{a()},[a]),(0,m.useEffect)(()=>(f(),()=>p()),[f,p]),(0,m.useEffect)(()=>{y.current?.scrollIntoView?.({behavior:`smooth`})},[r]),(0,g.jsxs)(`div`,{className:`flex h-full overflow-hidden`,children:[(0,g.jsx)(`div`,{className:`hidden w-56 flex-shrink-0 border-r border-slate-800 bg-slate-950 lg:block`,children:(0,g.jsx)(x,{sessions:e,activeSessionId:n,onSelectSession:d,onNewSession:()=>void s(),onArchiveSession:e=>void c(e),onRestoreSession:e=>void l(e),onDeleteSession:e=>void u(e)})}),(0,g.jsxs)(`div`,{className:`flex flex-1 flex-col`,children:[(0,g.jsx)(`div`,{className:`flex-1 overflow-y-auto px-4 py-4`,children:r.length===0?(0,g.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-3 text-slate-500`,children:[(0,g.jsx)(`div`,{className:`rounded-full bg-slate-800 p-3`,children:(0,g.jsx)(t,{size:24})}),(0,g.jsx)(`div`,{className:`text-sm`,children:`Start a conversation with Adam`}),(0,g.jsx)(`div`,{className:`text-xs text-slate-600`,children:`Type a message below to begin`})]}):(0,g.jsxs)(`div`,{className:`mx-auto max-w-3xl space-y-3`,children:[r.map(e=>(0,g.jsx)(_,{message:e},e.id)),(0,g.jsx)(`div`,{ref:y})]})}),(0,g.jsx)(`div`,{className:`mx-auto w-full max-w-3xl`,children:(0,g.jsx)(v,{onSend:async e=>{await o(e)},disabled:i})})]})]})}export{S as Chat};
|