adam-agent-server 1.6.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/App-ZRCRM7WR.js +13 -0
  2. package/dist/{adam-automator-skills-UFW5TXCC.js → adam-automator-skills-EZGBICHT.js} +1 -1
  3. package/dist/adam-tools-V5LPU47X.js +1 -0
  4. package/dist/{approval-handler-HQO62WK2.js → approval-handler-PB7PSLUS.js} +1 -1
  5. package/dist/audit-manager-BSBBDUER.js +1 -0
  6. package/dist/bree-engine-7S33CWS7.js +1 -0
  7. package/dist/channels-SITUUC4J.js +1 -0
  8. package/dist/{channels-J4STJ4X2.js → channels-ULFUCUUZ.js} +1 -1
  9. package/dist/{chunk-7446ZS6D.js → chunk-2L2347UQ.js} +1 -1
  10. package/dist/{chunk-FXQAUQTI.js → chunk-2YTDCR6A.js} +1 -1
  11. package/dist/chunk-4PQHGLZH.js +99 -0
  12. package/dist/{chunk-NCFVJCNQ.js → chunk-5EPG2US5.js} +2 -2
  13. package/dist/{chunk-2H7UOW4P.js → chunk-5QZXYKMS.js} +1 -1
  14. package/dist/chunk-5XOTPEAK.js +6 -0
  15. package/dist/{chunk-MDBVKBC7.js → chunk-6KF7OO2B.js} +1 -1
  16. package/dist/{chunk-TSPQ44HT.js → chunk-A5OCDYTW.js} +1 -1
  17. package/dist/{chunk-DWRYIN5N.js → chunk-AQ3ASS4B.js} +1 -1
  18. package/dist/{chunk-GMMWA5EG.js → chunk-B6LOT5CG.js} +1 -1
  19. package/dist/{chunk-MJSSCKMB.js → chunk-BCH2HAIM.js} +2 -2
  20. package/dist/{chunk-4C5ITATX.js → chunk-BQ3ZAYHC.js} +1 -1
  21. package/dist/{chunk-YHVYX3F4.js → chunk-DVN3BFPP.js} +1 -1
  22. package/dist/{chunk-P5ZXNBNV.js → chunk-EQZFOBAJ.js} +1 -1
  23. package/dist/{chunk-G5ESQEXN.js → chunk-FPZEZYUB.js} +1 -1
  24. package/dist/{chunk-YXYIA24D.js → chunk-GSFLLRS7.js} +1 -1
  25. package/dist/{chunk-7ZGSJCX5.js → chunk-HQRUJQN7.js} +1 -1
  26. package/dist/{chunk-52PR7XTN.js → chunk-IKPYPZ64.js} +1 -1
  27. package/dist/{chunk-FZCNYKNT.js → chunk-JJH2RCVC.js} +1 -1
  28. package/dist/chunk-K4C43YDD.js +7 -0
  29. package/dist/{chunk-V32YF3J5.js → chunk-M4YI4WVX.js} +1 -1
  30. package/dist/{chunk-WAG3MNMC.js → chunk-NASJH4NT.js} +1 -1
  31. package/dist/{chunk-TNL2LZB7.js → chunk-NUITL62I.js} +1 -1
  32. package/dist/{chunk-3LY6PD6A.js → chunk-NWMOV23A.js} +1 -1
  33. package/dist/chunk-PHT24MOV.js +1 -0
  34. package/dist/{chunk-ZL5JXLAX.js → chunk-QGYDGZSC.js} +1 -1
  35. package/dist/{chunk-VVSZZK5T.js → chunk-RI3V72RP.js} +2 -2
  36. package/dist/{chunk-RLJYEEQC.js → chunk-RZ7LCZVK.js} +1 -1
  37. package/dist/{chunk-5OQZPUBV.js → chunk-TAF2DBBC.js} +8 -8
  38. package/dist/{chunk-HWLSHTVX.js → chunk-ULTK7RD6.js} +3 -3
  39. package/dist/{chunk-DBP7GPWG.js → chunk-WMB7P64J.js} +1 -1
  40. package/dist/cli.js +2 -2
  41. package/dist/{config-KFPS7IEH.js → config-HBQPBIWL.js} +1 -1
  42. package/dist/{db-PZ2V7UCK.js → db-QEWTZGU3.js} +1 -1
  43. package/dist/{delivery-log-ACNJ66RD.js → delivery-log-AC476GX7.js} +1 -1
  44. package/dist/engine-6K4RG644.js +1 -0
  45. package/dist/{evolution-audit-OQDGPKYI.js → evolution-audit-XMBDUN3T.js} +1 -1
  46. package/dist/index.js +13 -10
  47. package/dist/{learner-QCD6BH2J.js → learner-VCS3Q7BR.js} +1 -1
  48. package/dist/{memories-QGMRSBJJ.js → memories-VMOGFVPU.js} +1 -1
  49. package/dist/{memory-extractor-3MRK43A2.js → memory-extractor-4WJNHYWR.js} +2 -2
  50. package/dist/memory-service-ZS6MBUIC.js +1 -0
  51. package/dist/outbound-gateway-H7RFG6D2.js +1 -0
  52. package/dist/role-presets-XAEOYEAW.js +1 -0
  53. package/dist/role-workspace-NKGAH6J6.js +1 -0
  54. package/dist/{roles-KYXNMO5H.js → roles-ZYCFQMAY.js} +1 -1
  55. package/dist/{session-manager-LZ77OT7A.js → session-manager-COLCNIB7.js} +1 -1
  56. package/dist/task-templates-4KCZOUN5.js +1 -0
  57. package/dist/workflow-executor-Z7JFMR56.js +1 -0
  58. package/package.json +25 -25
  59. package/web/dist/assets/{ChannelDetail-DHT8fW0C.js → ChannelDetail-DnL0_h8q.js} +1 -1
  60. package/web/dist/assets/{Channels-YHGNXcRu.js → Channels-dod8Q4oq.js} +1 -1
  61. package/web/dist/assets/{Dashboard-DsHC5W4C.js → Dashboard-Dl0vA6Ky.js} +1 -1
  62. package/web/dist/assets/{EnvVarEditor-Dxy1Kz1Z.js → EnvVarEditor-C-gErAzC.js} +1 -1
  63. package/web/dist/assets/{EventDefDetail-CwprP2ch.js → EventDefDetail-BhJZGNlX.js} +1 -1
  64. package/web/dist/assets/{Events-B19a8cEG.js → Events-DnNZ9-BN.js} +1 -1
  65. package/web/dist/assets/{Evolution-DT6iZvil.js → Evolution-BBWmrrnr.js} +1 -1
  66. package/web/dist/assets/{GoalDetail-BALsnPQl.js → GoalDetail-uqWQCOj3.js} +1 -1
  67. package/web/dist/assets/{Goals-BJIsKgfH.js → Goals-CylKmR9j.js} +1 -1
  68. package/web/dist/assets/{Logs-Cv15aV3l.js → Logs-6rf0KT0z.js} +1 -1
  69. package/web/dist/assets/{Memories-CKAXhAso.js → Memories-CrBTujU7.js} +1 -1
  70. package/web/dist/assets/{Plugins-NO0S2spH.js → Plugins-VKUSUcSE.js} +1 -1
  71. package/web/dist/assets/{RoleDetail-1FNyCD4u.js → RoleDetail-DJc4CWFN.js} +1 -1
  72. package/web/dist/assets/{Roles-grfjw2zy.js → Roles-6pmjn04G.js} +1 -1
  73. package/web/dist/assets/{Settings-9LRLfa_4.js → Settings-DW1jmrNj.js} +1 -1
  74. package/web/dist/assets/{Strategies-BMyd_7_5.js → Strategies-Bmke6qZo.js} +1 -1
  75. package/web/dist/assets/{Switch-CULsD-kC.js → Switch-CfTpXW9_.js} +1 -1
  76. package/web/dist/assets/{TaskDetail-C2yXy8gE.js → TaskDetail-CwJ_UKgt.js} +1 -1
  77. package/web/dist/assets/Work-DVdWNBEm.js +1 -0
  78. package/web/dist/assets/{index-qYKJGoIB.js → index-DYsO5Awn.js} +2 -2
  79. package/web/dist/index.html +1 -1
  80. package/dist/App-WJMHK5EO.js +0 -13
  81. package/dist/adam-tools-IAZSLWYB.js +0 -1
  82. package/dist/audit-manager-LC5EQXCI.js +0 -1
  83. package/dist/bree-engine-M5CZ6A62.js +0 -1
  84. package/dist/channels-5TFYQN5Z.js +0 -1
  85. package/dist/chunk-FIN36WAP.js +0 -99
  86. package/dist/chunk-GGIHDFRW.js +0 -6
  87. package/dist/chunk-I7ZZKPHE.js +0 -7
  88. package/dist/chunk-YDVTWPNA.js +0 -1
  89. package/dist/engine-5DHYHDAP.js +0 -1
  90. package/dist/memory-service-M5ADGITG.js +0 -1
  91. package/dist/outbound-gateway-QRL36F7K.js +0 -1
  92. package/dist/role-presets-DLO3XS54.js +0 -1
  93. package/dist/role-workspace-URSOBCDH.js +0 -1
  94. package/dist/task-templates-YPNWJOVV.js +0 -1
  95. package/dist/workflow-executor-3WMS2WV3.js +0 -1
  96. package/web/dist/assets/Work-dftf35Me.js +0 -1
@@ -1,4 +1,4 @@
1
- import{a as oe}from"./chunk-IZNEOYRP.js";import{k as F}from"./chunk-3LY6PD6A.js";import{b as ee}from"./chunk-7446ZS6D.js";import{a as Z,b as h}from"./chunk-I7ZZKPHE.js";import{e as N,f as D,j as Ae}from"./chunk-DBP7GPWG.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-7ZGSJCX5.js";import{b as u,d as v}from"./chunk-NCFVJCNQ.js";import{a as z,h as Le}from"./chunk-WBAPIPST.js";import{c as k,h as X}from"./chunk-MRTJFYPR.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(`
1
+ import{a as oe}from"./chunk-IZNEOYRP.js";import{k as F}from"./chunk-NWMOV23A.js";import{b as ee}from"./chunk-2L2347UQ.js";import{a as Z,b as h}from"./chunk-K4C43YDD.js";import{e as N,f as D,j as Ae}from"./chunk-WMB7P64J.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-HQRUJQN7.js";import{b as u,d as v}from"./chunk-5EPG2US5.js";import{a as z,h as Le}from"./chunk-WBAPIPST.js";import{c as k,h as X}from"./chunk-MRTJFYPR.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
2
  INSERT INTO strategies (id, role_id, task_type, name, prompt_template,
3
3
  alpha, beta, total_trials, avg_reward, created_at, updated_at)
