adam-agent-server 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/adam-tools-W5AOIGEQ.js +1 -0
  2. package/dist/{approval-handler-JZSXM4AD.js → approval-handler-ORD4MUVM.js} +1 -1
  3. package/dist/audit-manager-YCJT2WP5.js +1 -0
  4. package/dist/bree-engine-R5YLSDCL.js +1 -0
  5. package/dist/{channels-PUOPR5Y2.js → channels-HYSB2EEK.js} +1 -1
  6. package/dist/channels-JCMPPQED.js +1 -0
  7. package/dist/{chunk-KO5AFX5U.js → chunk-23VZKIB6.js} +1 -1
  8. package/dist/{chunk-GYHOPV4Q.js → chunk-2DLVAKH7.js} +1 -1
  9. package/dist/chunk-2YAP4YJV.js +57 -0
  10. package/dist/{chunk-HYDCXE5K.js → chunk-5S6BMWD2.js} +1 -1
  11. package/dist/chunk-5XUR3M23.js +12 -0
  12. package/dist/chunk-6775OYXA.js +47 -0
  13. package/dist/{chunk-KOWFPY2J.js → chunk-6FXNB7NE.js} +1 -1
  14. package/dist/{chunk-QQWRV23T.js → chunk-7L2WQM7N.js} +1 -1
  15. package/dist/{chunk-L4Y3GR6W.js → chunk-BR2JY5X2.js} +1 -1
  16. package/dist/{chunk-7BSWC62F.js → chunk-C6BOQJJF.js} +1 -1
  17. package/dist/{chunk-DMZM7RU6.js → chunk-DZEVMYPB.js} +1 -1
  18. package/dist/{chunk-J3NIPZ73.js → chunk-GBTG5B5R.js} +2 -2
  19. package/dist/chunk-GY52JA5I.js +10 -0
  20. package/dist/{chunk-YHH3QMLL.js → chunk-H54ZXA26.js} +1 -1
  21. package/dist/{chunk-3567PCEJ.js → chunk-H7VDC6FY.js} +2 -2
  22. package/dist/{chunk-I5IUTZA3.js → chunk-HDP7A4XY.js} +1 -1
  23. package/dist/{chunk-XF4IERYF.js → chunk-HTPUEIFT.js} +1 -1
  24. package/dist/{chunk-XAMLLKKA.js → chunk-ISZJV72D.js} +1 -1
  25. package/dist/{chunk-4VHBKJD5.js → chunk-JAS3TUZX.js} +2 -2
  26. package/dist/chunk-MTWLLE26.js +49 -0
  27. package/dist/{chunk-EZGMA3VV.js → chunk-QVKI7H7W.js} +1 -1
  28. package/dist/{chunk-24GTCFEV.js → chunk-QWCRZDZS.js} +1 -1
  29. package/dist/{chunk-NZEDILAK.js → chunk-R4GIIQ7G.js} +1 -1
  30. package/dist/chunk-RAW263MQ.js +99 -0
  31. package/dist/{chunk-T7GEINGZ.js → chunk-S3BAIZ4Q.js} +1 -1
  32. package/dist/chunk-VRJ7R766.js +1 -0
  33. package/dist/{chunk-CKIVKM5T.js → chunk-XL46AGRZ.js} +2 -2
  34. package/dist/{chunk-6THDALGC.js → chunk-Y3AMO6WC.js} +1 -1
  35. package/dist/{chunk-RUY23IJK.js → chunk-YVS565QY.js} +1 -1
  36. package/dist/{chunk-JKPSEMUZ.js → chunk-Z4D3L2HR.js} +1 -1
  37. package/dist/cli.js +1 -1
  38. package/dist/{config-CBNOT66B.js → config-EMNKHR3W.js} +1 -1
  39. package/dist/{db-XQUI4IBL.js → db-YUYXVV3A.js} +1 -1
  40. package/dist/{delivery-log-T56ZYDWO.js → delivery-log-VKONLSVD.js} +1 -1
  41. package/dist/engine-BM5BMPIC.js +1 -0
  42. package/dist/{evolution-audit-JZ2U7J4C.js → evolution-audit-LZSQPDHH.js} +1 -1
  43. package/dist/index.js +18 -12
  44. package/dist/learner-IJN6B7KV.js +1 -0
  45. package/dist/{memories-EKREXLT6.js → memories-ZII5QSTJ.js} +1 -1
  46. package/dist/{memory-extractor-JO7OHBZP.js → memory-extractor-DIYJFBCI.js} +2 -2
  47. package/dist/memory-service-QMYJPBAE.js +1 -0
  48. package/dist/outbound-gateway-6K6P2BEH.js +1 -0
  49. package/dist/role-presets-K2BDRZBS.js +1 -0
  50. package/dist/roles-L34L5MK3.js +1 -0
  51. package/dist/{session-manager-PWJLU6KZ.js → session-manager-GRJ3FV3L.js} +1 -1
  52. package/dist/{task-templates-ED2UCUPE.js → task-templates-23YOAF3E.js} +1 -1
  53. package/dist/workflow-executor-JTUWX5DC.js +1 -0
  54. package/package.json +1 -1
  55. package/dist/adam-tools-KTLBI4PA.js +0 -1
  56. package/dist/audit-manager-BPJEAX22.js +0 -1
  57. package/dist/bree-engine-CRK73AI4.js +0 -1
  58. package/dist/channels-WMTZJAO4.js +0 -1
  59. package/dist/chunk-DBI36EGR.js +0 -83
  60. package/dist/chunk-HQ66TFYI.js +0 -12
  61. package/dist/chunk-I67UMGJM.js +0 -10
  62. package/dist/chunk-NOUSHXGX.js +0 -6
  63. package/dist/chunk-WRETNOC3.js +0 -99
  64. package/dist/chunk-ZRUVORAJ.js +0 -49
  65. package/dist/engine-7DFJOADQ.js +0 -1
  66. package/dist/learner-4EO7ZKK4.js +0 -1
  67. package/dist/memory-service-Y3HVQYHM.js +0 -1
  68. package/dist/outbound-gateway-U5LP54JG.js +0 -1
  69. package/dist/role-presets-HWZHXBBA.js +0 -1
  70. package/dist/roles-3AEHVOEW.js +0 -1
  71. package/dist/workflow-executor-XFTTJQNE.js +0 -1