4
4
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -1,4 +1,4 @@
1
- import{b as o,d as u}from"./chunk-NCFVJCNQ.js";u();import{v4 as a}from"uuid";function R(t){o().prepare(`
1
+ import{b as o,d as u}from"./chunk-5EPG2US5.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(`
@@ -1,4 +1,4 @@
1
- import{a as B}from"./chunk-52PR7XTN.js";import{a as C}from"./chunk-SWP2JC54.js";import{a as L,b as k,c as T,j as $}from"./chunk-YHVYX3F4.js";import{d as I,h as P,i as de}from"./chunk-7ZGSJCX5.js";import{b as _,d as se}from"./chunk-NCFVJCNQ.js";import{c as D,h as ie}from"./chunk-MRTJFYPR.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(`
1
+ import{a as B}from"./chunk-IKPYPZ64.js";import{a as C}from"./chunk-SWP2JC54.js";import{a as L,b as k,c as T,j as $}from"./chunk-DVN3BFPP.js";import{d as I,h as P,i as de}from"./chunk-HQRUJQN7.js";import{b as _,d as se}from"./chunk-5EPG2US5.js";import{c as D,h as ie}from"./chunk-MRTJFYPR.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
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
3
  `):""}function X(t){let e=P(t);return e?.length?[we(V(e,"automation")),Re(V(e,"accessibility"))].filter(Boolean).join(`
4
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=[`
@@ -1,4 +1,4 @@
1
- import{b as n,d as o}from"./chunk-NCFVJCNQ.js";o();function a(e){return{id:e.id,sessionId:e.session_id,role:e.role,content:e.content,source:{type:e.source_type},taskId:e.task_id??void 0,channelMessageId:e.channel_message_id??void 0,metadata:e.metadata?JSON.parse(e.metadata):void 0,createdAt:e.created_at}}function c(e){n().prepare(`
1
+ import{b as n,d as o}from"./chunk-5EPG2US5.js";o();function a(e){return{id:e.id,sessionId:e.session_id,role:e.role,content:e.content,source:{type:e.source_type},taskId:e.task_id??void 0,channelMessageId:e.channel_message_id??void 0,metadata:e.metadata?JSON.parse(e.metadata):void 0,createdAt:e.created_at}}function c(e){n().prepare(`
2
2
  INSERT INTO chat_messages (id, session_id, role, content, source_type, task_id,
3
3
  channel_message_id, metadata, created_at)
4
4
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -1,4 +1,4 @@
1
- import{f as d,j as v}from"./chunk-DBP7GPWG.js";import{k as c,l as f,m as h,o as R,r as w}from"./chunk-7ZGSJCX5.js";import{c as p,h as y}from"./chunk-MRTJFYPR.js";w();v();y();import{v4 as i}from"uuid";var n=p("store"),u="role-chat-manager",m=[{name:"Engineer",cagPrompt:`Role: General-purpose software engineer.
1
+ import{f as d,j as v}from"./chunk-WMB7P64J.js";import{k as c,l as f,m as h,o as R,r as w}from"./chunk-HQRUJQN7.js";import{c as p,h as y}from"./chunk-MRTJFYPR.js";w();v();y();import{v4 as i}from"uuid";var n=p("store"),u="role-chat-manager",m=[{name:"Engineer",cagPrompt:`Role: General-purpose software engineer.
2
2
  Capabilities: Read, write, and edit code; run shell commands; search codebases.
3
3
  Approach: Analyze requirements \u2192 implement \u2192 test \u2192 verify. Write tests for new code. Follow existing code patterns.
4
4
  Best for: Feature implementation, bug fixes, refactoring, build/deploy scripts.
@@ -20,4 +20,4 @@ and routing tasks to the appropriate roles. You have broad memory access across
20
20
  Capabilities: Run preset Skills under .claude/skills/. Read/write files in the assigned workspace.
21
21
  Approach: When given an event and Skill name, invoke that Skill with the provided inputs. Do not interpret, do not deviate from the instruction, do not chain additional Skills unless told.
22
22
  Best for: Event-triggered deterministic logic (feature aggregation, threshold checks, artifact persistence, routing classification, event chaining).
23
- Constraints: Minimize LLM reasoning \u2014 call the specified Skill and return its output. If the instruction is ambiguous, return an error message instead of guessing.`,allowedTools:["Skill","Read","Write","Edit","Bash","Grep","Glob"],evaluationCriteria:{determinism:5,skill_invocation_rate:5},executionMode:"isolated",model:"claude-haiku-4-5-20251001"};function x(){let t=h(a.name);if(t)return t;let o=`role-${i().slice(0,8)}`,r=i(),s=Date.now(),e={id:o,name:a.name,cagPrompt:a.cagPrompt,learnedRules:[],memoryStreamId:r,status:"active",preferences:{},createdAt:s,allowedTools:a.allowedTools,evaluationCriteria:a.evaluationCriteria,executionMode:a.executionMode,model:a.model};return c(e),d(e),A(e.id).catch(l=>{n.warn({roleId:o,err:l},"Failed to seed adam-automator Skills")}),n.info({roleId:o,name:a.name},"Created adam-automator Role"),e}async function A(t){try{let{seedAdamAutomatorSkills:o}=await import("./adam-automator-skills-UFW5TXCC.js");await o(t)}catch{}}export{u as a,C as b,D as c,E as d,x as e};
23
+ Constraints: Minimize LLM reasoning \u2014 call the specified Skill and return its output. If the instruction is ambiguous, return an error message instead of guessing.`,allowedTools:["Skill","Read","Write","Edit","Bash","Grep","Glob"],evaluationCriteria:{determinism:5,skill_invocation_rate:5},executionMode:"isolated",model:"claude-haiku-4-5-20251001"};function x(){let t=h(a.name);if(t)return t;let o=`role-${i().slice(0,8)}`,r=i(),s=Date.now(),e={id:o,name:a.name,cagPrompt:a.cagPrompt,learnedRules:[],memoryStreamId:r,status:"active",preferences:{},createdAt:s,allowedTools:a.allowedTools,evaluationCriteria:a.evaluationCriteria,executionMode:a.executionMode,model:a.model};return c(e),d(e),A(e.id).catch(l=>{n.warn({roleId:o,err:l},"Failed to seed adam-automator Skills")}),n.info({roleId:o,name:a.name},"Created adam-automator Role"),e}async function A(t){try{let{seedAdamAutomatorSkills:o}=await import("./adam-automator-skills-EZGBICHT.js");await o(t)}catch{}}export{u as a,C as b,D as c,E as d,x as e};
@@ -1,4 +1,4 @@
1
- import{b as f}from"./chunk-VVSZZK5T.js";import{b as m}from"./chunk-YXYIA24D.js";import{c as h,h as v}from"./chunk-MRTJFYPR.js";v();var p=h("channels"),u=new Map,I=3e5,A=new Set(["telegram"]);function w(i){let e=i.trim().toLowerCase().match(/^(yes|y|是|允许|no|n|否|拒绝)\s+(\S+)$/);if(!e)return null;let[,c,l]=e,o=["yes","y","\u662F","\u5141\u8BB8"].includes(c);return{requestId:l,decision:o?"allow":"deny"}}function $(i){let n=m(i);return n?A.has(n.platform):!1}var T={low:"\u{1F7E2}",medium:"\u{1F7E1}",high:"\u{1F534}"},P={low:"\u4F4E",medium:"\u4E2D",high:"\u9AD8"};function k(i){let n=["\u{1F512} \u9700\u8981\u5BA1\u6279",""];for(let e of i.steps){if(e.description.startsWith("Execute task without OS sandbox"))n.push("\u26A0\uFE0F \u65E0\u6C99\u7BB1\u6267\u884C \u2014 \u6587\u4EF6\u7CFB\u7EDF\u9694\u79BB\u672A\u542F\u7528");else{let o=e.description.indexOf(": "),r=o>0?e.description.slice(0,o):"Operation";if(n.push(`\u64CD\u4F5C: ${r}`),r==="Bash"&&o>0)try{let t=JSON.parse(e.description.slice(o+2));if(t.command){let s=String(t.command).trim();n.push(`\u547D\u4EE4: ${s.length>120?s.slice(0,117)+"...":s}`)}}catch{let t=e.description.slice(o+2,o+122);n.push(`\u8BE6\u60C5: ${t}${e.description.length>o+122?"...":""}`)}else if(o>0){let t=e.description.slice(o+2,o+122);n.push(`\u8BE6\u60C5: ${t}${e.description.length>o+122?"...":""}`)}}let c=T[e.riskLevel]??"\u{1F7E1}",l=P[e.riskLevel]??e.riskLevel;n.push(`\u98CE\u9669: ${c} ${l}`),n.push("")}return n.join(`
1
+ import{b as f}from"./chunk-RI3V72RP.js";import{b as m}from"./chunk-GSFLLRS7.js";import{c as h,h as v}from"./chunk-MRTJFYPR.js";v();var p=h("channels"),u=new Map,I=3e5,A=new Set(["telegram"]);function w(i){let e=i.trim().toLowerCase().match(/^(yes|y|是|允许|no|n|否|拒绝)\s+(\S+)$/);if(!e)return null;let[,c,l]=e,o=["yes","y","\u662F","\u5141\u8BB8"].includes(c);return{requestId:l,decision:o?"allow":"deny"}}function $(i){let n=m(i);return n?A.has(n.platform):!1}var T={low:"\u{1F7E2}",medium:"\u{1F7E1}",high:"\u{1F534}"},P={low:"\u4F4E",medium:"\u4E2D",high:"\u9AD8"};function k(i){let n=["\u{1F512} \u9700\u8981\u5BA1\u6279",""];for(let e of i.steps){if(e.description.startsWith("Execute task without OS sandbox"))n.push("\u26A0\uFE0F \u65E0\u6C99\u7BB1\u6267\u884C \u2014 \u6587\u4EF6\u7CFB\u7EDF\u9694\u79BB\u672A\u542F\u7528");else{let o=e.description.indexOf(": "),r=o>0?e.description.slice(0,o):"Operation";if(n.push(`\u64CD\u4F5C: ${r}`),r==="Bash"&&o>0)try{let t=JSON.parse(e.description.slice(o+2));if(t.command){let s=String(t.command).trim();n.push(`\u547D\u4EE4: ${s.length>120?s.slice(0,117)+"...":s}`)}}catch{let t=e.description.slice(o+2,o+122);n.push(`\u8BE6\u60C5: ${t}${e.description.length>o+122?"...":""}`)}else if(o>0){let t=e.description.slice(o+2,o+122);n.push(`\u8BE6\u60C5: ${t}${e.description.length>o+122?"...":""}`)}}let c=T[e.riskLevel]??"\u{1F7E1}",l=P[e.riskLevel]??e.riskLevel;n.push(`\u98CE\u9669: ${c} ${l}`),n.push("")}return n.join(`
2
2
  `).trimEnd()}async function C(i,n,e,c,l,o=I){let r=e,t=r.slice(0,8);u.set(t,{planId:e,taskId:c,channelId:i,chatId:n,requestId:r,timestamp:Date.now(),timeoutMs:o});let s=f(),d=$(i);if(d){let a=`${l}
3
3
 
4
4
  `;await s.send({channelId:i,chatId:n,content:a,messageType:"approval",replyMarkup:{inlineKeyboard:[[{text:"\u2705 Allow",callbackData:`yes ${t}`},{text:"\u274C Deny",callbackData:`no ${t}`}]]}})}else{let a=[l,"",`Reply 'yes ${t}' or 'no ${t}'`].join(`
@@ -1,4 +1,4 @@
1
- import{l as f,r as h}from"./chunk-7ZGSJCX5.js";import{b as u,d as E}from"./chunk-NCFVJCNQ.js";E();h();function l(e){return{id:e.id,roleId:e.role_id,type:e.type,content:e.content,embedding:e.embedding?new Float32Array(e.embedding.buffer,e.embedding.byteOffset,e.embedding.byteLength/4):void 0,keywords:e.keywords?JSON.parse(e.keywords):[],importance:e.importance,sourceType:e.source_type,sourceTaskId:e.source_task_id??void 0,evidence:e.evidence?JSON.parse(e.evidence):void 0,createdAt:e.created_at,lastAccessed:e.last_accessed,retrievedCount:e.retrieved_count,tier:e.tier,supersededBy:e.superseded_by??void 0}}function b(e){return Buffer.from(e.buffer,e.byteOffset,e.byteLength)}function v(e){u().prepare(`
1
+ import{l as f,r as h}from"./chunk-HQRUJQN7.js";import{b as u,d as E}from"./chunk-5EPG2US5.js";E();h();function l(e){return{id:e.id,roleId:e.role_id,type:e.type,content:e.content,embedding:e.embedding?new Float32Array(e.embedding.buffer,e.embedding.byteOffset,e.embedding.byteLength/4):void 0,keywords:e.keywords?JSON.parse(e.keywords):[],importance:e.importance,sourceType:e.source_type,sourceTaskId:e.source_task_id??void 0,evidence:e.evidence?JSON.parse(e.evidence):void 0,createdAt:e.created_at,lastAccessed:e.last_accessed,retrievedCount:e.retrieved_count,tier:e.tier,supersededBy:e.superseded_by??void 0}}function b(e){return Buffer.from(e.buffer,e.byteOffset,e.byteLength)}function v(e){u().prepare(`
2
2
  INSERT INTO memories (id, role_id, type, content, embedding, keywords,
3
3
  importance, source_type, source_task_id, evidence,
4
4
  created_at, last_accessed, retrieved_count, tier, superseded_by)
@@ -1,3 +1,3 @@
1
- import{f as S}from"./chunk-2H7UOW4P.js";import{b as v}from"./chunk-FXQAUQTI.js";import{b as y}from"./chunk-4C5ITATX.js";import{e as m}from"./chunk-GMMWA5EG.js";import{b as g}from"./chunk-I7ZZKPHE.js";import{b as C}from"./chunk-VVSZZK5T.js";import{b as R}from"./chunk-YXYIA24D.js";import{a as h}from"./chunk-L7JP7DUO.js";import{a as k,b as P,c as o,d as f,e as T,f as x,g as E}from"./chunk-RLJYEEQC.js";import{c as w,h as _}from"./chunk-MRTJFYPR.js";_();import{v4 as M}from"uuid";var l=w("admin"),I=new Map,u=null,p=null,c=null,D=class{constructor(){h.on("task_status_change",e=>{(e.newStatus==="completed"||e.newStatus==="failed")&&this.handleTaskStatusChange(e.taskId,e.newStatus).catch(n=>{l.error({taskId:e.taskId,error:n},"Delivery processing failed")})}),h.on("plan_approval_request",e=>{this.handlePlanApprovalRequest(e.taskId,e.planId,e.plan).catch(n=>{l.error({taskId:e.taskId,error:n},"Delivery processing failed (plan_approval)")})}),l.info("DeliveryEngine initialized")}async handlePlanApprovalRequest(e,n,r){let t=g(e),i=this.getSourceChannelForTask(e);if(i){let d=y(r),{sendApprovalToChannel:b}=await import("./approval-handler-HQO62WK2.js");await b(i.channelId,i.chatId,n,e,d)}let a=y(r)+`
1
+ import{f as S}from"./chunk-5QZXYKMS.js";import{b as v}from"./chunk-2YTDCR6A.js";import{b as y}from"./chunk-BQ3ZAYHC.js";import{e as m}from"./chunk-B6LOT5CG.js";import{b as g}from"./chunk-K4C43YDD.js";import{b as C}from"./chunk-RI3V72RP.js";import{b as R}from"./chunk-GSFLLRS7.js";import{a as h}from"./chunk-L7JP7DUO.js";import{a as k,b as P,c as o,d as f,e as T,f as x,g as E}from"./chunk-RZ7LCZVK.js";import{c as w,h as _}from"./chunk-MRTJFYPR.js";_();import{v4 as M}from"uuid";var l=w("admin"),I=new Map,u=null,p=null,c=null,D=class{constructor(){h.on("task_status_change",e=>{(e.newStatus==="completed"||e.newStatus==="failed")&&this.handleTaskStatusChange(e.taskId,e.newStatus).catch(n=>{l.error({taskId:e.taskId,error:n},"Delivery processing failed")})}),h.on("plan_approval_request",e=>{this.handlePlanApprovalRequest(e.taskId,e.planId,e.plan).catch(n=>{l.error({taskId:e.taskId,error:n},"Delivery processing failed (plan_approval)")})}),l.info("DeliveryEngine initialized")}async handlePlanApprovalRequest(e,n,r){let t=g(e),i=this.getSourceChannelForTask(e);if(i){let d=y(r),{sendApprovalToChannel:b}=await import("./approval-handler-PB7PSLUS.js");await b(i.channelId,i.chatId,n,e,d)}let a=y(r)+`
2
2
 
3
3
  Task: ${e}`;await this.matchAndDeliver("plan_approval_request",{templateId:t?.templateId,roleId:t?.roleId,prompt:t?.prompt,taskStatus:"pending"},a,e)}getSourceChannelForTask(e){try{let n=m(e);if(!n)return null;let r=v(n.sessionId);return!r||r.source.type!=="channel"||!r.source.channelId||!r.source.chatId?null:{channelId:r.source.channelId,chatId:r.source.chatId}}catch{return null}}async handleTaskStatusChange(e,n){let r=g(e);if(!r)return;let t={templateId:r.templateId,roleId:r.roleId,prompt:r.prompt,taskStatus:n},i=n==="completed"?"task_complete":"task_error",a=r.result??r.error??"";await this.matchAndDeliver(i,t,a,e)}async matchAndDeliver(e,n,r,t){let i=S(e,n);if(i.length!==0){l.debug({eventType:e,ruleCount:i.length,taskId:t},"Matched delivery rules");for(let a of i){if(!this.checkRateLimit(a)){l.warn({ruleId:a.id,maxPerMinute:a.maxPerMinute},"Delivery rate limit exceeded, skipping");continue}if(a.skipOriginChannel&&a.target.type==="channel"&&t&&this.isOriginChannel(t,a.target))continue;let d={id:M(),ruleId:a.id,taskId:t,status:"pending",target:a.target,content:r,attempts:0,createdAt:Date.now(),expiresAt:Date.now()+k,source:"rule"};P(d),await this.attemptDelivery(d,a)}}}async attemptDeliveryPublic(e,n){return this.attemptDelivery(e,n)}async attemptDelivery(e,n){let r=C();try{if(e.target.type==="channel"){let t=e.target.chatId;!t&&e.target.channelId&&(t=R(e.target.channelId)?.config?.userId);let i=await r.send({taskId:e.taskId,channelId:e.target.channelId,chatId:t,content:e.content,messageType:"deliver"});i.success?(f(e.id),l.info({entryId:e.id,ruleId:n.id,targetType:"channel"},"Delivery successful")):o(e.id,"failed",i.error??"Gateway returned failure")}else if(e.target.type==="webhook"){let t=await r.send({taskId:e.taskId,webhookUrl:e.target.webhookUrl,content:e.content,messageType:"deliver"});t.success?(f(e.id),l.info({entryId:e.id,ruleId:n.id,targetType:"webhook"},"Webhook delivery successful")):o(e.id,"failed",t.error??"Gateway returned failure")}}catch(t){let i=t instanceof Error?t.message:String(t);o(e.id,"failed",i),l.warn({entryId:e.id,error:i},"Delivery attempt failed")}}checkRateLimit(e){let n=Date.now(),r=6e4,t=I.get(e.id);t||(t=[],I.set(e.id,t));let i=n-r;for(;t.length>0&&t[0]<i;)t.shift();return t.length>=e.maxPerMinute?!1:(t.push(n),!0)}isOriginChannel(e,n){try{if(n.type!=="channel"||!n.channelId)return!1;let r=m(e);if(!r)return!1;let t=v(r.sessionId);return t?t.source.type==="channel"&&t.source.channelId===n.channelId&&(!n.chatId||t.source.chatId===n.chatId):!1}catch{return!1}}async retryPending(){let e=T("rule",50),n=x("rule",50),r=[...e,...n];if(r.length!==0){l.debug({count:r.length},"Retrying pending/failed deliveries");for(let t of r){if(t.attempts>=3){o(t.id,"failed","Max retries (3) exceeded");continue}let i={id:t.ruleId??"retry-synthetic",eventType:"*",matchCriteria:{},target:t.target,maxPerMinute:5,skipOriginChannel:!0,enabled:!0,createdAt:0};await this.attemptDelivery(t,i)}}}};function $(){return c}function H(){c||(c=new D,u=setInterval(()=>{c?.retryPending().catch(s=>{l.error({error:s},"Delivery retry scan failed")})},6e4),p=setInterval(()=>{try{let s=E();s>0&&l.info({cleaned:s},"Expired delivery log entries cleaned up")}catch(s){l.error({error:s},"Delivery cleanup failed")}},36e5),l.info("DeliveryEngine started with retry (60s) and cleanup (1h) timers"))}function J(){u&&(clearInterval(u),u=null),p&&(clearInterval(p),p=null),c=null,I.clear(),l.info("DeliveryEngine stopped")}export{D as a,$ as b,H as c,J as d};
@@ -1,2 +1,2 @@
1
- import{b as r,d as s}from"./chunk-NCFVJCNQ.js";import{c as i}from"./chunk-FCV2DPZQ.js";function p(e){let n=r().prepare("SELECT value FROM config WHERE key = ?").get(e);if(n)try{return JSON.parse(n.value)}catch{return n.value}}function E(e,t){let n=r(),o=JSON.stringify(t),u=Date.now();n.prepare(`INSERT INTO config (key, value, updated_at) VALUES (?, ?, ?)
1
+ import{b as r,d as s}from"./chunk-5EPG2US5.js";import{c as i}from"./chunk-FCV2DPZQ.js";function p(e){let n=r().prepare("SELECT value FROM config WHERE key = ?").get(e);if(n)try{return JSON.parse(n.value)}catch{return n.value}}function E(e,t){let n=r(),o=JSON.stringify(t),u=Date.now();n.prepare(`INSERT INTO config (key, value, updated_at) VALUES (?, ?, ?)
2
2
  ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at`).run(e,o,u)}function k(){let t=r().prepare("SELECT key, value FROM config").all(),n={};for(let o of t)try{n[o.key]=JSON.parse(o.value)}catch{n[o.key]=o.value}return n}function b(e){let t=r(),n=t.prepare("INSERT OR IGNORE INTO config (key, value, updated_at) VALUES (?, ?, ?)"),o=Date.now(),u=0;return t.transaction(()=>{for(let[c,a]of Object.entries(e)){if(a==null||a==="")continue;n.run(c,JSON.stringify(a),o).changes>0&&u++}})(),u}function w(){return r().prepare("SELECT COUNT(*) as count FROM config").get().count===0}function O(e){return r().prepare("DELETE FROM config WHERE key = ?").run(e).changes>0}var d=i(()=>{s()});export{p as a,E as b,k as c,b as d,w as e,O as f,d as g};
@@ -1,4 +1,4 @@
1
- import{b as s,d as i}from"./chunk-NCFVJCNQ.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-5EPG2US5.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{a as p,g as N}from"./chunk-G5ESQEXN.js";import{b as o,d as C}from"./chunk-NCFVJCNQ.js";import{b as l,h as g}from"./chunk-WBAPIPST.js";import{c,e as A}from"./chunk-FCV2DPZQ.js";import*as h from"os";import*as y from"path";function u(e){return e.startsWith("~/")||e==="~"?y.join(h.homedir(),e.slice(1)):e}var _=c(()=>{"use strict";g()});function R(e){return w.includes(e)}function S(e){return v[e]}function E(){return w.map(e=>v[e])}function V(e,i=e!=="none"){return E().map(s=>T(s,e,i))}function T(e,i,s=i!=="none"){return process.platform==="darwin"?e.status==="runtime-enforced"&&(i!=="sandbox-exec"||!s)?{...e,availability:"runtime-unavailable",editable:!1,effectiveDisabledReason:"Current runtime has no macOS sandbox backend; Adam cannot enforce this capability on Roles."}:e.status==="runtime-enforced"?{...e,availability:"editable",editable:!0}:{...e,availability:e.status,editable:!1,effectiveDisabledReason:e.disabledReason}:{...e,availability:"platform-unsupported",editable:!1,effectiveDisabledReason:"macOS only"}}function z(e){if(!e?.length)return;for(let s of e)if(!R(s.id))throw new Error(`Unknown OS capability: ${s.id}`);let i=d(e);if(i?.length){for(let s of i){let t=S(s.id);if(t.status!=="runtime-enforced")throw new Error(`OS capability '${t.label}' is not editable in Role settings`);if(t.supportsTargets){if(!s.targets?.length)throw new Error(`OS capability '${t.label}' requires at least one target bundle id`);for(let n of s.targets)if(!D(n))throw new Error(`Invalid automation target bundle id: ${n}`)}else if(s.targets?.length)throw new Error(`OS capability '${t.label}' does not accept targets`)}return i}}function d(e){if(!e||e.length===0)return;let i=new Set,s=[];for(let t of e){if(!R(t.id))throw new Error(`Unknown OS capability: ${t.id}`);if(i.has(t.id))continue;i.add(t.id);let n=S(t.id),a={id:t.id};n.supportsTargets&&t.targets?.length&&(a.targets=[...new Set(t.targets.map(r=>r.trim()).filter(Boolean))]),s.push(a)}return s.length>0?s.sort((t,n)=>t.id.localeCompare(n.id)):void 0}function D(e){return x.test(e)}var w,v,x,O=c(()=>{"use strict";w=["location-services","calendars","contacts","files-and-folders","full-disk-access","homekit","media-and-apple-music","passkeys-access-for-web-browsers","photos","reminders","accessibility","app-management","automation","bluetooth","camera","developer-tools","focus","input-monitoring","local-network","microphone","motion-and-fitness","remote-desktop","screen-and-system-audio-recording","speech-recognition"],v={"location-services":{id:"location-services",label:"Location Services",description:"Access device location and region context.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},calendars:{id:"calendars",label:"Calendars",description:"Access Calendar data via macOS privacy controls.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},contacts:{id:"contacts",label:"Contacts",description:"Access Contacts data via macOS privacy controls.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"files-and-folders":{id:"files-and-folders",label:"Files & Folders",description:"Host-level file access categories managed outside Role sandboxing.",platform:"darwin",status:"host-only",disabledReason:"Role file boundaries are already controlled by visiblePaths and deniedReadPaths."},"full-disk-access":{id:"full-disk-access",label:"Full Disk Access",description:"Host-level macOS grant for protected storage locations.",platform:"darwin",status:"host-only",disabledReason:"This is a host app permission, not a Role-level control."},homekit:{id:"homekit",label:"HomeKit",description:"Access HomeKit devices and home automation data.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"media-and-apple-music":{id:"media-and-apple-music",label:"Media & Apple Music",description:"Access Apple Music and media library data.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"passkeys-access-for-web-browsers":{id:"passkeys-access-for-web-browsers",label:"Passkeys Access for Web Browsers",description:"Access passkeys for browser-integrated authentication.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},photos:{id:"photos",label:"Photos",description:"Access the Photos library via macOS privacy controls.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},reminders:{id:"reminders",label:"Reminders",description:"Access Reminder data via macOS privacy controls.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},accessibility:{id:"accessibility",label:"Accessibility",description:"Control desktop UI and accessibility automation surfaces.",platform:"darwin",status:"runtime-enforced"},"app-management":{id:"app-management",label:"App Management",description:"Manage or inspect other installed applications.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},automation:{id:"automation",label:"Automation",description:"Launch and control other apps via Apple Events.",platform:"darwin",status:"runtime-enforced",supportsTargets:!0},bluetooth:{id:"bluetooth",label:"Bluetooth",description:"Access nearby Bluetooth devices.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},camera:{id:"camera",label:"Camera",description:"Capture camera input.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"developer-tools":{id:"developer-tools",label:"Developer Tools",description:"Use system developer tooling privileges.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},focus:{id:"focus",label:"Focus",description:"Access Focus state and related automation.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"input-monitoring":{id:"input-monitoring",label:"Input Monitoring",description:"Observe keyboard and input device activity.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"local-network":{id:"local-network",label:"Local Network",description:"Discover and communicate with devices on the local network.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},microphone:{id:"microphone",label:"Microphone",description:"Capture microphone input.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"motion-and-fitness":{id:"motion-and-fitness",label:"Motion & Fitness",description:"Access motion and fitness sensor data.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"remote-desktop":{id:"remote-desktop",label:"Remote Desktop",description:"Control or observe remote desktop sessions.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"screen-and-system-audio-recording":{id:"screen-and-system-audio-recording",label:"Screen & System Audio Recording",description:"Capture the screen and system audio.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"speech-recognition":{id:"speech-recognition",label:"Speech Recognition",description:"Use system speech recognition services.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."}},x=/^[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$/});var L={};A(L,{createRole:()=>J,deleteRole:()=>U,getRole:()=>P,getRoleByName:()=>I,listRoles:()=>B,updateRole:()=>k,validateAdditionalDirectories:()=>f});import{existsSync as M}from"fs";import{resolve as m}from"path";function f(e,i){for(let s of e){let t=typeof s=="string"?s:s.path;if(!t.startsWith("/")&&!t.startsWith("~/")&&t!=="~")throw new Error(`additionalDirectories must be absolute paths: '${t}' is not absolute`);let n=m(u(t));if(!n.startsWith("/"))throw new Error(`additionalDirectories must be absolute paths: '${t}' is not absolute`);for(let a of l){let r=m(u(a));if(n.startsWith(r))throw new Error(`additionalDirectories cannot include hardcoded denied path: '${t}' matches '${a}'`)}if(i?.length)for(let a of i){let r=m(u(a));if(n.startsWith(r)||r.startsWith(n))throw new Error(`additionalDirectories cannot overlap with deniedReadPaths: '${t}' conflicts with '${a}'`)}if(!M(n))throw new Error(`additionalDirectories path does not exist: '${t}'`)}}function b(e){return{id:e.id,name:e.name,cagPrompt:e.cag_prompt,learnedRules:e.learned_rules?JSON.parse(e.learned_rules):[],memoryStreamId:e.memory_stream_id,status:e.status,performanceScore:e.performance_score??void 0,preferences:e.preferences?JSON.parse(e.preferences):{},createdAt:e.created_at,updatedAt:e.updated_at??void 0,allowedTools:e.allowed_tools?JSON.parse(e.allowed_tools):void 0,disallowedTools:e.disallowed_tools?JSON.parse(e.disallowed_tools):void 0,evaluationCriteria:e.evaluation_criteria?JSON.parse(e.evaluation_criteria):void 0,executionMode:e.execution_mode??void 0,model:e.model??void 0,maxBudgetUsd:e.max_budget_usd??void 0,approvalRequired:e.approval_required?JSON.parse(e.approval_required):void 0,source:e.source??void 0,additionalDirectories:(()=>{if(e.additional_directories!==null)try{let i=JSON.parse(e.additional_directories);return Array.isArray(i)?i.map(s=>typeof s=="string"?{path:s}:s):void 0}catch{return}})(),allowedChannels:e.allowed_channels?JSON.parse(e.allowed_channels):void 0,mcpServers:e.mcp_servers?JSON.parse(e.mcp_servers):void 0,inheritUserSettings:e.inherit_user_settings===1?!0:void 0,permissionMode:e.permission_mode??void 0,allowedBashPatterns:e.allowed_bash_patterns?JSON.parse(e.allowed_bash_patterns):void 0,deniedBashPatterns:e.denied_bash_patterns?JSON.parse(e.denied_bash_patterns):void 0,envVars:e.env_vars?JSON.parse(e.env_vars):void 0,osCapabilities:e.os_capabilities?d(JSON.parse(e.os_capabilities)):void 0}}function J(e){let i=p("defaults.deniedReadPaths")??[...l];e.additionalDirectories&&f(e.additionalDirectories,i),o().prepare(`
1
+ import{a as p,g as N}from"./chunk-FPZEZYUB.js";import{b as o,d as C}from"./chunk-5EPG2US5.js";import{b as l,h as g}from"./chunk-WBAPIPST.js";import{c,e as A}from"./chunk-FCV2DPZQ.js";import*as h from"os";import*as y from"path";function u(e){return e.startsWith("~/")||e==="~"?y.join(h.homedir(),e.slice(1)):e}var _=c(()=>{"use strict";g()});function R(e){return w.includes(e)}function S(e){return v[e]}function E(){return w.map(e=>v[e])}function V(e,i=e!=="none"){return E().map(s=>T(s,e,i))}function T(e,i,s=i!=="none"){return process.platform==="darwin"?e.status==="runtime-enforced"&&(i!=="sandbox-exec"||!s)?{...e,availability:"runtime-unavailable",editable:!1,effectiveDisabledReason:"Current runtime has no macOS sandbox backend; Adam cannot enforce this capability on Roles."}:e.status==="runtime-enforced"?{...e,availability:"editable",editable:!0}:{...e,availability:e.status,editable:!1,effectiveDisabledReason:e.disabledReason}:{...e,availability:"platform-unsupported",editable:!1,effectiveDisabledReason:"macOS only"}}function z(e){if(!e?.length)return;for(let s of e)if(!R(s.id))throw new Error(`Unknown OS capability: ${s.id}`);let i=d(e);if(i?.length){for(let s of i){let t=S(s.id);if(t.status!=="runtime-enforced")throw new Error(`OS capability '${t.label}' is not editable in Role settings`);if(t.supportsTargets){if(!s.targets?.length)throw new Error(`OS capability '${t.label}' requires at least one target bundle id`);for(let n of s.targets)if(!D(n))throw new Error(`Invalid automation target bundle id: ${n}`)}else if(s.targets?.length)throw new Error(`OS capability '${t.label}' does not accept targets`)}return i}}function d(e){if(!e||e.length===0)return;let i=new Set,s=[];for(let t of e){if(!R(t.id))throw new Error(`Unknown OS capability: ${t.id}`);if(i.has(t.id))continue;i.add(t.id);let n=S(t.id),a={id:t.id};n.supportsTargets&&t.targets?.length&&(a.targets=[...new Set(t.targets.map(r=>r.trim()).filter(Boolean))]),s.push(a)}return s.length>0?s.sort((t,n)=>t.id.localeCompare(n.id)):void 0}function D(e){return x.test(e)}var w,v,x,O=c(()=>{"use strict";w=["location-services","calendars","contacts","files-and-folders","full-disk-access","homekit","media-and-apple-music","passkeys-access-for-web-browsers","photos","reminders","accessibility","app-management","automation","bluetooth","camera","developer-tools","focus","input-monitoring","local-network","microphone","motion-and-fitness","remote-desktop","screen-and-system-audio-recording","speech-recognition"],v={"location-services":{id:"location-services",label:"Location Services",description:"Access device location and region context.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},calendars:{id:"calendars",label:"Calendars",description:"Access Calendar data via macOS privacy controls.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},contacts:{id:"contacts",label:"Contacts",description:"Access Contacts data via macOS privacy controls.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"files-and-folders":{id:"files-and-folders",label:"Files & Folders",description:"Host-level file access categories managed outside Role sandboxing.",platform:"darwin",status:"host-only",disabledReason:"Role file boundaries are already controlled by visiblePaths and deniedReadPaths."},"full-disk-access":{id:"full-disk-access",label:"Full Disk Access",description:"Host-level macOS grant for protected storage locations.",platform:"darwin",status:"host-only",disabledReason:"This is a host app permission, not a Role-level control."},homekit:{id:"homekit",label:"HomeKit",description:"Access HomeKit devices and home automation data.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"media-and-apple-music":{id:"media-and-apple-music",label:"Media & Apple Music",description:"Access Apple Music and media library data.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"passkeys-access-for-web-browsers":{id:"passkeys-access-for-web-browsers",label:"Passkeys Access for Web Browsers",description:"Access passkeys for browser-integrated authentication.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},photos:{id:"photos",label:"Photos",description:"Access the Photos library via macOS privacy controls.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},reminders:{id:"reminders",label:"Reminders",description:"Access Reminder data via macOS privacy controls.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},accessibility:{id:"accessibility",label:"Accessibility",description:"Control desktop UI and accessibility automation surfaces.",platform:"darwin",status:"runtime-enforced"},"app-management":{id:"app-management",label:"App Management",description:"Manage or inspect other installed applications.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},automation:{id:"automation",label:"Automation",description:"Launch and control other apps via Apple Events.",platform:"darwin",status:"runtime-enforced",supportsTargets:!0},bluetooth:{id:"bluetooth",label:"Bluetooth",description:"Access nearby Bluetooth devices.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},camera:{id:"camera",label:"Camera",description:"Capture camera input.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"developer-tools":{id:"developer-tools",label:"Developer Tools",description:"Use system developer tooling privileges.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},focus:{id:"focus",label:"Focus",description:"Access Focus state and related automation.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"input-monitoring":{id:"input-monitoring",label:"Input Monitoring",description:"Observe keyboard and input device activity.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"local-network":{id:"local-network",label:"Local Network",description:"Discover and communicate with devices on the local network.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},microphone:{id:"microphone",label:"Microphone",description:"Capture microphone input.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"motion-and-fitness":{id:"motion-and-fitness",label:"Motion & Fitness",description:"Access motion and fitness sensor data.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"remote-desktop":{id:"remote-desktop",label:"Remote Desktop",description:"Control or observe remote desktop sessions.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"screen-and-system-audio-recording":{id:"screen-and-system-audio-recording",label:"Screen & System Audio Recording",description:"Capture the screen and system audio.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."},"speech-recognition":{id:"speech-recognition",label:"Speech Recognition",description:"Use system speech recognition services.",platform:"darwin",status:"registered-unwired",disabledReason:"Not wired into Adam runtime yet."}},x=/^[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$/});var L={};A(L,{createRole:()=>J,deleteRole:()=>U,getRole:()=>P,getRoleByName:()=>I,listRoles:()=>B,updateRole:()=>k,validateAdditionalDirectories:()=>f});import{existsSync as M}from"fs";import{resolve as m}from"path";function f(e,i){for(let s of e){let t=typeof s=="string"?s:s.path;if(!t.startsWith("/")&&!t.startsWith("~/")&&t!=="~")throw new Error(`additionalDirectories must be absolute paths: '${t}' is not absolute`);let n=m(u(t));if(!n.startsWith("/"))throw new Error(`additionalDirectories must be absolute paths: '${t}' is not absolute`);for(let a of l){let r=m(u(a));if(n.startsWith(r))throw new Error(`additionalDirectories cannot include hardcoded denied path: '${t}' matches '${a}'`)}if(i?.length)for(let a of i){let r=m(u(a));if(n.startsWith(r)||r.startsWith(n))throw new Error(`additionalDirectories cannot overlap with deniedReadPaths: '${t}' conflicts with '${a}'`)}if(!M(n))throw new Error(`additionalDirectories path does not exist: '${t}'`)}}function b(e){return{id:e.id,name:e.name,cagPrompt:e.cag_prompt,learnedRules:e.learned_rules?JSON.parse(e.learned_rules):[],memoryStreamId:e.memory_stream_id,status:e.status,performanceScore:e.performance_score??void 0,preferences:e.preferences?JSON.parse(e.preferences):{},createdAt:e.created_at,updatedAt:e.updated_at??void 0,allowedTools:e.allowed_tools?JSON.parse(e.allowed_tools):void 0,disallowedTools:e.disallowed_tools?JSON.parse(e.disallowed_tools):void 0,evaluationCriteria:e.evaluation_criteria?JSON.parse(e.evaluation_criteria):void 0,executionMode:e.execution_mode??void 0,model:e.model??void 0,maxBudgetUsd:e.max_budget_usd??void 0,approvalRequired:e.approval_required?JSON.parse(e.approval_required):void 0,source:e.source??void 0,additionalDirectories:(()=>{if(e.additional_directories!==null)try{let i=JSON.parse(e.additional_directories);return Array.isArray(i)?i.map(s=>typeof s=="string"?{path:s}:s):void 0}catch{return}})(),allowedChannels:e.allowed_channels?JSON.parse(e.allowed_channels):void 0,mcpServers:e.mcp_servers?JSON.parse(e.mcp_servers):void 0,inheritUserSettings:e.inherit_user_settings===1?!0:void 0,permissionMode:e.permission_mode??void 0,allowedBashPatterns:e.allowed_bash_patterns?JSON.parse(e.allowed_bash_patterns):void 0,deniedBashPatterns:e.denied_bash_patterns?JSON.parse(e.denied_bash_patterns):void 0,envVars:e.env_vars?JSON.parse(e.env_vars):void 0,osCapabilities:e.os_capabilities?d(JSON.parse(e.os_capabilities)):void 0}}function J(e){let i=p("defaults.deniedReadPaths")??[...l];e.additionalDirectories&&f(e.additionalDirectories,i),o().prepare(`
2
2
  INSERT INTO roles (id, name, cag_prompt, learned_rules, memory_stream_id, status,
3
3
  performance_score, preferences, created_at, updated_at,
4
4
  allowed_tools, disallowed_tools, evaluation_criteria, execution_mode, model,
@@ -1,4 +1,4 @@
1
- import{a as l}from"./chunk-SWP2JC54.js";import{d as f,k as g,m as p,n as h,o as M,q as b}from"./chunk-YHVYX3F4.js";function v(t,n){let i=0,s=0,m=0;for(let e=0;e<t.length;e++)i+=t[e]*n[e],s+=t[e]*t[e],m+=n[e]*n[e];let o=Math.sqrt(s)*Math.sqrt(m);return o===0?0:i/o}async function S(t,n,i={}){let s=i.topK??10,m=i.hybridConfig??M,o;try{o=await l(n)}catch{}let e=o??new Float32Array(384),a=b(t,e,n,s*2,m,{excludeSuperseded:!0}),d=t?h(t):g,y=a.map(r=>{let u=r.embedding?v(e,r.embedding):0,C=Math.min(.3,(r.retrievedCount??0)*.05),x=p(r.createdAt,u,r.importance,d)+C;return{...r,score:x}});y.sort((r,u)=>u.score-r.score);let c=y.slice(0,s);for(let r of c)f(r.id);return c}async function T(t,n,i=5,s=2e3){try{let{estimateTokens:m}=await import("./token-estimator-HMPVGDCN.js"),o=await S(n,t,{topK:i});if(o.length===0)return"";let e=[],a=0,d=m(`[Memory Context \u2014 retrieved from prior interactions]
1
+ import{a as l}from"./chunk-SWP2JC54.js";import{d as f,k as g,m as p,n as h,o as M,q as b}from"./chunk-DVN3BFPP.js";function v(t,n){let i=0,s=0,m=0;for(let e=0;e<t.length;e++)i+=t[e]*n[e],s+=t[e]*t[e],m+=n[e]*n[e];let o=Math.sqrt(s)*Math.sqrt(m);return o===0?0:i/o}async function S(t,n,i={}){let s=i.topK??10,m=i.hybridConfig??M,o;try{o=await l(n)}catch{}let e=o??new Float32Array(384),a=b(t,e,n,s*2,m,{excludeSuperseded:!0}),d=t?h(t):g,y=a.map(r=>{let u=r.embedding?v(e,r.embedding):0,C=Math.min(.3,(r.retrievedCount??0)*.05),x=p(r.createdAt,u,r.importance,d)+C;return{...r,score:x}});y.sort((r,u)=>u.score-r.score);let c=y.slice(0,s);for(let r of c)f(r.id);return c}async function T(t,n,i=5,s=2e3){try{let{estimateTokens:m}=await import("./token-estimator-HMPVGDCN.js"),o=await S(n,t,{topK:i});if(o.length===0)return"";let e=[],a=0,d=m(`[Memory Context \u2014 retrieved from prior interactions]
2
2
 
3
3
  [User Request]
4
4
  `);for(let c of o){let r=m(`- [${c.tier??"episodic"}] ${c.content}
@@ -1 +1 @@
1
- import{f as ue}from"./chunk-GMMWA5EG.js";import{a as le,b as x,c as J,d as ge,e as me}from"./chunk-YXYIA24D.js";import{c as _,h as M}from"./chunk-MRTJFYPR.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-WEXZORHP.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{f as ue}from"./chunk-B6LOT5CG.js";import{a as le,b as x,c as J,d as ge,e as me}from"./chunk-GSFLLRS7.js";import{c as _,h as M}from"./chunk-MRTJFYPR.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-WEXZORHP.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};
@@ -0,0 +1,7 @@
1
+ import{b as i,d as a}from"./chunk-5EPG2US5.js";a();function d(e){return{id:e.id,parentId:e.parent_id??void 0,status:e.status,prompt:e.prompt,originalPrompt:e.original_prompt??void 0,config:JSON.parse(e.config),result:e.result??void 0,error:e.error??void 0,sdkSessionId:e.sdk_session_id??void 0,templateId:e.template_id??void 0,roleId:e.role_id??void 0,stepId:e.step_id??void 0,sourceSessionId:e.source_session_id??void 0,deliverTo:e.deliver_to?JSON.parse(e.deliver_to):void 0,reportTo:e.report_to?JSON.parse(e.report_to):void 0,createdAt:e.created_at,startedAt:e.started_at??void 0,completedAt:e.completed_at??void 0,costUsd:e.cost_usd??void 0,tokenUsage:e.token_usage?JSON.parse(e.token_usage):void 0,numTurns:e.num_turns??void 0,totalDurationMs:e.total_duration_ms??void 0,blockReason:e.block_reason_json?JSON.parse(e.block_reason_json):void 0}}function c(e){i().prepare(`
2
+ INSERT INTO tasks (id, parent_id, status, prompt, original_prompt, config, result, error,
3
+ sdk_session_id, template_id, role_id, step_id, source_session_id, notify_targets, deliver_to, report_to,
4
+ created_at, started_at, completed_at,
5
+ cost_usd, token_usage, num_turns, total_duration_ms)
6
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
7
+ `).run(e.id,e.parentId??null,e.status,e.prompt,e.originalPrompt??null,JSON.stringify(e.config),e.result??null,e.error??null,e.sdkSessionId??null,e.templateId??null,e.roleId??null,e.stepId??null,e.sourceSessionId??null,null,e.deliverTo?JSON.stringify(e.deliverTo):null,e.reportTo?JSON.stringify(e.reportTo):null,e.createdAt,e.startedAt??null,e.completedAt??null,e.costUsd??null,e.tokenUsage?JSON.stringify(e.tokenUsage):null,e.numTurns??null,e.totalDurationMs??null)}function g(e){let r=i().prepare("SELECT * FROM tasks WHERE id = ?").get(e);return r?d(r):void 0}function f(e,n){let r=i(),t=[],s=[],u={parentId:"parent_id",status:"status",prompt:"prompt",result:"result",error:"error",sdkSessionId:"sdk_session_id",templateId:"template_id",roleId:"role_id",stepId:"step_id",sourceSessionId:"source_session_id",originalPrompt:"original_prompt",startedAt:"started_at",completedAt:"completed_at",costUsd:"cost_usd",numTurns:"num_turns",totalDurationMs:"total_duration_ms"};for(let[o,l]of Object.entries(u))o in n&&(t.push(`${l} = ?`),s.push(n[o]??null));"config"in n&&(t.push("config = ?"),s.push(JSON.stringify(n.config))),"tokenUsage"in n&&(t.push("token_usage = ?"),s.push(n.tokenUsage?JSON.stringify(n.tokenUsage):null)),"deliverTo"in n&&(t.push("deliver_to = ?"),s.push(n.deliverTo?JSON.stringify(n.deliverTo):null)),"reportTo"in n&&(t.push("report_to = ?"),s.push(n.reportTo?JSON.stringify(n.reportTo):null)),"blockReason"in n&&(t.push("block_reason_json = ?"),s.push(n.blockReason?JSON.stringify(n.blockReason):null)),t.length!==0&&(s.push(e),r.prepare(`UPDATE tasks SET ${t.join(", ")} WHERE id = ?`).run(...s))}function m(e,n=100,r=0,t){let s=i(),u="SELECT * FROM tasks",o=[],l=[];return e&&(o.push("status = ?"),l.push(e)),t&&(o.push("role_id = ?"),l.push(t)),o.length>0&&(u+=" WHERE "+o.join(" AND ")),u+=" ORDER BY created_at DESC LIMIT ? OFFSET ?",l.push(n,r),s.prepare(u).all(...l).map(d)}function T(e){return i().prepare("SELECT * FROM tasks WHERE parent_id = ? ORDER BY created_at ASC").all(e).map(d)}function k(e){return i().prepare("SELECT COALESCE(SUM(cost_usd), 0) as total FROM tasks WHERE completed_at >= ? AND cost_usd IS NOT NULL").get(e).total}export{c as a,g as b,f as c,m as d,T as e,k as f};
@@ -1 +1 @@
1
- import{a as h,b as u,c,d as m,e as v,f as x}from"./chunk-FXQAUQTI.js";import{a as l}from"./chunk-SWP2JC54.js";import{b as S,d as y}from"./chunk-GMMWA5EG.js";import{a as i}from"./chunk-L7JP7DUO.js";import{a as C}from"./chunk-YHVYX3F4.js";import{e as p}from"./chunk-PG6LMSX6.js";import{v4 as D}from"uuid";import{v4 as I}from"uuid";function _(e){if(e.length<20)return null;let t=e.trim();return t.length>300?{content:`User request: ${t.slice(0,280)}...`,importance:3,type:"thought"}:{content:`User request: ${t}`,importance:3,type:"thought"}}function b(e){if(e.length<20)return null;let t=e.trim();return t.length>400?{content:`Assistant response: ${t.slice(0,370)}...`,importance:2,type:"event"}:{content:`Assistant response: ${t}`,importance:2,type:"event"}}function N(e){let t=S(e,200,0),s=[];for(let o of t){let r=o.role==="user"?_(o.content):b(o.content);r&&s.push(r)}return{facts:s}}function $(e){let t=e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter(s=>s.length>2);return[...new Set(t)].slice(0,20)}async function A(e,t){let{facts:s}=N(e),o=0;for(let r of s){let f=r.content.slice(0,500),g;try{g=await l(f)}catch{}let M=$(f),T={id:I(),roleId:t,type:r.type,content:f,embedding:g,keywords:M,importance:r.importance,sourceType:"session_archive",createdAt:Date.now(),lastAccessed:Date.now(),retrievedCount:0,tier:"episodic"};C(T),o++}return o}var n=new Map,a;function w(e){return`${e.type}:${e.channelId??""}:${e.chatId??""}`}function F(){n.clear();let e=m("active",1e3);for(let t of e)n.set(t.id,t)}function Q(e,t){let s=Date.now(),o={id:D(),status:"active",source:e,createdAt:s,lastActiveAt:s,messageCount:0};return h(o),n.set(o.id,o),i.emit({type:"session_created",session:o}),o}function V(e){for(let s of n.values())if(w(s.source)===w(e))return s;let t=v(e);return t&&n.set(t.id,t),t}function B(e){let t=n.get(e);return t||u(e)}function E(e){let t=Date.now();c(e,{status:"archived",archivedAt:t}),p().archiveExtractMemory&&u(e)&&A(e,"role-chat-manager").catch(()=>{}),n.delete(e),i.emit({type:"session_archived",sessionId:e})}function W(e){c(e,{status:"active",archivedAt:void 0});let t=u(e);return t&&(n.set(t.id,t),i.emit({type:"session_restored",session:t})),t}function X(e){y(e),x(e),n.delete(e),i.emit({type:"session_deleted",sessionId:e})}function Y(e){let t=Date.now();c(e,{lastActiveAt:t});let s=n.get(e);s&&(s.lastActiveAt=t)}function Z(e){let t=B(e);if(t){let s=t.messageCount+1;c(e,{messageCount:s});let o=n.get(e);o&&(o.messageCount=s)}}function ee(e){return m(e)}function P(){let t=p().sessionTimeoutMinutes*60*1e3,s=Date.now();for(let o of n.values())if(s-o.lastActiveAt>t)try{E(o.id)}catch{}}function R(e=6e4){d(),a=setInterval(P,e)}function d(){a&&(clearInterval(a),a=void 0)}function te(){return a}function se(){F(),R()}function oe(){d(),n.clear()}function ne(){d(),n.clear()}export{F as a,Q as b,V as c,B as d,E as e,W as f,X as g,Y as h,Z as i,ee as j,R as k,d as l,te as m,se as n,oe as o,ne as p};
1
+ import{a as h,b as u,c,d as m,e as v,f as x}from"./chunk-2YTDCR6A.js";import{a as l}from"./chunk-SWP2JC54.js";import{b as S,d as y}from"./chunk-B6LOT5CG.js";import{a as i}from"./chunk-L7JP7DUO.js";import{a as C}from"./chunk-DVN3BFPP.js";import{e as p}from"./chunk-PG6LMSX6.js";import{v4 as D}from"uuid";import{v4 as I}from"uuid";function _(e){if(e.length<20)return null;let t=e.trim();return t.length>300?{content:`User request: ${t.slice(0,280)}...`,importance:3,type:"thought"}:{content:`User request: ${t}`,importance:3,type:"thought"}}function b(e){if(e.length<20)return null;let t=e.trim();return t.length>400?{content:`Assistant response: ${t.slice(0,370)}...`,importance:2,type:"event"}:{content:`Assistant response: ${t}`,importance:2,type:"event"}}function N(e){let t=S(e,200,0),s=[];for(let o of t){let r=o.role==="user"?_(o.content):b(o.content);r&&s.push(r)}return{facts:s}}function $(e){let t=e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter(s=>s.length>2);return[...new Set(t)].slice(0,20)}async function A(e,t){let{facts:s}=N(e),o=0;for(let r of s){let f=r.content.slice(0,500),g;try{g=await l(f)}catch{}let M=$(f),T={id:I(),roleId:t,type:r.type,content:f,embedding:g,keywords:M,importance:r.importance,sourceType:"session_archive",createdAt:Date.now(),lastAccessed:Date.now(),retrievedCount:0,tier:"episodic"};C(T),o++}return o}var n=new Map,a;function w(e){return`${e.type}:${e.channelId??""}:${e.chatId??""}`}function F(){n.clear();let e=m("active",1e3);for(let t of e)n.set(t.id,t)}function Q(e,t){let s=Date.now(),o={id:D(),status:"active",source:e,createdAt:s,lastActiveAt:s,messageCount:0};return h(o),n.set(o.id,o),i.emit({type:"session_created",session:o}),o}function V(e){for(let s of n.values())if(w(s.source)===w(e))return s;let t=v(e);return t&&n.set(t.id,t),t}function B(e){let t=n.get(e);return t||u(e)}function E(e){let t=Date.now();c(e,{status:"archived",archivedAt:t}),p().archiveExtractMemory&&u(e)&&A(e,"role-chat-manager").catch(()=>{}),n.delete(e),i.emit({type:"session_archived",sessionId:e})}function W(e){c(e,{status:"active",archivedAt:void 0});let t=u(e);return t&&(n.set(t.id,t),i.emit({type:"session_restored",session:t})),t}function X(e){y(e),x(e),n.delete(e),i.emit({type:"session_deleted",sessionId:e})}function Y(e){let t=Date.now();c(e,{lastActiveAt:t});let s=n.get(e);s&&(s.lastActiveAt=t)}function Z(e){let t=B(e);if(t){let s=t.messageCount+1;c(e,{messageCount:s});let o=n.get(e);o&&(o.messageCount=s)}}function ee(e){return m(e)}function P(){let t=p().sessionTimeoutMinutes*60*1e3,s=Date.now();for(let o of n.values())if(s-o.lastActiveAt>t)try{E(o.id)}catch{}}function R(e=6e4){d(),a=setInterval(P,e)}function d(){a&&(clearInterval(a),a=void 0)}function te(){return a}function se(){F(),R()}function oe(){d(),n.clear()}function ne(){d(),n.clear()}export{F as a,Q as b,V as c,B as d,E as e,W as f,X as g,Y as h,Z as i,ee as j,R as k,d as l,te as m,se as n,oe as o,ne as p};
@@ -1,4 +1,4 @@
1
- import{c,d as m}from"./chunk-GGIHDFRW.js";import{b as a,d as _}from"./chunk-NCFVJCNQ.js";import{c as s,h as f}from"./chunk-MRTJFYPR.js";import{readFileSync as p,existsSync as l}from"fs";import{fileURLToPath as A}from"url";import{dirname as I,join as r}from"path";var O=A(import.meta.url),g=I(O),i,n;function u(){let e=r(g,"..","package.json");if(l(e))return e;let o=r(g,"..","..","package.json");return l(o)?o:r(process.cwd(),"package.json")}function P(){if(i===void 0){let e=u();i=JSON.parse(p(e,"utf-8")).version}return i}function S(){if(n===void 0){let e=u();n=JSON.parse(p(e,"utf-8")).name}return n}_();f();import{dirname as h,join as R}from"path";import{fileURLToPath as T}from"url";var y=h(T(import.meta.url)),d=R(y,"..");var k=d,U=s("cli:register-ai-digest"),t="ai-hourly-digest";function x(){try{if(m(t)){console.log(`[INFO] AI Digest template already exists (${t})`);return}}catch{}let e={id:t,name:"AI Hourly Digest",description:"\u6BCF\u5C0F\u65F6\u641C\u7D22 AI \u524D\u6CBF\u6587\u7AE0\uFF0C\u603B\u7ED3\u540E\u4FDD\u5B58\u5230 Omnifocus",trigger:{type:"cron",cron:"0 * * * *"},enabled:!0,steps:[{id:"search_ai_news",autoSelectRole:!0,requirements:{},prompt:`\u641C\u7D22\u8FC7\u53BB 24 \u5C0F\u65F6\u5185\u5173\u4E8E AI/\u4EBA\u5DE5\u667A\u80FD\u7684\u6700\u65B0\u524D\u6CBF\u6587\u7AE0\u3002
1
+ import{c,d as m}from"./chunk-5XOTPEAK.js";import{b as a,d as _}from"./chunk-5EPG2US5.js";import{c as s,h as f}from"./chunk-MRTJFYPR.js";import{readFileSync as p,existsSync as l}from"fs";import{fileURLToPath as A}from"url";import{dirname as I,join as r}from"path";var O=A(import.meta.url),g=I(O),i,n;function u(){let e=r(g,"..","package.json");if(l(e))return e;let o=r(g,"..","..","package.json");return l(o)?o:r(process.cwd(),"package.json")}function P(){if(i===void 0){let e=u();i=JSON.parse(p(e,"utf-8")).version}return i}function S(){if(n===void 0){let e=u();n=JSON.parse(p(e,"utf-8")).name}return n}_();f();import{dirname as h,join as R}from"path";import{fileURLToPath as T}from"url";var y=h(T(import.meta.url)),d=R(y,"..");var k=d,U=s("cli:register-ai-digest"),t="ai-hourly-digest";function x(){try{if(m(t)){console.log(`[INFO] AI Digest template already exists (${t})`);return}}catch{}let e={id:t,name:"AI Hourly Digest",description:"\u6BCF\u5C0F\u65F6\u641C\u7D22 AI \u524D\u6CBF\u6587\u7AE0\uFF0C\u603B\u7ED3\u540E\u4FDD\u5B58\u5230 Omnifocus",trigger:{type:"cron",cron:"0 * * * *"},enabled:!0,steps:[{id:"search_ai_news",autoSelectRole:!0,requirements:{},prompt:`\u641C\u7D22\u8FC7\u53BB 24 \u5C0F\u65F6\u5185\u5173\u4E8E AI/\u4EBA\u5DE5\u667A\u80FD\u7684\u6700\u65B0\u524D\u6CBF\u6587\u7AE0\u3002
2
2
 
3
3
  \u641C\u7D22\u6765\u6E90:
4
4
  1. Hacker News AI \u677F\u5757 (https://news.ycombinator.com/front?day=1)
@@ -1,4 +1,4 @@
1
- import{b as t,d}from"./chunk-NCFVJCNQ.js";d();function s(e){return{id:e.id,taskId:e.task_id,roleId:void 0,plan:JSON.parse(e.plan_json),status:e.status,approvalType:e.approval_type??void 0,deviationReport:e.deviation_report_json?JSON.parse(e.deviation_report_json):void 0,learnedRules:e.learned_rules_json?JSON.parse(e.learned_rules_json):void 0,createdAt:e.created_at,approvedAt:e.approved_at??void 0,reviewedAt:e.reviewed_at??void 0}}function p(e){t().prepare(`
1
+ import{b as t,d}from"./chunk-5EPG2US5.js";d();function s(e){return{id:e.id,taskId:e.task_id,roleId:void 0,plan:JSON.parse(e.plan_json),status:e.status,approvalType:e.approval_type??void 0,deviationReport:e.deviation_report_json?JSON.parse(e.deviation_report_json):void 0,learnedRules:e.learned_rules_json?JSON.parse(e.learned_rules_json):void 0,createdAt:e.created_at,approvedAt:e.approved_at??void 0,reviewedAt:e.reviewed_at??void 0}}function p(e){t().prepare(`
2
2
  INSERT INTO task_plans (id, task_id, plan_json, status, approval_type,
3
3
  deviation_report_json, learned_rules_json, created_at, approved_at, reviewed_at)
4
4
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
@@ -1 +1 @@
1
- import{e as T,j as $}from"./chunk-DBP7GPWG.js";import{e as R,i as x}from"./chunk-7ZGSJCX5.js";import{c as J,e as E}from"./chunk-FCV2DPZQ.js";var F={};E(F,{getGlobalEnabledState:()=>k,getInstalledPlugin:()=>N,getPluginManifest:()=>j,listInstalledPlugins:()=>v,listMarketplaceSources:()=>L,resolvePluginPaths:()=>A,scanDirectoryConfig:()=>w});import{existsSync as m,readFileSync as y,readdirSync as I}from"fs";import{join as u}from"path";import M from"os";function h(n){try{if(!m(n))return null;let t=y(n,"utf-8");return JSON.parse(t)}catch{return null}}function k(){return h(O())?.enabledPlugins??{}}function j(n){let t=n;function o(e,s){let l={};try{if(!m(e))return l;let c=y(e,"utf-8").replace(/^```yaml\r?\n/,"").replace(/^```\r?\n/,"");for(let d of s){let r=new RegExp(`^${d}:\\s*(.+)$`,"m"),g=c.match(r);g&&(l[d]=g[1].trim())}}catch{}return l}try{let e={name:"",skills:[],agents:[],mcpServers:[],hooks:[],lspServers:[]},s=u(t,".claude-plugin","plugin.json");if(m(s))try{let r=JSON.parse(y(s,"utf-8"));e.name=r.name??"",e.version=r.version,e.description=r.description,Array.isArray(r.lspServers)&&(e.lspServers=r.lspServers),Array.isArray(r.mcpServers)&&(e.mcpServers=r.mcpServers),Array.isArray(r.hooks)&&(e.hooks=r.hooks)}catch{}let l=u(t,"skills");if(m(l)){let r=I(l,{withFileTypes:!0});for(let g of r){if(!g.isDirectory()&&!g.isSymbolicLink())continue;let p=u(l,g.name,"SKILL.md"),i=o(p,["name","description"]);i.name&&e.skills.push({name:i.name,description:i.description??""})}}let a=u(t,"agents");if(m(a)){let r=I(a,{withFileTypes:!0});for(let g of r){if(!g.isFile()||!g.name.endsWith(".md"))continue;let p=o(u(a,g.name),["name","description"]);p.name&&e.agents.push({name:p.name,description:p.description??""})}}let c=u(t,".mcp.json");if(m(c))try{let r=JSON.parse(y(c,"utf-8"));r.mcpServers&&typeof r.mcpServers=="object"&&(e.mcpServers=Object.keys(r.mcpServers))}catch{}let d=u(t,"hooks","hooks.json");if(m(d))try{let r=JSON.parse(y(d,"utf-8"));Array.isArray(r)&&(e.hooks=r.map(g=>typeof g=="object"&&g!==null&&"event"in g?String(g.event):String(g)))}catch{}return e}catch{return null}}function v(n){let t=h(S());if(!t?.plugins)return[];let o=k(),e=[];for(let[s,l]of Object.entries(t.plugins))if(!(!Array.isArray(l)||l.length===0))for(let a of l){let c=a.scope??"user";n?.scope&&c!==n.scope||n?.projectPath&&a.projectPath!==n.projectPath||e.push({id:s,name:s.split("@")[0],version:a.version??"",scope:c,projectPath:a.projectPath,installPath:a.installPath??u(P(),s),enabled:o[s]??a.enabled??!0,installedAt:a.installedAt??"",lastUpdated:a.lastUpdated??""})}return e}function N(n){let t=h(S());if(!t?.plugins?.[n])return null;let o=t.plugins[n];if(!Array.isArray(o)||o.length===0)return null;let e=o[0],s=k();return{id:n,name:n.split("@")[0],version:e.version??"",scope:e.scope??"user",projectPath:e.projectPath,installPath:e.installPath??u(P(),n),enabled:s[n]??e.enabled??!0,installedAt:e.installedAt??"",lastUpdated:e.lastUpdated??""}}function A(n){let t=h(S()),o=new Map;for(let e of n){let s=t?.plugins?.[e];Array.isArray(s)&&s.length>0&&o.set(e,s[0].installPath??u(P(),e))}return o}function L(){return h(C())?.marketplaces??[]}function w(n){let t=u(n,".claude","settings.json"),o=h(t);return{enabledPlugins:o?.enabledPlugins??{},mcpServers:o?.mcpServers??{},allowedTools:o?.allowedTools??[],disallowedTools:o?.disallowedTools??[]}}var P,S,C,O,D=J(()=>{"use strict";P=()=>u(M.homedir(),".claude","plugins"),S=()=>u(P(),"installed_plugins.json"),C=()=>u(P(),"known_marketplaces.json"),O=()=>u(M.homedir(),".claude","settings.json")});D();$();x();var _={Read:{category:"File",label:"read"},Write:{category:"File",label:"write"},Edit:{category:"File",label:"edit"},Glob:{category:"Search",label:"find files"},Grep:{category:"Search",label:"search content"},Bash:{category:"Execution",label:"shell commands"},WebSearch:{category:"Web",label:"web search"},WebFetch:{category:"Web",label:"fetch pages"},NotebookEdit:{category:"Execution",label:"Jupyter notebooks"}};function z(n,t){let o=n.allowedTools??[],e=n.osCapabilities??[];if(o.length===0&&e.length===0&&Object.keys(n.mcpServers??{}).length===0&&(n.additionalDirectories?.length??0)===0&&(!t||t.plugins.length===0))return"No tool permissions";let s=new Map,l=[];for(let p of o){let i=_[p];if(i){let f=s.get(i.category)??[];f.push(i.label),s.set(i.category,f)}else l.push(p)}let a=[];for(let[p,i]of s)a.push(`${p} (${i.join(", ")})`);l.length>0&&a.push(l.join(", "));let c=a.join(" \xB7 "),d=p=>{c=c?`${c} \xB7 ${p}`:p},r=Object.keys(n.mcpServers??{});r.length>0&&d(`MCP: ${r.join(", ")}`);let g=n.additionalDirectories??[];if(g.length>0&&d(`Dirs: ${g.map(p=>p.path).join(", ")}`),e.length>0){let p=e.map(i=>{let f=R(i.id);return i.id==="automation"&&i.targets?.length?`${f.label} (${i.targets.join(", ")})`:f.label});d(`OS: ${p.join(", ")}`)}if(t&&t.plugins.length>0){let p=t.plugins.map(i=>{let f=[];return i.skills.length>0&&f.push(`skills: ${i.skills.map(b=>b.name).join(", ")}`),i.agents.length>0&&f.push(`agents: ${i.agents.map(b=>b.name).join(", ")}`),f.length>0?`${i.name} (${f.join("; ")})`:i.name});d(`Plugins: ${p.join(", ")}`)}return c}function W(n){let t=[],o=n.additionalDirectories??[];for(let e of o){if(!e.inheritPlugins&&!e.inheritMcp)continue;let s=w(e.path),l=Object.entries(s.enabledPlugins).filter(([,c])=>c).map(([c])=>c),a=A(l);for(let[,c]of a)t.includes(c)||t.push(c)}try{let e=T(n.name),s=v({scope:"project",projectPath:e});for(let l of s)l.installPath&&!t.includes(l.installPath)&&t.push(l.installPath)}catch{}return t}function Q(n){let t=W(n),o=[];for(let e of t){let s=j(e);s&&o.push({name:s.name||e.split("/").pop()||"unknown",description:s.description,skills:s.skills,agents:s.agents,mcpServers:s.mcpServers,hooks:s.hooks})}return{plugins:o}}export{k as a,j as b,v as c,N as d,L as e,w as f,F as g,D as h,z as i,W as j,Q as k};
1
+ import{e as T,j as $}from"./chunk-WMB7P64J.js";import{e as R,i as x}from"./chunk-HQRUJQN7.js";import{c as J,e as E}from"./chunk-FCV2DPZQ.js";var F={};E(F,{getGlobalEnabledState:()=>k,getInstalledPlugin:()=>N,getPluginManifest:()=>j,listInstalledPlugins:()=>v,listMarketplaceSources:()=>L,resolvePluginPaths:()=>A,scanDirectoryConfig:()=>w});import{existsSync as m,readFileSync as y,readdirSync as I}from"fs";import{join as u}from"path";import M from"os";function h(n){try{if(!m(n))return null;let t=y(n,"utf-8");return JSON.parse(t)}catch{return null}}function k(){return h(O())?.enabledPlugins??{}}function j(n){let t=n;function o(e,s){let l={};try{if(!m(e))return l;let c=y(e,"utf-8").replace(/^```yaml\r?\n/,"").replace(/^```\r?\n/,"");for(let d of s){let r=new RegExp(`^${d}:\\s*(.+)$`,"m"),g=c.match(r);g&&(l[d]=g[1].trim())}}catch{}return l}try{let e={name:"",skills:[],agents:[],mcpServers:[],hooks:[],lspServers:[]},s=u(t,".claude-plugin","plugin.json");if(m(s))try{let r=JSON.parse(y(s,"utf-8"));e.name=r.name??"",e.version=r.version,e.description=r.description,Array.isArray(r.lspServers)&&(e.lspServers=r.lspServers),Array.isArray(r.mcpServers)&&(e.mcpServers=r.mcpServers),Array.isArray(r.hooks)&&(e.hooks=r.hooks)}catch{}let l=u(t,"skills");if(m(l)){let r=I(l,{withFileTypes:!0});for(let g of r){if(!g.isDirectory()&&!g.isSymbolicLink())continue;let p=u(l,g.name,"SKILL.md"),i=o(p,["name","description"]);i.name&&e.skills.push({name:i.name,description:i.description??""})}}let a=u(t,"agents");if(m(a)){let r=I(a,{withFileTypes:!0});for(let g of r){if(!g.isFile()||!g.name.endsWith(".md"))continue;let p=o(u(a,g.name),["name","description"]);p.name&&e.agents.push({name:p.name,description:p.description??""})}}let c=u(t,".mcp.json");if(m(c))try{let r=JSON.parse(y(c,"utf-8"));r.mcpServers&&typeof r.mcpServers=="object"&&(e.mcpServers=Object.keys(r.mcpServers))}catch{}let d=u(t,"hooks","hooks.json");if(m(d))try{let r=JSON.parse(y(d,"utf-8"));Array.isArray(r)&&(e.hooks=r.map(g=>typeof g=="object"&&g!==null&&"event"in g?String(g.event):String(g)))}catch{}return e}catch{return null}}function v(n){let t=h(S());if(!t?.plugins)return[];let o=k(),e=[];for(let[s,l]of Object.entries(t.plugins))if(!(!Array.isArray(l)||l.length===0))for(let a of l){let c=a.scope??"user";n?.scope&&c!==n.scope||n?.projectPath&&a.projectPath!==n.projectPath||e.push({id:s,name:s.split("@")[0],version:a.version??"",scope:c,projectPath:a.projectPath,installPath:a.installPath??u(P(),s),enabled:o[s]??a.enabled??!0,installedAt:a.installedAt??"",lastUpdated:a.lastUpdated??""})}return e}function N(n){let t=h(S());if(!t?.plugins?.[n])return null;let o=t.plugins[n];if(!Array.isArray(o)||o.length===0)return null;let e=o[0],s=k();return{id:n,name:n.split("@")[0],version:e.version??"",scope:e.scope??"user",projectPath:e.projectPath,installPath:e.installPath??u(P(),n),enabled:s[n]??e.enabled??!0,installedAt:e.installedAt??"",lastUpdated:e.lastUpdated??""}}function A(n){let t=h(S()),o=new Map;for(let e of n){let s=t?.plugins?.[e];Array.isArray(s)&&s.length>0&&o.set(e,s[0].installPath??u(P(),e))}return o}function L(){return h(C())?.marketplaces??[]}function w(n){let t=u(n,".claude","settings.json"),o=h(t);return{enabledPlugins:o?.enabledPlugins??{},mcpServers:o?.mcpServers??{},allowedTools:o?.allowedTools??[],disallowedTools:o?.disallowedTools??[]}}var P,S,C,O,D=J(()=>{"use strict";P=()=>u(M.homedir(),".claude","plugins"),S=()=>u(P(),"installed_plugins.json"),C=()=>u(P(),"known_marketplaces.json"),O=()=>u(M.homedir(),".claude","settings.json")});D();$();x();var _={Read:{category:"File",label:"read"},Write:{category:"File",label:"write"},Edit:{category:"File",label:"edit"},Glob:{category:"Search",label:"find files"},Grep:{category:"Search",label:"search content"},Bash:{category:"Execution",label:"shell commands"},WebSearch:{category:"Web",label:"web search"},WebFetch:{category:"Web",label:"fetch pages"},NotebookEdit:{category:"Execution",label:"Jupyter notebooks"}};function z(n,t){let o=n.allowedTools??[],e=n.osCapabilities??[];if(o.length===0&&e.length===0&&Object.keys(n.mcpServers??{}).length===0&&(n.additionalDirectories?.length??0)===0&&(!t||t.plugins.length===0))return"No tool permissions";let s=new Map,l=[];for(let p of o){let i=_[p];if(i){let f=s.get(i.category)??[];f.push(i.label),s.set(i.category,f)}else l.push(p)}let a=[];for(let[p,i]of s)a.push(`${p} (${i.join(", ")})`);l.length>0&&a.push(l.join(", "));let c=a.join(" \xB7 "),d=p=>{c=c?`${c} \xB7 ${p}`:p},r=Object.keys(n.mcpServers??{});r.length>0&&d(`MCP: ${r.join(", ")}`);let g=n.additionalDirectories??[];if(g.length>0&&d(`Dirs: ${g.map(p=>p.path).join(", ")}`),e.length>0){let p=e.map(i=>{let f=R(i.id);return i.id==="automation"&&i.targets?.length?`${f.label} (${i.targets.join(", ")})`:f.label});d(`OS: ${p.join(", ")}`)}if(t&&t.plugins.length>0){let p=t.plugins.map(i=>{let f=[];return i.skills.length>0&&f.push(`skills: ${i.skills.map(b=>b.name).join(", ")}`),i.agents.length>0&&f.push(`agents: ${i.agents.map(b=>b.name).join(", ")}`),f.length>0?`${i.name} (${f.join("; ")})`:i.name});d(`Plugins: ${p.join(", ")}`)}return c}function W(n){let t=[],o=n.additionalDirectories??[];for(let e of o){if(!e.inheritPlugins&&!e.inheritMcp)continue;let s=w(e.path),l=Object.entries(s.enabledPlugins).filter(([,c])=>c).map(([c])=>c),a=A(l);for(let[,c]of a)t.includes(c)||t.push(c)}try{let e=T(n.name),s=v({scope:"project",projectPath:e});for(let l of s)l.installPath&&!t.includes(l.installPath)&&t.push(l.installPath)}catch{}return t}function Q(n){let t=W(n),o=[];for(let e of t){let s=j(e);s&&o.push({name:s.name||e.split("/").pop()||"unknown",description:s.description,skills:s.skills,agents:s.agents,mcpServers:s.mcpServers,hooks:s.hooks})}return{plugins:o}}export{k as a,j as b,v as c,N as d,L as e,w as f,F as g,D as h,z as i,W as j,Q as k};
@@ -0,0 +1 @@
1
+ import{d as w,h as S}from"./chunk-WBAPIPST.js";import{c as g,h as P}from"./chunk-MRTJFYPR.js";P();S();import{readFileSync as v,existsSync as E}from"fs";import{join as p}from"path";import{homedir as R}from"os";var T=g("ws"),x=p(R(),".adam"),f=p(x,"adam.port"),b=p(w,"adam.key");function d(){let n=process.env.ADAM_API_KEY;if(n)return n;if(E(b))return v(b,"utf-8").trim()||void 0}function m(){if(!E(f))return null;let n=parseInt(v(f,"utf-8").trim(),10);return isNaN(n)?null:n}function C(){let n=m();if(!n)throw new Error("Server not running. Run: adam server start");return`http://localhost:${n}`}var u=class extends Error{constructor(e,s){super(s);this.status=e;this.name="ApiError"}status};async function A(n,t={}){let s=`${C()}${n}`,r=d(),o=await fetch(s,{method:t.method||"GET",headers:{"Content-Type":"application/json",...r?{"x-api-key":r}:{},...t.headers},body:t.body?JSON.stringify(t.body):void 0});if(!o.ok){let a=await o.text().catch(()=>"Unknown error");throw new u(o.status,a)}return o.headers.get("content-type")?.includes("application/json")?o.json():o.text()}function D(){return A("/healthz")}var k=class{ws=null;callbacks=new Map;reconnectAttempts=0;reconnectTimer=null;url;constructor(t="/events"){let e=m();if(!e)throw new Error("Server not running. Run: adam server start");let s=d(),r=new URL(`ws://localhost:${e}${t}`);s&&r.searchParams.set("api_key",s),this.url=r.toString()}connect(){return new Promise((t,e)=>{try{this.ws=new WebSocket(this.url),this.ws.onopen=()=>{this.reconnectAttempts=0,t()},this.ws.onmessage=s=>{try{let r=JSON.parse(s.data),{type:o,data:c,...a}=r,i=this.callbacks.get(o);i&&i.forEach(l=>l(c??a))}catch(r){T.error({error:r},"Failed to parse WebSocket message")}},this.ws.onclose=()=>{this.scheduleReconnect()},this.ws.onerror=s=>{e(s)}}catch(s){e(s)}})}scheduleReconnect(){let t=[1e3,2e3,4e3,8e3,15e3],e=t[Math.min(this.reconnectAttempts,t.length-1)];this.reconnectAttempts++,this.reconnectTimer=setTimeout(()=>{this.connect().catch(()=>{})},e)}on(t,e){this.callbacks.has(t)||this.callbacks.set(t,new Set),this.callbacks.get(t).add(e)}off(t,e){this.callbacks.get(t)?.delete(e)}close(){this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.ws?.close()}isConnected(){return this.ws?.readyState===WebSocket.OPEN}},y=class{ws=null;callbacks=new Map;url;constructor(t){let e=m();if(!e)throw new Error("Server not running. Run: adam server start");let s=d(),r=new URL(`ws://localhost:${e}/tasks/${t}/stream`);s&&r.searchParams.set("api_key",s),this.url=r.toString()}connect(){return new Promise((t,e)=>{try{this.ws=new WebSocket(this.url),this.ws.onopen=()=>{t()},this.ws.onmessage=s=>{try{let r=JSON.parse(s.data),{type:o,data:c,...a}=r,i=this.callbacks.get(o);i&&i.forEach(h=>h(c??a));let l=this.callbacks.get("*");l&&l.forEach(h=>h(r))}catch(r){T.error({error:r},"Failed to parse task stream message")}},this.ws.onerror=s=>{e(s)},this.ws.onclose=()=>{}}catch(s){e(s)}})}on(t,e){this.callbacks.has(t)||this.callbacks.set(t,new Set),this.callbacks.get(t).add(e)}off(t,e){this.callbacks.get(t)?.delete(e)}close(){this.ws?.close()}isConnected(){return this.ws?.readyState===WebSocket.OPEN}};export{d as a,A as b,D as c,k as d,y as e};