@@ -0,0 +1 @@
1
+ import{k as a,l as b}from"./chunk-2YAP4YJV.js";import"./chunk-5XUR3M23.js";import"./chunk-H54ZXA26.js";import"./chunk-BR2JY5X2.js";import"./chunk-6775OYXA.js";import"./chunk-5V36ACKZ.js";import"./chunk-VRJ7R766.js";import"./chunk-Y3AMO6WC.js";import"./chunk-ISZJV72D.js";import"./chunk-23VZKIB6.js";import"./chunk-Z4D3L2HR.js";import"./chunk-2DLVAKH7.js";import"./chunk-HDP7A4XY.js";import"./chunk-QWCRZDZS.js";import"./chunk-L7JP7DUO.js";import"./chunk-R4GIIQ7G.js";import"./chunk-2CMR5AG7.js";import"./chunk-C6BOQJJF.js";import"./chunk-S3BAIZ4Q.js";import"./chunk-7K4AQBDD.js";import"./chunk-UQJZU3R5.js";import"./chunk-7IFLU3CY.js";import"./chunk-GSMC3VUM.js";import"./chunk-GBTG5B5R.js";import"./chunk-7L2WQM7N.js";import"./chunk-JAS3TUZX.js";import"./chunk-WBAPIPST.js";import"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";export{b as createAdamTools,a as getToolsFingerprint};
@@ -1 +1 @@
1
- import{a,b,c,d,e}from"./chunk-RUY23IJK.js";import"./chunk-CKIVKM5T.js";import"./chunk-KO5AFX5U.js";import"./chunk-EZGMA3VV.js";import"./chunk-L7JP7DUO.js";import"./chunk-4VHBKJD5.js";import"./chunk-WBAPIPST.js";import"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";export{b as formatPlanForChannel,e as getPendingApprovalRequestIds,d as handleInboundForApproval,a as parseApprovalReply,c as sendApprovalToChannel};
1
+ import{a,b,c,d,e}from"./chunk-YVS565QY.js";import"./chunk-XL46AGRZ.js";import"./chunk-23VZKIB6.js";import"./chunk-L7JP7DUO.js";import"./chunk-QVKI7H7W.js";import"./chunk-JAS3TUZX.js";import"./chunk-WBAPIPST.js";import"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";export{b as formatPlanForChannel,e as getPendingApprovalRequestIds,d as handleInboundForApproval,a as parseApprovalReply,c as sendApprovalToChannel};
@@ -0,0 +1 @@
1
+ import{j as a,k as b,l as c,m as d,n as e}from"./chunk-RAW263MQ.js";import"./chunk-5XUR3M23.js";import"./chunk-H54ZXA26.js";import"./chunk-YHVFZB6Q.js";import"./chunk-VRJ7R766.js";import"./chunk-Y3AMO6WC.js";import"./chunk-ISZJV72D.js";import"./chunk-5S6BMWD2.js";import"./chunk-DZEVMYPB.js";import"./chunk-QWCRZDZS.js";import"./chunk-L7JP7DUO.js";import"./chunk-QVKI7H7W.js";import"./chunk-R4GIIQ7G.js";import"./chunk-2CMR5AG7.js";import"./chunk-C6BOQJJF.js";import"./chunk-T33BLZV2.js";import"./chunk-GSMC3VUM.js";import"./chunk-GBTG5B5R.js";import"./chunk-7L2WQM7N.js";import"./chunk-JAS3TUZX.js";import"./chunk-WBAPIPST.js";import"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";export{a as evaluateTaskCompletion,e as getSecurityPosture,d as reportViolation,b as startAuditManager,c as stopAuditManager};
@@ -0,0 +1 @@
1
+ import{a,b,c}from"./chunk-MTWLLE26.js";import"./chunk-GY52JA5I.js";import"./chunk-6775OYXA.js";import"./chunk-5V36ACKZ.js";import"./chunk-YHVFZB6Q.js";import"./chunk-VRJ7R766.js";import"./chunk-Y3AMO6WC.js";import"./chunk-ISZJV72D.js";import"./chunk-XL46AGRZ.js";import"./chunk-23VZKIB6.js";import"./chunk-QWCRZDZS.js";import"./chunk-L7JP7DUO.js";import"./chunk-QVKI7H7W.js";import"./chunk-C6BOQJJF.js";import"./chunk-S3BAIZ4Q.js";import"./chunk-7K4AQBDD.js";import"./chunk-UQJZU3R5.js";import"./chunk-7IFLU3CY.js";import"./chunk-GSMC3VUM.js";import"./chunk-GBTG5B5R.js";import"./chunk-7L2WQM7N.js";import"./chunk-JAS3TUZX.js";import"./chunk-WBAPIPST.js";import"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";export{a as BreeEngine,b as getBreeEngine,c as setBreeEngine};
@@ -1 +1 @@
1
- import{a,b,c,d,e,f}from"./chunk-KO5AFX5U.js";import"./chunk-4VHBKJD5.js";import"./chunk-WBAPIPST.js";import"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";export{a as createChannel,e as deleteChannel,b as getChannel,d as listChannels,c as updateChannel,f as updateChannelStatus};
1
+ import{a,b,c,d,e,f}from"./chunk-23VZKIB6.js";import"./chunk-JAS3TUZX.js";import"./chunk-WBAPIPST.js";import"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";export{a as createChannel,e as deleteChannel,b as getChannel,d as listChannels,c as updateChannel,f as updateChannelStatus};
@@ -0,0 +1 @@
1
+ import{c as a,d as b,e as c}from"./chunk-6FXNB7NE.js";import"./chunk-23VZKIB6.js";import"./chunk-HDP7A4XY.js";import"./chunk-JAS3TUZX.js";import"./chunk-WBAPIPST.js";import"./chunk-INNDBLZE.js";import"./chunk-FCV2DPZQ.js";export{c as channelRoutes,b as getChannelManager,a as setChannelManager};
@@ -1,4 +1,4 @@
1
- import{b as s,d as i}from"./chunk-4VHBKJD5.js";i();function l(e){return{id:e.id,name:e.name,platform:e.platform,enabled:e.enabled===1,status:e.status,config:JSON.parse(e.config),linkedRoleId:e.linked_role_id??void 0,allowedChatIds:e.allowed_chat_ids?JSON.parse(e.allowed_chat_ids):void 0,createdAt:e.created_at,updatedAt:e.updated_at??void 0,lastMessageAt:e.last_message_at??void 0,messageCount:e.message_count}}function o(e){s().prepare(`
1
+ import{b as s,d as i}from"./chunk-JAS3TUZX.js";i();function l(e){return{id:e.id,name:e.name,platform:e.platform,enabled:e.enabled===1,status:e.status,config:JSON.parse(e.config),linkedRoleId:e.linked_role_id??void 0,allowedChatIds:e.allowed_chat_ids?JSON.parse(e.allowed_chat_ids):void 0,createdAt:e.created_at,updatedAt:e.updated_at??void 0,lastMessageAt:e.last_message_at??void 0,messageCount:e.message_count}}function o(e){s().prepare(`
2
2
  INSERT INTO channels (id, name, platform, enabled, status, config, linked_role_id,
3
3
  allowed_chat_ids, created_at, updated_at, last_message_at, message_count)
4
4
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -1,4 +1,4 @@
1
- import{b as i,d as u}from"./chunk-4VHBKJD5.js";u();function c(t){return{id:t.id,status:t.status,source:{type:t.source_type,channelId:t.source_channel_id??void 0,chatId:t.source_chat_id??void 0},title:t.title??void 0,createdAt:t.created_at,lastActiveAt:t.last_active_at,archivedAt:t.archived_at??void 0,messageCount:t.message_count}}function d(t){i().prepare(`
1
+ import{b as i,d as u}from"./chunk-JAS3TUZX.js";u();function c(t){return{id:t.id,status:t.status,source:{type:t.source_type,channelId:t.source_channel_id??void 0,chatId:t.source_chat_id??void 0},title:t.title??void 0,createdAt:t.created_at,lastActiveAt:t.last_active_at,archivedAt:t.archived_at??void 0,messageCount:t.message_count}}function d(t){i().prepare(`
2
2
  INSERT INTO chat_sessions (id, status, source_type, source_channel_id, source_chat_id,
3
3
  title, created_at, last_active_at, archived_at, message_count)
4
4
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -0,0 +1,57 @@
1
+ import{a as qe,c as We,d as ze,e as Ye}from"./chunk-5XUR3M23.js";import{b as Le,c as se,e as Oe}from"./chunk-H54ZXA26.js";import{a as Be,c as ce,e as Je}from"./chunk-BR2JY5X2.js";import{a as E,b as Ce,c as Pe,d as De,e as xe,f as Ae,h as Me,i as H,j as N,k as Q,l as $e,m as Ne,n as L,o as Ee,p as x,q as ie}from"./chunk-6775OYXA.js";import{a as Ue}from"./chunk-5V36ACKZ.js";import{a as we,b as ke,c as z,d as Te,e as Se,f as Re,g as ct,h as _e,i as _,k as Y}from"./chunk-VRJ7R766.js";import{b as he}from"./chunk-Y3AMO6WC.js";import{b as P,c as U,d as M}from"./chunk-ISZJV72D.js";import{d as le}from"./chunk-23VZKIB6.js";import{j as de}from"./chunk-Z4D3L2HR.js";import{e as ne,f as B,g as ve,i as re,j as J}from"./chunk-QWCRZDZS.js";import{a as oe}from"./chunk-L7JP7DUO.js";import{g as je}from"./chunk-C6BOQJJF.js";import{a as ae,b as O,c as Ge,f as Ve,g as Fe}from"./chunk-S3BAIZ4Q.js";import{d as T,j as ge}from"./chunk-GSMC3VUM.js";import{f as be,g as ee,i as dt,k as ye,l as v,n as $,o as D,p as Ie,q as te,r as W}from"./chunk-GBTG5B5R.js";import{c as A,d as fe,h as Z}from"./chunk-INNDBLZE.js";import{f as C}from"./chunk-FCV2DPZQ.js";import{createSdkMcpServer as Tt,tool as u}from"@anthropic-ai/claude-agent-sdk";import{z as n}from"zod";W();J();import{v4 as q}from"uuid";Z();var ut=A("goal-manager");async function Sn(e){let t;try{let r=JSON.parse(e);t={name:r.name??"",description:r.description,metric:r.metric??"",targetValue:r.targetValue??0,currentValue:r.currentValue??0,deadline:r.deadline??0,budget:r.budget??0,roleId:r.roleId??"engineer",status:"active"}}catch{t=await pt(e)}let o=mt(t);return{goalState:t,validationResult:o,rawInput:e}}async function pt(e){let t=`Extract SMART goal fields from this natural language input.
2
+
3
+ Input: "${e}"
4
+
5
+ Respond ONLY with a JSON object:
6
+ {
7
+ "name": "short goal name (max 100 chars)",
8
+ "description": "detailed description of what the goal aims to achieve",
9
+ "metric": "measurable metric name (e.g. completion, reports_written, accuracy_score)",
10
+ "targetValue": <number, the target to reach>,
11
+ "deadline_days": <number, days from now to complete>,
12
+ "budget": <number, estimated budget in USD>,
13
+ "role": "<best matching role: engineer | analyst | content_creator | reviewer>"
14
+ }
15
+
16
+ Rules:
17
+ - name: concise, actionable title
18
+ - metric: quantifiable measure of success; use "completion" if the goal is binary (done/not done)
19
+ - targetValue: realistic target for the metric; use 1 for binary goals
20
+ - deadline_days: reasonable timeframe; default 7 if unclear
21
+ - budget: estimated cost in USD; default 5 if unclear
22
+ - role: match to the nature of work (research=analyst, writing=content_creator, coding=engineer, review=reviewer)`;try{let r=(await Ue(t,"You extract structured SMART goal fields from natural language. Reply with only valid JSON.")).match(/\{[\s\S]*\}/);if(r){let i=JSON.parse(r[0]),a=i.deadline_days??7;return{name:(i.name??e.slice(0,100)).slice(0,100),description:i.description??e,metric:i.metric??"completion",targetValue:i.targetValue??1,currentValue:0,deadline:Date.now()+a*24*60*60*1e3,budget:i.budget??5,roleId:i.roleId??"engineer",status:"active"}}}catch(o){ut.warn({error:o},"LLM goal parsing failed, using fallback")}return{name:e.trim().slice(0,100),description:e.trim(),metric:"completion",targetValue:1,currentValue:0,deadline:Date.now()+10080*60*1e3,budget:5,roleId:"engineer",status:"active"}}function mt(e){let t=[],o=[];return(!e.name||e.name.trim().length===0)&&t.push("S: name must be non-empty"),(!e.description||e.description.trim().length===0)&&t.push("S: description must be non-empty"),(!e.metric||e.metric.trim().length===0)&&t.push("M: metric must be specified"),e.targetValue<=0&&t.push("A: targetValue must be > 0"),(!e.roleId||e.roleId.trim().length===0)&&t.push("R: roleId must be non-empty"),e.deadline<=Date.now()&&t.push("T: deadline must be in the future"),e.budget<=0&&o.push("budget is zero or negative; goal will have no spending limit"),{isValid:t.length===0,errors:t,warnings:o}}function Rn(e,t,o){let r=q(),i=Date.now(),a={id:r,name:e.name,description:e.description,roleId:e.roleId,metricType:e.metric,targetValue:e.targetValue,currentValue:e.currentValue,deadline:e.deadline,budgetUsd:e.budget,status:e.status,createdAt:i,deliverTo:t,reportTo:o};return H(a),a}function He(e,t){let o=Date.now(),r=[],i={id:q(),goalId:e,level:"L0",name:`${t}_goal_progress`,description:`Goal-level ${t} progress (monthly)`,weight:1,calibrationFactor:1,createdAt:o};r.push(i),L(i);let a={id:q(),goalId:e,level:"L1",parentId:i.id,name:`${t}_weekly_trend`,description:`Weekly trend for ${t}`,weight:.8,calibrationFactor:1,createdAt:o};r.push(a),L(a);let l={id:q(),goalId:e,level:"L2",parentId:a.id,name:`${t}_daily_process`,description:`Daily process metric for ${t}`,weight:.6,calibrationFactor:1,createdAt:o};r.push(l),L(l);let d={id:q(),goalId:e,level:"L3",parentId:l.id,name:`${t}_per_task`,description:`Per-task instant metric for ${t}`,weight:.4,calibrationFactor:1,createdAt:o};return r.push(d),L(d),r}var gt=3,ft=2,K=class{static async generateVariants(t,o,r=gt,i=ft){let a=x.getTopStrategies(t,o,r);if(a.length===0){let d=`baseline-${o}-v1`;return x.addStrategy(t,o,d,this.generateBaselinePrompt(t,o)),[d]}let l=[];for(let d=0;d<i;d++){let m=a[0].totalTrials+d+1,c=`${o}-evolved-v${m}`,f=a[0].promptTemplate,g=this.mutateTemplate(f);x.addStrategy(t,o,c,g),l.push(c)}return l}static generateBaselinePrompt(t,o){return`You are a ${t} agent specializing in ${o}.
23
+
24
+ ## Core Focus
25
+ Complete tasks with high quality.
26
+
27
+ ## Approach
28
+ 1. Understand the task requirements thoroughly
29
+ 2. Plan your approach before executing
30
+ 3. Execute systematically, checking your work
31
+ 4. Verify completion against requirements`}static mutateTemplate(t){let o=[this.addProcessEmphasis(),this.addQualityFocus(),this.addVerificationStep()],r=o[Math.floor(Math.random()*o.length)];return`${t}
32
+
33
+ ## Evolution
34
+ ${r}`}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,o,r){return{promptTemplate:this.generateBaselinePrompt(t,o),rationale:"Generated baseline - LLM integration in Phase 5"}}};Z();_e();import{v4 as w}from"uuid";import{spawnSync as Qe}from"child_process";import{createRequire as ht}from"module";import{dirname as bt,join as Ke}from"path";import{openSync as yt,readFileSync as It,unlinkSync as vt}from"fs";var wt=3e4,Xe=12e4;function Ze(){let t=ht(import.meta.url).resolve("@anthropic-ai/claude-agent-sdk");return Ke(bt(t),"cli.js")}function j(e,t){let o=Ze(),r=t?.timeout??wt;if(t?.json){let a=Ke("/tmp",`adam-cli-stdout-${process.pid}-${Date.now()}.txt`),l=yt(a,"w");try{let d=Qe("node",[o,...e],{cwd:t.cwd,timeout:r,stdio:["ignore",l,"pipe"],encoding:"utf-8"});if(d.status!==0)throw new Error(d.stderr?.trim()||`CLI exited with status ${d.status}`);return It(a,"utf-8")}finally{try{vt(a)}catch{}}}let i=Qe("node",[o,...e],{cwd:t?.cwd,timeout:r,encoding:"utf-8"});if(i.status!==0)throw new Error(i.stderr?.trim()||`CLI exited with status ${i.status}`);return i.stdout}function et(){let e=j(["plugin","list","--available","--json"],{json:!0});return JSON.parse(e)}function ue(e,t="user",o){return j(["plugin","install",e,"--scope",t],{cwd:o,timeout:Xe})}function pe(e,t,o){let r=["plugin","uninstall",e];return t&&r.push("--scope",t),j(r,{cwd:o,timeout:Xe})}function tt(e,t){return j(["plugin","enable",e])}function nt(e,t){return j(["plugin","disable",e])}function $n(){try{return!!Ze()}catch{return!1}}Z();import*as rt from"crypto";var G=A("api"),V=class{cancelTask(t){let o=P(t);o&&(U(t,{status:"cancelled",completedAt:Date.now()}),oe.emit({type:"task_status_change",taskId:t,oldStatus:o.status,newStatus:"cancelled"}),G.debug({taskId:t,oldStatus:o.status},"Task cancelled"))}resolveApproval(t,o,r){return G.debug({approvalId:t,action:o,reason:r},"Approval resolved (no-op in Pure C)"),!0}resolvePlanApproval(t,o,r,i){let a=Le(t);if(!a)return G.warn({planId:t},"Plan not found or already resolved"),!1;let l=P(a.taskId);return l?(Oe(t,o==="allow"?"approved":"denied",r),o==="allow"&&r==="permanent"&&qe({id:rt.randomUUID(),roleId:a.roleId,taskPattern:l.prompt.slice(0,100).replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),maxRiskLevel:a.plan.overallRisk,createdAt:Date.now(),createdByTaskId:l.id}),oe.emit({type:"plan_approval_decision",taskId:l.id,planId:t,decision:o,approvalType:r,reason:i}),G.debug({planId:t,decision:o,approvalType:r},"Plan approval resolved"),!0):(G.warn({planId:t},"Task not found for plan"),!1)}};import{existsSync as ot}from"fs";dt();var F=A("manager");function s(e){return{content:[{type:"text",text:JSON.stringify(e)}]}}async function k(e){let{listChannels:t}=await import("./channels-HYSB2EEK.js"),o=t(),{listSessions:r}=await import("./session-manager-GRJ3FV3L.js"),i=[...r("active"),...r("archived")],a=[];for(let l of e)if(l.type==="session"&&l.sessionId)a.push({type:"session",sessionId:l.sessionId});else if(l.type==="channel"){let d=l.channelId,m=l.chatId;if(!d&&l.channelName){let c=o.find(f=>f.name.toLowerCase().includes(l.channelName.toLowerCase()));c&&(d=c.id)}if(d&&!m){let c=i.find(f=>f.source.type==="channel"&&f.source.channelId===d&&f.source.chatId);c?.source.chatId?m=c.source.chatId:m=o.find(g=>g.id===d)?.config?.userId}d&&m?a.push({type:"channel",channelId:d,chatId:m}):F.warn({channelName:l.channelName,channelId:d,chatId:m},"Could not resolve channel notify target")}return a}async function St(e){let{listRoles:t}=await import("./roles-L34L5MK3.js"),o=t(void 0,100,0);for(let r of o)if(r.name.toLowerCase().includes(e.toLowerCase()))return r.id}var Rt={goalId:n.string()},_t={goalId:n.string(),status:n.string().optional(),currentValue:n.number().optional(),budgetUsd:n.number().optional(),notes:n.string().optional()},Ct={goalId:n.string(),goalDescription:n.string(),maxSubtasks:n.number().optional()},S=n.union([n.object({type:n.literal("session"),sessionId:n.string()}),n.object({type:n.literal("channel"),channelName:n.string()}),n.object({type:n.literal("channel"),channelId:n.string(),chatId:n.string().optional()})]),Pt={prompt:n.string(),roleId:n.string().optional().describe("Role ID. Call list_roles(requirements) first to find the best role for the task."),requirements:E.optional(),autoSelectRole:n.boolean().optional(),deliverTo:n.array(S).optional().describe("Where to deliver the task output (result full text). E.g., send result to a specific channel."),reportTo:n.array(S).optional().describe("Where to send status reports (completion summary). Defaults to the originating channel/session."),toolOverrides:n.object({allowedTools:n.array(n.string()).optional(),disallowedTools:n.array(n.string()).optional()}).optional()},Dt={taskId:n.string(),goalId:n.string().optional(),strategyId:n.string().optional()},xt={roleId:n.string(),taskType:n.string(),name:n.string().optional()},At={status:n.string().optional(),limit:n.number().optional()},Mt={taskId:n.string(),roleId:n.string()},$t={taskId:n.string().optional(),status:n.string().optional(),limit:n.number().optional()},Nt={roleId:n.string(),allowedTools:n.array(n.string()).optional(),disallowedTools:n.array(n.string()).optional(),osCapabilities:n.array(n.object({id:n.string().min(1),targets:n.array(n.string().min(1)).optional()})).optional().describe("Role-level OS capability grants. Use get_capabilities to inspect the runtime registry and valid target-scoped entries."),additionalDirectories:n.array(n.object({path:n.string(),mode:n.enum(["ro","rw"]).optional().describe("Read-only or read-write access. Default: rw. Enforced by OS sandbox."),inheritPlugins:n.boolean().optional(),inheritMcp:n.boolean().optional(),inheritPermissions:n.boolean().optional()})).optional(),allowedChannels:n.array(n.string()).optional(),inheritUserSettings:n.boolean().optional().describe("Enable/disable inheriting user-level settings (global plugins, MCP servers). Default: false (isolated).")},Ut={roleId:n.string().describe("Role ID to update."),name:n.string().min(1).optional(),cagPrompt:n.string().optional(),learnedRules:n.array(n.string()).optional(),status:n.enum(["active","inactive","retired"]).optional(),executionMode:n.enum(["isolated","inline"]).optional(),model:n.string().optional(),maxBudgetUsd:n.number().optional(),approvalRequired:n.array(n.string()).optional(),preferences:n.object({model:n.string().optional(),effort:n.enum(["low","medium","high","max"]).optional(),maxTurns:n.number().optional()}).optional(),permissionMode:n.enum(["default","acceptEdits","dontAsk","bypassPermissions","plan","auto"]).optional(),allowedBashPatterns:n.array(n.string()).optional(),deniedBashPatterns:n.array(n.string()).optional(),evaluationCriteria:n.record(n.string(),n.number()).optional(),envVars:n.record(n.string(),n.string()).optional()},Et={roleId:n.string().optional(),limit:n.number().optional()},Lt={name:n.string(),cagPrompt:n.string(),traits:n.array(n.string()).optional(),allowedTools:n.array(n.string()).optional(),disallowedTools:n.array(n.string()).optional(),osCapabilities:n.array(n.object({id:n.string().min(1),targets:n.array(n.string().min(1)).optional()})).optional().describe("Initial Role-level OS capability grants. Use get_capabilities to discover editable capability ids and target rules."),additionalDirectories:n.array(n.object({path:n.string(),mode:n.enum(["ro","rw"]).optional().describe("Read-only or read-write access. Default: rw. Enforced by OS sandbox."),inheritPlugins:n.boolean().optional(),inheritMcp:n.boolean().optional(),inheritPermissions:n.boolean().optional()})).optional()},Ot={roleId:n.string(),reason:n.string().optional()},qt={name:n.string(),description:n.string().optional(),roleId:n.string().optional(),metric:n.string().optional(),targetValue:n.number().optional(),deadline:n.number().optional(),budgetUsd:n.number().optional(),deliverTo:n.array(S).optional().describe("Where to deliver goal completion notifications.")},jt={name:n.string(),description:n.string().optional(),triggerType:n.enum(["cron","event"]),triggerCron:n.string().optional(),triggerEvent:n.string().optional(),prompt:n.string(),roleId:n.string().optional(),requirements:E.optional(),autoSelectRole:n.boolean().optional(),enabled:n.boolean().optional(),goalIds:n.array(n.string()).optional(),deliverTo:n.array(S).optional().describe("Where to deliver the task output (result full text)."),reportTo:n.array(S).optional().describe("Where to send status reports (completion summary).")},Gt={status:n.enum(["active","retired","probation"]).optional(),limit:n.number().optional(),requirements:E.optional()},Vt={enabled:n.boolean().optional()},Ft={},Wt={},Bt={prompt:n.string().describe("The task prompt to execute after the delay"),delayMinutes:n.number().optional().describe("Minutes from now to execute (e.g., 30 for 'half an hour later')"),runAt:n.string().optional().describe("ISO 8601 timestamp to execute at (e.g., '2026-04-01T15:00:00+08:00')"),roleId:n.string().describe("Role ID to assign the task to. Call list_roles first."),deliverTo:n.array(S).optional().describe("Where to deliver the task output (result full text)."),reportTo:n.array(S).optional().describe("Where to send status reports (completion summary).")},Jt={roleId:n.string().optional().describe("If provided, shows which plugins are installed in that role's workspace.")},zt={roleId:n.string().describe("Role ID to install the plugin under (project-scope)."),pluginId:n.string().describe("Plugin ID (e.g. 'github@anthropic'). Use list_available_plugins to discover available plugins.")},Yt={roleId:n.string().describe("Role ID to uninstall the plugin from."),pluginId:n.string().describe("Plugin ID to uninstall.")},Ht={roleId:n.string().describe("Role ID to bind the MCP server to."),mcpName:n.string().describe("Name for this MCP server (e.g., 'github', 'filesystem')."),mcpConfig:n.record(n.string(),n.unknown()).describe("MCP server configuration object.")},Qt={roleId:n.string().describe("Role ID to unbind the MCP server from."),mcpName:n.string().describe("Name of the MCP server to remove.")},Kt={pluginId:n.string().describe("Plugin ID (e.g., 'github@anthropic').")},Xt={pluginId:n.string().describe("Plugin ID (e.g., 'github@anthropic').")},Zt={pluginId:n.string().describe("Plugin ID (e.g., 'github@anthropic').")},en={pluginId:n.string().describe("Plugin ID (e.g., 'github@anthropic').")},tn={},nn={},rn={pluginId:n.string().describe("Plugin ID (e.g., 'github@anthropic').")},on={roleId:n.string().describe("Role ID to associate scanned plugins with."),path:n.string().describe("Directory path to scan for .claude/settings.json.")},sn={taskId:n.string().describe("Task ID to cancel.")},an={taskId:n.string().describe("Task ID to get logs for."),limit:n.number().optional().describe("Max log entries (default 20).")},ln={roleId:n.string().describe("Role ID to delete.")},dn={},cn={updates:n.record(n.string(),n.unknown()).describe("Config key-value pairs to update. Example: { 'defaults.maxTurns': 50, 'logging.level': 'debug' }")},un={roleId:n.string().describe("Role ID to list memories for."),limit:n.number().optional().describe("Max results (default 20).")},pn={templateId:n.string().describe("Template ID to update."),name:n.string().optional(),enabled:n.boolean().optional(),prompt:n.string().optional(),triggerCron:n.string().optional(),triggerEvent:n.string().optional(),roleId:n.string().optional()},mn={templateId:n.string().describe("Template ID to delete.")},gn={templateId:n.string().describe("Template ID to run immediately.")},fn={enabled:n.boolean().optional().describe("Filter by enabled status.")},hn={eventType:n.string().describe("Event type that triggers this rule (e.g., 'task_complete')."),channelId:n.string().describe("Channel ID to deliver to."),format:n.string().optional().describe("Format template (e.g., 'summary', 'full'). Default: 'summary'."),matchCriteria:n.record(n.string(),n.unknown()).optional().describe("JSON match criteria for event fields."),enabled:n.boolean().optional().describe("Enable this rule immediately (default true).")},bn={ruleId:n.string().describe("Delivery rule ID to delete.")},yn={roleId:n.string().optional().describe("Role ID to filter strategies by.")},it=[u("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.",Rt,async e=>{let t=N(e.goalId);if(!t)return s({error:"Goal not found"});let o=Date.now(),r=t.targetValue>0?t.currentValue/t.targetValue:0;return s({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:r,timeRemainingMs:Math.max(0,t.deadline-o),budgetRemainingUsd:t.budgetUsd})}),u("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(),Q(e.goalId,t)),s({success:!0})}),u("decompose_goal","Decompose a goal into actionable subtasks using LLM reasoning.",Ct,async e=>{let t=T(),o=Math.min(e.maxSubtasks??5,10);try{let{query:a}=await import("@anthropic-ai/claude-agent-sdk"),l=`Decompose this goal into ${o} actionable subtasks.
35
+
36
+ Goal: ${e.goalDescription}
37
+
38
+ Respond ONLY with a JSON array. Each item:
39
+ {
40
+ "description": "...",
41
+ "prompt": "detailed task instruction",
42
+ "complexity": "low|medium|high",
43
+ "role": "engineer|analyst|content_creator|reviewer",
44
+ "requirements": {
45
+ "tools": ["Read", "Write"],
46
+ "paths": [{"path": "/abs/path", "access": "ro"}],
47
+ "osCapabilities": [{"id": "automation", "targets": ["bundle.id"]}],
48
+ "network": false
49
+ }
50
+ }
51
+
52
+ Rules:
53
+ - Each subtask must be independently executable
54
+ - Order from foundational to dependent
55
+ - Be specific about what each subtask should accomplish
56
+ - For each subtask, specify the best role from: 'engineer', 'analyst', 'content_creator', 'reviewer'. Match role to the nature of the work.
57
+ - Include tools and paths required for the subtask where known. If unknown, omit the field.`,d=a({prompt:l,options:{cwd:process.cwd(),maxTurns:1,maxBudgetUsd:.02}}),m="";for await(let f of d){let g=f;g.type==="result"&&typeof g.result=="string"&&(m=g.result)}let c=m.match(/\[[\s\S]*\]/);if(c){let f=JSON.parse(c[0]),g=[];for(let h=0;h<Math.min(f.length,o);h++){let I=f[h],R=I.role,p=R?await St(R):void 0,b=await ie({prompt:I.prompt,roleId:p,requirements:I.requirements,config:t.defaults});if(!b.ok){g.push({id:`admission-failed-${h}`,description:I.description,prompt:I.prompt,dependencies:h>0&&g.length>0?[g[h-1].id]:[],estimatedComplexity:I.complexity??"medium",role:R,admissionError:`${b.code}: ${b.reason}`});continue}g.push({id:b.taskId,description:I.description,prompt:I.prompt,dependencies:h>0?[g[h-1].id]:[],estimatedComplexity:I.complexity??"medium",role:R})}if(g.length>0)return s({subtasks:g})}}catch(a){F.error({error:a},"LLM decomposition failed, using fallback")}let r=await Ae({taskId:w(),roleId:void 0,autoSelectRole:!1}),i=[];return r.ok||i.push({id:"admission-blocked",description:`Decomposition fallback blocked: ${r.reason}`,prompt:e.goalDescription,dependencies:[],estimatedComplexity:"medium",admissionError:`${r.code}: ${r.reason}`}),s({subtasks:i})}),u("dispatch_task","Create and dispatch a task. Workflow: (1) call list_roles(requirements) to find candidate roles by fit; (2) call dispatch_task with requirements AND the chosen roleId. requirements is STRONGLY RECOMMENDED \u2014 when present, admission validates role fit before creation and returns structured mismatch diagnostics. If you cannot produce clear requirements from the user's message, ASK THE USER instead of dispatching. Pass deliverTo (result delivery) and/or reportTo (status reports) to route output when the task completes.",Pt,async e=>{if(!e.roleId&&!e.autoSelectRole){let i=D("active",20,0).filter(a=>a.source!=="system").map(a=>({id:a.id,name:a.name,allowedTools:a.allowedTools??[],capabilitySummary:_(a)}));return s({error:"Must provide roleId or autoSelectRole=true with requirements.",availableRoles:i})}let t=e.deliverTo?await k(e.deliverTo):void 0,o=e.reportTo?await k(e.reportTo):void 0,r=await ie({prompt:e.prompt,roleId:e.roleId,requirements:e.requirements,autoSelectRole:e.autoSelectRole,deliverTo:t,reportTo:o,toolOverrides:e.toolOverrides});if(!r.ok){let i=(r.candidates??[]).map(l=>({id:l.roleId,name:l.name,fitScore:l.fitScore,missing:l.missing})),a=i.length>0?i:D("active",20,0).filter(l=>l.source!=="system").map(l=>({id:l.id,name:l.name,allowedTools:l.allowedTools??[],capabilitySummary:_(l)}));return s({error:r.reason,code:r.code,missing:r.missing,availableRoles:a})}return s({taskId:r.taskId,roleId:r.roleId,fitScore:r.fitScore,strategyId:r.strategyId,warnings:r.warnings})}),u("dispatch_workflow","Create and execute a multi-role workflow. Use when the user's request decomposes into sequential or parallel steps handled by different roles. Each step is a complete task; roles handle conditions and decisions internally. Use {{stepId.result}} in prompts to reference prior step outputs. Minimum 2 steps.",{steps:n.array(n.object({id:n.string().describe("Unique step identifier"),prompt:n.string().describe("Task prompt for this step"),roleId:n.string().optional().describe("Role ID for this step. Call list_roles first to find roles."),requirements:E.optional().describe("Task requirements for this step (D-012)."),autoSelectRole:n.boolean().optional().describe("Auto-select best role for this step (D-012)."),dependsOn:n.array(n.string()).optional().describe("Step IDs this step depends on"),config:n.object({timeout:n.number().optional(),maxTurns:n.number().optional()}).optional()})).min(2).describe("Workflow steps (min 2)"),name:n.string().optional().describe("Workflow name for tracking"),deliverTo:n.array(S).optional().describe("Where to deliver the aggregated workflow output"),reportTo:n.array(S).optional().describe("Where to send workflow status reports"),continueOnError:n.boolean().optional().describe("Continue remaining steps if one fails (default false)")},async e=>{let t=[];for(let p of e.steps){if(!p.roleId&&!p.autoSelectRole){t.push(`${p.id} (needs roleId or autoSelectRole)`);continue}if(p.roleId){let b=v(p.roleId);(!b||b.status!=="active")&&t.push(`${p.id} (roleId ${p.roleId} invalid/inactive)`)}}if(t.length>0){let p=D("active",20,0).filter(b=>b.source!=="system").map(b=>({id:b.id,name:b.name,capabilitySummary:_(b)}));return s({error:`Steps missing roleId/autoSelectRole or with invalid roleIds: ${t.join("; ")}.`,availableRoles:p})}let o=new Set(e.steps.map(p=>p.id));for(let p of e.steps)if(p.dependsOn)for(let b of p.dependsOn){if(!o.has(b))return s({error:`Step "${p.id}" depends on unknown step "${b}"`});if(b===p.id)return s({error:`Step "${p.id}" cannot depend on itself`})}let r=new Set,i=new Set,a=new Map(e.steps.map(p=>[p.id,p.dependsOn??[]])),l=p=>{if(i.has(p))return!0;if(r.has(p))return!1;r.add(p),i.add(p);for(let b of a.get(p)??[])if(l(b))return!0;return i.delete(p),!1};for(let p of e.steps)if(l(p.id))return s({error:"Circular dependency detected in workflow steps"});let d=e.deliverTo?await k(e.deliverTo):void 0,m=e.reportTo?await k(e.reportTo):void 0,c=w(),f=T(),g={id:`workflow-${c}`,name:e.name??"Ad-hoc workflow",trigger:{type:"manual"},steps:e.steps.map(p=>({id:p.id,prompt:p.prompt,roleId:p.roleId,requirements:p.requirements,autoSelectRole:p.autoSelectRole,dependsOn:p.dependsOn,config:p.config})),enabled:!0,createdAt:Date.now(),config:{...f.defaults,continueOnError:e.continueOnError??!1},deliverTo:d,reportTo:m};ae(g);let{WorkflowExecutor:h}=await import("./workflow-executor-JTUWX5DC.js");new h().execute(g,c).catch(p=>{F.error({executionId:c,error:p},"dispatch_workflow execution failed")});let R=e.steps.map(p=>{let b=p.roleId??(p.autoSelectRole?"[auto-selected]":"[no role]");return(p.roleId?v(p.roleId):void 0)?.name??b});return s({executionId:c,templateId:g.id,stepCount:e.steps.length,roles:[...new Set(R)],status:"started"})}),u("evaluate_result","Evaluate a completed task's result and record a trial for Thompson Sampling.",Dt,async e=>{let{goalId:t,taskId:o,strategyId:r}=e,i=Ee(t??"",o);return r&&t&&x.recordTrial(r,t,o,i.reward,i.breakdown.L2||void 0,i.breakdown.L3||void 0,"Evaluated via adam-tools"),s({reward:i.reward,metricL2Score:i.breakdown.L2||void 0,metricL3Score:i.breakdown.L3||void 0,source:i.source,reasoning:`Evaluated via ${i.source} with confidence ${i.confidence.toFixed(2)}`})}),u("create_strategy","Create a new strategy variant for a role/taskType using LLM evolution.",xt,async e=>{let{roleId:t,taskType:o}=e;await K.generateVariants(t,o,3,1);let r=x.getStrategies(t,o),i=r[r.length-1];return s(i?{id:i.id,name:i.name,promptTemplate:i.promptTemplate}:{error:`Failed to create strategy for ${t}/${o}`})}),u("list_goals","List all goals with progress percentage, budget, deadline, and time remaining. Goal statuses: active (in progress), paused, completed, failed. Use this to check current goal status before making decisions.",At,async e=>{let t=e.status;return s($e(t,e.limit??10,0))}),u("delete_goal","Delete a goal by ID.",{goalId:n.string()},async e=>N(e.goalId)?(Ne(e.goalId),s({success:!0,goalId:e.goalId})):s({error:"Goal not found"})),u("pause_goal","Pause an active goal.",{goalId:n.string()},async e=>N(e.goalId)?(Q(e.goalId,{status:"paused",updatedAt:Date.now()}),s({success:!0,goalId:e.goalId,status:"paused"})):s({error:"Goal not found"})),u("assign_role","Assign a role to a pending task.",Mt,async e=>{let{taskId:t,roleId:o}=e;if(!P(t))return s({error:`Task not found: ${t}`});let i=v(o);return i?(U(t,{roleId:o}),F.debug({taskId:t,roleId:o,roleName:i.name},"Role assigned to task"),s({success:!0,taskId:t,roleId:o})):s({error:`Role not found: ${o}`})}),...We(),u("read_task_status","Read a single task's details (prompt, status, result, roleId) by ID, or list all tasks filtered by status (pending, running, completed, failed). Use this to check task progress and results.",$t,async e=>{if(e.taskId){let o=P(e.taskId);return s(o??{error:"Task not found"})}let t=e.status;return s(M(t,e.limit??100,0))}),u("modify_role_permissions","Update a role's RBAC permissions (paths, tools, OS capabilities).",Nt,async e=>{if(!v(e.roleId))return s({error:`Role not found: ${e.roleId}`});let o={};if(e.allowedTools&&(o.allowedTools=e.allowedTools),e.disallowedTools&&(o.disallowedTools=e.disallowedTools),e.osCapabilities!==void 0)try{o.osCapabilities=ee(e.osCapabilities)}catch(r){return s({error:r instanceof Error?r.message:String(r)})}return e.additionalDirectories!==void 0&&(o.additionalDirectories=e.additionalDirectories),e.allowedChannels!==void 0&&(o.allowedChannels=e.allowedChannels),"inheritUserSettings"in e&&(o.inheritUserSettings=e.inheritUserSettings),$(e.roleId,o),s({success:!0})}),u("update_role","Update a role's identity and config fields (name, CAG prompt, learned rules, status, model, execution mode, preferences, permission mode, bash patterns, evaluation criteria, env vars). For permission fields (allowedTools, disallowedTools, osCapabilities, additionalDirectories, allowedChannels, inheritUserSettings) use modify_role_permissions instead.",Ut,async e=>{if(!v(e.roleId))return s({error:`Role not found: ${e.roleId}`});let{roleId:o,...r}=e,i={...r,updatedAt:Date.now()};$(o,i);let a=v(o);if(!a)return s({error:"Role disappeared after update"});if(e.cagPrompt!==void 0||e.learnedRules!==void 0){let l=ne(a.name);ot(l)&&ve(l,a)}return s({success:!0,role:a})}),u("view_audit_log","View the evolution audit log for role changes.",Et,async e=>{let{listEvolutionAudit:t}=await import("./evolution-audit-LZSQPDHH.js"),o=t(e.limit??50);return s({entries:o})}),u("list_roles","List all roles with their capabilities including bound plugins (skills/agents). Use this to discover available roles before dispatching tasks. Pass requirements to get ranked results with fitScore showing which roles best match the task.",Gt,async e=>{if(e.requirements){let r=e.requirements,a=xe(r).slice(0,e.limit??50).map(l=>{let d=l.role,m=Y(d),c=m.plugins.map(y=>y.name),f=ne(d.name),g=Ce(d,f),h=r.tools?(d.allowedTools??[]).filter(y=>r.tools.includes(y)):void 0,I=r.paths?r.paths.filter(y=>Pe(y,g)):void 0,R=new Set((d.osCapabilities??[]).map(y=>y.id)),p=r.osCapabilities?r.osCapabilities.filter(y=>R.has(y.id)).map(y=>y.id):void 0,b=new Set(c),me=r.plugins?r.plugins.filter(y=>b.has(y)):void 0,st=r.network===!0?(d.osCapabilities??[]).some(y=>y.id==="local-network"):void 0,at=l.missing?.osCapabilities,lt=De(d,r);return{id:d.id,name:d.name,status:d.status,allowedTools:d.allowedTools??[],disallowedTools:d.disallowedTools??[],osCapabilities:d.osCapabilities??[],additionalDirectories:d.additionalDirectories??[],cagPrompt:d.cagPrompt.slice(0,500)+(d.cagPrompt.length>500?"...":""),capabilitySummary:_(d,m),plugins:m.plugins.map(y=>({name:y.name,skills:y.skills.map(X=>X.name),agents:y.agents.map(X=>X.name)})),fitScore:l.fitScore,fits:l.evaluation.ok,matchedTools:h,matchedPaths:I,matchedOsCapabilities:p,matchedPlugins:me,matchedNetwork:st,missingCapabilities:l.missing?{tools:l.missing.tools,paths:l.missing.paths,osCapabilities:at?.map(y=>y.id),plugins:l.missing.plugins,network:l.missing.network}:void 0,warnings:lt,why:l.evaluation.ok?`Role '${d.name}' satisfies all requirements (fitScore: ${l.fitScore.toFixed(2)})`:`Role '${d.name}' does not satisfy requirements: ${l.evaluation.ok?"unknown":l.evaluation.reason}`}});return s({roles:a})}let o=D(e.status,e.limit??50,0).map(r=>{let i=Y(r);return{id:r.id,name:r.name,status:r.status,allowedTools:r.allowedTools??[],disallowedTools:r.disallowedTools??[],osCapabilities:r.osCapabilities??[],additionalDirectories:r.additionalDirectories??[],cagPrompt:r.cagPrompt.slice(0,500)+(r.cagPrompt.length>500?"...":""),capabilitySummary:_(r,i),plugins:i.plugins.map(a=>({name:a.name,skills:a.skills.map(l=>l.name),agents:a.agents.map(l=>l.name)}))}});return s({roles:o})}),u("create_role","Create a new role with a name, CAG prompt, and optional tool permissions or OS capabilities.",Lt,async e=>{let t;try{t=ee(e.osCapabilities)}catch(i){return s({error:i instanceof Error?i.message:String(i)})}let o=`role-${w().slice(0,8)}`,r={id:o,name:e.name,cagPrompt:e.cagPrompt,learnedRules:[],memoryStreamId:`mem-${w().slice(0,8)}`,status:"active",preferences:{},createdAt:Date.now(),allowedTools:e.allowedTools,disallowedTools:e.disallowedTools,osCapabilities:t,additionalDirectories:e.additionalDirectories};return ye(r),B(r),s({roleId:o,name:e.name,allowedTools:e.allowedTools,osCapabilities:r.osCapabilities,additionalDirectories:e.additionalDirectories??[]})}),u("retire_role","Retire a role (marks as retired, stops receiving tasks).",Ot,async e=>v(e.roleId)?($(e.roleId,{status:"retired"}),F.info({roleId:e.roleId,reason:e.reason},"Role retired"),s({success:!0})):s({error:`Role not found: ${e.roleId}`})),u("create_goal","Create a new goal with optional budget, deadline, and metric tracking.",qt,async e=>{let t=w(),o=Date.now(),r=o+10080*60*1e3,i={id:t,name:e.name,description:e.description,roleId:e.roleId??"engineer",metricType:e.metric??"completion",targetValue:e.targetValue??1,currentValue:0,deadline:e.deadline??r,budgetUsd:e.budgetUsd??5,status:"active",createdAt:o,deliverTo:e.deliverTo?await k(e.deliverTo):void 0};H(i),He(t,i.metricType);let a=N(t);return s({goalId:a.id,name:a.name,status:a.status})}),u("create_template","Create a recurring scheduled task using cron expressions (e.g., 'every hour', 'daily at 9am', 'weekly'). For one-shot delayed tasks ('in 30 minutes', 'tomorrow at 3pm'), use schedule_task instead.",jt,async e=>{let{createTaskTemplate:t}=await import("./task-templates-23YOAF3E.js"),o=w(),r=w(),i=e.deliverTo?await k(e.deliverTo):void 0,a=e.reportTo?await k(e.reportTo):void 0,l={id:o,name:e.name,description:e.description,trigger:{type:e.triggerType,cron:e.triggerCron,event:e.triggerEvent},steps:[{id:r,prompt:e.prompt}],rolePreference:e.roleId,enabled:e.enabled??!0,createdAt:Date.now(),goalIds:e.goalIds,deliverTo:i,reportTo:a};return t(l),s({templateId:o,name:l.name,trigger:l.trigger})}),u("list_templates","List task templates (automations). Use this to check existing scheduled/recurring tasks before creating new ones.",{enabled:n.boolean().optional().describe("Filter by enabled status. Omit to list all."),limit:n.number().optional().describe("Max results (default 50)")},async e=>{let{listTaskTemplates:t}=await import("./task-templates-23YOAF3E.js"),o=t(e.enabled,e.limit??50,0);return s(o.map(r=>({id:r.id,name:r.name,description:r.description,trigger:r.trigger,enabled:r.enabled,rolePreference:r.rolePreference,deliverTo:r.deliverTo,createdAt:r.createdAt})))}),u("send_to_channel","Send a message (text, image, voice, video, file) to a connected channel by name. Use this to deliver task results, media, or notifications to a specific channel (e.g., WeChat on iPad). For media: provide mediaUrl as an absolute local file path and mediaType. Do NOT use remote URLs \u2014 download files locally first.",{channelName:n.string().describe("The channel name, e.g., 'WeChat on iPad'"),message:n.string().describe("The message content to send (text caption when sending media)"),mediaUrl:n.string().optional().describe("Absolute local file path to the media file (e.g. /Users/.../file.png). Must exist on disk. Do NOT use remote URLs \u2014 download files locally first."),mediaType:n.enum(["image","audio","video","file"]).optional().describe("Type of the media file. Required when mediaUrl is provided")},async e=>{if(e.mediaUrl){if(e.mediaUrl.includes("://")&&!e.mediaUrl.startsWith("file://"))return s({error:`mediaUrl must be a local file path, not a remote URL. Got: ${e.mediaUrl.slice(0,80)}. Download the file to a local path first, then pass the local path.`});let l=e.mediaUrl.startsWith("file://")?new URL(e.mediaUrl).pathname:e.mediaUrl;if(!ot(l))return s({error:`Media file not found: ${l}. Verify the file exists before sending.`});if(!e.mediaType)return s({error:"mediaType is required when mediaUrl is provided. Specify one of: image, audio, video, file."})}let t=await k([{type:"channel",channelName:e.channelName}]);if(t.length===0)return s({error:`Channel "${e.channelName}" not found or no chatId available`});let o=t[0];if(o.type!=="channel")return s({error:"Resolved target is not a channel"});let{getOutboundGateway:r}=await import("./outbound-gateway-6K6P2BEH.js"),a=await r().send({channelId:o.channelId,chatId:o.chatId,content:e.message,messageType:"deliver",mediaUrl:e.mediaUrl,mediaType:e.mediaType});return s({success:a.success,channelName:e.channelName,...a.error?{error:a.error}:{}})}),u("list_channels","List all connected channels with their platform, status, and chatId for message delivery. Use this to discover available channels before sending messages or setting up notifications.",Vt,async e=>{let t=le(e.enabled),o=[...de("active"),...de("archived")],r=t.map(i=>{let a,l=o.find(d=>d.source.type==="channel"&&d.source.channelId===i.id&&d.source.chatId);return l?.source.chatId?a=l.source.chatId:a=i.config?.userId,{id:i.id,name:i.name,platform:i.platform,status:i.status,chatId:a}});return s({channels:r})}),u("get_system_status","Get current system status: execution pool capacity (active/max/queued slots), running task count, and system health. Use this to check if the system has capacity before dispatching tasks.",Ft,async()=>{let e=T(),t=M("running"),o=M("pending");return s({executionPool:{active:t.length,max:e.execution?.maxConcurrent??5,queued:o.length},timestamp:new Date().toISOString()})}),u("schedule_task","Schedule a one-shot delayed task. roleId is required \u2014 call list_roles first. Use this when the user wants something done later (e.g., '\u534A\u5C0F\u65F6\u540E', 'in 30 minutes', 'tomorrow at 3pm'). For recurring schedules ('every day', 'weekly'), use create_template instead.",Bt,async e=>{let t=v(e.roleId);if(!t||t.status!=="active"){let g=D("active",20,0).filter(h=>h.source!=="system").map(h=>({id:h.id,name:h.name,allowedTools:h.allowedTools??[],capabilitySummary:_(h)}));return s({error:`Role not found or not active: ${e.roleId}. Pick a roleId from the list below.`,availableRoles:g})}let o=Date.now(),r;if(e.delayMinutes!==void 0&&e.runAt!==void 0)return s({error:"Provide exactly one of delayMinutes or runAt, not both"});if(e.delayMinutes!==void 0)r=o+e.delayMinutes*60*1e3;else if(e.runAt!==void 0){if(r=new Date(e.runAt).getTime(),isNaN(r))return s({error:"Invalid ISO 8601 timestamp in runAt"})}else return s({error:"Provide either delayMinutes or runAt"});if(r<=o)return s({error:"Scheduled time must be in the future"});let i=10080*60*1e3;if(r-o>i)return s({error:"Schedule exceeds maximum of 7 days"});let a=w(),l=new Date(r).toISOString(),d=e.deliverTo?await k(e.deliverTo):void 0,m=e.reportTo?await k(e.reportTo):void 0;ae({id:a,name:e.prompt.slice(0,80),description:`One-shot scheduled task: ${e.prompt.slice(0,200)}`,trigger:{type:"once",runAt:l},steps:[{id:"main",prompt:e.prompt}],rolePreference:e.roleId,config:{...T().defaults},tags:["scheduled","once"],enabled:!0,createdAt:o,deliverTo:d,reportTo:m});let{getBreeEngine:c}=await import("./bree-engine-R5YLSDCL.js"),f=c();return f&&f.scheduleOnceJob(a),s({templateId:a,executeAt:l,prompt:e.prompt})}),u("cancel_scheduled_task","Cancel a previously scheduled one-shot task by its template ID. The task will not execute.",{templateId:n.string().describe("The template ID returned by schedule_task")},async e=>{let t=O(e.templateId);if(!t)return s({error:`Template not found: ${e.templateId}`});if(t.trigger.type!=="once")return s({error:"This is not a one-shot scheduled task. Use disable_template for recurring automations."});Ve(e.templateId);let{getBreeEngine:o}=await import("./bree-engine-R5YLSDCL.js"),r=o();return r&&await r.unscheduleJob(e.templateId),s({cancelled:!0,templateId:e.templateId})}),u("list_available_plugins","List all installed plugins with their scope and global enabled state. If roleId is provided, shows which plugins are installed in that role's workspace.",Jt,async e=>{let t=we(),o=z(),r=e.roleId?(()=>{let{getRoleWorkspacePath:i}=(J(),C(re)),{getRole:a}=(W(),C(te)),{listInstalledPlugins:l}=(_e(),C(ct)),d=a(e.roleId);if(!d)return[];let m=i(d.name);return l({scope:"project",projectPath:m}).map(c=>c.id)})():[];return s({plugins:o.map(i=>({id:i.id,name:i.name,scope:i.scope,projectPath:i.projectPath,enabled:i.enabled,globalEnabled:t[i.id]??i.enabled,isInstalledInRole:r.includes(i.id),description:i.version?`v${i.version}`:void 0}))})}),u("install_plugin_for_role","Install a plugin into a role's workspace (project-scope). The plugin will be available when that role executes tasks.",zt,async e=>{let{getRole:t}=(W(),C(te)),{getRoleWorkspacePath:o}=(J(),C(re)),r=t(e.roleId);if(!r)return s({error:`Role not found: ${e.roleId}`});let i=o(r.name);try{return ue(e.pluginId,"project",i),s({success:!0,roleId:e.roleId,pluginId:e.pluginId,scope:"project",cwd:i})}catch(a){return s({error:`Failed to install plugin: ${a}`})}}),u("uninstall_plugin_from_role","Uninstall a plugin from a role's workspace.",Yt,async e=>{let{getRole:t}=(W(),C(te)),{getRoleWorkspacePath:o}=(J(),C(re)),r=t(e.roleId);if(!r)return s({error:`Role not found: ${e.roleId}`});let i=o(r.name);try{return pe(e.pluginId,"project",i),s({success:!0,roleId:e.roleId,pluginId:e.pluginId})}catch(a){return s({error:`Failed to uninstall plugin: ${a}`})}}),u("bind_mcp_to_role","Bind an MCP server configuration to a role. The MCP server will be available to the role during task execution.",Ht,async e=>{let t=v(e.roleId);if(!t)return s({error:`Role not found: ${e.roleId}`});let r={...t.mcpServers??{},[e.mcpName]:e.mcpConfig};try{return $(e.roleId,{mcpServers:r}),B(t),s({success:!0,roleId:e.roleId,mcpName:e.mcpName,mcpServers:r})}catch(i){return s({error:`Failed to bind MCP server: ${i}`})}}),u("unbind_mcp_from_role","Remove an MCP server binding from a role.",Qt,async e=>{let t=v(e.roleId);if(!t)return s({error:`Role not found: ${e.roleId}`});let o={...t.mcpServers??{}};if(!(e.mcpName in o))return s({error:`MCP server "${e.mcpName}" not bound to this role`});delete o[e.mcpName];try{return $(e.roleId,{mcpServers:o}),B(t),s({success:!0,roleId:e.roleId,mcpName:e.mcpName})}catch(r){return s({error:`Failed to unbind MCP server: ${r}`})}}),u("get_capabilities","Get a comprehensive overview of Adam's current capabilities: available roles and their tools, OS capability registry, connected channels, installed plugins, active automations, and execution capacity. Call this when the user asks what you can do, or asks for help.",Wt,async()=>{let{listTaskTemplates:e}=await import("./task-templates-23YOAF3E.js"),t=T(),o=D(void 0,100,0),r=le(),i=e(!0,100,0),a=M("running"),l=M("pending"),d=ze(),m=await Ye();return s({roles:{description:"Specialized worker identities \u2014 each has its own tools, MCP servers, plugins (skills/agents), and learned rules",active:o.filter(c=>c.status==="active"&&c.source!=="system").map(c=>{let f=Y(c);return{name:c.name,tools:c.allowedTools??[],osCapabilities:c.osCapabilities??[],mcpServers:Object.keys(c.mcpServers??{}),channels:c.allowedChannels??[],capabilitySummary:_(c,f),plugins:f.plugins.map(g=>({name:g.name,skills:g.skills.map(h=>h.name),agents:g.agents.map(h=>h.name)}))}}),retired:o.filter(c=>c.status==="retired").length,probation:o.filter(c=>c.status==="probation").length},osCapabilities:{description:"Role-level OS capability registry. Only editable entries can be assigned to roles on this runtime.",sandbox:{platform:d.platform,available:m},registry:be(d.platform,m)},channels:{description:"Send/receive messages via connected platforms",connected:r.filter(c=>c.enabled).map(c=>({name:c.name,platform:c.platform,status:c.status}))},plugins:{description:"Extensions that add capabilities to roles",installed:z().filter(c=>c.enabled).map(c=>({name:c.name,scope:c.scope,description:c.version?`v${c.version}`:void 0}))},automations:{description:"Recurring cron tasks and event-triggered templates",active:i.map(c=>({name:c.name,trigger:c.trigger}))},execution:{description:"Parallel task execution pool",maxConcurrent:t.execution?.maxConcurrent??5,running:a.length,queued:l.length},coreFeatures:["Goal management \u2014 SMART goals with budget/deadline/metric, auto-decomposition into subtasks","Memory \u2014 per-Role vector + keyword searchable memory across tasks","Strategy evolution \u2014 Thompson Sampling optimizes task approaches over time","Monitor \u2014 automatic quality scoring, role retirement/reinstatement","Delivery engine \u2014 event-driven result routing to channels/webhooks","Schedule \u2014 cron recurring templates + one-shot delayed tasks"]})}),u("enable_plugin","Enable a globally installed plugin (makes it available to all roles).",Kt,async e=>{try{return tt(e.pluginId),s({success:!0,pluginId:e.pluginId})}catch(t){return s({error:`Failed to enable plugin: ${t}`})}}),u("disable_plugin","Disable a globally installed plugin (removes it from all roles).",Xt,async e=>{try{return nt(e.pluginId),s({success:!0,pluginId:e.pluginId})}catch(t){return s({error:`Failed to disable plugin: ${t}`})}}),u("install_plugin_for_user","Install a plugin globally for the current user (user-scope).",Zt,async e=>{try{return ue(e.pluginId,"user"),s({success:!0,pluginId:e.pluginId,scope:"user"})}catch(t){return s({error:`Failed to install plugin: ${t}`})}}),u("uninstall_plugin_for_user","Uninstall a globally installed plugin from the current user.",en,async e=>{try{return pe(e.pluginId,"user"),s({success:!0,pluginId:e.pluginId})}catch(t){return s({error:`Failed to uninstall plugin: ${t}`})}}),u("browse_marketplace","Browse all available plugins from configured marketplaces (shows installed and available).",tn,async()=>{try{let e=et(),t=z();return s({available:e,installed:t})}catch(e){return s({error:`Failed to browse marketplace: ${e}`})}}),u("list_marketplace_sources","List configured plugin marketplace sources.",nn,async()=>{let e=Se();return s({sources:e})}),u("get_plugin_detail","Get detailed manifest for an installed plugin (skills, agents, MCP servers, hooks).",rn,async e=>{let t=Te(e.pluginId);if(!t)return s({error:`Plugin not found: ${e.pluginId}`});let o=ke(t.installPath);return s({id:t.id,name:t.name,version:t.version,scope:t.scope,projectPath:t.projectPath,enabled:t.enabled,manifest:o})}),u("scan_directory","Scan a directory for .claude/settings.json and return its plugin/MCP configuration.",on,async e=>{let{getRole:t}=await import("./roles-L34L5MK3.js");if(!t(e.roleId))return s({error:`Role not found: ${e.roleId}`});try{let r=Re(e.path);return s({roleId:e.roleId,path:e.path,config:r})}catch(r){return s({error:`Failed to scan directory: ${r}`})}}),u("cancel_task","Cancel a running or pending task by setting its status to 'cancelled'. Emits a task_status_change event.",sn,async e=>{let t=P(e.taskId);if(!t)return s({error:`Task not found: ${e.taskId}`});let o=t.status;U(e.taskId,{status:"cancelled"});let{serverBus:r}=await import("./server-bus-GEGVMSCA.js");return r.emit({type:"task_status_change",taskId:e.taskId,oldStatus:o,newStatus:"cancelled"}),s({success:!0,taskId:e.taskId,status:"cancelled"})}),u("view_task_logs","Retrieve step-by-step execution logs for a task.",an,async e=>{let t=he(e.taskId,e.limit??20);return s({taskId:e.taskId,count:t.length,logs:t})}),u("delete_role","Delete a role by ID. This removes the role and its workspace.",ln,async e=>v(e.roleId)?(Ie(e.roleId),s({success:!0,roleId:e.roleId})):s({error:`Role not found: ${e.roleId}`})),u("view_config","Get the current runtime configuration (mutable fields and restart-required fields).",dn,async()=>{let{MUTABLE_PATHS:e,RESTART_REQUIRED_PATHS:t}=await import("./runtime-VDBZZ4KG.js"),o=T(),r={};try{let d=T().server?.port??7100,m=await fetch(`http://127.0.0.1:${d}/config`);m.ok&&(r=await m.json())}catch{}let i=[...e,...t],a=[...t],l={};for(let d of i){let m=d.split("."),c=o;for(let f of m)if(c&&typeof c=="object")c=c[f];else{c=void 0;break}l[d]={value:c,mutable:!t.includes(d)}}return s({config:l,mutable:[...e],restartRequired:[...t]})}),u("update_config","Update mutable runtime configuration fields. Returns partial-success: some fields may update while others return errors.",cn,async e=>{let{isRestartRequiredPath:t}=await import("./runtime-VDBZZ4KG.js"),{setConfigValue:o}=await import("./config-EMNKHR3W.js"),r=ge(e.updates,o);if(e.updates["logging.level"]&&fe(e.updates["logging.level"]),r.updated.length>0){let{serverBus:i}=await import("./server-bus-GEGVMSCA.js");i.emit({type:"config_changed",changes:r.updated.map(a=>({path:a,value:e.updates[a]}))})}return s(r)}),u("list_memories","List memories stored under a specific role.",un,async e=>{let t=je(e.roleId,e.limit??20);return s({roleId:e.roleId,count:t.length,memories:t})}),u("update_template","Update a task template's fields (name, prompt, cron, enabled, etc.).",pn,async e=>{let t=O(e.templateId);if(!t)return s({error:`Template not found: ${e.templateId}`});let o={};if(e.name!==void 0&&(o.name=e.name),e.enabled!==void 0&&(o.enabled=e.enabled),e.prompt!==void 0){let r=t.steps?.length?[...t.steps]:[];r.length===0?r.push({id:w(),prompt:e.prompt}):r[0]={...r[0],prompt:e.prompt},o.steps=r}return(e.triggerCron!==void 0||e.triggerEvent!==void 0)&&(o.trigger={type:e.triggerEvent?"event":"cron",cron:e.triggerCron,event:e.triggerEvent}),e.roleId!==void 0&&(o.rolePreference=e.roleId),Ge(e.templateId,o),s({success:!0,templateId:e.templateId,updated:Object.keys(o)})}),u("delete_template","Delete a task template by ID.",mn,async e=>O(e.templateId)?(Fe(e.templateId),s({success:!0,templateId:e.templateId})):s({error:`Template not found: ${e.templateId}`})),u("run_template","Trigger a template immediately (runs the webhook endpoint for its name).",gn,async e=>{let t=O(e.templateId);if(!t)return s({error:`Template not found: ${e.templateId}`});try{let o=T().server?.port??7100,r=await fetch(`http://127.0.0.1:${o}/webhooks/${t.name}`,{method:"POST"}),i=await r.json();return r.ok?s({success:!0,templateId:e.templateId,templateName:t.name,response:i}):s({error:`Webhook failed: ${i.code??r.status} \u2014 ${i.message??""}`})}catch(o){return s({error:`Failed to trigger template: ${o}`})}}),u("list_delivery_rules","List delivery rules, optionally filtered by enabled status.",fn,async e=>{let t=ce(e.enabled);return s({count:t.length,rules:t})}),u("create_delivery_rule","Create a new delivery rule for event-driven result routing.",hn,async e=>{let t=w(),o={id:t,eventType:e.eventType,matchCriteria:e.matchCriteria??{},target:{type:"channel",channelId:e.channelId},formatTemplate:e.format,maxPerMinute:10,skipOriginChannel:!1,enabled:e.enabled??!0,createdAt:Date.now()};return Be(o),s({success:!0,ruleId:t,rule:o})}),u("delete_delivery_rule","Delete a delivery rule by ID.",bn,async e=>ce().find(r=>r.id===e.ruleId)?(Je(e.ruleId),s({success:!0,ruleId:e.ruleId})):s({error:`Delivery rule not found: ${e.ruleId}`})),u("list_strategies","List Thompson Sampling strategy populations for a role, or all strategies if roleId omitted.",yn,async e=>{let t;if(e.roleId)t=Me(e.roleId);else{let{getDb:o}=await import("./db-YUYXVV3A.js");t=o().prepare("SELECT * FROM strategies ORDER BY created_at").all().map(i=>({id:i.id,roleId:i.role_id,name:i.name,taskType:i.task_type,createdAt:i.created_at,updatedAt:i.updated_at??void 0,promptTemplate:i.prompt_template??"",alpha:i.alpha,beta:i.beta,totalTrials:i.trials,avgReward:i.total_reward&&i.trials>0?i.total_reward/i.trials:void 0,enabled:i.enabled===1}))}return s({roleId:e.roleId??null,count:t.length,strategies:t})}),u("authorize_task_operation","Authorize a pending privilege escalation for a task. The paused operation will proceed.",{taskId:n.string(),operationId:n.string().optional().describe("ID of the specific operation. If omitted, authorizes the most recent pending operation."),scope:n.enum(["once","permanent"]).default("once").describe("'once' = this operation only. 'permanent' = auto-authorize matching patterns in the future.")},async e=>{let t=se(e.taskId),o=e.operationId?t.find(i=>i.id===e.operationId):t.find(i=>i.status==="pending");return o?(new V().resolvePlanApproval(o.id,"allow",e.scope),s({success:!0,operationId:o.id,decision:"allow",scope:e.scope})):s({error:"No pending operation found for this task"})}),u("deny_task_operation","Deny a pending privilege escalation for a task. The paused operation will be rejected.",{taskId:n.string(),operationId:n.string().optional(),reason:n.string().optional().describe("Reason for denial, provided to the executor as feedback.")},async e=>{let t=se(e.taskId),o=e.operationId?t.find(i=>i.id===e.operationId):t.find(i=>i.status==="pending");return o?(new V().resolvePlanApproval(o.id,"deny","once",e.reason),s({success:!0,operationId:o.id,decision:"deny"})):s({error:"No pending operation found for this task"})})];function br(){return it.map(e=>e.name).sort().join(",")}function yr(){return Tt({name:"adam-tools",version:"1.0.0",tools:it})}export{V as a,Sn as b,Rn as c,He as d,et as e,ue as f,pe as g,tt as h,nt as i,$n as j,br as k,yr as l};
@@ -1,4 +1,4 @@
1
- import{b as o,d as u}from"./chunk-4VHBKJD5.js";u();import{v4 as a}from"uuid";function R(t){o().prepare(`
1
+ import{b as o,d as u}from"./chunk-JAS3TUZX.js";u();import{v4 as a}from"uuid";function R(t){o().prepare(`
2
2
  INSERT INTO evolution_audit (id, timestamp, old_rules, new_rules, diff, trigger_task_id, role_id, source)
3
3
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)
4
4
  `).run(a(),t.timestamp,t.oldRules,t.newRules,t.diff,t.triggerTaskId??null,t.roleId??null,t.source??"reflection")}function f(t=100,e=0){return o().prepare(`
@@ -0,0 +1,12 @@
1
+ import{a as B}from"./chunk-R4GIIQ7G.js";import{a as C}from"./chunk-2CMR5AG7.js";import{a as L,b as k,c as T,j as $}from"./chunk-C6BOQJJF.js";import{d as I,h as P,i as de}from"./chunk-GBTG5B5R.js";import{b as _,d as se}from"./chunk-JAS3TUZX.js";import{c as D,h as ie}from"./chunk-INNDBLZE.js";import{tool as p}from"@anthropic-ai/claude-agent-sdk";import{z as a}from"zod";import{v4 as le}from"uuid";function l(t){return{content:[{type:"text",text:JSON.stringify(t)}]}}var ce={query:a.string().describe("Search query for memory retrieval"),roleId:a.string().optional().describe("Role ID to scope search (omit for cross-role)"),topK:a.number().optional().describe("Max results to return (default 5)")},pe={query:a.string().describe("Search query for memory retrieval"),topK:a.number().optional().describe("Max results to return (default 5)")},me={id:a.string().optional().describe("Memory ID to update. Omit to create new."),roleId:a.string().describe("Role ID to save memory under"),content:a.string().describe("Memory content text"),type:a.enum(["event","thought","reflection"]).optional().describe("Memory type (default: thought)"),keywords:a.array(a.string()).optional().describe("Keywords for BM25 search"),importance:a.number().min(1).max(5).optional().describe("Importance 1-5 (default: 3)"),tier:a.enum(["working","episodic","semantic"]).optional().describe("Memory tier (default: episodic)")},ue={id:a.string().optional().describe("Memory ID to update. Omit to create new."),content:a.string().describe("Memory content text"),type:a.enum(["event","thought","reflection"]).optional().describe("Memory type (default: thought)"),keywords:a.array(a.string()).optional().describe("Keywords for BM25 search"),importance:a.number().min(1).max(5).optional().describe("Importance 1-5 (default: 3)"),tier:a.enum(["working","episodic","semantic"]).optional().describe("Memory tier (default: episodic)")},N={id:a.string().describe("Memory ID to delete")};async function j(t,e){let r=t??e.roleId,n=e.topK??5,i=await B(r,e.query,{topK:n});return l({results:i.map(o=>({id:o.id,type:o.type,content:o.content,keywords:o.keywords,importance:o.importance,score:o.score}))})}async function F(t,e){let r=t??e.roleId;if(!r)return l({error:"roleId is required"});let n,i=!0;try{n=await C(e.content)}catch{i=!1}if(e.id){if(!k(e.id))return l({error:`Memory ${e.id} not found`});let v=T(e.id,{content:e.content,embedding:n,keywords:e.keywords,importance:e.importance,type:e.type});return l({id:e.id,action:"updated",success:v,embeddingUpdated:i})}let o=`mem-${le().slice(0,8)}`,s=Date.now();return L({id:o,roleId:r,type:e.type??"thought",content:e.content,embedding:n,keywords:e.keywords??[],importance:e.importance??3,sourceType:"manual",createdAt:s,lastAccessed:s,retrievedCount:0,tier:e.tier??"episodic"}),l({id:o,action:"created",success:!0,embeddingUpdated:i})}async function K(t,e){if(t){let r=k(e.id);if(!r)return l({error:`Memory ${e.id} not found`});if(r.roleId!==t)return l({error:`Memory ${e.id} does not belong to this role`})}return $(e.id),l({id:e.id,deleted:!0})}function Ue(t){return t?[p("search_memories","Search agent memory using hybrid vector + keyword search. Returns scored memories ranked by relevance, recency, and importance.",pe,async e=>j(t,e)),p("save_memory","Create a new memory or update an existing one. Provide 'id' to update, omit to create. Embedding is auto-generated from content.",ue,async e=>F(t,e)),p("delete_memory","Delete a memory by ID.",N,async e=>K(t,e))]:[p("search_memories","Search agent memory using hybrid vector + keyword search. Returns scored memories ranked by relevance, recency, and importance.",ce,async e=>j(void 0,e)),p("save_memory","Create a new memory or update an existing one. Provide 'id' to update, omit to create. Embedding is auto-generated from content.",me,async e=>F(void 0,e)),p("delete_memory","Delete a memory by ID.",N,async e=>K(void 0,e))]}import{accessSync as q,constants as H}from"fs";import{accessSync as fe,constants as ye,existsSync as U,realpathSync as be}from"fs";import{join as E}from"path";import{spawn as he}from"child_process";import{execFileSync as ge}from"child_process";var u=null;function f(){if(u)return u;let t=typeof import.meta.dirname=="string"?import.meta.dirname:__dirname??".",e=E(t,"landlock-exec","landlock-exec");if(U(e))return u=e,e;let r=process.env.PATH?.split(":").find(n=>U(E(n,"landlock-exec")));return r?(u=E(r,"landlock-exec"),u):e}var y=class{platform="landlock";async isAvailable(){if(process.platform!=="linux")return!1;try{fe(f(),ye.X_OK)}catch{return!1}try{return ge(f(),["--check"],{timeout:5e3,stdio:["ignore","pipe","pipe"]}),!0}catch{return!1}}spawn(e){let r=e.command??"node",n=e.args??[],i=[];for(let o of e.visiblePaths??[]){let s=o.mode==="rw"?"--rw":"--ro",d;try{d=be(o.path)}catch{d=o.path}i.push(s,d),d!==o.path&&i.push(s,o.path)}return i.push("--",r,...n),he(f(),i,{cwd:e.cwd,env:e.env,stdio:"pipe",signal:e.signal})}};function G(){if(process.platform==="linux")try{return q(f(),H.X_OK),"landlock"}catch{return"none"}if(process.platform==="darwin")try{return q("/usr/bin/sandbox-exec",H.X_OK),"sandbox-exec"}catch{return"none"}return"none"}ie();import{spawn as _e}from"child_process";import{readFileSync as z,writeFileSync as Pe,mkdtempSync as ke,realpathSync as A,rmSync as Ee}from"fs";import{join as c}from"path";import{tmpdir as Ae}from"os";de();var ve=["com.apple.Accessibility","com.apple.CoreGraphics","com.apple.SpeakSelection","com.apple.TimeMachine","com.apple.assistant","com.apple.assistant.backedup","com.apple.assistant.support"],xe=["com.apple.coreservices.appleevents"];function Se(t){if(!I.test(t))throw new Error(`Invalid bundle id for SBPL appleevent destination: ${t}`)}function V(t,e){return P(t)?.find(r=>r.id===e)}function we(t){if(!t)return"";let e=["","; ===== Role OS capability: Automation =====","(allow lsopen)","(allow mach-lookup",...xe.map(n=>` (global-name "${n}")`),")"],r=t.targets??[];for(let n of r)Se(n),e.push(`(allow appleevent-send (appleevent-destination "${n}"))`);return e.join(`
2
+ `)}function Re(t){return t?["","; ===== Role OS capability: Accessibility =====","(allow signal)","(allow mach-priv-host-port)","(allow mach-task-name)",'(allow mach-lookup (local-name "com.apple.axserver"))',"(allow user-preference-read",...ve.map(r=>` (preference-domain "${r}")`),")"].join(`
3
+ `):""}function X(t){let e=P(t);return e?.length?[we(V(e,"automation")),Re(V(e,"accessibility"))].filter(Boolean).join(`
4
+ `):""}var Y=D("sandbox-macos"),J="/usr/bin/sandbox-exec";function Oe(){let t=[c(typeof import.meta.dirname=="string"?import.meta.dirname:".","profiles","role-sandbox.sb"),c(typeof import.meta.dirname=="string"?import.meta.dirname:".","..","src","sandbox","profiles","role-sandbox.sb"),c(process.cwd(),"src","sandbox","profiles","role-sandbox.sb")];for(let e of t)try{return z(e,"utf-8"),e}catch{}return t[t.length-1]}var Me=Oe();function b(t){if(!t.startsWith("/"))throw new Error(`Sandbox path must be absolute: ${t}`);if(t.includes('"')||t.includes(")")||t.includes("(")||t.includes("$"))throw new Error(`Sandbox path contains invalid characters for SBPL: ${t}`)}function De(t){let e=[`
5
+ ; ===== Per-Role writable paths =====`];for(let r of t){if(r.mode!=="rw")continue;let n;try{n=A(r.path)}catch{n=r.path}b(n),e.push(`(allow file-write* (subpath "${n}"))`),n!==r.path&&(b(r.path),e.push(`(allow file-write* (subpath "${r.path}"))`))}return e.join(`
6
+ `)}function Ie(t){if(!t.length)return"";let e=[`
7
+ ; ===== Global read blacklist (deniedReadPaths) =====`];for(let r of t){let n;try{n=A(r)}catch{n=r}try{b(n),e.push(`(deny file-read-data (subpath "${n}"))`),e.push(`(deny file-read-metadata (subpath "${n}"))`),n!==r&&(b(r),e.push(`(deny file-read-data (subpath "${r}"))`),e.push(`(deny file-read-metadata (subpath "${r}"))`))}catch(i){Y.warn({path:r,error:i.message},"Skipping deniedReadPath: invalid for SBPL")}}return e.join(`
8
+ `)}var h=class{platform="sandbox-exec";async isAvailable(){try{let{existsSync:e}=await import("fs");return e(J)}catch{return!1}}spawn(e){let{command:r,args:n,cwd:i,env:o,signal:s,visiblePaths:d,deniedReadPaths:v,osCapabilities:Z}=e,ee=z(Me,"utf-8"),te=De(d),re=Ie(v??[]),ne=X(Z),oe=ee+te+re+ne+`
9
+ `,x=A(ke(c(Ae(),"adam-sandbox-"))),S=c(x,"role.sb");Pe(S,oe,"utf-8");let w=x,R=o?.HOME??process.env.HOME??"/tmp",ae={...o,TMPDIR:w,CLAUDE_CODE_TMPDIR:w,CLAUDE_CONFIG_DIR:c(R,".claude")};Y.debug({command:r,visiblePaths:d.length,profilePath:S},"Spawning sandboxed process");let M=_e(J,["-f",S,"-D",`TMPDIR=${w}`,"-D",`CLAUDE_CONFIG=${c(R,".claude")}`,"-D",`HOME_CACHE=${c(R,"Library","Caches")}`,r,...n],{cwd:i,env:ae,stdio:"pipe",signal:s});return M.on("exit",()=>{try{Ee(x,{recursive:!0,force:!0})}catch{}}),M}};import{spawn as Ce}from"child_process";var m=null,W=null,g=null;function Le(){if(m)return m;let t=W??G();return W=t,t==="sandbox-exec"?m=new h:t==="landlock"?m=new y:m=new O(t),m}async function pt(){return g!==null||(g=await Le().isAvailable()),g}var O=class{platform;constructor(e){this.platform=e}async isAvailable(){return!1}spawn(e){let r=e.command??"node",n=e.args??[];return Ce(r,n,{cwd:e.cwd,env:e.env,stdio:"pipe",signal:e.signal})}};se();function Te(t){return{id:t.id,roleId:t.role_id??void 0,taskPattern:t.task_pattern,maxRiskLevel:t.max_risk_level,createdAt:t.created_at,createdByTaskId:t.created_by_task_id??void 0}}var Q={low:1,medium:2,high:3};function ft(t){_().prepare(`
10
+ INSERT INTO approval_rules (id, role_id, task_pattern, max_risk_level, created_at, created_by_task_id)
11
+ VALUES (?, ?, ?, ?, ?, ?)
12
+ `).run(t.id,t.roleId??null,t.taskPattern,t.maxRiskLevel,t.createdAt,t.createdByTaskId??null)}function yt(t,e,r){let i=_().prepare("SELECT * FROM approval_rules ORDER BY created_at DESC").all();for(let o of i)if(!(o.role_id&&o.role_id!==t)&&!(Q[r]>Q[o.max_risk_level]))try{if(new RegExp(o.task_pattern,"i").test(e))return Te(o)}catch{}}export{ft as a,yt as b,Ue as c,Le as d,pt as e};
@@ -0,0 +1,47 @@
1
+ import{a as oe}from"./chunk-5V36ACKZ.js";import{k as F}from"./chunk-VRJ7R766.js";import{b as ee}from"./chunk-Y3AMO6WC.js";import{a as Z,b as h}from"./chunk-ISZJV72D.js";import{e as N,f as D,j as Ae}from"./chunk-QWCRZDZS.js";import{a as Q}from"./chunk-UQJZU3R5.js";import{d as K}from"./chunk-GSMC3VUM.js";import{c as te,i as Ce,l as re,o as ne,r as xe}from"./chunk-GBTG5B5R.js";import{b as u,d as v}from"./chunk-JAS3TUZX.js";import{a as z,h as Le}from"./chunk-WBAPIPST.js";import{c as k,h as X}from"./chunk-INNDBLZE.js";Ce();import{homedir as Ie}from"os";import{resolve as j}from"path";import{z as g}from"zod";Le();function ie(){return[...z]}xe();Ae();var Oe=new Set(ie()),Pe=g.object({tools:g.array(g.string().refine(t=>Oe.has(t),{message:"Unknown tool"})).optional(),paths:g.array(g.object({path:g.string().refine(t=>t.startsWith("/")||t.startsWith("~"),{message:"path must be absolute or tilde-prefixed"}),access:g.enum(["ro","rw"])})).optional(),osCapabilities:g.array(g.object({id:g.enum(te),targets:g.array(g.string()).optional()})).optional(),network:g.boolean().optional(),plugins:g.array(g.string()).optional()});function ae(t){return t.startsWith("~")?t.replace(/^~/,Ie()):t}function Ne(t){let e=ae(t);return e.startsWith("/")?j(e):null}function ce(t,e){let n=[{path:j(e),access:"rw"}];for(let r of t.additionalDirectories??[])n.push({path:j(ae(r.path)),access:r.mode??"rw"});return n}function U(t,e){let n=Ne(t.path);if(!n)return!1;let r=e.filter(o=>n===o.path||n.startsWith(`${o.path}/`)).sort((o,s)=>s.path.length-o.path.length);if(r.length===0)return!1;let i=r[0];return t.access==="rw"?i.access==="rw":!0}function B(t,e){if(!t?.length)return[];let n=new Set(e??[]);return t.filter(r=>!n.has(r))}function G(t,e){if(!t?.length)return[];let n=new Set((e??[]).map(r=>r.id));return t.filter(r=>!n.has(r.id))}function W(t,e){if(!t?.length)return[];let n=new Set(e);return t.filter(r=>!n.has(r))}function H(t,e){return t?(e??[]).some(n=>n.id==="local-network"):!0}function le(t,e,n,r){let i=[];if(e.tools?.length){let o=B(e.tools,t.allowedTools).length;i.push((e.tools.length-o)/e.tools.length)}if(e.paths?.length){let o=e.paths.filter(s=>U(s,n)).length;i.push(o/e.paths.length)}if(e.osCapabilities?.length){let o=G(e.osCapabilities,t.osCapabilities).length;i.push((e.osCapabilities.length-o)/e.osCapabilities.length)}if(e.plugins?.length){let o=W(e.plugins,r).length;i.push((e.plugins.length-o)/e.plugins.length)}return e.network===!0&&i.push(H(e.network,t.osCapabilities)?1:0),i.length===0?1:i.reduce((o,s)=>o+s,0)/i.length}function De(t,e){if(!e.tools?.length||!t.approvalRequired?.length)return[];let n=new Set(t.approvalRequired),r=e.tools.filter(o=>n.has(o));if(!r.length)return[];let i=e.paths?.filter(o=>o.access==="rw").length??0;return[{code:"APPROVAL_WILL_TRIGGER",tools:r,expectedPromptCount:Math.max(r.length,i||r.length)}]}function Fe(t,e,n,r){let i=B(e.tools,t.allowedTools),o=(e.paths??[]).filter(d=>!U(d,n)),s=G(e.osCapabilities,t.osCapabilities),c=W(e.plugins,r),a={};return i.length&&(a.tools=i),o.length&&(a.paths=o),s.length&&(a.osCapabilities=s),c.length&&(a.plugins=c),e.network===!0&&!H(e.network,t.osCapabilities)&&(a.network=!0),a}function de(t,e){D(t);let n=N(t.name),r=ce(t,n),o=F(t).plugins.map(l=>l.name),s=B(e.tools,t.allowedTools);if(s.length)return{ok:!1,code:"ROLE_TOOL_MISMATCH",reason:`Missing tools: ${s.join(", ")}`,missing:{tools:s}};let c=(e.paths??[]).filter(l=>!U(l,r));if(c.length)return{ok:!1,code:"ROLE_PATH_SCOPE_MISMATCH",reason:`Missing path scope: ${c.map(l=>`${l.path} (${l.access})`).join(", ")}`,missing:{paths:c}};let a=G(e.osCapabilities,t.osCapabilities);if(a.length)return{ok:!1,code:"ROLE_OS_CAPABILITY_MISMATCH",reason:`Missing OS capabilities: ${a.map(l=>l.id).join(", ")}`,missing:{osCapabilities:a}};let d=W(e.plugins,o);return d.length?{ok:!1,code:"ROLE_PLUGIN_MISMATCH",reason:`Missing plugins: ${d.join(", ")}`,missing:{plugins:d}}:e.network===!0&&!H(e.network,t.osCapabilities)?{ok:!1,code:"ROLE_NETWORK_MISMATCH",reason:"Role lacks network capability (local-network)",missing:{network:!0}}:{ok:!0,roleId:t.id,executionProfile:t,fitScore:le(t,e,r,o),warnings:De(t,e)}}function se(t){return ne("active",100,0).filter(e=>e.source!=="system").map(e=>{D(e);let n=ce(e,N(e.name)),i=F(e).plugins.map(s=>s.name),o=de(e,t);return{role:e,evaluation:o,fitScore:le(e,t,n,i),missing:Fe(e,t,n,i)}}).sort((e,n)=>{let r=n.fitScore-e.fitScore;return r!==0?r:(n.role.performanceScore??0)-(e.role.performanceScore??0)})}async function ue(t){let{requirements:e,roleId:n,autoSelectRole:r}=t;if(!n&&!r)return{ok:!1,code:"REQUIREMENTS_MISSING",reason:"Must provide either roleId or autoSelectRole=true"};if(e){let l=Pe.safeParse(e);if(!l.success)return{ok:!1,code:"REQUIREMENTS_MISSING",reason:g.prettifyError(l.error)}}if(r&&!e)return{ok:!1,code:"REQUIREMENTS_MISSING",reason:"autoSelectRole requires a requirements object"};let i=e??{};if(n&&!r){let l=re(n);if(!l||l.status!=="active")return{ok:!1,code:"ROLE_NOT_FOUND",reason:`Role not found or not active: ${n}`};let p=de(l,i);return p.ok?(p.auditCandidates=[{roleId:l.id,name:l.name,fitScore:p.fitScore,fits:!0}],p):(e&&(p.candidates=se(e).map(S=>({roleId:S.role.id,name:S.role.name,fitScore:S.fitScore,missing:S.missing}))),p)}let o=se(e),s=o.filter(l=>l.evaluation.ok);if(!s.length)return{ok:!1,code:"ROLE_SELECTION_AMBIGUOUS",reason:"No role covers the requirements",candidates:o.map(l=>({roleId:l.role.id,name:l.role.name,fitScore:l.fitScore,missing:l.missing}))};let c=s[0],a=c.evaluation,d=s[1];return d&&d.fitScore===c.fitScore&&(a.tieBreakReason=`fitScore tie at ${c.fitScore}; chose ${c.role.name} by performanceScore`),a.auditCandidates=o.map(l=>({roleId:l.role.id,name:l.role.name,fitScore:l.fitScore,fits:l.evaluation.ok})),a}v();function L(t){return{id:t.id,roleId:t.role_id,taskType:t.task_type,name:t.name,promptTemplate:t.prompt_template,alpha:t.alpha,beta:t.beta,totalTrials:t.total_trials,avgReward:t.avg_reward??void 0,createdAt:t.created_at,updatedAt:t.updated_at??void 0}}function pe(t){u().prepare(`
2
+ INSERT INTO strategies (id, role_id, task_type, name, prompt_template,
3
+ alpha, beta, total_trials, avg_reward, created_at, updated_at)
4
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
5
+ `).run(t.id,t.roleId,t.taskType,t.name,t.promptTemplate,t.alpha,t.beta,t.totalTrials,t.avgReward??null,t.createdAt,t.updatedAt??null)}function ge(t){let n=u().prepare("SELECT * FROM strategies WHERE id = ?").get(t);return n?L(n):void 0}function at(t=100){return u().prepare("SELECT * FROM strategies ORDER BY created_at LIMIT ?").all(t).map(L)}function ct(t){return u().prepare("SELECT * FROM strategies WHERE role_id = ? ORDER BY created_at").all(t).map(L)}function b(t,e){return u().prepare("SELECT * FROM strategies WHERE role_id = ? AND task_type = ? ORDER BY created_at").all(t,e).map(L)}function me(t,e){u().prepare(`
6
+ UPDATE strategies
7
+ SET alpha = alpha + ?,
8
+ beta = beta + ?,
9
+ total_trials = total_trials + 1,
10
+ avg_reward = CASE
11
+ WHEN total_trials = 0 THEN ?
12
+ ELSE (avg_reward * total_trials + ?) / (total_trials + 1)
13
+ END,
14
+ updated_at = ?
15
+ WHERE id = ?
16
+ `).run(e,1-e,e,e,Date.now(),t)}v();function fe(t){return{id:t.id,name:t.name,description:t.description??void 0,roleId:t.role,metricType:t.metric_type,targetValue:t.target_value,currentValue:t.current_value,deadline:t.deadline,budgetUsd:t.budget_usd,status:t.status,createdAt:t.created_at,updatedAt:t.updated_at??void 0,sourceSessionId:t.source_session_id??void 0,deliverTo:t.deliver_to?JSON.parse(t.deliver_to):void 0,reportTo:t.report_to?JSON.parse(t.report_to):void 0}}function ut(t){u().prepare(`
17
+ INSERT INTO goals (id, name, description, role, metric_type, target_value,
18
+ current_value, deadline, budget_usd, status, created_at, updated_at,
19
+ source_session_id, deliver_to, report_to)
20
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
21
+ `).run(t.id,t.name,t.description??null,t.roleId,t.metricType,t.targetValue,t.currentValue,t.deadline,t.budgetUsd,t.status,t.createdAt,t.updatedAt??null,t.sourceSessionId??null,t.deliverTo?JSON.stringify(t.deliverTo):null,t.reportTo?JSON.stringify(t.reportTo):null)}function he(t){let n=u().prepare("SELECT * FROM goals WHERE id = ?").get(t);return n?fe(n):void 0}function pt(t,e){let n=u(),r=[],i=[],o={name:"name",description:"description",roleId:"role",metricType:"metric_type",targetValue:"target_value",currentValue:"current_value",deadline:"deadline",budgetUsd:"budget_usd",status:"status",updatedAt:"updated_at",sourceSessionId:"source_session_id"};for(let[s,c]of Object.entries(o))s in e&&(r.push(`${c} = ?`),i.push(e[s]??null));"deliverTo"in e&&(r.push("deliver_to = ?"),i.push(JSON.stringify(e.deliverTo))),"reportTo"in e&&(r.push("report_to = ?"),i.push(JSON.stringify(e.reportTo))),r.length!==0&&(i.push(t),n.prepare(`UPDATE goals SET ${r.join(", ")} WHERE id = ?`).run(...i))}function gt(t,e=100,n=0){let r=u(),i="SELECT * FROM goals",o=[];return t&&(i+=" WHERE status = ?",o.push(t)),i+=" ORDER BY created_at DESC LIMIT ? OFFSET ?",o.push(e,n),r.prepare(i).all(...o).map(fe)}function mt(t){u().prepare("DELETE FROM goals WHERE id = ?").run(t)}var C=class{static collect(e,n){let r=h(e);if(!r)return this.emptyMetrics(e,n);let i=ee(e,500,0),o=r.completedAt&&r.startedAt?r.completedAt-r.startedAt:0,s=new Set,c=0,a=0;for(let l of i)l.type==="tool_call"&&l.toolName&&s.add(l.toolName),l.type==="error"&&c++,l.type==="approval_request"&&a++;let d={taskId:e,goalId:n,timestamp:Date.now(),durationMs:o,costUsd:r.costUsd??0,turns:r.numTurns??0,toolCount:s.size,errorCount:c,approvalCount:a,rawScore:0,isComplete:r.status==="completed"};return d.rawScore=this.computeRawScore(d),d}static computeRawScore(e){let r=1-Math.min(e.durationMs/6e5,1),o=1-Math.min(e.costUsd/5,1),c=1-Math.min(e.turns/50,1),a;e.toolCount>=3&&e.toolCount<=15?a=1:e.toolCount<3?a=e.toolCount/3:a=Math.max(0,1-(e.toolCount-15)/15);let d=e.errorCount===0?1:Math.max(0,1-e.errorCount*.2),l=Math.min(1,.5+e.approvalCount*.25);return .3*r+.2*o+.2*c+.1*a+.15*d+.05*l}static cache=new Map;static persist(e){this.cache.set(e.taskId,e)}static getCached(e){return this.cache.get(e)}static clearCache(){this.cache.clear()}static emptyMetrics(e,n){return{taskId:e,goalId:n,timestamp:Date.now(),durationMs:0,costUsd:0,turns:0,toolCount:0,errorCount:0,approvalCount:0,rawScore:0,isComplete:!1}}};v();function je(t){return{id:t.id,strategyId:t.strategy_id,goalId:t.goal_id,taskId:t.task_id??void 0,reward:t.reward??void 0,metricL2Score:t.metric_l2_score??void 0,metricL3Score:t.metric_l3_score??void 0,context:t.context??void 0,completedAt:t.completed_at}}function be(t){u().prepare(`
22
+ INSERT INTO trials (id, strategy_id, goal_id, task_id, reward,
23
+ metric_l2_score, metric_l3_score, context, completed_at)
24
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
25
+ `).run(t.id,t.strategyId,t.goalId,t.taskId??null,t.reward??null,t.metricL2Score??null,t.metricL3Score??null,t.context??null,t.completedAt)}function Se(t,e=100){return u().prepare("SELECT * FROM trials WHERE goal_id = ? ORDER BY completed_at DESC LIMIT ?").all(t,e).map(je)}var x=class{static collect(e){let n=he(e);if(!n)return this.emptyMetrics(e);let r=Date.now(),i=n.targetValue>0?Math.min(n.currentValue/n.targetValue,1):0,o=Math.max(0,(n.deadline-r)/(1e3*60*60*24)),s=this.calculateBudgetSpent(e),c=n.budgetUsd>0?Math.max(0,1-s/n.budgetUsd):1,a=this.calculateExpectedCompletion(n),d={goalId:e,metricType:n.metricType,targetValue:n.targetValue,currentValue:n.currentValue,progressPct:i,deadlineRemainingDays:o,budgetRemainingPct:c,expectedCompletionPct:a,rawScore:0};return d.rawScore=this.computeRawScore(d),d}static computeRawScore(e){let n=Math.min(e.progressPct,1),r;e.expectedCompletionPct>=1?r=1:e.expectedCompletionPct>=.8?r=.5+(e.expectedCompletionPct-.8)*2.5:r=e.expectedCompletionPct*.625;let i=e.budgetRemainingPct;return .5*n+.3*r+.2*i}static calculateExpectedCompletion(e){let n=Date.now(),r=e.deadline-e.createdAt,i=n-e.createdAt;if(r<=0)return 0;let o=i/r;if(o<.1)return .5;let s=e.targetValue>0?e.currentValue/e.targetValue:0;return o>0?s/o:0}static calculateBudgetSpent(e){let n=Se(e,1e3),r=0,i=new Set;for(let o of n)if(o.taskId&&!i.has(o.taskId)){i.add(o.taskId);let s=h(o.taskId);s?.costUsd&&(r+=s.costUsd)}return r}static emptyMetrics(e){return{goalId:e,metricType:"",targetValue:0,currentValue:0,progressPct:0,deadlineRemainingDays:0,budgetRemainingPct:0,expectedCompletionPct:0,rawScore:0}}};X();var Ue=k("agent"),y=class{static cache=new Map;static CACHE_TTL=1440*60*1e3;static async callClaude(e){let i=(await oe(e,'You are an AI quality evaluator. Respond with JSON: {"score": 0-1, "confidence": 0-1, "reasoning": "..."}')).match(/\{[\s\S]*\}/);if(!i)throw new Error("Failed to parse LLM Judge response as JSON");let o=JSON.parse(i[0]);return{score:Math.max(0,Math.min(1,o.score??0)),confidence:Math.max(.3,Math.min(.95,o.confidence??.5)),reasoning:o.reasoning??"No reasoning provided"}}static async evaluate(e,n){let r=`${e}:${n}`,i=this.cache.get(r);if(i&&Date.now()-i.evaluatedAt<this.CACHE_TTL)return i;let o=h(e);if(!o){let p={taskId:e,criteria:n,score:0,confidence:.3,reasoning:"Task not found",evaluatedAt:Date.now()};return this.cache.set(r,p),p}let s=this.getPromptTemplate(o.prompt??"",o.result??o.error??"",n),c,a,d;try{let p=await this.callClaude(s);c=p.score,a=p.confidence,d=p.reasoning}catch(p){Ue.warn({error:p,taskId:e},"LLM Judge Claude API call failed, using heuristic fallback"),o.status==="failed"?(c=.1,a=.6,d=`Task failed: ${o.error??"unknown error"} (heuristic fallback)`):o.status==="completed"&&o.result?(c=.7,a=.5,d="Task completed with result (heuristic fallback due to API error)"):o.status==="completed"?(c=.5,a=.4,d="Task completed without explicit result (heuristic fallback)"):(c=.3,a=.3,d=`Task in status: ${o.status} (heuristic fallback)`)}let l={taskId:e,criteria:n,score:c,confidence:a,reasoning:d,evaluatedAt:Date.now()};return this.cache.set(r,l),l}static shouldUseObjective(e){let n=h(e);return n?n.status==="completed"&&n.costUsd!==void 0&&n.numTurns!==void 0:!1}static clearCache(){this.cache.clear()}static getPromptTemplate(e,n,r){return`You are an expert evaluator. Evaluate the following task result against these criteria:
26
+
27
+ Task: ${e}
28
+ Result: ${n}
29
+ Criteria: ${r}
30
+
31
+ Provide:
32
+ 1. Score (0-1): How well did the task meet the criteria?
33
+ 2. Confidence (0-1): How confident are you in this evaluation?
34
+ 3. Reasoning: Brief explanation of your scoring
35
+
36
+ Respond in JSON: {"score": number, "confidence": number, "reasoning": "string"}`}};v();function Be(t){return{id:t.id,goalId:t.goal_id,level:t.level,parentId:t.parent_id??void 0,name:t.name,description:t.description??void 0,weight:t.weight,calibrationFactor:t.calibration_factor,createdAt:t.created_at}}function xt(t){u().prepare(`
37
+ INSERT INTO metric_tree (id, goal_id, level, parent_id, name, description,
38
+ weight, calibration_factor, created_at)
39
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
40
+ `).run(t.id,t.goalId,t.level,t.parentId??null,t.name,t.description??null,t.weight,t.calibrationFactor,t.createdAt)}function Re(t){return u().prepare("SELECT * FROM metric_tree WHERE goal_id = ? ORDER BY level, created_at").all(t).map(Be)}var Ge={L0:.2,L1:.15,L2:.35,L3:.3},A=class t{goalId;nodes;children;constructor(e,n){this.goalId=e,this.nodes=new Map(n.map(r=>[r.id,r])),this.children=new Map;for(let r of n){let i=r.parentId,o=this.children.get(i)??[];o.push(r),this.children.set(i,o)}this.validateAcyclicity()}validateAcyclicity(){for(let e of this.nodes.values()){if(e.parentId&&!this.nodes.has(e.parentId))continue;let n=new Set,r=e.id;for(;r;){if(n.has(r))throw new Error(`Cycle detected in metric tree at node ${r}`);n.add(r),r=this.nodes.get(r)?.parentId}}}static buildFromGoal(e){let n=Re(e);return new t(e,n)}static fromNodes(e,n){return new t(e,n)}queryPath(e){let n=[];for(let r of this.nodes.values())r.level===e&&n.push(r);return n.sort((r,i)=>i.weight-r.weight)}aggregateScores(e,n){let r=this.queryPath(e);if(r.length===0)return 0;let i=0,o=0;for(let s of r){let c=n.get(s.id)??0,a=s.weight*s.calibrationFactor;i+=c*a,o+=a}return o>0?i/o:0}getWeightedScore(e){let n=0;for(let[r,i]of Object.entries(Ge)){let o=this.aggregateScores(r,e);n+=o*i}return Math.max(0,Math.min(1,n))}getNodeCount(){return this.nodes.size}getChildren(e){return this.children.get(e)??[]}};X();var Ut=k("agent");function Te(t,e){let n=Date.now(),r=A.buildFromGoal(t),i=new Map,o=x.collect(t);for(let a of r.queryPath("L0"))i.set(a.id,o.rawScore);let s=We(r);if(e){let a=C.collect(e,t);if(a.isComplete){for(let l of r.queryPath("L3"))i.set(l.id,a.rawScore);let d=r.getNodeCount()>0?r.getWeightedScore(i):Math.max(0,Math.min(1,a.rawScore*.65+o.rawScore*.35));return{goalId:t,taskId:e,reward:d,breakdown:{L0:o.rawScore,L1:0,L2:0,L3:a.rawScore},calibrationFactors:s,source:"objective",confidence:.9,computedAt:n}}}if(e&&!y.shouldUseObjective(e)){let d=y.evaluate(e,"general_quality"),l=o.rawScore*.5+.5*.5;return{goalId:t,taskId:e,reward:o.rawScore,breakdown:{L0:o.rawScore,L1:0,L2:0,L3:0,llmJudge:.5},calibrationFactors:s,source:"llm_judge",confidence:.4,computedAt:n}}let c=r.getNodeCount()>0?r.getWeightedScore(i):o.rawScore;return{goalId:t,reward:c,breakdown:{L0:o.rawScore,L1:0,L2:0,L3:0},calibrationFactors:s,source:"fallback",confidence:.3,computedAt:n}}function We(t){let e={L0:1,L1:1,L2:1,L3:1};for(let n of["L0","L1","L2","L3"]){let r=t.queryPath(n);r.length>0&&(e[n]=r[0].calibrationFactor)}return e}import{v4 as we}from"uuid";var M=class{static sampleBeta(e,n){let r=this.sampleGamma(e,1),i=this.sampleGamma(n,1);return r/(r+i)}static sampleGamma(e,n){if(e<1)return this.sampleGamma(e+1,n)*Math.pow(Math.random(),1/e);let r=e-1/3,i=1/Math.sqrt(9*r);for(;;){let o,s;do o=this.randn(),s=1+i*o;while(s<=0);s=s*s*s;let c=Math.random();if(c<1-.0331*o*o*o*o||Math.log(c)<.5*o*o+r*(1-s+Math.log(s)))return r*s/n}}static randn(){let e=Math.random(),n=Math.random();return Math.sqrt(-2*Math.log(e))*Math.cos(2*Math.PI*n)}static sample(e){if(e.length===0)return null;let n=null,r=-1;for(let i of e){let o=this.sampleBeta(i.alpha,i.beta);o>r&&(r=o,n=i)}return n}static getProbabilities(e,n=1e4){let r=new Map;for(let o=0;o<n;o++){let s=this.sample(e);s&&r.set(s.id,(r.get(s.id)||0)+1)}let i=new Map;for(let[o,s]of r)i.set(o,s/n);return i}};var He=5,$=20,_e=.5,I=class{static selectStrategy(e,n){let r=b(e,n);return M.sample(r)}static recordTrial(e,n,r,i,o,s,c){me(e,i),be({id:we(),strategyId:e,goalId:n,taskId:r,reward:i,metricL2Score:o,metricL3Score:s,context:c,completedAt:Date.now()})}static getStrategies(e,n){return b(e,n)}static getStrategyById(e){return ge(e)}static getPopulationStats(e,n){let r=b(e,n);if(r.length===0)return{count:0,avgTrials:0,avgReward:0,minTrials:0,maxTrials:0};let o=r.reduce((a,d)=>a+d.totalTrials,0)/r.length,s=r.filter(a=>a.avgReward!==void 0).map(a=>a.avgReward),c=s.length>0?s.reduce((a,d)=>a+d,0)/s.length:0;return{count:r.length,avgTrials:o,avgReward:c,minTrials:Math.min(...r.map(a=>a.totalTrials)),maxTrials:Math.max(...r.map(a=>a.totalTrials))}}static shouldEvolve(e,n){let r=this.getPopulationStats(e,n);return r.count<He?!0:r.count<$&&r.maxTrials>0}static addStrategy(e,n,r,i){if(b(e,n).length>=$)throw new Error(`Strategy population at maximum (${$}) for ${e}/${n}`);let s={id:`strat-${we().slice(0,8)}`,roleId:e,taskType:n,name:r,promptTemplate:i,alpha:_e,beta:_e,totalTrials:0,createdAt:Date.now()};return pe(s),s}static getTopStrategies(e,n,r=3){let o=b(e,n).filter(s=>s.totalTrials>0);return o.sort((s,c)=>(c.avgReward??0)-(s.avgReward??0)),o.slice(0,r)}static getSamplingProbabilities(e,n){let r=b(e,n);return M.getProbabilities(r)}static evaluateAndRecord(e,n,r,i,o,s){let c=Te(n,r);return this.recordTrial(e,n,r,c.reward,i,o,s),c.reward}};import{v4 as Je}from"uuid";v();import{v4 as $e}from"uuid";function ve(t){u().prepare(`
41
+ INSERT INTO manager_decisions
42
+ (id, task_id, role_id, decision_type, requirements_json, fit_score, candidates_json, tie_break_reason, created_at)
43
+ VALUES (?, ?, ?, 'admission', ?, ?, ?, ?, ?)
44
+ `).run($e(),t.taskId,t.chosenRoleId,JSON.stringify(t.requirements),t.fitScore,JSON.stringify(t.candidates),t.tieBreakReason??null,Date.now())}function Ve(t){let e=t.toLowerCase(),n={coding:["code","implement","fix","debug","refactor","build"],analysis:["analyze","data","report","statistics","investigate"],content:["write","translate","summarize","content","draft"],review:["review","check","audit","evaluate","assess"],admin:["config","permission","deploy","manage"]};for(let[r,i]of Object.entries(n))if(i.some(o=>e.includes(o)))return r;return"general"}async function or(t){let{prompt:e,roleId:n,requirements:r,autoSelectRole:i,deliverTo:o,reportTo:s,toolOverrides:c,config:a,sourceSessionId:d,parentId:l,templateId:p,stepId:S}=t,O;try{O=K()}catch{O=Q}let w=Je(),ye=Ve(e),f=await ue({taskId:w,requirements:r,roleId:n,autoSelectRole:i});if(!f.ok)return{ok:!1,code:f.code,reason:f.reason,requirements:r,missing:f.missing,candidates:f.candidates};let{executionProfile:R}=f,E=f.roleId,V,q=e,P=I.selectStrategy(E,ye);P?.promptTemplate&&(q=`${P.promptTemplate}
45
+
46
+ ## Task
47
+ ${e}`,V=P.id);let m=O.defaults,T={allowedTools:R.allowedTools??[],disallowedTools:R.disallowedTools??[],approvalRequired:R.approvalRequired??[],maxBudgetUsd:R.maxBudgetUsd??m.maxBudgetUsd,plugins:[]},_={allowedTools:qe(T.allowedTools,m.allowedTools),disallowedTools:J(T.disallowedTools,m.disallowedTools),approvalRequired:J(T.approvalRequired,m.approvalRequired),maxBudgetUsd:T.maxBudgetUsd>0?Math.min(T.maxBudgetUsd,m.maxBudgetUsd):m.maxBudgetUsd,plugins:J(T.plugins,m.plugins??[])},Y=_.allowedTools;c?.allowedTools&&(Y=c.allowedTools);let Me={timeout:a?.timeout??m.timeout,approvalRequired:_.approvalRequired,approvalTimeout:a?.approvalTimeout??m.approvalTimeout,allowedTools:Y,disallowedTools:c?.disallowedTools??_.disallowedTools,maxTurns:a?.maxTurns??m.maxTurns,maxBudgetUsd:_.maxBudgetUsd,mcpServers:a?.mcpServers,model:a?.model??R.model??m.model,effort:a?.effort??m.effort,settingSources:a?.settingSources??m.settingSources,workspacePath:a?.workspacePath,env:a?.env??m.env,claudeCodePath:m.claudeCodePath,plugins:a?.plugins??_.plugins,requirements:r,executionProfile:R},Ee={id:w,status:"pending",prompt:q,originalPrompt:e,roleId:E,parentId:l,templateId:p,stepId:S,deliverTo:o,reportTo:s,config:Me,sourceSessionId:d,createdAt:Date.now()};Z(Ee),f.auditCandidates&&ve({taskId:w,chosenRoleId:E,requirements:r??{},fitScore:f.fitScore,tieBreakReason:f.tieBreakReason,candidates:f.auditCandidates});let{serverBus:ke}=await import("./server-bus-GEGVMSCA.js");return ke.emit({type:"task_created",taskId:w}),{ok:!0,taskId:w,roleId:E,requirements:r??{},fitScore:f.fitScore,strategyId:V,warnings:f.warnings}}function qe(t,e){return t?.length?e?.length?t.filter(n=>e.includes(n)):t:e??[]}function J(t=[],e=[]){let n=new Set(t);for(let r of e)n.add(r);return[...n]}export{Pe as a,ce as b,U as c,De as d,se as e,ue as f,at as g,ct as h,ut as i,he as j,pt as k,gt as l,mt as m,xt as n,Te as o,I as p,or as q};
@@ -1 +1 @@
1
- import{a as le,b as x,c as J,d as ge,e as me}from"./chunk-KO5AFX5U.js";import{f as ue}from"./chunk-I5IUTZA3.js";import{c as _,h as M}from"./chunk-INNDBLZE.js";import{z as g}from"zod/v4";import{v4 as Dt}from"uuid";import{randomUUID as be}from"crypto";import Ye from"crypto";var pe="2.1.7",F="bot";function Ze(t){let e=t.split(".").map(r=>parseInt(r,10)),s=e[0]??0,i=e[1]??0,n=e[2]??0;return(s&255)<<16|(i&255)<<8|n&255}var Y=Ze(pe),et=35e3,fe=15e3,tt=1e4;function L(){return{channel_version:pe}}function nt(t){return t.endsWith("/")?t:`${t}/`}function st(){let t=Ye.randomBytes(4).readUInt32BE(0);return Buffer.from(String(t),"utf-8").toString("base64")}function it(t){let e={"Content-Type":"application/json",AuthorizationType:"ilink_bot_token","Content-Length":String(Buffer.byteLength(t.body,"utf-8")),"X-WECHAT-UIN":st(),"iLink-App-Id":F,"iLink-App-ClientVersion":String(Y)};return t.token?.trim()&&(e.Authorization=`Bearer ${t.token.trim()}`),t.routeTag&&(e.SKRouteTag=t.routeTag),e}async function D(t){let e=nt(t.baseUrl),s=new URL(t.endpoint,e),i=it({token:t.token,routeTag:t.routeTag,body:t.body}),n=new AbortController,r=setTimeout(()=>n.abort(),t.timeoutMs);try{let o=await fetch(s.toString(),{method:"POST",headers:i,body:t.body,signal:n.signal});clearTimeout(r);let a=await o.text();if(!o.ok)throw new Error(`${t.label} ${o.status}: ${a}`);return a}catch(o){throw clearTimeout(r),o}}async function he(t){let e=t.timeoutMs??et;try{let s=await D({baseUrl:t.baseUrl,endpoint:"ilink/bot/getupdates",body:JSON.stringify({get_updates_buf:t.get_updates_buf??"",base_info:L()}),token:t.token,routeTag:t.routeTag,timeoutMs:e,label:"getUpdates"});return JSON.parse(s)}catch(s){if(s instanceof Error&&s.name==="AbortError")return{ret:0,msgs:[],get_updates_buf:t.get_updates_buf};throw s}}var rt={[-2]:2,[-3]:3},ot=1e3;async function E(t){let e=(await import("./logger-QCJUU7GV.js")).getLogger("channels"),s=new Map;for(;;){let i=await D({baseUrl:t.baseUrl,endpoint:"ilink/bot/sendmessage",body:JSON.stringify({...t.body,base_info:L()}),token:t.token,routeTag:t.routeTag,timeoutMs:t.timeoutMs??fe,label:"sendMessage"});e.info({status:200,responseBody:i.slice(0,300)},"apiFetch sendMessage response");try{let n=JSON.parse(i);if(n.ret&&n.ret!==0){let r=rt[n.ret],o=(s.get(n.ret)??0)+1;if(s.set(n.ret,o),r!==void 0&&o<r){e.warn({ret:n.ret,attempt:o,maxRetries:r},"sendMessage: retriable iLink error, retrying"),await new Promise(a=>setTimeout(a,ot*o));continue}throw e.error({ret:n.ret,errmsg:n.errmsg,attempt:o},"sendMessage: iLink API error, no more retries"),new Error(`sendMessage failed: iLink ret=${n.ret}${n.errmsg?` errmsg=${n.errmsg}`:""}`)}}catch(n){if(n instanceof SyntaxError)e.warn({rawText:i.slice(0,200)},"sendMessage: non-JSON response, treating as success");else throw n}return}}async function ye(t){await D({baseUrl:t.baseUrl,endpoint:"ilink/bot/sendtyping",body:JSON.stringify({...t.body,base_info:L()}),token:t.token,routeTag:t.routeTag,timeoutMs:t.timeoutMs??tt,label:"sendTyping"})}async function _e(t){let e=await D({baseUrl:t.baseUrl,endpoint:"ilink/bot/getuploadurl",body:JSON.stringify({filekey:t.filekey,media_type:t.media_type,to_user_id:t.to_user_id,rawsize:t.rawsize,rawfilemd5:t.rawfilemd5,filesize:t.filesize,thumb_rawsize:t.thumb_rawsize,thumb_rawfilemd5:t.thumb_rawfilemd5,thumb_filesize:t.thumb_filesize,no_need_thumb:t.no_need_thumb,aeskey:t.aeskey,base_info:L()}),token:t.token,routeTag:t.routeTag,timeoutMs:t.timeoutMs??fe,label:"getUploadUrl"});return JSON.parse(e)}var at=5*6e4,dt=35e3,we="3",w=new Map;function Z(t){return Date.now()-t.startedAt<at}function ct(){for(let[t,e]of w)Z(e)||w.delete(t)}async function xe(t,e,s){let i=t.endsWith("/")?t:`${t}/`,n=new URL(`ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(e)}`,i),r={"iLink-App-Id":F};s&&(r.SKRouteTag=s);let o=await fetch(n.toString(),{headers:r});if(!o.ok){let a=await o.text().catch(()=>"(unreadable)");throw new Error(`Failed to fetch QR code: ${o.status} ${o.statusText} body=${a}`)}return await o.json()}async function ut(t,e,s){let i=t.endsWith("/")?t:`${t}/`,n=new URL(`ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(e)}`,i),r={"iLink-App-Id":F,"iLink-App-ClientVersion":String(Y)};s&&(r.SKRouteTag=s);let o=new AbortController,a=setTimeout(()=>o.abort(),dt);try{let d=await fetch(n.toString(),{headers:r,signal:o.signal});clearTimeout(a);let c=await d.text();if(!d.ok)throw new Error(`Failed to poll QR status: ${d.status} ${d.statusText}`);return JSON.parse(c)}catch(d){if(clearTimeout(a),d instanceof Error&&d.name==="AbortError")return{status:"wait"};throw d}}async function Ie(t){let e=t.accountId||be();ct();let s=w.get(e);if(!t.force&&s&&Z(s)&&s.qrcodeUrl)return{qrcodeUrl:s.qrcodeUrl,message:"QR code ready. Scan with WeChat.",sessionKey:e};if(!t.apiBaseUrl)return{message:"No baseUrl configured for this WeChat channel.",sessionKey:e};try{let i=t.botType||we,n=await xe(t.apiBaseUrl,i,t.routeTag),r={sessionKey:e,id:be(),qrcode:n.qrcode,qrcodeUrl:n.qrcode_img_content,startedAt:Date.now()};return w.set(e,r),{qrcodeUrl:n.qrcode_img_content,message:"Scan the QR code with WeChat to connect.",sessionKey:e}}catch(i){return{message:`Failed to start login: ${String(i)}`,sessionKey:e}}}var lt=3;async function Te(t){let e=w.get(t.sessionKey);if(!e)return{connected:!1,message:"No active login session. Start QR login first."};if(!Z(e))return w.delete(t.sessionKey),{connected:!1,message:"QR code expired. Please start again."};let s=Math.max(t.timeoutMs??48e4,1e3),i=Date.now()+s,n=1;for(;Date.now()<i;){try{let r=await ut(t.apiBaseUrl,e.qrcode,t.routeTag);switch(e.status=r.status,r.status){case"wait":break;case"scaned":break;case"expired":{if(n++,n>lt)return w.delete(t.sessionKey),{connected:!1,message:"Login timeout: QR expired multiple times."};try{let o=t.botType||we,a=await xe(t.apiBaseUrl,o,t.routeTag);e.qrcode=a.qrcode,e.qrcodeUrl=a.qrcode_img_content,e.startedAt=Date.now()}catch(o){return w.delete(t.sessionKey),{connected:!1,message:`QR refresh failed: ${String(o)}`}}break}case"confirmed":return r.ilink_bot_id?(w.delete(t.sessionKey),{connected:!0,botToken:r.bot_token,accountId:r.ilink_bot_id,baseUrl:r.baseurl,userId:r.ilink_user_id,message:"Connected to WeChat successfully!"}):(w.delete(t.sessionKey),{connected:!1,message:"Login failed: server did not return bot ID."})}}catch(r){return w.delete(t.sessionKey),{connected:!1,message:`Login failed: ${String(r)}`}}await new Promise(r=>setTimeout(r,1e3))}return w.delete(t.sessionKey),{connected:!1,message:"Login timeout. Please try again."}}import T from"fs";import*as R from"fs/promises";import I from"path";import{homedir as H}from"os";var W={IMAGE:1,VIDEO:2,FILE:3,VOICE:4},A={NONE:0,USER:1,BOT:2},y={NONE:0,TEXT:1,IMAGE:2,VOICE:3,FILE:4,VIDEO:5},P={NEW:0,GENERATING:1,FINISH:2},Re={TYPING:1,CANCEL:2};M();var gt=_("channels"),ee=-14,B=3600*1e3,C=new Map;function Me(t){let e=Date.now()+B;C.set(t,e),gt.info({channelId:t},`Session paused until ${new Date(e).toISOString()} (${B/1e3}s)`)}function j(t){let e=C.get(t);return e===void 0?!1:Date.now()>=e?(C.delete(t),!1):!0}function Ue(t){let e=C.get(t);if(e===void 0)return 0;let s=e-Date.now();return s<=0?(C.delete(t),0):s}function ke(t){C.delete(t)}M();import*as z from"fs/promises";import $e from"path";import{homedir as wt}from"os";import{createCipheriv as mt,createDecipheriv as pt}from"crypto";function Se(t,e){let s=mt("aes-128-ecb",e,null);return Buffer.concat([s.update(t),s.final()])}function Ce(t,e){let s=pt("aes-128-ecb",e,null);return Buffer.concat([s.update(t),s.final()])}function Ee(t){return Math.ceil((t+1)/16)*16}function te(t,e){return`${e}/download?encrypted_query_param=${encodeURIComponent(t)}`}function Ae(t){return`${t.cdnBaseUrl}/upload?encrypted_query_param=${encodeURIComponent(t.uploadParam)}&filekey=${encodeURIComponent(t.filekey)}`}M();var sn=_("channels");function ft(t){let e=Buffer.from(t,"base64");if(e.length===16)return e;if(e.length===32&&/^[0-9a-fA-F]{32}$/.test(e.toString("ascii")))return Buffer.from(e.toString("ascii"),"hex");throw new Error(`aes_key must decode to 16 raw bytes or 32-char hex, got ${e.length} bytes`)}async function Pe(t){let e=await fetch(t);if(!e.ok)throw new Error(`CDN download ${e.status} ${e.statusText}`);return Buffer.from(await e.arrayBuffer())}async function v(t){let{encryptQueryParam:e,aesKeyBase64:s,cdnBaseUrl:i,fullUrl:n}=t,r=ft(s),o=n?.trim()||(e?te(e,i):null);if(!o)throw new Error("CDN download: need full_url or encrypt_query_param");let a=await Pe(o);return Ce(a,r)}async function ve(t){let{encryptQueryParam:e,cdnBaseUrl:s,fullUrl:i}=t,n=i?.trim()||(e?te(e,s):null);if(!n)throw new Error("CDN download: need full_url or encrypt_query_param");return Pe(n)}M();var Q=_("channels"),Oe=24e3;function ht(t,e){let s=t.byteLength,i=44+s,n=Buffer.allocUnsafe(i),r=0;return n.write("RIFF",r),r+=4,n.writeUInt32LE(i-8,r),r+=4,n.write("WAVE",r),r+=4,n.write("fmt ",r),r+=4,n.writeUInt32LE(16,r),r+=4,n.writeUInt16LE(1,r),r+=2,n.writeUInt16LE(1,r),r+=2,n.writeUInt32LE(e,r),r+=4,n.writeUInt32LE(e*2,r),r+=4,n.writeUInt16LE(2,r),r+=2,n.writeUInt16LE(16,r),r+=2,n.write("data",r),r+=4,n.writeUInt32LE(s,r),r+=4,Buffer.from(t.buffer,t.byteOffset,t.byteLength).copy(n,r),n}async function qe(t){try{let{decode:e}=await import("silk-wasm");Q.debug(`silkToWav: decoding ${t.length} bytes of SILK`);let s=await e(t,Oe);Q.debug(`silkToWav: decoded duration=${s.duration}ms pcmBytes=${s.data.byteLength}`);let i=ht(s.data,Oe);return Q.debug(`silkToWav: WAV size=${i.length}`),i}catch(e){return Q.warn(`silkToWav: transcode failed, will use raw silk err=${String(e)}`),null}}import yt from"path";var _t={".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".csv":"text/csv",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".mp3":"audio/mpeg",".ogg":"audio/ogg",".wav":"audio/wav",".amr":"audio/amr",".silk":"audio/x-silk",".mp4":"video/mp4",".mov":"video/quicktime",".webm":"video/webm",".mkv":"video/x-matroska",".avi":"video/x-msvideo",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp"},bt={"image/jpeg":".jpg","image/jpg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/bmp":".bmp","video/mp4":".mp4","video/quicktime":".mov","video/webm":".webm","video/x-matroska":".mkv","video/x-msvideo":".avi","audio/mpeg":".mp3","audio/ogg":".ogg","audio/wav":".wav","audio/amr":".amr","audio/x-silk":".silk","application/pdf":".pdf","application/zip":".zip","application/x-tar":".tar","application/gzip":".gz","text/plain":".txt","text/csv":".csv"};function V(t){let e=yt.extname(t).toLowerCase();return _t[e]??"application/octet-stream"}function Ne(t){let e=t.split(";")[0].trim().toLowerCase();return bt[e]??".bin"}var S=_("channels"),Fe=100*1024*1024;function xt(t){return Ne(t)??".bin"}async function O(t,e,s,i,n=Fe,r){if(t.length>n)throw new Error(`Media too large: ${t.length} bytes exceeds ${n} bytes`);let o=$e.join(wt(),".adam","wechat","media",i,s);await z.mkdir(o,{recursive:!0});let a;if(r&&/^[a-zA-Z0-9._-]+$/.test(r))a=r;else{let c=e?xt(e):".bin",u=Date.now(),p=Math.random().toString(36).slice(2,7);a=`${u}-${p}${c}`}let d=$e.join(o,a);return await z.writeFile(d,t),S.debug(`saveMedia: saved ${t.length} bytes to ${d}`),d}async function Le(t,e){let{cdnBaseUrl:s,channelId:i}=e;if(t.type===y.IMAGE){let n=t.image_item;if(!n?.media?.encrypt_query_param&&!n?.media?.full_url)return null;let r=n.aeskey?Buffer.from(n.aeskey,"hex").toString("base64"):n.media?.aes_key;try{let o=r?await v({encryptQueryParam:n.media?.encrypt_query_param,aesKeyBase64:r,cdnBaseUrl:s,fullUrl:n.media?.full_url}):await ve({encryptQueryParam:n.media?.encrypt_query_param,cdnBaseUrl:s,fullUrl:n.media?.full_url});return{path:await O(o,"image/png","inbound",i),mimeType:"image/png",type:"image"}}catch(o){return S.error({channelId:i},`Image download/decrypt failed: ${String(o)}`),null}}if(t.type===y.VOICE){let n=t.voice_item;if(!n?.media?.encrypt_query_param&&!n?.media?.full_url||!n?.media?.aes_key)return null;try{let r=await v({encryptQueryParam:n.media.encrypt_query_param,aesKeyBase64:n.media.aes_key,cdnBaseUrl:s,fullUrl:n.media.full_url}),o=await qe(r);if(o){let a=await O(o,"audio/wav","inbound",i);return S.debug(`Voice: saved WAV to ${a}`),{path:a,mimeType:"audio/wav",type:"audio"}}else{let a=await O(r,"audio/silk","inbound",i);return S.debug(`Voice: silk transcode unavailable, saved raw SILK to ${a}`),{path:a,mimeType:"audio/silk",type:"audio"}}}catch(r){return S.error({channelId:i},`Voice download/transcode failed: ${String(r)}`),null}}if(t.type===y.FILE){let n=t.file_item;if(!n?.media?.encrypt_query_param&&!n?.media?.full_url||!n?.media?.aes_key)return null;try{let r=await v({encryptQueryParam:n.media.encrypt_query_param,aesKeyBase64:n.media.aes_key,cdnBaseUrl:s,fullUrl:n.media.full_url}),o=V(n.file_name??"file.bin");return{path:await O(r,o,"inbound",i,Fe,n.file_name),mimeType:o,type:"file"}}catch(r){return S.error({channelId:i},`File download failed: ${String(r)}`),null}}if(t.type===y.VIDEO){let n=t.video_item;if(!n?.media?.encrypt_query_param&&!n?.media?.full_url||!n?.media?.aes_key)return null;try{let r=await v({encryptQueryParam:n.media.encrypt_query_param,aesKeyBase64:n.media.aes_key,cdnBaseUrl:s,fullUrl:n.media.full_url});return{path:await O(r,"video/mp4","inbound",i),mimeType:"video/mp4",type:"video"}}catch(r){return S.error({channelId:i},`Video download failed: ${String(r)}`),null}}return null}import Be from"path";import ne from"crypto";import It from"fs/promises";M();var U=_("channels"),G=3;async function Tt(t){let{buf:e,uploadFullUrl:s,uploadParam:i,filekey:n,cdnBaseUrl:r,label:o,aeskey:a}=t,d=Se(e,a),c=s?.trim(),u;if(c)u=c;else if(i)u=Ae({cdnBaseUrl:r,uploadParam:i,filekey:n});else throw new Error(`${o}: CDN upload URL missing (need upload_full_url or upload_param)`);U.debug(`${o}: CDN POST url=${u} ciphertextSize=${d.length}`);let p,l;for(let h=1;h<=G;h++)try{let m=await fetch(u,{method:"POST",headers:{"Content-Type":"application/octet-stream"},body:new Uint8Array(d)});if(m.status>=400&&m.status<500){let b=m.headers.get("x-error-message")??await m.text();throw U.error(`${o}: CDN client error attempt=${h} status=${m.status} errMsg=${b}`),new Error(`CDN upload client error ${m.status}: ${b}`)}if(m.status!==200){let b=m.headers.get("x-error-message")??`status ${m.status}`;throw U.error(`${o}: CDN server error attempt=${h} status=${m.status} errMsg=${b}`),new Error(`CDN upload server error: ${b}`)}if(p=m.headers.get("x-encrypted-param")??void 0,!p)throw U.error(`${o}: CDN response missing x-encrypted-param header attempt=${h}`),new Error("CDN upload response missing x-encrypted-param header");U.debug(`${o}: CDN upload success attempt=${h}`);break}catch(m){if(l=m,m instanceof Error&&m.message.includes("client error"))throw m;h<G?U.warn(`${o}: attempt ${h} failed, retrying... err=${String(m)}`):U.error(`${o}: all ${G} attempts failed err=${String(m)}`)}if(!p)throw l instanceof Error?l:new Error(`CDN upload failed after ${G} attempts`);return{downloadParam:p}}async function se(t){let{filePath:e,toUserId:s,opts:i,cdnBaseUrl:n,mediaType:r,label:o}=t,a=await It.readFile(e),d=a.length,c=ne.createHash("md5").update(a).digest("hex"),u=Ee(d),p=ne.randomBytes(16).toString("hex"),l=ne.randomBytes(16);U.debug(`${o}: file=${e} rawsize=${d} filesize=${u} md5=${c} filekey=${p}`);let h=await _e({...i,filekey:p,media_type:r,to_user_id:s,rawsize:d,rawfilemd5:c,filesize:u,no_need_thumb:!0,aeskey:l.toString("hex")}),m=h.upload_full_url?.trim(),b=h.upload_param;if(!m&&!b)throw new Error(`${o}: getUploadUrl returned no upload URL (need upload_full_url or upload_param)`);let{downloadParam:Je}=await Tt({buf:a,uploadFullUrl:m||void 0,uploadParam:b??void 0,filekey:p,cdnBaseUrl:n,aeskey:l,label:`${o}[orig filekey=${p}]`});return{filekey:p,downloadEncryptedQueryParam:Je,aeskey:l.toString("hex"),fileSize:d,fileSizeCiphertext:u}}async function De(t){return se({...t,mediaType:W.IMAGE,label:"uploadImageToWeixin"})}async function We(t){return se({...t,mediaType:W.VIDEO,label:"uploadVideoToWeixin"})}async function ie(t){return se({...t,mediaType:W.FILE,label:"uploadFileAttachmentToWeixin"})}M();var q=_("channels");function Rt(){return`adam-wechat-${Date.now()}-${Math.random().toString(36).slice(2,7)}`}function Mt(t){let e=t;return e=e.replace(/```[^\n]*\n?([\s\S]*?)```/g,(s,i)=>i.trim()),e=e.replace(/!\[[^\]]*\]\([^)]*\)/g,""),e=e.replace(/\[([^\]]+)\]\([^)]*\)/g,"$1"),e=e.replace(/^\|[\s:|-]+\|$/gm,""),e=e.replace(/^\|(.+)\|$/gm,(s,i)=>i.split("|").map(n=>n.trim()).join(" ")),e}async function re(t){let{to:e,text:s,mediaItem:i,opts:n,label:r}=t,o=[],a=Mt(s);a&&o.push({type:y.TEXT,text_item:{text:a}}),o.push(i);let d="";for(let c of o){d=Rt();let u={msg:{from_user_id:"",to_user_id:e,client_id:d,message_type:A.BOT,message_state:P.FINISH,item_list:[c],context_token:n.contextToken}};await E({baseUrl:n.baseUrl,token:n.token,routeTag:n.routeTag,body:u})}return q.debug(`${r}: sent to=${e} messageId=${d}`),{messageId:d}}async function Ut(t){let{to:e,text:s,uploaded:i,opts:n}=t,r={type:y.IMAGE,image_item:{media:{encrypt_query_param:i.downloadEncryptedQueryParam,aes_key:Buffer.from(i.aeskey).toString("base64"),encrypt_type:1},mid_size:i.fileSizeCiphertext}};return re({to:e,text:s,mediaItem:r,opts:n,label:"sendImageMessage"})}async function kt(t){let{to:e,text:s,uploaded:i,opts:n}=t,r={type:y.VIDEO,video_item:{media:{encrypt_query_param:i.downloadEncryptedQueryParam,aes_key:Buffer.from(i.aeskey).toString("base64"),encrypt_type:1},video_size:i.fileSizeCiphertext}};return re({to:e,text:s,mediaItem:r,opts:n,label:"sendVideoMessage"})}async function je(t){let{to:e,text:s,fileName:i,uploaded:n,opts:r}=t,o={type:y.FILE,file_item:{media:{encrypt_query_param:n.downloadEncryptedQueryParam,aes_key:Buffer.from(n.aeskey).toString("base64"),encrypt_type:1},file_name:i,len:String(n.fileSize)}};return re({to:e,text:s,mediaItem:o,opts:r,label:"sendFileMessage"})}async function Qe(t){let{filePath:e,to:s,text:i,opts:n,cdnBaseUrl:r}=t,o=V(e),a={baseUrl:n.baseUrl,token:n.token,routeTag:n.routeTag};if(o.startsWith("video/")){q.debug(`sendWeixinMediaFile: uploading video filePath=${e} to=${s}`);let u=await We({filePath:e,toUserId:s,opts:a,cdnBaseUrl:r});return kt({to:s,text:i,uploaded:u,opts:n})}if(o.startsWith("image/")){q.debug(`sendWeixinMediaFile: uploading image filePath=${e} to=${s}`);let u=await De({filePath:e,toUserId:s,opts:a,cdnBaseUrl:r});return Ut({to:s,text:i,uploaded:u,opts:n})}if(o.startsWith("audio/")){let u=Be.basename(e);q.debug(`sendWeixinMediaFile: uploading audio as file filePath=${e} name=${u} to=${s}`);let p=await ie({filePath:e,fileName:u,toUserId:s,opts:a,cdnBaseUrl:r});return je({to:s,text:i,fileName:u,uploaded:p,opts:n})}let d=Be.basename(e);q.debug(`sendWeixinMediaFile: uploading file attachment filePath=${e} name=${d} to=${s}`);let c=await ie({filePath:e,fileName:d,toUserId:s,opts:a,cdnBaseUrl:r});return je({to:s,text:i,fileName:d,uploaded:c,opts:n})}M();var f=_("channels"),Ve="https://novac2c.cdn.weixin.qq.com/c2c",de=new Map;function Ke(t){return I.join(H(),".adam","wechat",`${t}.context-tokens.json`)}function St(t){let e=Ke(t);try{let s=T.readFileSync(e,"utf-8"),i=JSON.parse(s);for(let[n,r]of Object.entries(i))typeof r=="string"&&r&&de.set(`${t}:${n}`,r);f.debug({channelId:t,count:Object.keys(i).length},"Restored context tokens from disk")}catch{}}function Ct(t,e,s){let i=Ke(t);try{let n={};try{let o=T.readFileSync(i,"utf-8");n=JSON.parse(o)}catch{}n[e]=s;let r=I.dirname(i);T.mkdirSync(r,{recursive:!0}),T.writeFileSync(i,JSON.stringify(n),"utf-8")}catch(n){f.warn({channelId:t,userId:e},`Failed to persist context token: ${String(n)}`)}}function Et(t,e,s){de.set(`${t}:${e}`,s),Ct(t,e,s)}function oe(t,e){return de.get(`${t}:${e}`)}function He(t){return I.join(H(),".adam","wechat",`${t}.sync`)}function At(t){try{return T.readFileSync(He(t),"utf-8")}catch{return""}}function Pt(t,e){let s=He(t);T.mkdirSync(I.dirname(s),{recursive:!0}),T.writeFileSync(s,e,"utf-8")}var ae=1440*60*1e3,ze=10,vt=20,Ge=1440*60*1e3,Ot=1320*60*1e3,qt=1,Nt=7200*1e3;function Xe(t){return I.join(H(),".adam","wechat",`${t}.session.json`)}function $t(t){let e=new Map,s=Xe(t);try{let i=T.readFileSync(s,"utf-8"),n=JSON.parse(i);for(let[r,o]of Object.entries(n))o&&typeof o.lastUserMessageAt=="number"&&e.set(r,o);f.debug({channelId:t,count:e.size},"Restored sessions from disk")}catch{}return e}function N(t,e){let s=Xe(t);try{let i={};for(let[r,o]of e)i[r]=o;let n=I.dirname(s);T.mkdirSync(n,{recursive:!0}),T.writeFileSync(s,JSON.stringify(i),"utf-8")}catch(i){f.warn({channelId:t},`Failed to persist sessions: ${String(i)}`)}}var Ft=0;function $(){return`adam-wechat-${Date.now()}-${++Ft}`}var K=class{platform="wechat";id;config;status="disconnected";messageHandler=null;pollAbort=null;getUpdatesBuf="";sessions=new Map;pendingQueue=new Map;lastReminderAt=new Map;constructor(e,s){if(this.id=e,!s.baseUrl)throw new Error("WeChat adapter requires baseUrl");this.config=s}async connect(){if(!this.config.botToken)throw new Error("WeChat adapter requires botToken. Complete QR login first.");this.status="connecting",this.getUpdatesBuf=At(this.id),St(this.id),this.sessions=$t(this.id),this.pollAbort=new AbortController,this.status="connected",f.info({channelId:this.id},"WeChat adapter connected, starting long-poll"),this.startLongPoll()}async disconnect(){this.pollAbort&&(this.pollAbort.abort(),this.pollAbort=null),this.status="disconnected",f.info({channelId:this.id},"WeChat adapter disconnected")}getStatus(){if(this.status==="connected"&&j(this.id))return"error";if(this.status==="connected"){for(let[,e]of this.sessions)if(this.isSessionActive(e)&&e.quotaRemaining<=0)return"degraded"}return this.status}async sendMessage(e,s){if(j(this.id)){let c=Math.ceil(Ue(this.id)/6e4);throw new Error(`WeChat session paused, ${c} min remaining. Re-scan QR to reconnect.`)}let i=this.getOrCreateSession(e),r=this.getSessionRemainingMs(i)/36e5;if(!this.isSessionActive(i))return f.warn({channelId:this.id,chatId:e.slice(0,12),lastUserMessageAt:i.lastUserMessageAt,sessionExpired:!0},"iLink session expired (>24h), message queued"),this.enqueueMessage(e,s),`queued-${$()}`;if(i.quotaRemaining<=0)return f.warn({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:0,remainingHours:r.toFixed(1)},"iLink quota exhausted, message queued"),this.enqueueMessage(e,s),`queued-${$()}`;let o=$(),a=oe(this.id,e),d=this.config.cdnBaseUrl??Ve;try{if(s.mediaUrl){let c=!s.mediaUrl.includes("://")||s.mediaUrl.startsWith("file://"),u=I.join(H(),".adam","wechat","media","outbound-tmp");await R.mkdir(u,{recursive:!0});let p=this.getExtensionFromMediaType(s.mediaType),l;if(c){let m=s.mediaUrl.startsWith("file://")?new URL(s.mediaUrl).pathname:I.isAbsolute(s.mediaUrl)?s.mediaUrl:I.resolve(s.mediaUrl),b=await R.readFile(m);l=I.join(u,`${Date.now()}-${Math.random().toString(36).slice(2,7)}${p}`),await R.writeFile(l,b)}else{let m=await fetch(s.mediaUrl);if(!m.ok)throw new Error(`Failed to fetch media: ${m.status}`);let b=Buffer.from(await m.arrayBuffer());l=I.join(u,`${Date.now()}-${Math.random().toString(36).slice(2,7)}${p}`),await R.writeFile(l,b)}let h=await Qe({filePath:l,to:e,text:s.content??"",opts:{baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,contextToken:a},cdnBaseUrl:d});return await R.unlink(l).catch(()=>{}),i.quotaRemaining--,N(this.id,this.sessions),f.info({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:i.quotaRemaining,sessionRemainingHours:(this.getSessionRemainingMs(i)/36e5).toFixed(1)},"iLink send success: quota decremented"),this.checkAndSendReminder(e,i).catch(m=>{f.warn({channelId:this.id,chatId:e.slice(0,12)},`Reminder send failed: ${String(m)}`)}),h.messageId}return await E({baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,body:{msg:{from_user_id:"",to_user_id:e,client_id:o,message_type:A.BOT,message_state:P.FINISH,item_list:s.content?[{type:y.TEXT,text_item:{text:s.content}}]:void 0,context_token:a}}}),i.quotaRemaining--,N(this.id,this.sessions),f.info({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:i.quotaRemaining,sessionRemainingHours:(this.getSessionRemainingMs(i)/36e5).toFixed(1)},"iLink send success: quota decremented"),this.checkAndSendReminder(e,i).catch(c=>{f.warn({channelId:this.id,chatId:e.slice(0,12)},`Reminder send failed: ${String(c)}`)}),o}catch(c){if(c instanceof Error&&c.message.includes("ret=-2"))return i.quotaRemaining=0,N(this.id,this.sessions),f.warn({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:0},"iLink quota exhausted (ret=-2 confirmed), message queued"),this.enqueueMessage(e,s),`queued-${$()}`;throw c}}onMessage(e){this.messageHandler=e}async sendTypingIndicator(e){if(j(this.id))return;let s=oe(this.id,e);try{await ye({baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,body:{ilink_user_id:e,status:Re.TYPING}})}catch{}}updateConfig(e){Object.assign(this.config,e)}getOrCreateSession(e){let s=this.sessions.get(e);return s||(s={lastUserMessageAt:0,quotaRemaining:0},this.sessions.set(e,s)),s}isSessionActive(e){return e.lastUserMessageAt>0&&Date.now()-e.lastUserMessageAt<=ae}getSessionRemainingMs(e){return e.lastUserMessageAt===0?0:Math.max(0,ae-(Date.now()-e.lastUserMessageAt))}enqueueMessage(e,s){let i=this.pendingQueue.get(e);i||(i=[],this.pendingQueue.set(e,i));let n=Date.now();i=i.filter(r=>n-r.queuedAt<Ge),i.length>=vt&&(i.shift(),f.warn({channelId:this.id,chatId:e.slice(0,12)},"Queue full, dropping oldest message")),i.push({message:s,queuedAt:n}),this.pendingQueue.set(e,i),f.info({channelId:this.id,chatId:e.slice(0,12),queueDepth:i.length},"Message enqueued")}async flushQueue(e){let s=this.pendingQueue.get(e);if(!s||s.length===0)return;let i=this.getOrCreateSession(e),n=Math.min(s.length,Math.max(0,i.quotaRemaining-2));if(n<=0){f.info({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:i.quotaRemaining},"Queue flush skipped: insufficient quota (reserving 2 for conversation)");return}f.info({channelId:this.id,chatId:e.slice(0,12),queueDepth:s.length,sending:n,quotaRemaining:i.quotaRemaining},"Flushing queued messages");let r=0;for(;r<n&&s.length>0;){let o=s[0];if(Date.now()-o.queuedAt>Ge){s.shift();continue}try{if(await this.sendMessage(e,o.message),s.shift(),r++,i.quotaRemaining<=0)break}catch{f.warn({channelId:this.id,chatId:e.slice(0,12)},"Queue flush: send failed, stopping");break}}s.length===0&&this.pendingQueue.delete(e),f.info({channelId:this.id,chatId:e.slice(0,12),sent:r,remaining:s.length},"Queue flush complete")}async checkAndSendReminder(e,s){let i=Date.now(),n=this.lastReminderAt.get(e)??0;if(i-n<Nt)return;let r=this.getSessionRemainingMs(s),a=i-s.lastUserMessageAt>=Ot,d=s.quotaRemaining<=qt;if(!a&&!d)return;let c=(r/36e5).toFixed(1),u;a&&d?u=`[\u7CFB\u7EDF\u63D0\u9192] \u6D88\u606F\u7A97\u53E3\u5373\u5C06\u5173\u95ED\uFF08\u5269\u4F59${c}\u5C0F\u65F6/${s.quotaRemaining}\u6761\u914D\u989D\uFF09\u3002\u8BF7\u56DE\u590D\u4EFB\u610F\u6D88\u606F\u4EE5\u4FDD\u6301\u8FDE\u63A5\u3002`:a?u=`[\u7CFB\u7EDF\u63D0\u9192] \u6D88\u606F\u7A97\u53E3\u5373\u5C06\u5173\u95ED\uFF08\u5269\u4F59${c}\u5C0F\u65F6\uFF09\u3002\u8BF7\u56DE\u590D\u4EFB\u610F\u6D88\u606F\u4EE5\u4FDD\u6301\u8FDE\u63A5\u3002`:u=`[\u7CFB\u7EDF\u63D0\u9192] \u6D88\u606F\u914D\u989D\u5373\u5C06\u7528\u5B8C\uFF08\u5269\u4F59${s.quotaRemaining}\u6761\uFF09\u3002\u8BF7\u56DE\u590D\u4EFB\u610F\u6D88\u606F\u4EE5\u91CD\u7F6E\u914D\u989D\u3002`;let p=oe(this.id,e);try{await E({baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,body:{msg:{from_user_id:"",to_user_id:e,client_id:$(),message_type:A.BOT,message_state:P.FINISH,item_list:[{type:y.TEXT,text_item:{text:u}}],context_token:p}}}),s.quotaRemaining--,this.lastReminderAt.set(e,i),N(this.id,this.sessions),f.info({channelId:this.id,chatId:e.slice(0,12),remainingHours:c,quotaRemaining:s.quotaRemaining,trigger:a?"time":"quota"},"iLink session reminder sent")}catch(l){f.warn({channelId:this.id,chatId:e.slice(0,12)},`Reminder send failed: ${String(l)}`)}}async startLongPoll(){let e=this.pollAbort?.signal,s=0,i=3,n=3e4,r=2e3;for(;!e?.aborted;)try{let o=await he({baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,get_updates_buf:this.getUpdatesBuf});if(o.ret===ee||o.errcode===ee){Me(this.id),this.status="error",f.error({channelId:this.id},"Session expired (errcode=-14), pausing for 1 hour"),await this.sleep(B,e),ke(this.id),this.status="connected";continue}if(o.ret!==void 0&&o.ret!==0||o.errcode!==void 0&&o.errcode!==0){s++,f.error({channelId:this.id,ret:o.ret,errcode:o.errcode},"getUpdates API error"),s>=i?(s=0,await this.sleep(n,e)):await this.sleep(r,e);continue}s=0,o.get_updates_buf&&(this.getUpdatesBuf=o.get_updates_buf,Pt(this.id,o.get_updates_buf));for(let d of o.msgs??[])await this.processInbound(d)}catch(o){if(e?.aborted)return;s++,f.error({channelId:this.id,error:o},"getUpdates error"),s>=i?(s=0,await this.sleep(n,e)):await this.sleep(r,e)}}async processInbound(e){if(!this.messageHandler)return;let s=!!e.group_id,i=s?e.group_id:e.from_user_id??"",n=e.from_user_id??"";e.context_token&&i&&Et(this.id,i,e.context_token);let r=this.getOrCreateSession(i),o=r.quotaRemaining;r.lastUserMessageAt=Date.now(),r.quotaRemaining=ze,N(this.id,this.sessions),f.info({channelId:this.id,chatId:i.slice(0,12),quotaReset:!0,prevQuota:o,newQuota:ze,sessionWindowMs:ae},"iLink session reset: user message received, quota restored"),this.flushQueue(i);let a="",d,c=[];for(let l of e.item_list??[])l.type===y.TEXT&&l.text_item?.text&&(a+=l.text_item.text),l.type===y.IMAGE&&(d="image",c.push(l)),l.type===y.VOICE&&(d="audio",c.push(l),l.voice_item?.text&&!a&&(a=l.voice_item.text)),l.type===y.FILE&&(d="file",c.push(l)),l.type===y.VIDEO&&(d="video",c.push(l));if(!a&&!d)return;let u;if(c.length>0){let l=this.config.cdnBaseUrl??Ve;try{let h=await Le(c[0],{cdnBaseUrl:l,channelId:this.id});h&&(u=h.path,d=h.type)}catch(h){f.error({channelId:this.id},`Media download failed: ${String(h)}`)}}let p={channelId:this.id,platform:"wechat",chatId:i,senderId:n,content:a,mediaType:d,mediaPath:u,isGroup:s,timestamp:e.create_time_ms??Date.now(),raw:e};this.messageHandler(p)}getExtensionFromMediaType(e){switch(e){case"image":return".png";case"video":return".mp4";case"audio":return".mp3";default:return".bin"}}sleep(e,s){return new Promise((i,n)=>{let r=setTimeout(i,e);s?.addEventListener("abort",()=>{clearTimeout(r),n(new Error("aborted"))},{once:!0})})}};M();var Lt=_("channels"),X=class{platform="discord";id;config;status="disconnected";messageHandler=null;client=null;constructor(e,s){if(this.id=e,!s.botToken)throw new Error("Discord adapter requires botToken");this.config=s}async connect(){this.status="connecting";try{let{Client:e,GatewayIntentBits:s}=await import("discord.js");this.client=new e({intents:[s.Guilds,s.GuildMessages,s.MessageContent,s.DirectMessages]});let i=this.client;i.on("messageCreate",n=>{if(!this.messageHandler||n.author.bot||this.config.allowedGuildIds?.length&&n.guildId&&!this.config.allowedGuildIds.includes(n.guildId))return;let r={channelId:this.id,platform:"discord",chatId:n.channelId,senderId:n.author.id,senderName:n.author.displayName??n.author.username,content:n.content,isGroup:!!n.guildId,timestamp:n.createdTimestamp,raw:n};this.messageHandler(r)}),await i.login(this.config.botToken),this.status="connected",Lt.info({channelId:this.id},"Discord bot connected")}catch(e){throw this.status="error",e}}async disconnect(){this.client&&await this.client.destroy(),this.client=null,this.status="disconnected"}getStatus(){return this.status}async sendMessage(e,s){if(!this.client)throw new Error("Discord client not connected");let n=await this.client.channels.fetch(e);if(!n||!("send"in n))throw new Error(`Channel ${e} not found or not text channel`);return(await n.send({content:s.content,reply:s.replyToMessageId?{messageReference:s.replyToMessageId}:void 0})).id}onMessage(e){this.messageHandler=e}async sendTypingIndicator(e){if(!this.client)return;let i=await this.client.channels.fetch(e);i&&"sendTyping"in i&&await i.sendTyping()}};var k=g.object({id:g.string().uuid()}),Wt=g.object({name:g.string().min(1,"name is required"),platform:g.string().min(1,"platform is required"),config:g.record(g.string(),g.unknown()),enabled:g.boolean().optional().default(!0),linkedRoleId:g.string().optional(),allowedChatIds:g.array(g.string()).optional()}),Bt=g.object({name:g.string().min(1).optional(),enabled:g.boolean().optional(),config:g.record(g.string(),g.unknown()).optional(),linkedRoleId:g.string().optional(),allowedChatIds:g.array(g.string()).optional()}),ce;function Zn(t){ce=t}function es(){return ce}async function ts(t){let e=ce;t.get("/channels",{schema:{tags:["Channels"],summary:"List channels",querystring:{type:"object",properties:{enabled:{type:"boolean"}}}}},async(s,i)=>({channels:ge(s.query.enabled)})),t.post("/channels",{schema:{tags:["Channels"],summary:"Create a channel",body:{type:"object",required:["name","platform","config"],properties:{name:{type:"string",minLength:1},platform:{type:"string",minLength:1},config:{type:"object"},enabled:{type:"boolean"},linkedRoleId:{type:"string"},allowedChatIds:{type:"array",items:{type:"string"}}}}}},async(s,i)=>{let n=Wt.safeParse(s.body);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let{name:r,platform:o,config:a,enabled:d,linkedRoleId:c,allowedChatIds:u}=n.data,p={id:Dt(),name:r,platform:o,enabled:d,status:"disconnected",config:a,linkedRoleId:c,allowedChatIds:u,createdAt:Date.now(),messageCount:0};return le(p),i.status(201).send({channel:p})}),t.get("/channels/:id",{schema:{tags:["Channels"],summary:"Get channel by ID",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);return r?{channel:r}:i.status(404).send({code:"NOT_FOUND",message:"Channel not found"})}),t.patch("/channels/:id",{schema:{tags:["Channels"],summary:"Update channel",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",properties:{name:{type:"string"},enabled:{type:"boolean"},config:{type:"object"},linkedRoleId:{type:"string"},allowedChatIds:{type:"array",items:{type:"string"}}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});let o=Bt.safeParse(s.body);return o.success?(J(r.id,o.data),{channel:x(r.id)}):i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(o.error)})}),t.delete("/channels/:id",{schema:{tags:["Channels"],summary:"Delete channel",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);return r?(me(r.id),i.status(204).send()):i.status(404).send({code:"NOT_FOUND",message:"Channel not found"})}),t.post("/channels/:id/connect",{schema:{tags:["Channels"],summary:"Connect channel",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});if(!e)return i.status(501).send({code:"NOT_IMPLEMENTED",message:"Channel manager not initialized"});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});if(!e.hasAdapter(r.id)&&r.platform==="discord"){let o=r.config;if(!o.botToken)return i.status(400).send({code:"MISSING_CONFIG",message:"Discord channel requires botToken in config"});let a=new X(r.id,{botToken:o.botToken});await e.addChannel(r,a)}if(!e.hasAdapter(r.id))return i.status(400).send({code:"NO_ADAPTER",message:"No adapter registered for this channel. Install the appropriate adapter first."});try{return await e.connectChannel(r.id),{channelId:r.id,status:"connected"}}catch(o){return i.status(500).send({code:"CONNECT_FAILED",message:String(o)})}}),t.post("/channels/:id/disconnect",{schema:{tags:["Channels"],summary:"Disconnect channel",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});if(!e)return i.status(501).send({code:"NOT_IMPLEMENTED",message:"Channel manager not initialized"});let r=x(n.data.id);return r?(await e.disconnectChannel(r.id),{channelId:r.id,status:"disconnected"}):i.status(404).send({code:"NOT_FOUND",message:"Channel not found"})}),t.get("/channels/:id/messages",{schema:{tags:["Channels"],summary:"Get channel message history",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(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});let{limit:o=50,offset:a=0}=s.query;return{messages:ue(r.id,o,a)}}),t.post("/channels/:id/wechat/qr-start",{schema:{tags:["WeChat"],summary:"Start WeChat QR login",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});if(r.platform!=="wechat")return i.status(400).send({code:"INVALID_PLATFORM",message:"Channel is not a WeChat channel"});let o=r.config;return await Ie({apiBaseUrl:o.baseUrl,routeTag:o.routeTag})}),t.post("/channels/:id/wechat/qr-wait",{schema:{tags:["WeChat"],summary:"Wait for WeChat QR scan",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",properties:{sessionKey:{type:"string"},timeoutMs:{type:"number"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});if(r.platform!=="wechat")return i.status(400).send({code:"INVALID_PLATFORM",message:"Channel is not a WeChat channel"});let o=r.config,{sessionKey:a,timeoutMs:d}=s.body??{},c=await Te({sessionKey:a??"",apiBaseUrl:o.baseUrl,timeoutMs:d??12e4,routeTag:o.routeTag});if(c.connected&&c.botToken){let u={...o,botToken:c.botToken,accountId:c.accountId,baseUrl:c.baseUrl??o.baseUrl,userId:c.userId};if(J(r.id,{config:u}),e){let p=new K(r.id,u),l=x(r.id);l&&await e.addChannel(l,p)}}return{connected:c.connected,accountId:c.accountId,message:c.message}})}export{K as a,X as b,Zn as c,es as d,ts as e};
1
+ import{a as le,b as x,c as J,d as ge,e as me}from"./chunk-23VZKIB6.js";import{f as ue}from"./chunk-HDP7A4XY.js";import{c as _,h as M}from"./chunk-INNDBLZE.js";import{z as g}from"zod/v4";import{v4 as Dt}from"uuid";import{randomUUID as be}from"crypto";import Ye from"crypto";var pe="2.1.7",F="bot";function Ze(t){let e=t.split(".").map(r=>parseInt(r,10)),s=e[0]??0,i=e[1]??0,n=e[2]??0;return(s&255)<<16|(i&255)<<8|n&255}var Y=Ze(pe),et=35e3,fe=15e3,tt=1e4;function L(){return{channel_version:pe}}function nt(t){return t.endsWith("/")?t:`${t}/`}function st(){let t=Ye.randomBytes(4).readUInt32BE(0);return Buffer.from(String(t),"utf-8").toString("base64")}function it(t){let e={"Content-Type":"application/json",AuthorizationType:"ilink_bot_token","Content-Length":String(Buffer.byteLength(t.body,"utf-8")),"X-WECHAT-UIN":st(),"iLink-App-Id":F,"iLink-App-ClientVersion":String(Y)};return t.token?.trim()&&(e.Authorization=`Bearer ${t.token.trim()}`),t.routeTag&&(e.SKRouteTag=t.routeTag),e}async function D(t){let e=nt(t.baseUrl),s=new URL(t.endpoint,e),i=it({token:t.token,routeTag:t.routeTag,body:t.body}),n=new AbortController,r=setTimeout(()=>n.abort(),t.timeoutMs);try{let o=await fetch(s.toString(),{method:"POST",headers:i,body:t.body,signal:n.signal});clearTimeout(r);let a=await o.text();if(!o.ok)throw new Error(`${t.label} ${o.status}: ${a}`);return a}catch(o){throw clearTimeout(r),o}}async function he(t){let e=t.timeoutMs??et;try{let s=await D({baseUrl:t.baseUrl,endpoint:"ilink/bot/getupdates",body:JSON.stringify({get_updates_buf:t.get_updates_buf??"",base_info:L()}),token:t.token,routeTag:t.routeTag,timeoutMs:e,label:"getUpdates"});return JSON.parse(s)}catch(s){if(s instanceof Error&&s.name==="AbortError")return{ret:0,msgs:[],get_updates_buf:t.get_updates_buf};throw s}}var rt={[-2]:2,[-3]:3},ot=1e3;async function E(t){let e=(await import("./logger-QCJUU7GV.js")).getLogger("channels"),s=new Map;for(;;){let i=await D({baseUrl:t.baseUrl,endpoint:"ilink/bot/sendmessage",body:JSON.stringify({...t.body,base_info:L()}),token:t.token,routeTag:t.routeTag,timeoutMs:t.timeoutMs??fe,label:"sendMessage"});e.info({status:200,responseBody:i.slice(0,300)},"apiFetch sendMessage response");try{let n=JSON.parse(i);if(n.ret&&n.ret!==0){let r=rt[n.ret],o=(s.get(n.ret)??0)+1;if(s.set(n.ret,o),r!==void 0&&o<r){e.warn({ret:n.ret,attempt:o,maxRetries:r},"sendMessage: retriable iLink error, retrying"),await new Promise(a=>setTimeout(a,ot*o));continue}throw e.error({ret:n.ret,errmsg:n.errmsg,attempt:o},"sendMessage: iLink API error, no more retries"),new Error(`sendMessage failed: iLink ret=${n.ret}${n.errmsg?` errmsg=${n.errmsg}`:""}`)}}catch(n){if(n instanceof SyntaxError)e.warn({rawText:i.slice(0,200)},"sendMessage: non-JSON response, treating as success");else throw n}return}}async function ye(t){await D({baseUrl:t.baseUrl,endpoint:"ilink/bot/sendtyping",body:JSON.stringify({...t.body,base_info:L()}),token:t.token,routeTag:t.routeTag,timeoutMs:t.timeoutMs??tt,label:"sendTyping"})}async function _e(t){let e=await D({baseUrl:t.baseUrl,endpoint:"ilink/bot/getuploadurl",body:JSON.stringify({filekey:t.filekey,media_type:t.media_type,to_user_id:t.to_user_id,rawsize:t.rawsize,rawfilemd5:t.rawfilemd5,filesize:t.filesize,thumb_rawsize:t.thumb_rawsize,thumb_rawfilemd5:t.thumb_rawfilemd5,thumb_filesize:t.thumb_filesize,no_need_thumb:t.no_need_thumb,aeskey:t.aeskey,base_info:L()}),token:t.token,routeTag:t.routeTag,timeoutMs:t.timeoutMs??fe,label:"getUploadUrl"});return JSON.parse(e)}var at=5*6e4,dt=35e3,we="3",w=new Map;function Z(t){return Date.now()-t.startedAt<at}function ct(){for(let[t,e]of w)Z(e)||w.delete(t)}async function xe(t,e,s){let i=t.endsWith("/")?t:`${t}/`,n=new URL(`ilink/bot/get_bot_qrcode?bot_type=${encodeURIComponent(e)}`,i),r={"iLink-App-Id":F};s&&(r.SKRouteTag=s);let o=await fetch(n.toString(),{headers:r});if(!o.ok){let a=await o.text().catch(()=>"(unreadable)");throw new Error(`Failed to fetch QR code: ${o.status} ${o.statusText} body=${a}`)}return await o.json()}async function ut(t,e,s){let i=t.endsWith("/")?t:`${t}/`,n=new URL(`ilink/bot/get_qrcode_status?qrcode=${encodeURIComponent(e)}`,i),r={"iLink-App-Id":F,"iLink-App-ClientVersion":String(Y)};s&&(r.SKRouteTag=s);let o=new AbortController,a=setTimeout(()=>o.abort(),dt);try{let d=await fetch(n.toString(),{headers:r,signal:o.signal});clearTimeout(a);let c=await d.text();if(!d.ok)throw new Error(`Failed to poll QR status: ${d.status} ${d.statusText}`);return JSON.parse(c)}catch(d){if(clearTimeout(a),d instanceof Error&&d.name==="AbortError")return{status:"wait"};throw d}}async function Ie(t){let e=t.accountId||be();ct();let s=w.get(e);if(!t.force&&s&&Z(s)&&s.qrcodeUrl)return{qrcodeUrl:s.qrcodeUrl,message:"QR code ready. Scan with WeChat.",sessionKey:e};if(!t.apiBaseUrl)return{message:"No baseUrl configured for this WeChat channel.",sessionKey:e};try{let i=t.botType||we,n=await xe(t.apiBaseUrl,i,t.routeTag),r={sessionKey:e,id:be(),qrcode:n.qrcode,qrcodeUrl:n.qrcode_img_content,startedAt:Date.now()};return w.set(e,r),{qrcodeUrl:n.qrcode_img_content,message:"Scan the QR code with WeChat to connect.",sessionKey:e}}catch(i){return{message:`Failed to start login: ${String(i)}`,sessionKey:e}}}var lt=3;async function Te(t){let e=w.get(t.sessionKey);if(!e)return{connected:!1,message:"No active login session. Start QR login first."};if(!Z(e))return w.delete(t.sessionKey),{connected:!1,message:"QR code expired. Please start again."};let s=Math.max(t.timeoutMs??48e4,1e3),i=Date.now()+s,n=1;for(;Date.now()<i;){try{let r=await ut(t.apiBaseUrl,e.qrcode,t.routeTag);switch(e.status=r.status,r.status){case"wait":break;case"scaned":break;case"expired":{if(n++,n>lt)return w.delete(t.sessionKey),{connected:!1,message:"Login timeout: QR expired multiple times."};try{let o=t.botType||we,a=await xe(t.apiBaseUrl,o,t.routeTag);e.qrcode=a.qrcode,e.qrcodeUrl=a.qrcode_img_content,e.startedAt=Date.now()}catch(o){return w.delete(t.sessionKey),{connected:!1,message:`QR refresh failed: ${String(o)}`}}break}case"confirmed":return r.ilink_bot_id?(w.delete(t.sessionKey),{connected:!0,botToken:r.bot_token,accountId:r.ilink_bot_id,baseUrl:r.baseurl,userId:r.ilink_user_id,message:"Connected to WeChat successfully!"}):(w.delete(t.sessionKey),{connected:!1,message:"Login failed: server did not return bot ID."})}}catch(r){return w.delete(t.sessionKey),{connected:!1,message:`Login failed: ${String(r)}`}}await new Promise(r=>setTimeout(r,1e3))}return w.delete(t.sessionKey),{connected:!1,message:"Login timeout. Please try again."}}import T from"fs";import*as R from"fs/promises";import I from"path";import{homedir as H}from"os";var W={IMAGE:1,VIDEO:2,FILE:3,VOICE:4},A={NONE:0,USER:1,BOT:2},y={NONE:0,TEXT:1,IMAGE:2,VOICE:3,FILE:4,VIDEO:5},P={NEW:0,GENERATING:1,FINISH:2},Re={TYPING:1,CANCEL:2};M();var gt=_("channels"),ee=-14,B=3600*1e3,C=new Map;function Me(t){let e=Date.now()+B;C.set(t,e),gt.info({channelId:t},`Session paused until ${new Date(e).toISOString()} (${B/1e3}s)`)}function j(t){let e=C.get(t);return e===void 0?!1:Date.now()>=e?(C.delete(t),!1):!0}function Ue(t){let e=C.get(t);if(e===void 0)return 0;let s=e-Date.now();return s<=0?(C.delete(t),0):s}function ke(t){C.delete(t)}M();import*as z from"fs/promises";import $e from"path";import{homedir as wt}from"os";import{createCipheriv as mt,createDecipheriv as pt}from"crypto";function Se(t,e){let s=mt("aes-128-ecb",e,null);return Buffer.concat([s.update(t),s.final()])}function Ce(t,e){let s=pt("aes-128-ecb",e,null);return Buffer.concat([s.update(t),s.final()])}function Ee(t){return Math.ceil((t+1)/16)*16}function te(t,e){return`${e}/download?encrypted_query_param=${encodeURIComponent(t)}`}function Ae(t){return`${t.cdnBaseUrl}/upload?encrypted_query_param=${encodeURIComponent(t.uploadParam)}&filekey=${encodeURIComponent(t.filekey)}`}M();var sn=_("channels");function ft(t){let e=Buffer.from(t,"base64");if(e.length===16)return e;if(e.length===32&&/^[0-9a-fA-F]{32}$/.test(e.toString("ascii")))return Buffer.from(e.toString("ascii"),"hex");throw new Error(`aes_key must decode to 16 raw bytes or 32-char hex, got ${e.length} bytes`)}async function Pe(t){let e=await fetch(t);if(!e.ok)throw new Error(`CDN download ${e.status} ${e.statusText}`);return Buffer.from(await e.arrayBuffer())}async function v(t){let{encryptQueryParam:e,aesKeyBase64:s,cdnBaseUrl:i,fullUrl:n}=t,r=ft(s),o=n?.trim()||(e?te(e,i):null);if(!o)throw new Error("CDN download: need full_url or encrypt_query_param");let a=await Pe(o);return Ce(a,r)}async function ve(t){let{encryptQueryParam:e,cdnBaseUrl:s,fullUrl:i}=t,n=i?.trim()||(e?te(e,s):null);if(!n)throw new Error("CDN download: need full_url or encrypt_query_param");return Pe(n)}M();var Q=_("channels"),Oe=24e3;function ht(t,e){let s=t.byteLength,i=44+s,n=Buffer.allocUnsafe(i),r=0;return n.write("RIFF",r),r+=4,n.writeUInt32LE(i-8,r),r+=4,n.write("WAVE",r),r+=4,n.write("fmt ",r),r+=4,n.writeUInt32LE(16,r),r+=4,n.writeUInt16LE(1,r),r+=2,n.writeUInt16LE(1,r),r+=2,n.writeUInt32LE(e,r),r+=4,n.writeUInt32LE(e*2,r),r+=4,n.writeUInt16LE(2,r),r+=2,n.writeUInt16LE(16,r),r+=2,n.write("data",r),r+=4,n.writeUInt32LE(s,r),r+=4,Buffer.from(t.buffer,t.byteOffset,t.byteLength).copy(n,r),n}async function qe(t){try{let{decode:e}=await import("silk-wasm");Q.debug(`silkToWav: decoding ${t.length} bytes of SILK`);let s=await e(t,Oe);Q.debug(`silkToWav: decoded duration=${s.duration}ms pcmBytes=${s.data.byteLength}`);let i=ht(s.data,Oe);return Q.debug(`silkToWav: WAV size=${i.length}`),i}catch(e){return Q.warn(`silkToWav: transcode failed, will use raw silk err=${String(e)}`),null}}import yt from"path";var _t={".pdf":"application/pdf",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".txt":"text/plain",".csv":"text/csv",".zip":"application/zip",".tar":"application/x-tar",".gz":"application/gzip",".mp3":"audio/mpeg",".ogg":"audio/ogg",".wav":"audio/wav",".amr":"audio/amr",".silk":"audio/x-silk",".mp4":"video/mp4",".mov":"video/quicktime",".webm":"video/webm",".mkv":"video/x-matroska",".avi":"video/x-msvideo",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".webp":"image/webp",".bmp":"image/bmp"},bt={"image/jpeg":".jpg","image/jpg":".jpg","image/png":".png","image/gif":".gif","image/webp":".webp","image/bmp":".bmp","video/mp4":".mp4","video/quicktime":".mov","video/webm":".webm","video/x-matroska":".mkv","video/x-msvideo":".avi","audio/mpeg":".mp3","audio/ogg":".ogg","audio/wav":".wav","audio/amr":".amr","audio/x-silk":".silk","application/pdf":".pdf","application/zip":".zip","application/x-tar":".tar","application/gzip":".gz","text/plain":".txt","text/csv":".csv"};function V(t){let e=yt.extname(t).toLowerCase();return _t[e]??"application/octet-stream"}function Ne(t){let e=t.split(";")[0].trim().toLowerCase();return bt[e]??".bin"}var S=_("channels"),Fe=100*1024*1024;function xt(t){return Ne(t)??".bin"}async function O(t,e,s,i,n=Fe,r){if(t.length>n)throw new Error(`Media too large: ${t.length} bytes exceeds ${n} bytes`);let o=$e.join(wt(),".adam","wechat","media",i,s);await z.mkdir(o,{recursive:!0});let a;if(r&&/^[a-zA-Z0-9._-]+$/.test(r))a=r;else{let c=e?xt(e):".bin",u=Date.now(),p=Math.random().toString(36).slice(2,7);a=`${u}-${p}${c}`}let d=$e.join(o,a);return await z.writeFile(d,t),S.debug(`saveMedia: saved ${t.length} bytes to ${d}`),d}async function Le(t,e){let{cdnBaseUrl:s,channelId:i}=e;if(t.type===y.IMAGE){let n=t.image_item;if(!n?.media?.encrypt_query_param&&!n?.media?.full_url)return null;let r=n.aeskey?Buffer.from(n.aeskey,"hex").toString("base64"):n.media?.aes_key;try{let o=r?await v({encryptQueryParam:n.media?.encrypt_query_param,aesKeyBase64:r,cdnBaseUrl:s,fullUrl:n.media?.full_url}):await ve({encryptQueryParam:n.media?.encrypt_query_param,cdnBaseUrl:s,fullUrl:n.media?.full_url});return{path:await O(o,"image/png","inbound",i),mimeType:"image/png",type:"image"}}catch(o){return S.error({channelId:i},`Image download/decrypt failed: ${String(o)}`),null}}if(t.type===y.VOICE){let n=t.voice_item;if(!n?.media?.encrypt_query_param&&!n?.media?.full_url||!n?.media?.aes_key)return null;try{let r=await v({encryptQueryParam:n.media.encrypt_query_param,aesKeyBase64:n.media.aes_key,cdnBaseUrl:s,fullUrl:n.media.full_url}),o=await qe(r);if(o){let a=await O(o,"audio/wav","inbound",i);return S.debug(`Voice: saved WAV to ${a}`),{path:a,mimeType:"audio/wav",type:"audio"}}else{let a=await O(r,"audio/silk","inbound",i);return S.debug(`Voice: silk transcode unavailable, saved raw SILK to ${a}`),{path:a,mimeType:"audio/silk",type:"audio"}}}catch(r){return S.error({channelId:i},`Voice download/transcode failed: ${String(r)}`),null}}if(t.type===y.FILE){let n=t.file_item;if(!n?.media?.encrypt_query_param&&!n?.media?.full_url||!n?.media?.aes_key)return null;try{let r=await v({encryptQueryParam:n.media.encrypt_query_param,aesKeyBase64:n.media.aes_key,cdnBaseUrl:s,fullUrl:n.media.full_url}),o=V(n.file_name??"file.bin");return{path:await O(r,o,"inbound",i,Fe,n.file_name),mimeType:o,type:"file"}}catch(r){return S.error({channelId:i},`File download failed: ${String(r)}`),null}}if(t.type===y.VIDEO){let n=t.video_item;if(!n?.media?.encrypt_query_param&&!n?.media?.full_url||!n?.media?.aes_key)return null;try{let r=await v({encryptQueryParam:n.media.encrypt_query_param,aesKeyBase64:n.media.aes_key,cdnBaseUrl:s,fullUrl:n.media.full_url});return{path:await O(r,"video/mp4","inbound",i),mimeType:"video/mp4",type:"video"}}catch(r){return S.error({channelId:i},`Video download failed: ${String(r)}`),null}}return null}import Be from"path";import ne from"crypto";import It from"fs/promises";M();var U=_("channels"),G=3;async function Tt(t){let{buf:e,uploadFullUrl:s,uploadParam:i,filekey:n,cdnBaseUrl:r,label:o,aeskey:a}=t,d=Se(e,a),c=s?.trim(),u;if(c)u=c;else if(i)u=Ae({cdnBaseUrl:r,uploadParam:i,filekey:n});else throw new Error(`${o}: CDN upload URL missing (need upload_full_url or upload_param)`);U.debug(`${o}: CDN POST url=${u} ciphertextSize=${d.length}`);let p,l;for(let h=1;h<=G;h++)try{let m=await fetch(u,{method:"POST",headers:{"Content-Type":"application/octet-stream"},body:new Uint8Array(d)});if(m.status>=400&&m.status<500){let b=m.headers.get("x-error-message")??await m.text();throw U.error(`${o}: CDN client error attempt=${h} status=${m.status} errMsg=${b}`),new Error(`CDN upload client error ${m.status}: ${b}`)}if(m.status!==200){let b=m.headers.get("x-error-message")??`status ${m.status}`;throw U.error(`${o}: CDN server error attempt=${h} status=${m.status} errMsg=${b}`),new Error(`CDN upload server error: ${b}`)}if(p=m.headers.get("x-encrypted-param")??void 0,!p)throw U.error(`${o}: CDN response missing x-encrypted-param header attempt=${h}`),new Error("CDN upload response missing x-encrypted-param header");U.debug(`${o}: CDN upload success attempt=${h}`);break}catch(m){if(l=m,m instanceof Error&&m.message.includes("client error"))throw m;h<G?U.warn(`${o}: attempt ${h} failed, retrying... err=${String(m)}`):U.error(`${o}: all ${G} attempts failed err=${String(m)}`)}if(!p)throw l instanceof Error?l:new Error(`CDN upload failed after ${G} attempts`);return{downloadParam:p}}async function se(t){let{filePath:e,toUserId:s,opts:i,cdnBaseUrl:n,mediaType:r,label:o}=t,a=await It.readFile(e),d=a.length,c=ne.createHash("md5").update(a).digest("hex"),u=Ee(d),p=ne.randomBytes(16).toString("hex"),l=ne.randomBytes(16);U.debug(`${o}: file=${e} rawsize=${d} filesize=${u} md5=${c} filekey=${p}`);let h=await _e({...i,filekey:p,media_type:r,to_user_id:s,rawsize:d,rawfilemd5:c,filesize:u,no_need_thumb:!0,aeskey:l.toString("hex")}),m=h.upload_full_url?.trim(),b=h.upload_param;if(!m&&!b)throw new Error(`${o}: getUploadUrl returned no upload URL (need upload_full_url or upload_param)`);let{downloadParam:Je}=await Tt({buf:a,uploadFullUrl:m||void 0,uploadParam:b??void 0,filekey:p,cdnBaseUrl:n,aeskey:l,label:`${o}[orig filekey=${p}]`});return{filekey:p,downloadEncryptedQueryParam:Je,aeskey:l.toString("hex"),fileSize:d,fileSizeCiphertext:u}}async function De(t){return se({...t,mediaType:W.IMAGE,label:"uploadImageToWeixin"})}async function We(t){return se({...t,mediaType:W.VIDEO,label:"uploadVideoToWeixin"})}async function ie(t){return se({...t,mediaType:W.FILE,label:"uploadFileAttachmentToWeixin"})}M();var q=_("channels");function Rt(){return`adam-wechat-${Date.now()}-${Math.random().toString(36).slice(2,7)}`}function Mt(t){let e=t;return e=e.replace(/```[^\n]*\n?([\s\S]*?)```/g,(s,i)=>i.trim()),e=e.replace(/!\[[^\]]*\]\([^)]*\)/g,""),e=e.replace(/\[([^\]]+)\]\([^)]*\)/g,"$1"),e=e.replace(/^\|[\s:|-]+\|$/gm,""),e=e.replace(/^\|(.+)\|$/gm,(s,i)=>i.split("|").map(n=>n.trim()).join(" ")),e}async function re(t){let{to:e,text:s,mediaItem:i,opts:n,label:r}=t,o=[],a=Mt(s);a&&o.push({type:y.TEXT,text_item:{text:a}}),o.push(i);let d="";for(let c of o){d=Rt();let u={msg:{from_user_id:"",to_user_id:e,client_id:d,message_type:A.BOT,message_state:P.FINISH,item_list:[c],context_token:n.contextToken}};await E({baseUrl:n.baseUrl,token:n.token,routeTag:n.routeTag,body:u})}return q.debug(`${r}: sent to=${e} messageId=${d}`),{messageId:d}}async function Ut(t){let{to:e,text:s,uploaded:i,opts:n}=t,r={type:y.IMAGE,image_item:{media:{encrypt_query_param:i.downloadEncryptedQueryParam,aes_key:Buffer.from(i.aeskey).toString("base64"),encrypt_type:1},mid_size:i.fileSizeCiphertext}};return re({to:e,text:s,mediaItem:r,opts:n,label:"sendImageMessage"})}async function kt(t){let{to:e,text:s,uploaded:i,opts:n}=t,r={type:y.VIDEO,video_item:{media:{encrypt_query_param:i.downloadEncryptedQueryParam,aes_key:Buffer.from(i.aeskey).toString("base64"),encrypt_type:1},video_size:i.fileSizeCiphertext}};return re({to:e,text:s,mediaItem:r,opts:n,label:"sendVideoMessage"})}async function je(t){let{to:e,text:s,fileName:i,uploaded:n,opts:r}=t,o={type:y.FILE,file_item:{media:{encrypt_query_param:n.downloadEncryptedQueryParam,aes_key:Buffer.from(n.aeskey).toString("base64"),encrypt_type:1},file_name:i,len:String(n.fileSize)}};return re({to:e,text:s,mediaItem:o,opts:r,label:"sendFileMessage"})}async function Qe(t){let{filePath:e,to:s,text:i,opts:n,cdnBaseUrl:r}=t,o=V(e),a={baseUrl:n.baseUrl,token:n.token,routeTag:n.routeTag};if(o.startsWith("video/")){q.debug(`sendWeixinMediaFile: uploading video filePath=${e} to=${s}`);let u=await We({filePath:e,toUserId:s,opts:a,cdnBaseUrl:r});return kt({to:s,text:i,uploaded:u,opts:n})}if(o.startsWith("image/")){q.debug(`sendWeixinMediaFile: uploading image filePath=${e} to=${s}`);let u=await De({filePath:e,toUserId:s,opts:a,cdnBaseUrl:r});return Ut({to:s,text:i,uploaded:u,opts:n})}if(o.startsWith("audio/")){let u=Be.basename(e);q.debug(`sendWeixinMediaFile: uploading audio as file filePath=${e} name=${u} to=${s}`);let p=await ie({filePath:e,fileName:u,toUserId:s,opts:a,cdnBaseUrl:r});return je({to:s,text:i,fileName:u,uploaded:p,opts:n})}let d=Be.basename(e);q.debug(`sendWeixinMediaFile: uploading file attachment filePath=${e} name=${d} to=${s}`);let c=await ie({filePath:e,fileName:d,toUserId:s,opts:a,cdnBaseUrl:r});return je({to:s,text:i,fileName:d,uploaded:c,opts:n})}M();var f=_("channels"),Ve="https://novac2c.cdn.weixin.qq.com/c2c",de=new Map;function Ke(t){return I.join(H(),".adam","wechat",`${t}.context-tokens.json`)}function St(t){let e=Ke(t);try{let s=T.readFileSync(e,"utf-8"),i=JSON.parse(s);for(let[n,r]of Object.entries(i))typeof r=="string"&&r&&de.set(`${t}:${n}`,r);f.debug({channelId:t,count:Object.keys(i).length},"Restored context tokens from disk")}catch{}}function Ct(t,e,s){let i=Ke(t);try{let n={};try{let o=T.readFileSync(i,"utf-8");n=JSON.parse(o)}catch{}n[e]=s;let r=I.dirname(i);T.mkdirSync(r,{recursive:!0}),T.writeFileSync(i,JSON.stringify(n),"utf-8")}catch(n){f.warn({channelId:t,userId:e},`Failed to persist context token: ${String(n)}`)}}function Et(t,e,s){de.set(`${t}:${e}`,s),Ct(t,e,s)}function oe(t,e){return de.get(`${t}:${e}`)}function He(t){return I.join(H(),".adam","wechat",`${t}.sync`)}function At(t){try{return T.readFileSync(He(t),"utf-8")}catch{return""}}function Pt(t,e){let s=He(t);T.mkdirSync(I.dirname(s),{recursive:!0}),T.writeFileSync(s,e,"utf-8")}var ae=1440*60*1e3,ze=10,vt=20,Ge=1440*60*1e3,Ot=1320*60*1e3,qt=1,Nt=7200*1e3;function Xe(t){return I.join(H(),".adam","wechat",`${t}.session.json`)}function $t(t){let e=new Map,s=Xe(t);try{let i=T.readFileSync(s,"utf-8"),n=JSON.parse(i);for(let[r,o]of Object.entries(n))o&&typeof o.lastUserMessageAt=="number"&&e.set(r,o);f.debug({channelId:t,count:e.size},"Restored sessions from disk")}catch{}return e}function N(t,e){let s=Xe(t);try{let i={};for(let[r,o]of e)i[r]=o;let n=I.dirname(s);T.mkdirSync(n,{recursive:!0}),T.writeFileSync(s,JSON.stringify(i),"utf-8")}catch(i){f.warn({channelId:t},`Failed to persist sessions: ${String(i)}`)}}var Ft=0;function $(){return`adam-wechat-${Date.now()}-${++Ft}`}var K=class{platform="wechat";id;config;status="disconnected";messageHandler=null;pollAbort=null;getUpdatesBuf="";sessions=new Map;pendingQueue=new Map;lastReminderAt=new Map;constructor(e,s){if(this.id=e,!s.baseUrl)throw new Error("WeChat adapter requires baseUrl");this.config=s}async connect(){if(!this.config.botToken)throw new Error("WeChat adapter requires botToken. Complete QR login first.");this.status="connecting",this.getUpdatesBuf=At(this.id),St(this.id),this.sessions=$t(this.id),this.pollAbort=new AbortController,this.status="connected",f.info({channelId:this.id},"WeChat adapter connected, starting long-poll"),this.startLongPoll()}async disconnect(){this.pollAbort&&(this.pollAbort.abort(),this.pollAbort=null),this.status="disconnected",f.info({channelId:this.id},"WeChat adapter disconnected")}getStatus(){if(this.status==="connected"&&j(this.id))return"error";if(this.status==="connected"){for(let[,e]of this.sessions)if(this.isSessionActive(e)&&e.quotaRemaining<=0)return"degraded"}return this.status}async sendMessage(e,s){if(j(this.id)){let c=Math.ceil(Ue(this.id)/6e4);throw new Error(`WeChat session paused, ${c} min remaining. Re-scan QR to reconnect.`)}let i=this.getOrCreateSession(e),r=this.getSessionRemainingMs(i)/36e5;if(!this.isSessionActive(i))return f.warn({channelId:this.id,chatId:e.slice(0,12),lastUserMessageAt:i.lastUserMessageAt,sessionExpired:!0},"iLink session expired (>24h), message queued"),this.enqueueMessage(e,s),`queued-${$()}`;if(i.quotaRemaining<=0)return f.warn({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:0,remainingHours:r.toFixed(1)},"iLink quota exhausted, message queued"),this.enqueueMessage(e,s),`queued-${$()}`;let o=$(),a=oe(this.id,e),d=this.config.cdnBaseUrl??Ve;try{if(s.mediaUrl){let c=!s.mediaUrl.includes("://")||s.mediaUrl.startsWith("file://"),u=I.join(H(),".adam","wechat","media","outbound-tmp");await R.mkdir(u,{recursive:!0});let p=this.getExtensionFromMediaType(s.mediaType),l;if(c){let m=s.mediaUrl.startsWith("file://")?new URL(s.mediaUrl).pathname:I.isAbsolute(s.mediaUrl)?s.mediaUrl:I.resolve(s.mediaUrl),b=await R.readFile(m);l=I.join(u,`${Date.now()}-${Math.random().toString(36).slice(2,7)}${p}`),await R.writeFile(l,b)}else{let m=await fetch(s.mediaUrl);if(!m.ok)throw new Error(`Failed to fetch media: ${m.status}`);let b=Buffer.from(await m.arrayBuffer());l=I.join(u,`${Date.now()}-${Math.random().toString(36).slice(2,7)}${p}`),await R.writeFile(l,b)}let h=await Qe({filePath:l,to:e,text:s.content??"",opts:{baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,contextToken:a},cdnBaseUrl:d});return await R.unlink(l).catch(()=>{}),i.quotaRemaining--,N(this.id,this.sessions),f.info({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:i.quotaRemaining,sessionRemainingHours:(this.getSessionRemainingMs(i)/36e5).toFixed(1)},"iLink send success: quota decremented"),this.checkAndSendReminder(e,i).catch(m=>{f.warn({channelId:this.id,chatId:e.slice(0,12)},`Reminder send failed: ${String(m)}`)}),h.messageId}return await E({baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,body:{msg:{from_user_id:"",to_user_id:e,client_id:o,message_type:A.BOT,message_state:P.FINISH,item_list:s.content?[{type:y.TEXT,text_item:{text:s.content}}]:void 0,context_token:a}}}),i.quotaRemaining--,N(this.id,this.sessions),f.info({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:i.quotaRemaining,sessionRemainingHours:(this.getSessionRemainingMs(i)/36e5).toFixed(1)},"iLink send success: quota decremented"),this.checkAndSendReminder(e,i).catch(c=>{f.warn({channelId:this.id,chatId:e.slice(0,12)},`Reminder send failed: ${String(c)}`)}),o}catch(c){if(c instanceof Error&&c.message.includes("ret=-2"))return i.quotaRemaining=0,N(this.id,this.sessions),f.warn({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:0},"iLink quota exhausted (ret=-2 confirmed), message queued"),this.enqueueMessage(e,s),`queued-${$()}`;throw c}}onMessage(e){this.messageHandler=e}async sendTypingIndicator(e){if(j(this.id))return;let s=oe(this.id,e);try{await ye({baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,body:{ilink_user_id:e,status:Re.TYPING}})}catch{}}updateConfig(e){Object.assign(this.config,e)}getOrCreateSession(e){let s=this.sessions.get(e);return s||(s={lastUserMessageAt:0,quotaRemaining:0},this.sessions.set(e,s)),s}isSessionActive(e){return e.lastUserMessageAt>0&&Date.now()-e.lastUserMessageAt<=ae}getSessionRemainingMs(e){return e.lastUserMessageAt===0?0:Math.max(0,ae-(Date.now()-e.lastUserMessageAt))}enqueueMessage(e,s){let i=this.pendingQueue.get(e);i||(i=[],this.pendingQueue.set(e,i));let n=Date.now();i=i.filter(r=>n-r.queuedAt<Ge),i.length>=vt&&(i.shift(),f.warn({channelId:this.id,chatId:e.slice(0,12)},"Queue full, dropping oldest message")),i.push({message:s,queuedAt:n}),this.pendingQueue.set(e,i),f.info({channelId:this.id,chatId:e.slice(0,12),queueDepth:i.length},"Message enqueued")}async flushQueue(e){let s=this.pendingQueue.get(e);if(!s||s.length===0)return;let i=this.getOrCreateSession(e),n=Math.min(s.length,Math.max(0,i.quotaRemaining-2));if(n<=0){f.info({channelId:this.id,chatId:e.slice(0,12),quotaRemaining:i.quotaRemaining},"Queue flush skipped: insufficient quota (reserving 2 for conversation)");return}f.info({channelId:this.id,chatId:e.slice(0,12),queueDepth:s.length,sending:n,quotaRemaining:i.quotaRemaining},"Flushing queued messages");let r=0;for(;r<n&&s.length>0;){let o=s[0];if(Date.now()-o.queuedAt>Ge){s.shift();continue}try{if(await this.sendMessage(e,o.message),s.shift(),r++,i.quotaRemaining<=0)break}catch{f.warn({channelId:this.id,chatId:e.slice(0,12)},"Queue flush: send failed, stopping");break}}s.length===0&&this.pendingQueue.delete(e),f.info({channelId:this.id,chatId:e.slice(0,12),sent:r,remaining:s.length},"Queue flush complete")}async checkAndSendReminder(e,s){let i=Date.now(),n=this.lastReminderAt.get(e)??0;if(i-n<Nt)return;let r=this.getSessionRemainingMs(s),a=i-s.lastUserMessageAt>=Ot,d=s.quotaRemaining<=qt;if(!a&&!d)return;let c=(r/36e5).toFixed(1),u;a&&d?u=`[\u7CFB\u7EDF\u63D0\u9192] \u6D88\u606F\u7A97\u53E3\u5373\u5C06\u5173\u95ED\uFF08\u5269\u4F59${c}\u5C0F\u65F6/${s.quotaRemaining}\u6761\u914D\u989D\uFF09\u3002\u8BF7\u56DE\u590D\u4EFB\u610F\u6D88\u606F\u4EE5\u4FDD\u6301\u8FDE\u63A5\u3002`:a?u=`[\u7CFB\u7EDF\u63D0\u9192] \u6D88\u606F\u7A97\u53E3\u5373\u5C06\u5173\u95ED\uFF08\u5269\u4F59${c}\u5C0F\u65F6\uFF09\u3002\u8BF7\u56DE\u590D\u4EFB\u610F\u6D88\u606F\u4EE5\u4FDD\u6301\u8FDE\u63A5\u3002`:u=`[\u7CFB\u7EDF\u63D0\u9192] \u6D88\u606F\u914D\u989D\u5373\u5C06\u7528\u5B8C\uFF08\u5269\u4F59${s.quotaRemaining}\u6761\uFF09\u3002\u8BF7\u56DE\u590D\u4EFB\u610F\u6D88\u606F\u4EE5\u91CD\u7F6E\u914D\u989D\u3002`;let p=oe(this.id,e);try{await E({baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,body:{msg:{from_user_id:"",to_user_id:e,client_id:$(),message_type:A.BOT,message_state:P.FINISH,item_list:[{type:y.TEXT,text_item:{text:u}}],context_token:p}}}),s.quotaRemaining--,this.lastReminderAt.set(e,i),N(this.id,this.sessions),f.info({channelId:this.id,chatId:e.slice(0,12),remainingHours:c,quotaRemaining:s.quotaRemaining,trigger:a?"time":"quota"},"iLink session reminder sent")}catch(l){f.warn({channelId:this.id,chatId:e.slice(0,12)},`Reminder send failed: ${String(l)}`)}}async startLongPoll(){let e=this.pollAbort?.signal,s=0,i=3,n=3e4,r=2e3;for(;!e?.aborted;)try{let o=await he({baseUrl:this.config.baseUrl,token:this.config.botToken,routeTag:this.config.routeTag,get_updates_buf:this.getUpdatesBuf});if(o.ret===ee||o.errcode===ee){Me(this.id),this.status="error",f.error({channelId:this.id},"Session expired (errcode=-14), pausing for 1 hour"),await this.sleep(B,e),ke(this.id),this.status="connected";continue}if(o.ret!==void 0&&o.ret!==0||o.errcode!==void 0&&o.errcode!==0){s++,f.error({channelId:this.id,ret:o.ret,errcode:o.errcode},"getUpdates API error"),s>=i?(s=0,await this.sleep(n,e)):await this.sleep(r,e);continue}s=0,o.get_updates_buf&&(this.getUpdatesBuf=o.get_updates_buf,Pt(this.id,o.get_updates_buf));for(let d of o.msgs??[])await this.processInbound(d)}catch(o){if(e?.aborted)return;s++,f.error({channelId:this.id,error:o},"getUpdates error"),s>=i?(s=0,await this.sleep(n,e)):await this.sleep(r,e)}}async processInbound(e){if(!this.messageHandler)return;let s=!!e.group_id,i=s?e.group_id:e.from_user_id??"",n=e.from_user_id??"";e.context_token&&i&&Et(this.id,i,e.context_token);let r=this.getOrCreateSession(i),o=r.quotaRemaining;r.lastUserMessageAt=Date.now(),r.quotaRemaining=ze,N(this.id,this.sessions),f.info({channelId:this.id,chatId:i.slice(0,12),quotaReset:!0,prevQuota:o,newQuota:ze,sessionWindowMs:ae},"iLink session reset: user message received, quota restored"),this.flushQueue(i);let a="",d,c=[];for(let l of e.item_list??[])l.type===y.TEXT&&l.text_item?.text&&(a+=l.text_item.text),l.type===y.IMAGE&&(d="image",c.push(l)),l.type===y.VOICE&&(d="audio",c.push(l),l.voice_item?.text&&!a&&(a=l.voice_item.text)),l.type===y.FILE&&(d="file",c.push(l)),l.type===y.VIDEO&&(d="video",c.push(l));if(!a&&!d)return;let u;if(c.length>0){let l=this.config.cdnBaseUrl??Ve;try{let h=await Le(c[0],{cdnBaseUrl:l,channelId:this.id});h&&(u=h.path,d=h.type)}catch(h){f.error({channelId:this.id},`Media download failed: ${String(h)}`)}}let p={channelId:this.id,platform:"wechat",chatId:i,senderId:n,content:a,mediaType:d,mediaPath:u,isGroup:s,timestamp:e.create_time_ms??Date.now(),raw:e};this.messageHandler(p)}getExtensionFromMediaType(e){switch(e){case"image":return".png";case"video":return".mp4";case"audio":return".mp3";default:return".bin"}}sleep(e,s){return new Promise((i,n)=>{let r=setTimeout(i,e);s?.addEventListener("abort",()=>{clearTimeout(r),n(new Error("aborted"))},{once:!0})})}};M();var Lt=_("channels"),X=class{platform="discord";id;config;status="disconnected";messageHandler=null;client=null;constructor(e,s){if(this.id=e,!s.botToken)throw new Error("Discord adapter requires botToken");this.config=s}async connect(){this.status="connecting";try{let{Client:e,GatewayIntentBits:s}=await import("discord.js");this.client=new e({intents:[s.Guilds,s.GuildMessages,s.MessageContent,s.DirectMessages]});let i=this.client;i.on("messageCreate",n=>{if(!this.messageHandler||n.author.bot||this.config.allowedGuildIds?.length&&n.guildId&&!this.config.allowedGuildIds.includes(n.guildId))return;let r={channelId:this.id,platform:"discord",chatId:n.channelId,senderId:n.author.id,senderName:n.author.displayName??n.author.username,content:n.content,isGroup:!!n.guildId,timestamp:n.createdTimestamp,raw:n};this.messageHandler(r)}),await i.login(this.config.botToken),this.status="connected",Lt.info({channelId:this.id},"Discord bot connected")}catch(e){throw this.status="error",e}}async disconnect(){this.client&&await this.client.destroy(),this.client=null,this.status="disconnected"}getStatus(){return this.status}async sendMessage(e,s){if(!this.client)throw new Error("Discord client not connected");let n=await this.client.channels.fetch(e);if(!n||!("send"in n))throw new Error(`Channel ${e} not found or not text channel`);return(await n.send({content:s.content,reply:s.replyToMessageId?{messageReference:s.replyToMessageId}:void 0})).id}onMessage(e){this.messageHandler=e}async sendTypingIndicator(e){if(!this.client)return;let i=await this.client.channels.fetch(e);i&&"sendTyping"in i&&await i.sendTyping()}};var k=g.object({id:g.string().uuid()}),Wt=g.object({name:g.string().min(1,"name is required"),platform:g.string().min(1,"platform is required"),config:g.record(g.string(),g.unknown()),enabled:g.boolean().optional().default(!0),linkedRoleId:g.string().optional(),allowedChatIds:g.array(g.string()).optional()}),Bt=g.object({name:g.string().min(1).optional(),enabled:g.boolean().optional(),config:g.record(g.string(),g.unknown()).optional(),linkedRoleId:g.string().optional(),allowedChatIds:g.array(g.string()).optional()}),ce;function Zn(t){ce=t}function es(){return ce}async function ts(t){let e=ce;t.get("/channels",{schema:{tags:["Channels"],summary:"List channels",querystring:{type:"object",properties:{enabled:{type:"boolean"}}}}},async(s,i)=>({channels:ge(s.query.enabled)})),t.post("/channels",{schema:{tags:["Channels"],summary:"Create a channel",body:{type:"object",required:["name","platform","config"],properties:{name:{type:"string",minLength:1},platform:{type:"string",minLength:1},config:{type:"object"},enabled:{type:"boolean"},linkedRoleId:{type:"string"},allowedChatIds:{type:"array",items:{type:"string"}}}}}},async(s,i)=>{let n=Wt.safeParse(s.body);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let{name:r,platform:o,config:a,enabled:d,linkedRoleId:c,allowedChatIds:u}=n.data,p={id:Dt(),name:r,platform:o,enabled:d,status:"disconnected",config:a,linkedRoleId:c,allowedChatIds:u,createdAt:Date.now(),messageCount:0};return le(p),i.status(201).send({channel:p})}),t.get("/channels/:id",{schema:{tags:["Channels"],summary:"Get channel by ID",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);return r?{channel:r}:i.status(404).send({code:"NOT_FOUND",message:"Channel not found"})}),t.patch("/channels/:id",{schema:{tags:["Channels"],summary:"Update channel",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",properties:{name:{type:"string"},enabled:{type:"boolean"},config:{type:"object"},linkedRoleId:{type:"string"},allowedChatIds:{type:"array",items:{type:"string"}}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});let o=Bt.safeParse(s.body);return o.success?(J(r.id,o.data),{channel:x(r.id)}):i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(o.error)})}),t.delete("/channels/:id",{schema:{tags:["Channels"],summary:"Delete channel",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);return r?(me(r.id),i.status(204).send()):i.status(404).send({code:"NOT_FOUND",message:"Channel not found"})}),t.post("/channels/:id/connect",{schema:{tags:["Channels"],summary:"Connect channel",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});if(!e)return i.status(501).send({code:"NOT_IMPLEMENTED",message:"Channel manager not initialized"});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});if(!e.hasAdapter(r.id)&&r.platform==="discord"){let o=r.config;if(!o.botToken)return i.status(400).send({code:"MISSING_CONFIG",message:"Discord channel requires botToken in config"});let a=new X(r.id,{botToken:o.botToken});await e.addChannel(r,a)}if(!e.hasAdapter(r.id))return i.status(400).send({code:"NO_ADAPTER",message:"No adapter registered for this channel. Install the appropriate adapter first."});try{return await e.connectChannel(r.id),{channelId:r.id,status:"connected"}}catch(o){return i.status(500).send({code:"CONNECT_FAILED",message:String(o)})}}),t.post("/channels/:id/disconnect",{schema:{tags:["Channels"],summary:"Disconnect channel",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});if(!e)return i.status(501).send({code:"NOT_IMPLEMENTED",message:"Channel manager not initialized"});let r=x(n.data.id);return r?(await e.disconnectChannel(r.id),{channelId:r.id,status:"disconnected"}):i.status(404).send({code:"NOT_FOUND",message:"Channel not found"})}),t.get("/channels/:id/messages",{schema:{tags:["Channels"],summary:"Get channel message history",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(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});let{limit:o=50,offset:a=0}=s.query;return{messages:ue(r.id,o,a)}}),t.post("/channels/:id/wechat/qr-start",{schema:{tags:["WeChat"],summary:"Start WeChat QR login",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});if(r.platform!=="wechat")return i.status(400).send({code:"INVALID_PLATFORM",message:"Channel is not a WeChat channel"});let o=r.config;return await Ie({apiBaseUrl:o.baseUrl,routeTag:o.routeTag})}),t.post("/channels/:id/wechat/qr-wait",{schema:{tags:["WeChat"],summary:"Wait for WeChat QR scan",params:{type:"object",required:["id"],properties:{id:{type:"string",format:"uuid"}}},body:{type:"object",properties:{sessionKey:{type:"string"},timeoutMs:{type:"number"}}}}},async(s,i)=>{let n=k.safeParse(s.params);if(!n.success)return i.status(400).send({code:"VALIDATION_ERROR",message:g.prettifyError(n.error)});let r=x(n.data.id);if(!r)return i.status(404).send({code:"NOT_FOUND",message:"Channel not found"});if(r.platform!=="wechat")return i.status(400).send({code:"INVALID_PLATFORM",message:"Channel is not a WeChat channel"});let o=r.config,{sessionKey:a,timeoutMs:d}=s.body??{},c=await Te({sessionKey:a??"",apiBaseUrl:o.baseUrl,timeoutMs:d??12e4,routeTag:o.routeTag});if(c.connected&&c.botToken){let u={...o,botToken:c.botToken,accountId:c.accountId,baseUrl:c.baseUrl??o.baseUrl,userId:c.userId};if(J(r.id,{config:u}),e){let p=new K(r.id,u),l=x(r.id);l&&await e.addChannel(l,p)}}return{connected:c.connected,accountId:c.accountId,message:c.message}})}export{K as a,X as b,Zn as c,es as d,ts as e};