agentix-cli 0.116.0 → 0.118.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/README.md +5 -5
  2. package/dist/{App-7Z2PWARZ.js → App-XMSNIAU6.js} +2 -2
  3. package/dist/{ChatApp-GFAIRLGZ.js → ChatApp-BFYTIQF3.js} +2 -2
  4. package/dist/{agent-LXLZGVW3.js → agent-E6W5VBYH.js} +2 -2
  5. package/dist/{board-dashboard-CPCSSVZE.js → board-dashboard-D5FQZKO4.js} +215 -101
  6. package/dist/board-dashboard-D5FQZKO4.js.map +1 -0
  7. package/dist/chunk-23SQSUBI.js +3 -0
  8. package/dist/chunk-23SQSUBI.js.map +1 -0
  9. package/dist/{chunk-UUMNP47Q.js → chunk-2G227TF3.js} +2 -2
  10. package/dist/{chunk-JLCJVPRC.js → chunk-4PQREYBU.js} +2 -2
  11. package/dist/{chunk-4FU4BFCH.js → chunk-5NTWGUSJ.js} +3 -3
  12. package/dist/chunk-5NTWGUSJ.js.map +1 -0
  13. package/dist/{chunk-6LCP6SVR.js → chunk-5PR6DZYW.js} +3 -3
  14. package/dist/chunk-5PR6DZYW.js.map +1 -0
  15. package/dist/{chunk-HOY2GIKV.js → chunk-5UFIHT66.js} +2 -2
  16. package/dist/{chunk-AWQIUI7N.js → chunk-6PC4EZ4P.js} +2 -2
  17. package/dist/chunk-AD4QZZVN.js +8 -0
  18. package/dist/{failure-candidates-PBPF45GN.js.map → chunk-AD4QZZVN.js.map} +1 -1
  19. package/dist/chunk-B6OXEIOF.js +126 -0
  20. package/dist/chunk-B6OXEIOF.js.map +1 -0
  21. package/dist/chunk-BDJWN3PL.js +4 -0
  22. package/dist/chunk-BDJWN3PL.js.map +1 -0
  23. package/dist/{chunk-7IF3LXAU.js → chunk-FSXWNVGL.js} +2 -2
  24. package/dist/{chunk-YMNQYODO.js → chunk-FTZCNID3.js} +2 -2
  25. package/dist/{chunk-S56ZGAFM.js → chunk-GJKYOEDE.js} +2 -2
  26. package/dist/{chunk-KI4CIUVJ.js → chunk-HK7TU5NX.js} +2 -2
  27. package/dist/chunk-IMLLHT7U.js +54 -0
  28. package/dist/chunk-IMLLHT7U.js.map +1 -0
  29. package/dist/chunk-IOYRRGK7.js +2 -0
  30. package/dist/chunk-IOYRRGK7.js.map +1 -0
  31. package/dist/{chunk-R277UDDQ.js → chunk-IVCFXLAR.js} +2 -2
  32. package/dist/{chunk-WRICEAR6.js → chunk-NDPU6AX2.js} +2 -2
  33. package/dist/{chunk-ELWKTURG.js → chunk-NG677JHW.js} +8 -8
  34. package/dist/chunk-NG677JHW.js.map +1 -0
  35. package/dist/{chunk-CCL73Z2P.js → chunk-PVQPXZHE.js} +58 -58
  36. package/dist/{chunk-CCL73Z2P.js.map → chunk-PVQPXZHE.js.map} +1 -1
  37. package/dist/{chunk-B65YTB3T.js → chunk-RJBRYUKU.js} +2 -2
  38. package/dist/{chunk-QLWGLRT5.js → chunk-TJ7IUHC7.js} +2 -2
  39. package/dist/{chunk-HSYNOMM2.js → chunk-U46G24CD.js} +2 -2
  40. package/dist/{chunk-CKYSGX54.js → chunk-V4PVGEWI.js} +196 -197
  41. package/dist/chunk-V4PVGEWI.js.map +1 -0
  42. package/dist/chunk-WCXXXAHV.js +3 -0
  43. package/dist/{chunk-DMHQIACQ.js.map → chunk-WCXXXAHV.js.map} +1 -1
  44. package/dist/chunk-XGOBZCYC.js +2 -0
  45. package/dist/chunk-XGOBZCYC.js.map +1 -0
  46. package/dist/{chunk-IEZ6OYFJ.js → chunk-ZDWE47LM.js} +8 -8
  47. package/dist/chunk-ZDWE47LM.js.map +1 -0
  48. package/dist/cli.js +1 -1
  49. package/dist/{client-CU5GNTKR.js → client-TSYZXEH7.js} +2 -2
  50. package/dist/{config-ITVBNUWW.js → config-QAE3LNFQ.js} +2 -2
  51. package/dist/config-mutator-WRQ7MFQL.js +2 -0
  52. package/dist/{doctor-MLD3XCYE.js → doctor-PVLVKLRA.js} +2 -2
  53. package/dist/failure-candidates-JNGUVBDG.js +2 -0
  54. package/dist/{grants-BRAVOGBP.js → grants-V2ZNLWSJ.js} +2 -2
  55. package/dist/index.d.ts +107 -3
  56. package/dist/index.js +1 -1
  57. package/dist/program-ZYG3YPH2.js +721 -0
  58. package/dist/program-ZYG3YPH2.js.map +1 -0
  59. package/dist/{promote-JMJPWZI7.js → promote-IRBBEXGG.js} +2 -2
  60. package/dist/push-bridge-325SXDGN.js +2 -0
  61. package/dist/{query-QGPVKGYY.js → query-NAU7J34H.js} +2 -2
  62. package/dist/{registry-PZNC5XYT.js → registry-I5PXGCO6.js} +2 -2
  63. package/dist/{request-planner-M4IKDZBU.js → request-planner-CRG3OGGG.js} +2 -2
  64. package/dist/{review-candidates-6DNRBJZ6.js → review-candidates-HAP7P6SH.js} +2 -2
  65. package/dist/{routing-7NSB6O2S.js → routing-G33LLOTF.js} +2 -2
  66. package/dist/schedule-tool-IP7ZCQKI.js +2 -0
  67. package/dist/scheduler-QXLPYSNJ.js +2 -0
  68. package/dist/{seat-ZRCUQCUP.js → seat-IJN7NETF.js} +2 -2
  69. package/dist/{select-OLNLTEBR.js → select-D7AZ2XZF.js} +2 -2
  70. package/dist/{set-enabled-LG3ESZDC.js → set-enabled-5YSDIQXU.js} +2 -2
  71. package/dist/{surface-usage-HCJTUS6Z.js → surface-usage-WSY4SHHL.js} +2 -2
  72. package/dist/{tool-RBXRPIBV.js → tool-GQIQWHWB.js} +2 -2
  73. package/dist/{tool-S6U42ULD.js → tool-XADSW6NL.js} +2 -2
  74. package/dist/wiki-PPX3HYXW.js +2 -0
  75. package/dist/wiki-PPX3HYXW.js.map +1 -0
  76. package/package.json +1 -1
  77. package/dist/board-dashboard-CPCSSVZE.js.map +0 -1
  78. package/dist/chunk-4FU4BFCH.js.map +0 -1
  79. package/dist/chunk-6LCP6SVR.js.map +0 -1
  80. package/dist/chunk-BRL3UPFW.js +0 -2
  81. package/dist/chunk-BRL3UPFW.js.map +0 -1
  82. package/dist/chunk-CKYSGX54.js.map +0 -1
  83. package/dist/chunk-DMHQIACQ.js +0 -3
  84. package/dist/chunk-EKOVLUKH.js +0 -2
  85. package/dist/chunk-EKOVLUKH.js.map +0 -1
  86. package/dist/chunk-ELWKTURG.js.map +0 -1
  87. package/dist/chunk-FBEMUCBO.js +0 -54
  88. package/dist/chunk-FBEMUCBO.js.map +0 -1
  89. package/dist/chunk-IEZ6OYFJ.js.map +0 -1
  90. package/dist/chunk-J3SIOMDL.js +0 -126
  91. package/dist/chunk-J3SIOMDL.js.map +0 -1
  92. package/dist/chunk-JIT5GPTX.js +0 -4
  93. package/dist/chunk-JIT5GPTX.js.map +0 -1
  94. package/dist/chunk-Y3CZE54A.js +0 -2
  95. package/dist/chunk-Y3CZE54A.js.map +0 -1
  96. package/dist/config-mutator-5YRHHA2I.js +0 -2
  97. package/dist/failure-candidates-PBPF45GN.js +0 -8
  98. package/dist/program-IBOVOVZI.js +0 -703
  99. package/dist/program-IBOVOVZI.js.map +0 -1
  100. package/dist/push-bridge-IFUQLIMF.js +0 -2
  101. package/dist/schedule-tool-ZP7H55EL.js +0 -2
  102. package/dist/scheduler-XV5UQQYH.js +0 -2
  103. package/dist/wiki-XKQN5CWR.js +0 -2
  104. /package/dist/{App-7Z2PWARZ.js.map → App-XMSNIAU6.js.map} +0 -0
  105. /package/dist/{ChatApp-GFAIRLGZ.js.map → ChatApp-BFYTIQF3.js.map} +0 -0
  106. /package/dist/{agent-LXLZGVW3.js.map → agent-E6W5VBYH.js.map} +0 -0
  107. /package/dist/{chunk-UUMNP47Q.js.map → chunk-2G227TF3.js.map} +0 -0
  108. /package/dist/{chunk-JLCJVPRC.js.map → chunk-4PQREYBU.js.map} +0 -0
  109. /package/dist/{chunk-HOY2GIKV.js.map → chunk-5UFIHT66.js.map} +0 -0
  110. /package/dist/{chunk-AWQIUI7N.js.map → chunk-6PC4EZ4P.js.map} +0 -0
  111. /package/dist/{chunk-7IF3LXAU.js.map → chunk-FSXWNVGL.js.map} +0 -0
  112. /package/dist/{chunk-YMNQYODO.js.map → chunk-FTZCNID3.js.map} +0 -0
  113. /package/dist/{chunk-S56ZGAFM.js.map → chunk-GJKYOEDE.js.map} +0 -0
  114. /package/dist/{chunk-KI4CIUVJ.js.map → chunk-HK7TU5NX.js.map} +0 -0
  115. /package/dist/{chunk-R277UDDQ.js.map → chunk-IVCFXLAR.js.map} +0 -0
  116. /package/dist/{chunk-WRICEAR6.js.map → chunk-NDPU6AX2.js.map} +0 -0
  117. /package/dist/{chunk-B65YTB3T.js.map → chunk-RJBRYUKU.js.map} +0 -0
  118. /package/dist/{chunk-QLWGLRT5.js.map → chunk-TJ7IUHC7.js.map} +0 -0
  119. /package/dist/{chunk-HSYNOMM2.js.map → chunk-U46G24CD.js.map} +0 -0
  120. /package/dist/{client-CU5GNTKR.js.map → client-TSYZXEH7.js.map} +0 -0
  121. /package/dist/{config-ITVBNUWW.js.map → config-QAE3LNFQ.js.map} +0 -0
  122. /package/dist/{config-mutator-5YRHHA2I.js.map → config-mutator-WRQ7MFQL.js.map} +0 -0
  123. /package/dist/{doctor-MLD3XCYE.js.map → doctor-PVLVKLRA.js.map} +0 -0
  124. /package/dist/{grants-BRAVOGBP.js.map → failure-candidates-JNGUVBDG.js.map} +0 -0
  125. /package/dist/{promote-JMJPWZI7.js.map → grants-V2ZNLWSJ.js.map} +0 -0
  126. /package/dist/{push-bridge-IFUQLIMF.js.map → promote-IRBBEXGG.js.map} +0 -0
  127. /package/dist/{query-QGPVKGYY.js.map → push-bridge-325SXDGN.js.map} +0 -0
  128. /package/dist/{registry-PZNC5XYT.js.map → query-NAU7J34H.js.map} +0 -0
  129. /package/dist/{routing-7NSB6O2S.js.map → registry-I5PXGCO6.js.map} +0 -0
  130. /package/dist/{request-planner-M4IKDZBU.js.map → request-planner-CRG3OGGG.js.map} +0 -0
  131. /package/dist/{review-candidates-6DNRBJZ6.js.map → review-candidates-HAP7P6SH.js.map} +0 -0
  132. /package/dist/{schedule-tool-ZP7H55EL.js.map → routing-G33LLOTF.js.map} +0 -0
  133. /package/dist/{scheduler-XV5UQQYH.js.map → schedule-tool-IP7ZCQKI.js.map} +0 -0
  134. /package/dist/{seat-ZRCUQCUP.js.map → scheduler-QXLPYSNJ.js.map} +0 -0
  135. /package/dist/{surface-usage-HCJTUS6Z.js.map → seat-IJN7NETF.js.map} +0 -0
  136. /package/dist/{select-OLNLTEBR.js.map → select-D7AZ2XZF.js.map} +0 -0
  137. /package/dist/{set-enabled-LG3ESZDC.js.map → set-enabled-5YSDIQXU.js.map} +0 -0
  138. /package/dist/{wiki-XKQN5CWR.js.map → surface-usage-WSY4SHHL.js.map} +0 -0
  139. /package/dist/{tool-RBXRPIBV.js.map → tool-GQIQWHWB.js.map} +0 -0
  140. /package/dist/{tool-S6U42ULD.js.map → tool-XADSW6NL.js.map} +0 -0
@@ -1,3 +0,0 @@
1
- import{a as l}from"./chunk-JWDJMFU6.js";import{mkdirSync as U,readFileSync as D,renameSync as F,writeFileSync as H}from"fs";import{dirname as K,resolve as J}from"path";function P(e,t=160){if(!e)return e;let r=e.replace(/\s+/g," ").trim();return r.length>t?r.slice(0,t-1)+"\u2026":r}function C(e){let t=new Map;for(let n of e.cronRuns??[]){let s=t.get(n.jobId);(!s||s.startedAt<n.startedAt)&&t.set(n.jobId,n)}let r={success:0,failed:0};for(let n of e.cronRuns??[])n.status==="success"?r.success++:r.failed++;return{id:e.id,name:e.name,url:e.url,reachable:e.reachable,error:P(e.error),uptimeSec:e.uptimeSec,inflight:e.inflight,restart:e.restart?.state&&e.restart.state!=="none"?e.restart:void 0,agents:e.agents.map(n=>({id:n.id,name:n.name,tier:n.tier,active:n.active,errors:n.errors,lastActive:n.lastActive,last:n.lastSummary?{text:P(n.lastSummary.text),at:n.lastSummary.at,ok:n.lastSummary.ok}:void 0})),crons:{today:r,items:(e.crons??[]).map(n=>{let s=t.get(n.id);return{id:n.id,enabled:n.enabled,schedule:n.schedule,agent:n.agent,nextRun:n.nextRun,consecutiveErrors:n.consecutiveErrors,last:s?{status:s.status,at:s.startedAt,text:P(s.status==="success"?s.responseSummary:s.errorSummary)}:void 0}})}}}function j(e){let t=[];for(let r of e)for(let n of r.agents)for(let s of n.runningTasks??[])t.push({node:r.url,nodeName:r.name,agentId:n.id,agentName:n.name,taskId:s.id,preview:P(s.messagePreview),channel:s.channel,startedAt:s.startedAt});return t.sort((r,n)=>r.startedAt<n.startedAt?1:-1)}var E=/^\/api\/app\/tasks\/(cancel|followup)$/;async function L(e,t,r,n,s,o){let i=new URL(e.url||r,"http://localhost");if(n==="GET"&&(r==="/api/app/fleet"||r==="/api/app/activity")){let c=O(i.searchParams.get("timezone")),d=await o.snapshot({date:$(c),timezone:c});return r==="/api/app/activity"?b(t,200,{ts:d.ts,tasks:j(d.nodes)}):b(t,200,{ts:d.ts,nodes:d.nodes.map(C)})}if(n==="GET"&&r==="/api/app/approvals")return b(t,200,{nodes:await o.approvals()});if(n!=="POST")return!1;let p=r.match(E);if(!(p||["/api/app/nodes/restart","/api/app/nodes/reload","/api/app/crons/toggle","/api/app/approvals/decide"].includes(r)))return!1;let a;try{a=await A(e)}catch(c){return b(t,400,{error:c.message})}let h=w(a.node);if(!h)return b(t,400,{error:"node is required"});let y=`operator (phone: ${s})`,u;if(p){let c=w(a.taskId);if(!c)return b(t,400,{error:"taskId is required"});let d=`/api/tasks/${encodeURIComponent(c)}/${p[1]}`;if(p[1]==="cancel")u=await o.nodePost(h,d,{reason:`cancelled by ${y}`});else{let k=w(a.message);if(!k)return b(t,400,{error:"message is required"});u=await o.nodePost(h,d,{message:k,sender:y})}}else if(r==="/api/app/nodes/restart")u=await o.nodePost(h,a.cancel===!0?"/daemon/restart/cancel":"/daemon/restart",{});else if(r==="/api/app/nodes/reload")u=await o.nodePost(h,"/reload",{});else if(r==="/api/app/crons/toggle"){let c=w(a.cronId);if(!c||typeof a.enabled!="boolean")return b(t,400,{error:"cronId and enabled (true or false) are required"});u=await o.nodePost(h,`/crons/${encodeURIComponent(c)}/enabled`,{enabled:a.enabled})}else{let c=w(a.key),d=a.action;if(!c||d!=="yes"&&d!=="no"&&d!=="later")return b(t,400,{error:"key and action (yes, no or later) are required"});u=await o.decide(h,c,d,y)}return b(t,u.status,u.body)}function w(e){return typeof e=="string"?e.trim():""}function O(e){if(!e)return"UTC";try{return new Intl.DateTimeFormat("en-US",{timeZone:e}),e}catch{return"UTC"}}function $(e,t=new Date){return new Intl.DateTimeFormat("en-CA",{timeZone:e,year:"numeric",month:"2-digit",day:"2-digit"}).format(t)}async function A(e,t=16*1024){let r=0,n=[];for await(let i of e){if(r+=i.length,r>t)throw new Error("body too large");n.push(i)}let s=Buffer.concat(n).toString("utf-8").trim();if(!s)return{};let o=JSON.parse(s);if(!o||typeof o!="object"||Array.isArray(o))throw new Error("expected a JSON object");return o}function b(e,t,r){return e.writeHead(t,{"Content-Type":"application/json","Cache-Control":"no-store"}),e.end(JSON.stringify(r)),!0}function I(e){return e==="/api/app/push"||e.startsWith("/api/app/push/")||e==="/api/app/alerts"}var M=2048,x=/^[A-Za-z0-9_-]{8,256}$/;async function Q(e,t,r,n,s,o){if(!I(r))return!1;let i={};if(n==="POST")try{i=await A(e)}catch(a){return R(t,400,{error:a.message})}let p={path:r,method:n,body:i,device:{id:s.id,name:s.name}};if(!o.forward){let a=z(p,o);return R(t,a.status,a.body)}let m;try{m=await o.forward(p),S.note(p,m)}catch(a){m=q(p,`${o.reason??"Can't reach the computer that sends notifications"}: ${a?.message??a}`)}return R(t,m.status,m.body)}var v=class{phones=new Map;file=null;persistTo(t){if(this.file!==t){this.file=t;try{let r=JSON.parse(D(t,"utf-8"));for(let[n,s]of Object.entries(r??{}))s&&typeof s=="object"&&typeof s.subscribed=="boolean"&&this.phones.set(n,{subscribed:s.subscribed,prefs:G(s.prefs)})}catch{}}}note(t,r){if(r.status!==200||!r.body||typeof r.body!="object")return;let n=r.body,s=this.phones.get(t.device.id)??{subscribed:!1,prefs:{}};if(t.method==="GET"&&t.path==="/api/app/push")s.subscribed=n.available===!0&&Number(n.subscriptions)>0,s.prefs=N(n);else if(t.path==="/api/app/push/prefs")s.prefs={...s.prefs,...N(n)};else if(t.path==="/api/app/push/subscribe")s.subscribed=!0;else if(t.path==="/api/app/push/unsubscribe")n.removed&&(s.subscribed=!1);else return;this.phones.set(t.device.id,s),this.save()}save(){if(this.file)try{U(K(this.file),{recursive:!0});let t=`${this.file}.${process.pid}.tmp`;H(t,JSON.stringify(Object.fromEntries(this.phones))+`
2
- `,{encoding:"utf-8",mode:384}),F(t,this.file)}catch{}}on(t,r){return this.phones.get(t)?.prefs[l[r].field]??l[r].default}finishOn(t){return!!this.phones.get(t)?.subscribed&&this.on(t,"finish")}},S=new v;function Y(){return S.persistTo(J(process.cwd(),".agentx/push-relayed.json")),S}function N(e){let t={};for(let r of Object.values(l))typeof e[r.field]=="boolean"&&(t[r.field]=e[r.field]);return t}function G(e){return e&&typeof e=="object"&&!Array.isArray(e)?N(e):{}}function q(e,t){return e.method==="GET"&&e.path==="/api/app/push"?{status:200,body:{available:!1,reason:t,publicKey:null,subscriptions:0,...T()}}:e.method==="GET"&&e.path==="/api/app/alerts"?{status:200,body:{items:[],error:t}}:{status:502,body:{error:t}}}function z(e,t){let{path:r,method:n,body:s,device:o}=e;if(!I(r))return{status:404,body:{error:"not found"}};let i=t.store(),p=i?t.publicKey():null,m=i?p?void 0:"This computer has no push keys yet. On it, run: agentx app push-keys":t.reason??"Notifications are not set up on this computer.";if(n==="GET"&&r==="/api/app/push")return g(200,{available:!m,reason:m??null,publicKey:p,subscriptions:i&&p?i.list(o.id).filter(u=>u.publicKey===p).length:0,...i?i.prefs.all(o.id):T()});if(n==="GET"&&r==="/api/app/alerts")return g(200,{items:i?i.recent(t.keepRecent,o.id):[]});if(n!=="POST"||r!=="/api/app/push/subscribe"&&r!=="/api/app/push/unsubscribe"&&r!=="/api/app/push/prefs")return g(404,{error:"not found"});if(!i||m)return g(503,{error:m});if(r==="/api/app/push/prefs"){let u=Object.keys(l).filter(f=>s[l[f].field]!==void 0),c=u.map(f=>l[f].field).join(", "),d=Object.values(l).map(f=>f.field).join(" or ");if(u.length===0)return g(400,{error:`send ${d}, true or false`});if(u.some(f=>typeof s[l[f].field]!="boolean"))return g(400,{error:`${c} must be true or false`});let k={};for(let f of u)i.prefs.set(o.id,f,s[l[f].field]),k[l[f].field]=s[l[f].field];return g(200,{ok:!0,...k})}let a=B(s.endpoint,t.allowedHosts);if(!a){let u="";try{u=new URL(String(s.endpoint)).hostname}catch{}return g(400,{error:`not a known push service${u?`: ${u}`:""} (see channels.push.allowedHosts)`})}if(r==="/api/app/push/unsubscribe")return g(200,{ok:!0,removed:i.unsubscribe(a,o.id)});let h=s.keys?.p256dh,y=s.keys?.auth;return typeof h!="string"||!x.test(h)||typeof y!="string"||!x.test(y)?g(400,{error:"keys.p256dh and keys.auth are required"}):s.publicKey!==void 0&&s.publicKey!==p?g(409,{error:"this computer's push keys changed; turn notifications on again"}):(i.subscribe({endpoint:a,p256dh:h,auth:y,deviceId:o.id,deviceName:o.name,publicKey:p}),g(200,{ok:!0}))}function g(e,t){return{status:e,body:t}}function T(){let e={};for(let t of Object.values(l))e[t.field]=t.default;return e}function B(e,t){if(typeof e!="string"||e.length>M)return null;try{let r=new URL(e);if(r.protocol!=="https:"||r.port||r.username||r.password)return null;let n=r.hostname.toLowerCase();return t.some(o=>{let i=o.toLowerCase().replace(/^\.+|\.+$/g,"");return!!i&&(n===i||n.endsWith("."+i))})?e:null}catch{return null}}function R(e,t,r){return e.writeHead(t,{"Content-Type":"application/json","Cache-Control":"no-store"}),e.end(JSON.stringify(r)),!0}export{L as a,A as b,I as c,Q as d,S as e,Y as f,z as g};
3
- //# sourceMappingURL=chunk-DMHQIACQ.js.map
@@ -1,2 +0,0 @@
1
- import{a as o}from"./chunk-KI4CIUVJ.js";import{resolve as a}from"path";import{existsSync as d,readdirSync as c,mkdirSync as l}from"fs";var g=class{baseDir;agentsDir;mode;sharedStore;agentStores=new Map;log;constructor(t=a(process.cwd(),".agentx/wiki"),e=console.error.bind(console,"[wiki-hub]"),r="graph"){this.baseDir=t,this.agentsDir=a(t,"agents"),this.mode=r,this.log=e,l(this.agentsDir,{recursive:!0}),this.sharedStore=new o(t,e)}getMode(){return this.mode}getAgentWiki(t){let e=`${t}:${this.mode}`;if(this.agentStores.has(e))return this.agentStores.get(e);let r=a(this.agentsDir,t,this.mode),i=new o(r,this.log);return this.agentStores.set(e,i),i}getBaseDir(){return this.baseDir}getSharedStore(){return this.sharedStore}listAgents(){let t=new Set,e=this.sharedStore.listEntries();for(let r of e)t.add(r.agentId);if(d(this.agentsDir))for(let r of c(this.agentsDir))!r.startsWith("_")&&!r.startsWith(".")&&t.add(r);return[...t].sort()}getAgentEntries(t){return this.sharedStore.listEntries({agentId:t})}getUnabsorbedEntries(t){let e=this.getAgentWiki(t),r=this.getAgentEntries(t),i=new Set,n=e.rebuildIndex();for(let s of n.articles)if(s.sources)for(let h of s.sources)i.add(h);return r.filter(s=>!i.has(s.id))}summary(){return this.listAgents().map(e=>{let r=this.getAgentEntries(e),n=this.getAgentWiki(e).rebuildIndex(),s=this.getUnabsorbedEntries(e);return{agentId:e,totalEntries:r.length,totalArticles:n.articles.length,unabsorbed:s.length,articles:n.articles}})}};export{g as a};
2
- //# sourceMappingURL=chunk-EKOVLUKH.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/wiki/hub.ts"],"sourcesContent":["import { WikiStore } from \"./store\"\nimport { resolve } from \"path\"\nimport { existsSync, readdirSync, mkdirSync } from \"fs\"\nimport type { WikiEntry } from \"./types\"\n\nexport type WikiMode = \"flat\" | \"graph\" | \"unified\"\n\n/**\n * WikiHub: manages per-agent wikis with a shared raw entry pool.\n * Supports two compilation modes:\n * - flat: Karpathy pattern — tags, LLM-chosen paths, worldview, gap detection\n * - graph: Knowledge graph — kind, parent, hierarchy, events, entities\n *\n * Both modes share the same raw entries. Articles stored separately:\n * agents/<id>/flat/ ← Karpathy compilation\n * agents/<id>/graph/ ← Knowledge graph compilation\n */\nexport class WikiHub {\n private baseDir: string\n private agentsDir: string\n private mode: WikiMode\n private sharedStore: WikiStore\n private agentStores: Map<string, WikiStore> = new Map()\n private log: (...args: unknown[]) => void\n\n constructor(\n baseDir: string = resolve(process.cwd(), \".agentx/wiki\"),\n log: (...args: unknown[]) => void = console.error.bind(console, \"[wiki-hub]\"),\n mode: WikiMode = \"graph\",\n ) {\n this.baseDir = baseDir\n this.agentsDir = resolve(baseDir, \"agents\")\n this.mode = mode\n this.log = log\n\n mkdirSync(this.agentsDir, { recursive: true })\n this.sharedStore = new WikiStore(baseDir, log)\n }\n\n getMode(): WikiMode { return this.mode }\n\n /**\n * Get or create the wiki store for a specific agent (mode-aware).\n * flat: agents/<id>/flat/\n * graph: agents/<id>/graph/\n */\n getAgentWiki(agentId: string): WikiStore {\n const key = `${agentId}:${this.mode}`\n if (this.agentStores.has(key)) return this.agentStores.get(key)!\n\n const agentDir = resolve(this.agentsDir, agentId, this.mode)\n const store = new WikiStore(agentDir, this.log)\n this.agentStores.set(key, store)\n return store\n }\n\n /** The wiki root: shared sidecars (_facts.json, _questions.json) live here. */\n getBaseDir(): string {\n return this.baseDir\n }\n\n getSharedStore(): WikiStore {\n return this.sharedStore\n }\n\n listAgents(): string[] {\n const agents = new Set<string>()\n\n const entries = this.sharedStore.listEntries()\n for (const e of entries) agents.add(e.agentId)\n\n if (existsSync(this.agentsDir)) {\n for (const dir of readdirSync(this.agentsDir)) {\n if (!dir.startsWith(\"_\") && !dir.startsWith(\".\")) {\n agents.add(dir)\n }\n }\n }\n\n return [...agents].sort()\n }\n\n getAgentEntries(agentId: string): WikiEntry[] {\n return this.sharedStore.listEntries({ agentId })\n }\n\n getUnabsorbedEntries(agentId: string): WikiEntry[] {\n const agentWiki = this.getAgentWiki(agentId)\n const agentEntries = this.getAgentEntries(agentId)\n\n const absorbedIds = new Set<string>()\n const index = agentWiki.rebuildIndex()\n for (const article of index.articles) {\n if (article.sources) {\n for (const s of article.sources) absorbedIds.add(s)\n }\n }\n\n return agentEntries.filter(e => !absorbedIds.has(e.id))\n }\n\n summary(): AgentWikiSummary[] {\n const agents = this.listAgents()\n return agents.map(agentId => {\n const entries = this.getAgentEntries(agentId)\n const wiki = this.getAgentWiki(agentId)\n const index = wiki.rebuildIndex()\n const unabsorbed = this.getUnabsorbedEntries(agentId)\n\n return {\n agentId,\n totalEntries: entries.length,\n totalArticles: index.articles.length,\n unabsorbed: unabsorbed.length,\n articles: index.articles,\n }\n })\n }\n}\n\nexport interface AgentWikiSummary {\n agentId: string\n totalEntries: number\n totalArticles: number\n unabsorbed: number\n articles: Array<{ title: string; path: string; tags?: string[] }>\n}\n"],"mappings":"wCACA,OAAS,WAAAA,MAAe,OACxB,OAAS,cAAAC,EAAY,eAAAC,EAAa,aAAAC,MAAiB,KAe5C,IAAMC,EAAN,KAAc,CACX,QACA,UACA,KACA,YACA,YAAsC,IAAI,IAC1C,IAER,YACEC,EAAkBL,EAAQ,QAAQ,IAAI,EAAG,cAAc,EACvDM,EAAoC,QAAQ,MAAM,KAAK,QAAS,YAAY,EAC5EC,EAAiB,QACjB,CACA,KAAK,QAAUF,EACf,KAAK,UAAYL,EAAQK,EAAS,QAAQ,EAC1C,KAAK,KAAOE,EACZ,KAAK,IAAMD,EAEXH,EAAU,KAAK,UAAW,CAAE,UAAW,EAAK,CAAC,EAC7C,KAAK,YAAc,IAAIK,EAAUH,EAASC,CAAG,CAC/C,CAEA,SAAoB,CAAE,OAAO,KAAK,IAAK,CAOvC,aAAaG,EAA4B,CACvC,IAAMC,EAAM,GAAGD,KAAW,KAAK,OAC/B,GAAI,KAAK,YAAY,IAAIC,CAAG,EAAG,OAAO,KAAK,YAAY,IAAIA,CAAG,EAE9D,IAAMC,EAAWX,EAAQ,KAAK,UAAWS,EAAS,KAAK,IAAI,EACrDG,EAAQ,IAAIJ,EAAUG,EAAU,KAAK,GAAG,EAC9C,YAAK,YAAY,IAAID,EAAKE,CAAK,EACxBA,CACT,CAGA,YAAqB,CACnB,OAAO,KAAK,OACd,CAEA,gBAA4B,CAC1B,OAAO,KAAK,WACd,CAEA,YAAuB,CACrB,IAAMC,EAAS,IAAI,IAEbC,EAAU,KAAK,YAAY,YAAY,EAC7C,QAAWC,KAAKD,EAASD,EAAO,IAAIE,EAAE,OAAO,EAE7C,GAAId,EAAW,KAAK,SAAS,EAC3B,QAAWe,KAAOd,EAAY,KAAK,SAAS,EACtC,CAACc,EAAI,WAAW,GAAG,GAAK,CAACA,EAAI,WAAW,GAAG,GAC7CH,EAAO,IAAIG,CAAG,EAKpB,MAAO,CAAC,GAAGH,CAAM,EAAE,KAAK,CAC1B,CAEA,gBAAgBJ,EAA8B,CAC5C,OAAO,KAAK,YAAY,YAAY,CAAE,QAAAA,CAAQ,CAAC,CACjD,CAEA,qBAAqBA,EAA8B,CACjD,IAAMQ,EAAY,KAAK,aAAaR,CAAO,EACrCS,EAAe,KAAK,gBAAgBT,CAAO,EAE3CU,EAAc,IAAI,IAClBC,EAAQH,EAAU,aAAa,EACrC,QAAWI,KAAWD,EAAM,SAC1B,GAAIC,EAAQ,QACV,QAAWC,KAAKD,EAAQ,QAASF,EAAY,IAAIG,CAAC,EAItD,OAAOJ,EAAa,OAAOH,GAAK,CAACI,EAAY,IAAIJ,EAAE,EAAE,CAAC,CACxD,CAEA,SAA8B,CAE5B,OADe,KAAK,WAAW,EACjB,IAAIN,GAAW,CAC3B,IAAMK,EAAU,KAAK,gBAAgBL,CAAO,EAEtCW,EADO,KAAK,aAAaX,CAAO,EACnB,aAAa,EAC1Bc,EAAa,KAAK,qBAAqBd,CAAO,EAEpD,MAAO,CACL,QAAAA,EACA,aAAcK,EAAQ,OACtB,cAAeM,EAAM,SAAS,OAC9B,WAAYG,EAAW,OACvB,SAAUH,EAAM,QAClB,CACF,CAAC,CACH,CACF","names":["resolve","existsSync","readdirSync","mkdirSync","WikiHub","baseDir","log","mode","WikiStore","agentId","key","agentDir","store","agents","entries","e","dir","agentWiki","agentEntries","absorbedIds","index","article","s","unabsorbed"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/crons/schedule-tool.ts"],"sourcesContent":["import { existsSync, readFileSync } from \"fs\"\nimport { applyConfigMutation, findConfigPath, getAtPath, setAtPath, unsetAtPath } from \"@/daemon/config-mutator\"\nimport { parseEnglishToCron, slugifyScheduleId } from \"@/utils/nl-cron\"\nimport {\n buildScheduleJob,\n DEFAULT_SCHEDULE_TIMEZONE,\n formatFireTime,\n humanizeCron,\n isPendingCreate,\n isValidScheduleId,\n isValidTimezone,\n nextFireTime,\n SUPPORTED_PHRASES_HINT,\n type NotifyTarget,\n type ScheduleApproval,\n} from \"./schedule-ops\"\n\n// --- Agent-facing `schedule` tool ---\n//\n// Lets an agent list / create / pause / resume / delete routines from any\n// chat. Writes go through the same builder and config mutator as the\n// `agentx schedule` CLI, with two differences that make it safe to hand to\n// a model:\n//\n// 1. create and delete are REQUESTS. Create writes the job disabled with an\n// `approval` marker (the scheduler refuses to run it while that marker\n// says \"create\"); delete only marks the job. The operator is notified\n// with the parsed cron and next fire time, and only\n// `agentx schedule approve|reject <id>` resolves the request. There is\n// no action here that approves anything.\n// 2. Ownership. Jobs record `createdBy`; an agent may touch only its own\n// unless its config says `admin: true`.\n\nexport type ScheduleAction = \"list\" | \"create\" | \"pause\" | \"resume\" | \"delete\"\n\nexport interface ScheduleCaller {\n agentId: string\n /** Chat the request came from — the default notify target. */\n channel?: string\n chatId?: string\n accountId?: string\n}\n\nexport interface ScheduleToolDeps {\n configPath?: string\n /** Hot-reload the daemon after a write. Default true. */\n reload?: boolean\n now?: () => Date\n /** Deliver the approval request to the operator. Throws on failure. */\n notifyOperator?: (dest: NotifyTarget, text: string) => Promise<void>\n}\n\n/** Channels that are not a conversation someone reads, so they never make a\n * sensible default delivery target for a routine's output. */\nconst NON_DELIVERABLE_CHANNELS = new Set([\"cron\", \"heartbeat\", \"api\", \"a2a\", \"mesh\"])\n\nconst PROMPT_PREVIEW = 160\n\nfunction str(v: unknown): string | undefined {\n return typeof v === \"string\" && v.trim() ? v.trim() : undefined\n}\n\nfunction preview(s: string, n = PROMPT_PREVIEW): string {\n const flat = s.replace(/\\s+/g, \" \").trim()\n return flat.length > n ? `${flat.slice(0, n - 1)}…` : flat\n}\n\nfunction readRawConfig(configPath?: string): any {\n const path = findConfigPath(configPath)\n if (!existsSync(path)) throw new Error(`config not found at ${path}`)\n return JSON.parse(readFileSync(path, \"utf-8\"))\n}\n\nfunction isAdmin(cfg: any, agentId: string): boolean {\n return cfg?.agents?.[agentId]?.admin === true\n}\n\nfunction canManage(cfg: any, job: any, caller: ScheduleCaller): boolean {\n return isAdmin(cfg, caller.agentId) || job?.createdBy === caller.agentId\n}\n\nfunction ownershipError(id: string, job: any): string {\n const owner = job?.createdBy ? `agent \"${job.createdBy}\"` : \"the operator\"\n return `Not allowed: \"${id}\" was created by ${owner}. Agents manage only schedules they created (unless configured admin).`\n}\n\nfunction resolveNotify(args: Record<string, unknown>, caller: ScheduleCaller): NotifyTarget | undefined | \"invalid\" {\n const raw = str(args.notify)\n if (raw === \"none\") return undefined\n if (raw && raw !== \"here\") {\n const parts = raw.split(\":\")\n if (parts.length < 2 || !parts[0] || !parts[1]) return \"invalid\"\n // chatIds can contain \":\" (gitlab \"org/repo:issue:1\"), so the channel\n // is the first segment and the rest is the chat id.\n return { channel: parts[0], chatId: parts.slice(1).join(\":\") }\n }\n if (caller.channel && caller.chatId && !NON_DELIVERABLE_CHANNELS.has(caller.channel)) {\n return { channel: caller.channel, chatId: caller.chatId, ...(caller.accountId ? { accountId: caller.accountId } : {}) }\n }\n return undefined\n}\n\nfunction describeJob(id: string, job: any, now: Date): string {\n const tz = job.timezone || \"UTC\"\n const next = job.enabled && !isPendingCreate(job) ? formatFireTime(nextFireTime(job.schedule, tz, now), tz) : \"—\"\n const state = job.approval\n ? `pending ${job.approval.action} approval`\n : job.enabled ? \"active\" : \"paused\"\n const lines = [\n `- ${id} [${state}] ${job.schedule} — ${humanizeCron(job.schedule)} (${tz})`,\n ` agent: ${job.agent}; created by: ${job.createdBy || \"operator\"}; next: ${next}`,\n ]\n if (job.notify) lines.push(` notify: ${job.notify.channel} ${job.notify.chatId}`)\n if (job.command) lines.push(` command: ${preview(String(job.command))}`)\n else if (job.prompt) lines.push(` prompt: ${preview(String(job.prompt))}`)\n return lines.join(\"\\n\")\n}\n\nasync function notifyApproval(\n cfg: any,\n deps: ScheduleToolDeps,\n text: string,\n): Promise<string> {\n const dest = cfg?.notifications?.destination\n if (!dest?.channel || !dest?.chatId) {\n return \"No operator notification destination is configured (notifications.destination); the operator must check `agentx schedule list`.\"\n }\n if (!deps.notifyOperator) return \"Operator notification is unavailable in this context.\"\n try {\n await deps.notifyOperator({ channel: dest.channel, chatId: dest.chatId, accountId: dest.accountId }, text)\n return \"The operator has been notified.\"\n } catch (e: any) {\n return `Could not notify the operator (${e?.message ?? e}); the request is still recorded.`\n }\n}\n\n/**\n * Run one tool action. Returns the text the agent sees. Throws only on\n * programming errors — every expected refusal is returned as text so the\n * model can relay it.\n */\nexport async function runScheduleTool(\n args: Record<string, unknown>,\n caller: ScheduleCaller | null,\n deps: ScheduleToolDeps = {},\n): Promise<string> {\n const action = (str(args.action) || \"list\").toLowerCase() as ScheduleAction\n const now = deps.now ? deps.now() : new Date()\n\n let cfg: any\n try {\n cfg = readRawConfig(deps.configPath)\n } catch (e: any) {\n return `Error: ${e.message}`\n }\n const crons: Record<string, any> = cfg.crons || {}\n\n if (action === \"list\") {\n const mineOnly = args.mine === true\n const entries = Object.entries(crons).filter(([, j]) => !mineOnly || (caller && j?.createdBy === caller.agentId))\n if (!entries.length) return mineOnly ? \"You have no schedules.\" : \"No schedules.\"\n return entries.map(([id, j]) => describeJob(id, j, now)).join(\"\\n\")\n }\n\n if (!caller?.agentId) {\n return \"Error: caller agent is unknown (AGENTX_AGENT_ID not set). Pass callerAgentId.\"\n }\n if (!cfg.agents?.[caller.agentId]) {\n return `Error: caller \"${caller.agentId}\" is not an agent on this node.`\n }\n\n const id = str(args.id)\n const mutate = (fn: (c: any) => void) =>\n applyConfigMutation(fn, { configPath: deps.configPath, reload: deps.reload })\n\n if (action === \"create\") {\n const when = str(args.when)\n const prompt = str(args.prompt)\n if (!when || !prompt) return \"Error: create needs `when` (plain English) and `prompt`.\"\n const parsed = parseEnglishToCron(when)\n if (!parsed) return `Error: couldn't parse \"${when}\". ${SUPPORTED_PHRASES_HINT}.`\n\n const agent = str(args.agent) || caller.agentId\n if (!cfg.agents?.[agent]) return `Error: agent \"${agent}\" not found on this node.`\n\n const timezone = str(args.timezone) || DEFAULT_SCHEDULE_TIMEZONE\n if (!isValidTimezone(timezone)) return `Error: unknown timezone \"${timezone}\".`\n\n const jobId = id || slugifyScheduleId(parsed.matched, agent)\n if (!isValidScheduleId(jobId)) return `Error: invalid id \"${jobId}\" (letters, digits, \"-\" and \"_\" only).`\n if (crons[jobId]) return `Error: a schedule \"${jobId}\" already exists. Pick another \\`id\\`.`\n\n const notify = resolveNotify(args, caller)\n if (notify === \"invalid\") return 'Error: `notify` must be \"here\", \"none\", or \"channel:chatId\".'\n\n const approval: ScheduleApproval = {\n action: \"create\",\n requestedBy: caller.agentId,\n requestedAt: now.toISOString(),\n }\n const job = buildScheduleJob({\n parsed,\n agent,\n prompt,\n timezone,\n notify,\n enabled: false,\n createdBy: caller.agentId,\n approval,\n })\n\n const result = await mutate((c) => setAtPath(c, `crons.${jobId}`, job))\n if (!result.success) return `Error: ${result.error}`\n\n const next = formatFireTime(nextFireTime(parsed.cron, timezone, now), timezone)\n const request = [\n `Schedule approval requested by ${caller.agentId}`,\n `Create: ${jobId}`,\n `When: ${parsed.human} — cron \\`${parsed.cron}\\` (${timezone})`,\n `Next fire: ${next}`,\n `Agent: ${agent}`,\n notify ? `Notify: ${notify.channel} ${notify.chatId}` : \"Notify: none\",\n `Prompt: ${preview(prompt, 400)}`,\n \"\",\n `Approve: agentx schedule approve ${jobId}`,\n `Reject: agentx schedule reject ${jobId}`,\n ].join(\"\\n\")\n const notified = await notifyApproval(cfg, deps, request)\n\n return [\n `Requested schedule \"${jobId}\": ${parsed.human} (cron ${parsed.cron}, ${timezone}); next fire would be ${next}.`,\n \"It is saved DISABLED and will not run until the operator approves it.\",\n notified,\n ].join(\"\\n\")\n }\n\n if (!id) return `Error: ${action} needs \\`id\\`.`\n const job = crons[id]\n if (!job) return `Error: schedule \"${id}\" not found.`\n if (!canManage(cfg, job, caller)) return ownershipError(id, job)\n\n if (action === \"pause\" || action === \"resume\") {\n const enable = action === \"resume\"\n if (enable && isPendingCreate(job)) {\n return `\"${id}\" is still awaiting operator approval; it can't be resumed until approved.`\n }\n if (job.enabled === enable) return `\"${id}\" is already ${enable ? \"active\" : \"paused\"}.`\n const result = await mutate((c) => setAtPath(c, `crons.${id}.enabled`, enable))\n if (!result.success) return `Error: ${result.error}`\n return `\"${id}\" ${enable ? \"resumed\" : \"paused\"}.`\n }\n\n if (action === \"delete\") {\n // Withdrawing your own never-approved request removes nothing that ever\n // ran, so it needs no approval.\n if (isPendingCreate(job) && job.approval.requestedBy === caller.agentId) {\n const result = await mutate((c) => unsetAtPath(c, `crons.${id}`))\n if (!result.success) return `Error: ${result.error}`\n return `Withdrew the pending request \"${id}\".`\n }\n // Never replace a pending create marker with a delete marker: rejecting\n // that delete would leave a disabled job with no marker, which its owner\n // could then resume without the create ever being approved.\n if (isPendingCreate(job)) {\n return `\"${id}\" is a creation request still awaiting approval; only its requester or the operator (\\`agentx schedule reject ${id}\\`) can drop it.`\n }\n if (job.approval?.action === \"delete\") return `Deletion of \"${id}\" is already awaiting approval.`\n\n const approval: ScheduleApproval = {\n action: \"delete\",\n requestedBy: caller.agentId,\n requestedAt: now.toISOString(),\n }\n const result = await mutate((c) => {\n if (!getAtPath(c, `crons.${id}`)) throw new Error(`schedule \"${id}\" not found`)\n setAtPath(c, `crons.${id}.approval`, approval)\n })\n if (!result.success) return `Error: ${result.error}`\n\n const tz = job.timezone || \"UTC\"\n const request = [\n `Schedule approval requested by ${caller.agentId}`,\n `Delete: ${id}`,\n `When: ${humanizeCron(job.schedule)} — cron \\`${job.schedule}\\` (${tz})`,\n `Next fire: ${job.enabled ? formatFireTime(nextFireTime(job.schedule, tz, now), tz) : \"— (paused)\"}`,\n `Agent: ${job.agent}`,\n \"\",\n `Approve: agentx schedule approve ${id}`,\n `Reject: agentx schedule reject ${id}`,\n ].join(\"\\n\")\n const notified = await notifyApproval(cfg, deps, request)\n return [\n `Deletion of \"${id}\" requested. It keeps its current state until the operator approves.`,\n notified,\n ].join(\"\\n\")\n }\n\n return `Error: unknown action \"${action}\". Use list, create, pause, resume or delete.`\n}\n\n/**\n * Who is calling. The runtime-exported environment wins over model-supplied\n * arguments: an agent launched by AgentX cannot claim another identity by\n * passing `callerAgentId`. The arguments are the fallback for runtimes that\n * don't export the variables (e.g. an operator-configured MCP entry).\n */\nexport function resolveScheduleCaller(\n args: Record<string, unknown>,\n env: NodeJS.ProcessEnv = process.env,\n): ScheduleCaller | null {\n const agentId = str(env.AGENTX_AGENT_ID) || str(args.callerAgentId)\n if (!agentId) return null\n const envChat = Boolean(str(env.AGENTX_CHANNEL) && str(env.AGENTX_CHAT_ID))\n const channel = envChat ? str(env.AGENTX_CHANNEL) : str(args.channel)\n const chatId = envChat ? str(env.AGENTX_CHAT_ID) : str(args.chatId)\n const accountId = str(args.accountId)\n return { agentId, channel, chatId, ...(accountId ? { accountId } : {}) }\n}\n"],"mappings":"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","names":["existsSync","readFileSync","NON_DELIVERABLE_CHANNELS","PROMPT_PREVIEW","str","v","preview","s","n","flat","readRawConfig","configPath","path","findConfigPath","existsSync","readFileSync","isAdmin","cfg","agentId","canManage","job","caller","ownershipError","id","owner","resolveNotify","args","raw","parts","describeJob","now","tz","next","isPendingCreate","formatFireTime","nextFireTime","state","lines","humanizeCron","notifyApproval","deps","text","dest","e","runScheduleTool","action","crons","mineOnly","entries","j","mutate","fn","applyConfigMutation","when","prompt","parsed","parseEnglishToCron","SUPPORTED_PHRASES_HINT","agent","timezone","DEFAULT_SCHEDULE_TIMEZONE","isValidTimezone","jobId","slugifyScheduleId","isValidScheduleId","notify","approval","buildScheduleJob","result","c","setAtPath","request","notified","enable","unsetAtPath","getAtPath","resolveScheduleCaller","env","envChat","channel","chatId","accountId"]}
@@ -1,54 +0,0 @@
1
- import{b as M,d as B,h as Fe}from"./chunk-BRK6M6LA.js";import{l as U,m as F,n as He}from"./chunk-UIBUZ2N3.js";import{a as q,e as Ue}from"./chunk-2QNT5JDS.js";import{a as m,b as Be}from"./chunk-QIJLFPWE.js";import{z as s}from"zod";var ze,We,Ke,Xe,Ze,Ge,Ye,Ve,Je,H,z=m(()=>{"use strict";ze=s.enum(["mon","tue","wed","thu","fri","sat","sun"]),We=s.object({days:s.array(ze).default(["mon","tue","wed","thu","fri"]),start:s.string().regex(/^\d{2}:\d{2}$/),end:s.string().regex(/^\d{2}:\d{2}$/),lunch:s.object({start:s.string().regex(/^\d{2}:\d{2}$/),end:s.string().regex(/^\d{2}:\d{2}$/)}).optional()}),Ke=s.object({title:s.string(),responsibilities:s.array(s.string()).default([]),sopPath:s.string().optional(),kpis:s.array(s.string()).default([])}),Xe=s.object({role:s.string(),reportsTo:s.string().optional(),schedule:We,utilizationTarget:s.number().min(0).max(1).default(.8)}),Ze=s.object({channel:s.string(),chatId:s.string(),accountId:s.string().optional()}),Ge=s.discriminatedUnion("type",[s.object({type:s.literal("backlog"),path:s.string().default(".agentx/backlog.md")}),s.object({type:s.literal("gitlab"),projects:s.array(s.string()).default([])}),s.object({type:s.literal("wiki"),path:s.string(),glob:s.string().default("**/*.md")})]),Ye=s.object({id:s.string(),pm:s.string().optional(),client:s.string().optional()}),Ve=s.object({channel:s.string().optional(),chatId:s.string().optional(),username:s.string().optional(),senderId:s.string().optional(),client:s.string(),project:s.string().optional(),displayName:s.string().optional()}),Je=s.object({name:s.string().optional(),kind:s.enum(["client","internal","own"]).optional(),respondWithin:s.string().optional(),standing:s.array(s.string()).default([])}),H=s.object({enabled:s.boolean().default(!1),timezone:s.string().default("UTC"),mainChannel:Ze,workSource:Ge,roles:s.record(s.string(),Ke).default({}),orgChart:s.record(s.string(),Xe).default({}),projects:s.array(Ye).default([]),contactMap:s.array(Ve).default([]),clients:s.record(s.string(),Je).default({}),workTickMinutes:s.number().int().min(1).max(60).default(15),idleQueueThreshold:s.number().int().min(0).default(0),standup:s.object({enabled:s.boolean().default(!0),plansDir:s.string().default(".agentx/plans"),maxAgentsPerDay:s.number().int().min(1).max(100).default(20),dryRun:s.boolean().default(!1)}).default({})})});import{z as d}from"zod";function Sn(r,n){let t=new Set(r.labels||[]);if(r.state==="closed"){let o=n.find(i=>i.kind==="closed");if(o)return o.id}for(let o of n)if(o.kind==="scoped-label"&&o.scopedLabel&&t.has(o.scopedLabel))return o.id;for(let o of n)if(o.kind==="label"&&o.mapsToLabel&&t.has(o.mapsToLabel))return o.id;let a=n.find(o=>o.kind==="open-backlog");if(a){let o=a.scopedPrefix+"::";return[...t].some(l=>l.startsWith(o))?null:a.id}return n[0]?.id??null}function En(r,n){let t=[],a=[],o=!1,i=!1;return n.kind==="scoped-label"&&n.scopedLabel?t.push(n.scopedLabel):n.kind==="label"&&n.mapsToLabel?t.push(n.mapsToLabel):n.kind==="closed"&&(o=!0),r&&(r.kind==="scoped-label"&&r.scopedLabel?a.push(r.scopedLabel):r.kind==="label"&&r.mapsToLabel?a.push(r.mapsToLabel):r.kind==="closed"&&n.kind!=="closed"&&(i=!0)),{addLabels:t.length?t:void 0,removeLabels:a.length?a:void 0,closeIssue:o||void 0,reopen:i||void 0}}var Qe,et,tt,nt,rt,at,W,ot,K,X=m(()=>{"use strict";Qe=d.object({name:d.string(),color:d.string().regex(/^#[0-9a-f]{6}$/i).default("#6366f1"),description:d.string().optional()}),et=d.object({id:d.string().regex(/^[a-z0-9_-]+$/,"column id must be lowercase slug"),title:d.string(),kind:d.enum(["open-backlog","scoped-label","closed","label"]).default("label"),mapsToLabel:d.string().optional(),scopedLabel:d.string().optional(),scopedPrefix:d.string().default("Status"),accent:d.string().optional()}),tt=d.object({enabled:d.boolean().default(!0),staleDoingMinutes:d.number().int().min(1).default(45),respectLunchBreak:d.boolean().default(!0),respectSchedule:d.boolean().default(!0),action:d.enum(["badge","notify"]).default("badge")}),nt=d.discriminatedUnion("type",[d.object({type:d.literal("gitlab"),projects:d.array(d.string()).min(1)})]),rt=[{id:"open",title:"Open",kind:"open-backlog",scopedPrefix:"Status",accent:"#6b7280"},{id:"todo",title:"To Do",kind:"scoped-label",scopedLabel:"Status::To Do",scopedPrefix:"Status",accent:"#fb7a35"},{id:"doing",title:"Doing",kind:"scoped-label",scopedLabel:"Status::Doing",scopedPrefix:"Status",accent:"#22c55e"},{id:"onhold",title:"On Hold",kind:"scoped-label",scopedLabel:"Status::On Hold",scopedPrefix:"Status",accent:"#f59e0b"},{id:"review",title:"Review",kind:"scoped-label",scopedLabel:"Status::Review",scopedPrefix:"Status",accent:"#3b82f6"},{id:"closed",title:"Closed",kind:"closed",scopedPrefix:"Status",accent:"#6b7280"}],at=d.object({id:d.string().regex(/^[a-z0-9_-]+$/,"board id must be lowercase slug"),name:d.string(),source:nt,primaryToolLabel:d.string().optional(),labels:d.array(Qe).default([]),columns:d.array(et).min(1).default(rt),timeRangeDays:d.number().int().min(1).max(365).default(30),closedWindowDays:d.number().int().min(1).max(365).default(30),reconciliation:tt.default({})}),W=d.array(at).default([]),ot=d.object({name:d.string(),url:d.string(),dashboardUrl:d.string().optional(),token:d.string().optional(),dashboardToken:d.string().optional()}),K=d.object({enabled:d.boolean().default(!1),port:d.number().int().default(4202),bind:d.string().default("127.0.0.1"),token:d.string().optional(),daemonUrl:d.string().default("http://localhost:18800"),daemons:d.array(ot).default([]),draftAgent:d.string().optional()}).default({})});function ct(r){let n=String(r??"").trim().toLowerCase();if(!n)return{ok:!1,error:"is empty"};let t=n.split("+").map(i=>i.trim());if(t.some(i=>!i))return{ok:!1,error:`"${r}" has an empty part; write it like opt+space`};let a=dt[t[t.length-1]]??t[t.length-1],o=new Set;for(let i of t.slice(0,-1)){let l=it[i];if(!l)return{ok:!1,error:`"${i}" is not a modifier; use ctrl, opt, shift or cmd`};if(o.has(l))return{ok:!1,error:`"${r}" names ${l} twice`};o.add(l)}return ut(a)?!Z(a)&&!["ctrl","opt","cmd"].some(i=>o.has(i))?{ok:!1,error:`"${r}" needs ctrl, opt or cmd, or it would take that key away from your typing`}:{ok:!0,value:[...st.filter(i=>o.has(i)),a].join("+")}:{ok:!1,error:`"${a}" is not a key AgentX Voice can use; use a letter, a digit, f1 to f20, or space, period, comma, slash, return, tab`}}function G(r){let n=ct(r);return n.ok?void 0:n.error}function wn(r){let n={ctrl:"\u2303",opt:"\u2325",shift:"\u21E7",cmd:"\u2318"},t={space:"Space",period:".",comma:",",slash:"/",semicolon:";",quote:"'",minus:"-",equal:"=",leftbracket:"[",rightbracket:"]",backslash:"\\",grave:"`",return:"Return",tab:"Tab"},a=r.split("+"),o=a.pop()??"";return a.map(i=>n[i]??i).join("")+(t[o]??o.toUpperCase())}var it,st,lt,dt,Z,ut,E,Y=m(()=>{"use strict";it={ctrl:"ctrl",control:"ctrl",opt:"opt",option:"opt",alt:"opt",shift:"shift",cmd:"cmd",command:"cmd"},st=["ctrl","opt","shift","cmd"],lt=["space","period","comma","slash","semicolon","quote","minus","equal","leftbracket","rightbracket","backslash","grave","return","tab"],dt={".":"period",",":"comma","/":"slash",";":"semicolon","'":"quote","-":"minus","=":"equal","`":"grave",enter:"return"},Z=r=>/^f([1-9]|1[0-9]|20)$/.test(r),ut=r=>/^[a-z0-9]$/.test(r)||lt.includes(r)||Z(r);E={talk:"opt+space",stop:"cmd+opt+period",paste:"cmd+opt+v"}});function Q(r){let n=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(r);if(!n)return null;let[t,a,o]=n.slice(1).map(b=>parseInt(b,16)/255),i=Math.max(t,a,o),l=Math.min(t,a,o),u=i-l;return u<.04?null:((i===t?(a-o)/u%6:i===a?(o-t)/u+2:(t-a)/u+4)*60+360)%360}function ft(r){let n=Q(r);if(n===null)return x.find(o=>o.id==="lagoon");let t=x[0],a=360;for(let o of x){let i=Math.abs(o.hue-n),l=Math.min(i,360-i);l<a&&(t=o,a=l)}return t}function Tn(r,n=k){let t=l=>x.find(u=>u.id===l),a=t(r?.palette);if(a)return{...a,set:!0};let o=r?.color;return{...o&&Q(o)!==null?ft(o):t(n)??t(k),set:!1}}var x,V,J,L,k,ee=m(()=>{"use strict";x=[{id:"sunrise",label:"Sunrise",hue:18,colors:["#E8505B","#F2726F","#F79A5A","#FBBF4A","#FFE3A3"]},{id:"desert",label:"Desert",hue:36,colors:["#A4492C","#C8683E","#D9905E","#E7B98A","#F6E3C4"]},{id:"forest",label:"Forest",hue:100,colors:["#2F5D34","#4C7D3A","#6FA046","#9CC25E","#D5EBA4"]},{id:"lagoon",label:"Lagoon",hue:172,colors:["#0B6E73","#0E9594","#1FBFB2","#56DCCB","#B8F4EA"]},{id:"ocean",label:"Ocean",hue:205,colors:["#15457E","#1C6BA8","#2B93CF","#5DBBE8","#BFE6FA"]},{id:"dusk",label:"Dusk",hue:268,colors:["#2E2A7A","#5B3E9E","#8C4FB0","#C8649E","#F4A7B9"]},{id:"blossom",label:"Blossom",hue:330,colors:["#A3245B","#CF3F78","#E8699A","#F49BB8","#FFD6E0"]}],V=["orb","character"],J=["off","rarely","sometimes","often"],L=x.map(r=>r.id);k="lagoon"});function te(r){let n=(r.match(/[؀-ۿ]/g)??[]).length,t=(r.match(/[a-zA-ZÀ-ÿ]/g)??[]).length;if(n&&n>=t)return"ar";let a=0,o=0;for(let i of r.toLowerCase().replace(/[’]/g,"'").match(/[a-zà-ÿœ']+/g)??[])mt.has(i)&&a++,gt.has(i)||i.startsWith("l'")||i.startsWith("d'")||i.startsWith("qu'")?o++:pt.test(i)&&(o+=.5);return a===o?null:a>o?"en":"fr"}var mt,gt,pt,ne=m(()=>{"use strict";mt=new Set("the and is are was were i you he she we they it this that to of in for with not but yes what have has will would can your my".split(" ")),gt=new Set("le la les des du de un une et est sont je tu il elle nous vous ils elles ce cette c'est pas pour que qui avec dans sur au aux mais tr\xE8s oui non merci bonjour votre mon".split(" ")),pt=/[éèêëàâçùûîïôœ]/});function vn(r,n=O){let t=r;if(t=t.replace(/```[\s\S]*?```/g,". "),t=t.replace(/`[^`]*`/g,""),t=t.replace(/\*\*(.*?)\*\*/g,"$1"),t=t.replace(/__(.*?)__/g,"$1"),t=t.replace(/\*([^*]+)\*/g,"$1"),t=t.replace(/_([^_]+)_/g,"$1"),t=t.replace(/~~(.*?)~~/g,"$1"),t=t.replace(/\[([^\]]+)\]\([^)]+\)/g,"$1"),t=t.replace(/!\[([^\]]*)\]\([^)]+\)/g,"image$1 "),t=t.replace(/^#{1,6}\s+/gm,""),t=t.replace(/^[\s]*[-*+]\s+/gm,". "),t=t.replace(/^[\s]*\d+\.\s+/gm,". "),t=t.replace(/^[-=_]{3,}$/gm,""),t=t.replace(/^>\s*/gm,""),t=t.replace(/https?:\/\/\S+/g,"link"),t=t.replace(/\/\w+(\/\w+)+/g,a=>a.split("/").filter(Boolean).join(" slash ")),t=t.replace(/&/g," and "),t=t.replace(/@/g," at "),t=t.replace(/=>/g," returns "),t=t.replace(/->/g," to "),t=t.replace(/\|/g," or "),t=t.replace(/\be\.g\./gi,"for example"),t=t.replace(/\bi\.e\./gi,"that is"),t=t.replace(/\betc\./gi,"etcetera"),t=t.replace(/\bvs\.?\b/gi,"versus"),t=t.replace(/\n{2,}/g,". "),t=t.replace(/\n/g," "),t=t.replace(/\s+/g," "),t=t.replace(/\.\s*\./g,"."),t=t.replace(/\s+([.,!?])/g,"$1"),t=t.trim().replace(/^[.,:;]+\s*/,""),t.length>n){let a=t.slice(0,n),o=([...t.slice(0,n+1).matchAll(/[.!?؟](?=\s)/g)].at(-1)?.index??-1)+1;t=(o>=n/2?a.slice(0,o):a.replace(/\s+\S*$/,"")+"...")+" "+bt[te(a)??"en"]}return t}var O,bt,re=m(()=>{"use strict";ne();O=500,bt={en:"The rest is on screen.",fr:"La suite est \xE0 l'\xE9cran.",ar:"\u0627\u0644\u0628\u0627\u0642\u064A \u0639\u0644\u0649 \u0627\u0644\u0634\u0627\u0634\u0629."}});function On(r,n=j){let t=new Set(n.map(ae)),a=r.replace(/\[([^\][]*)\]|\(([^()]*)\)/g,(o,i,l)=>t.has(ae(i??l))?"":o);return!/[\p{L}\p{N}]/u.test(a)}var j,Ln,ae,oe=m(()=>{"use strict";j=["background noise","noise","mumbling","babbling","unintelligible","inaudible","muffled speech","pause","silence","music","outro jingle","blank audio"],Ln="I didn't catch that.",ae=r=>r.toLowerCase().replace(/[_\s]+/g," ").trim()});import{z as c}from"zod";var ie,ht,se,le=m(()=>{"use strict";ie=c.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/,"use HH:MM, 24-hour"),ht=c.object({id:c.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/,"lowercase letters, digits, - and _"),enabled:c.boolean().default(!0),chats:c.array(c.string().min(1)).default([]),senders:c.array(c.string().min(1)).default([]),agent:c.string().min(1),prompt:c.string().max(4e3).optional(),quietHours:c.object({start:ie,end:ie}).optional(),autoAck:c.boolean().default(!1)}).refine(r=>r.chats.length>0||r.senders.length>0,{message:"a rule needs at least one chat or sender"}),se=c.object({enabled:c.boolean().default(!1),secretEnv:c.string().regex(/^[A-Z_][A-Z0-9_]*$/).default("WACLI_WEBHOOK_SECRET"),batchSeconds:c.number().int().min(0).max(600).default(20),timezone:c.string().optional(),allowAutoAck:c.boolean().default(!1),describeMedia:c.boolean().default(!0),wacli:c.object({bin:c.string().default("wacli"),account:c.string().optional(),store:c.string().optional()}).default({}),rules:c.array(ht).default([])}).default({})});function yt(r){r.exec(`
2
- CREATE TABLE IF NOT EXISTS requests (
3
- id TEXT PRIMARY KEY,
4
- state TEXT NOT NULL,
5
- channel TEXT NOT NULL,
6
- chat_id TEXT NOT NULL,
7
- sender TEXT,
8
- agent_id TEXT NOT NULL,
9
- text TEXT NOT NULL,
10
- created_at INTEGER NOT NULL,
11
- updated_at INTEGER NOT NULL,
12
- attention_reason TEXT,
13
- notified_at INTEGER,
14
- question TEXT,
15
- closed_at INTEGER,
16
- evidence TEXT,
17
- close_reason TEXT
18
- );
19
- CREATE INDEX IF NOT EXISTS idx_requests_state_created ON requests(state, created_at);
20
- CREATE INDEX IF NOT EXISTS idx_requests_chat ON requests(agent_id, channel, chat_id, created_at);
21
- CREATE TABLE IF NOT EXISTS request_links (
22
- request_id TEXT NOT NULL,
23
- kind TEXT NOT NULL,
24
- ref TEXT NOT NULL,
25
- at INTEGER NOT NULL,
26
- PRIMARY KEY (kind, ref),
27
- FOREIGN KEY (request_id) REFERENCES requests(id) ON DELETE CASCADE
28
- );
29
- CREATE INDEX IF NOT EXISTS idx_request_links_request ON request_links(request_id);
30
- `),F(r,"requests",U);let n=r.prepare("PRAGMA table_info(requests)").all();for(let[t,a]of[["pickup_at","INTEGER"],["owner_note","TEXT"],["note_said","INTEGER"],["asked_agent","TEXT"]])if(!n.some(o=>o.name===t))try{r.exec(`ALTER TABLE requests ADD COLUMN ${t} ${a}`)}catch(o){if(!/duplicate column name/i.test(String(o?.message)))throw o}}function Pn(r){return!!r.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'requests'").get()}function h(r){return{id:r.id,state:r.state,channel:r.channel,chatId:r.chat_id,sender:r.sender??null,person:r.person??null,agentId:r.agent_id,text:r.text,createdAt:r.created_at,updatedAt:r.updated_at,attentionReason:r.attention_reason??null,notifiedAt:r.notified_at??null,question:r.question??null,closedAt:r.closed_at??null,evidence:r.evidence??null,closeReason:r.close_reason??null,ownerNote:r.owner_note??null,noteSaid:!!r.note_said,askedAgent:r.asked_agent??null}}var y,g,N,$,p,de,ue=m(()=>{"use strict";He();y=["in_progress","waiting_owner","waiting_other","needs_attention"],g=["done","declined","dropped"],N=4e3,$=500;p=r=>Array(r).fill("?").join(","),de=class{constructor(n){this.db=n;yt(n),n.pragma("foreign_keys = ON")}addCandidate(n){this.db.prepare(`INSERT OR IGNORE INTO requests (id, state, channel, chat_id, sender, person, agent_id, text, created_at, updated_at)
31
- VALUES (?, 'candidate', ?, ?, ?, ?, ?, ?, ?, ?)`).run(n.id,n.channel,n.chatId,n.sender??null,n.person??null,n.agentId,n.text.slice(0,N),n.now,n.now),this.link(n.id,"run",n.runId,n.now)}get(n){let t=this.db.prepare("SELECT * FROM requests WHERE id = ?").get(n);return t?h(t):null}byLink(n,t){let a=this.db.prepare("SELECT r.* FROM requests r JOIN request_links l ON l.request_id = r.id WHERE l.kind = ? AND l.ref = ?").get(n,t);return a?h(a):null}link(n,t,a,o){this.db.prepare("INSERT OR IGNORE INTO request_links (request_id, kind, ref, at) VALUES (?, ?, ?, ?)").run(n,t,a,o)}links(n){return this.db.prepare("SELECT kind, ref, at FROM request_links WHERE request_id = ? ORDER BY at, rowid").all(n)}lastAnswer(n){try{return this.db.prepare(`SELECT t.agent_id AS agentId, t.final_response AS text, COALESCE(t.finished_at, t.started_at) AS at
32
- FROM request_links l JOIN task_traces t ON t.task_id = l.ref
33
- WHERE l.request_id = ? AND l.kind = 'run' AND t.final_response IS NOT NULL AND t.final_response != ''
34
- ORDER BY t.started_at DESC LIMIT 1`).get(n)??null}catch{return null}}touch(n,t){this.db.prepare("UPDATE requests SET updated_at = ? WHERE id = ?").run(t,n)}progress(n,t,a="in_progress"){this.db.prepare(`UPDATE requests SET state = ?, updated_at = ?, attention_reason = NULL, notified_at = NULL, question = NULL
35
- WHERE id = ? AND state NOT IN (${p(g.length)})`).run(a,t,n,...g)}waitOnOwner(n,t,a){this.db.prepare(`UPDATE requests SET state = 'waiting_owner', updated_at = ?, question = ?, attention_reason = NULL, notified_at = NULL
36
- WHERE id = ? AND state NOT IN (${p(g.length)})`).run(a,t.slice(0,N),n,...g)}needsAttention(n,t,a){return this.db.prepare(`UPDATE requests SET state = 'needs_attention', updated_at = ?, attention_reason = ?, notified_at = NULL
37
- WHERE id = ? AND state NOT IN ('needs_attention', ${p(g.length)})`).run(a,t.replace(/\s+/g," ").trim().slice(0,$),n,...g).changes>0}close(n,t,a,o){let i=a.trim();if(!i)throw new Error(t==="done"?"a finished request needs a link to the evidence":`a ${t} request needs a reason`);return this.db.prepare(`UPDATE requests SET state = ?, closed_at = ?, updated_at = ?, evidence = ?, close_reason = ?
38
- WHERE id = ? AND state NOT IN (${p(g.length)})`).run(t,o,o,t==="done"?i.slice(0,$):null,t==="done"?null:i.slice(0,$),n,...g).changes>0}discardCandidate(n){return this.db.prepare("DELETE FROM requests WHERE id = ? AND state = 'candidate'").run(n).changes>0}listOpen(){return this.db.prepare(`SELECT * FROM requests WHERE state IN (${p(y.length)}) ORDER BY created_at, rowid`).all(...y).map(h)}quietSince(n,t){return this.db.prepare(`SELECT * FROM requests WHERE state IN (${p(n.length)}) AND updated_at < ? ORDER BY created_at, rowid`).all(...n,t).map(h)}awaitingNotice(){return this.db.prepare("SELECT * FROM requests WHERE state = 'needs_attention' AND notified_at IS NULL ORDER BY created_at, rowid").all().map(h)}markNotified(n,t){this.db.prepare("UPDATE requests SET notified_at = ? WHERE id = ?").run(t,n)}listByState(n){return this.db.prepare("SELECT * FROM requests WHERE state = ? ORDER BY created_at, rowid").all(n).map(h)}requestPickup(n,t){return this.db.prepare(`UPDATE requests SET state = 'in_progress', updated_at = ?, attention_reason = NULL, notified_at = NULL, pickup_at = ?
39
- WHERE id = ? AND state = 'needs_attention'`).run(t,t,n).changes>0}handOff(n,t,a,o){return this.db.prepare(`UPDATE requests SET agent_id = ?, state = 'in_progress', updated_at = ?, attention_reason = NULL, notified_at = NULL,
40
- question = NULL, pickup_at = ?, owner_note = ?, note_said = NULL, asked_agent = COALESCE(asked_agent, agent_id)
41
- WHERE id = ? AND state IN (${p(y.length)})`).run(t,o,o,a.trim().slice(0,N)||null,n,...y).changes>0}setNoteSaid(n,t,a){this.db.prepare(`UPDATE requests SET note_said = ? WHERE id = ? AND owner_note = ?${a?" AND pickup_at IS NULL":""}`).run(a?1:null,n,t)}takePickups(){return this.db.prepare("UPDATE requests SET pickup_at = NULL WHERE pickup_at IS NOT NULL RETURNING *").all().map(h).filter(n=>n.state==="in_progress").sort((n,t)=>n.createdAt-t.createdAt)}pruneClosed(n){return this.db.prepare(`DELETE FROM requests WHERE state IN (${p(g.length)}) AND closed_at < ?`).run(...g,n).changes}}});function Bn(r){return Object.assign({channel:me,chatId:r,sender:"operator"},{[ge]:!0})}function Un(r){return!!r&&r[ge]===!0}function Et(r,n,t,a=!1){let o=_(n);if(r.channels.length&&!r.channels.map(_).includes(o))return!1;if(T.has(o))return a&&!xt.has((t?.name??"").toLowerCase());let i=St.has(o)?t?.username:t?.id,l=i?ce(o,i):"";return l?r.from.some(u=>{let f=u.trim().toLowerCase(),b=f.indexOf(":");return b>0&&f.slice(0,b)===o&&ce(o,f.slice(b+1))===l}):!1}function Fn(r){if(!r)return;let n=a=>typeof a=="string"&&a?a.slice(0,120):void 0,t={name:n(r.sender),id:n(r.senderId),username:n(r.senderUsername)};return t.name||t.id||t.username?t:void 0}function kt(r){return/\btimed? ?out\b|timeout/i.test(r)?"timed out":"failed"}var me,ge,T,xt,_,St,ce,w,S,fe,pe=m(()=>{"use strict";ue();me="requests",ge=Symbol("requests.pickup");T=new Set(["voice","app","dashboard","webrtc"]),xt=new Set(["camera"]),_=r=>r.toLowerCase().split("@")[0],St=new Set(["github","gitlab"]),ce=(r,n)=>r==="whatsapp"?n.replace(/@.*$/,"").replace(/\D/g,""):n.trim().toLowerCase().replace(/^@/,"");w=(r,n=200)=>{let t=r.replace(/\s+/g," ").trim();return t.length>n?`${t.slice(0,n-1)}\u2026`:t},S=(r,n,t)=>`${r}\0${n}\0${t}`,fe=class{constructor(n,t,a,o=Date.now){this.store=n;this.settings=t;this.log=a;this.now=o}live=new Map;guard(n,t){try{t()}catch(a){this.log(`[requests] ${n} failed: ${a?.message??a}`)}}isListedOwner(n){let t=_(n.channel),a=this.settings().channels;return a.length&&!a.map(_).includes(t)?!1:n.person?.role==="owner"&&!T.has(t)}liveRequestId(n,t,a){return this.live.get(S(n,t,a))?.requestId??null}taskStarted(n){n.taskId&&this.guard("capture",()=>{if(!this.settings().enabled)return;let t=this.now(),a=n.resumedFrom?this.store.byLink("run",n.resumedFrom):null,o=S(n.agentId,n.channel,n.chatId);if(a){this.store.link(a.id,"run",n.taskId,t),a.state==="candidate"?this.store.touch(a.id,t):this.store.progress(a.id,t),this.live.set(o,{requestId:a.id,runId:n.taskId});return}let i=n.pickup&&n.channel===me?this.store.get(n.chatId):null;if(i&&i.agentId===n.agentId){this.store.link(i.id,"run",n.taskId,t),this.store.touch(i.id,t),this.live.set(o,{requestId:i.id,runId:n.taskId});return}!n.humanRoot||!(Et(this.settings(),n.channel,n.sender,n.operator===!0)||this.isListedOwner(n))||(this.live.set(o,{requestId:`req-${n.taskId}`,runId:n.taskId}),this.store.addCandidate({id:`req-${n.taskId}`,runId:n.taskId,channel:n.channel,chatId:n.chatId,sender:n.sender?.name??n.sender?.username??n.sender?.id??null,person:n.person?.id??null,agentId:n.agentId,text:n.requestText??n.fullMessage??n.messagePreview,now:t}))})}taskCompleted(n){n.taskId&&this.guard("run end",()=>{let t=S(n.agentId,n.channel,n.chatId);this.live.get(t)?.runId===n.taskId&&this.live.delete(t);let a=this.store.byLink("run",n.taskId);if(!a)return;let o=this.now();if(!n.interrupted){if(n.error&&n.errorKind!=="cancelled"){let i=kt(n.error);this.store.needsAttention(a.id,`${n.agentId} ${i}: ${w(n.error)}`,o)&&this.log(`[requests] ${a.id} needs attention: run ${n.taskId} ${i}`);return}a.state==="candidate"?this.store.discardCandidate(a.id):this.store.touch(a.id,o)}})}delegationStarted(n){this.guard("delegation start",()=>{if(!this.settings().enabled)return;let t=this.live.get(S(n.caller,n.origin.channel,n.origin.chatId));if(!t)return;let a=this.now();this.store.link(t.requestId,"delegation",n.id,a),this.store.progress(t.requestId,a,"waiting_other")})}delegationDone(n,t,a){this.guard("delegation end",()=>{let o=this.store.byLink("delegation",n.id);if(!o)return;let i=this.now(),l=n.peer?`${n.callee} on ${n.peer}`:n.callee;if(t==="done"){this.store.progress(o.id,i);return}let u={error:"failed",timeout:"did not answer in time",lost:"was lost in a restart"}[t];this.store.needsAttention(o.id,`The work handed to ${l} ${u}: ${w(a)}`,i)&&this.log(`[requests] ${o.id} needs attention: delegation ${n.id} ${t}`)})}cardRaised(n,t){t&&this.guard("card",()=>{if(!this.settings().enabled)return;let a=this.live.get(S(n.raised_by,t.channel,t.chatId))?.requestId;if(!a)return;let o=this.now();this.store.link(a,"card",n.id,o),this.store.waitOnOwner(a,n.ask,o)})}cardResolved(n){this.guard("card result",()=>{let t=this.store.byLink("card",n.id);if(!t)return;let a=this.now(),o=n.outcome??n.if_silent;n.status==="decided"||o==="approve"?t.state==="waiting_owner"&&this.store.progress(t.id,a):this.store.needsAttention(t.id,`Your answer did not come before the card expired (${w(n.ask)}); "${o}" was applied`,a)&&this.log(`[requests] ${t.id} needs attention: card ${n.id} expired unanswered`)})}closingNote(n){try{let t=this.store.byLink("delegation",n);return!t||!y.includes(t.state)?void 0:`This is part of the owner's open request ${t.id}. It stays on their list until it is closed. If it is finished now, close it with agentx_request: {action:"done", id:"${t.id}", evidence:"<link to the proof>"}. If you will not do it, use decline with the reason. If work goes on, leave it open.`}catch{return}}resumeOutcome(n){this.guard("restart",()=>{let t=this.store.byLink("run",n.taskId);if(!t)return;let a=this.now();n.decision==="resumed"?t.state==="candidate"?this.store.touch(t.id,a):this.store.progress(t.id,a):(n.decision==="reported"||n.decision==="resume-failed"||n.decision==="skipped")&&this.store.needsAttention(t.id,`Cut off by a restart and not picked up again (${w(n.reason)})`,a)&&this.log(`[requests] ${t.id} needs attention: run ${n.taskId} cut off by a restart`)})}}});import{randomBytes as wt,timingSafeEqual as he}from"crypto";import{chmodSync as _t,existsSync as Tt,mkdirSync as At,readFileSync as Rt,writeFileSync as It}from"fs";import{networkInterfaces as vt}from"os";import{dirname as Ct,resolve as Lt}from"path";function Zn(r){return Object.assign(r,{[ye]:!0})}function xe(r){return!!r&&r[ye]===!0}function jt(r=process.cwd()){return Lt(r,".agentx","operator.key")}function Gn(r=process.cwd(),n={}){let t=jt(r);try{if(Tt(t)){let o=Rt(t,"utf-8").trim();if(o)return o}if(!n.create)return null;let a=wt(32).toString("hex");return At(Ct(t),{recursive:!0}),It(t,a+`
42
- `,{mode:384}),_t(t,384),a}catch{return null}}function Nt(r,n){let t=Array.isArray(n)?n[0]:n;if(!r||!t)return!1;let a=Buffer.from(r),o=Buffer.from(t.trim());return a.length===o.length&&he(a,o)}function Dt(r,n,t,a){if(!r||typeof r!="object")return!1;let o=String(r.channel??"").toLowerCase().split("@")[0];return a.has(o)?Nt(t,n[Ot]):!1}function Pt(r,n){let t=r[$t];if((Array.isArray(t)?t[0]:t)!=="1")return!1;let a=r.authorization,o=(Array.isArray(a)?a[0]:a)||"",i=o.toLowerCase().startsWith("bearer ")?o.slice(7).trim():"";if(!i)return!1;let l=Buffer.from(i);for(let u of n){if(!u)continue;let f=Buffer.from(u);if(f.length===l.length&&he(f,l))return!0}return!1}function qt(r,n=Mt()){let t=be(r??"");if(!t||t==="::1"||t.startsWith("127."))return!0;for(let a of n)if(be(a)===t)return!0;return!1}function Mt(){return Object.values(vt()).flatMap(r=>(r??[]).map(n=>n.address))}function Yn(r,n,t){if(Dt(r,n.headers,t.key,t.operatorChannels))return!0;if(!r||typeof r!="object")return!1;let a=String(r.channel??"").toLowerCase().split("@")[0];return!t.operatorChannels.has(a)||qt(n.remoteAddress,t.ownAddresses)?!1:Pt(n.headers,t.peerTokens)}var Ot,ye,$t,be,Se=m(()=>{"use strict";Ot="x-agentx-operator",ye=Symbol("requests.operator");$t="x-agentx-operator-vouch";be=r=>r.toLowerCase().replace(/^::ffff:/,"").replace(/%.*$/,"")});function nr(r,n){return r.find(t=>t.id===n)?.name??(n===A?"Owner":n)}function Ee(r,n){let t=n.trim().toLowerCase();return r==="whatsapp"?t.replace(/@.*$/,"").replace(/\D/g,""):t.replace(/^@/,"")}function ke(r){let n=r.indexOf(":");if(n<=0||n===r.length-1)return null;let t=D(r.slice(0,n).trim()),a=Ee(t,r.slice(n+1));return a?{channel:t,value:a}:null}function we(r){let n=new Set,t=new Map;for(let a of r){if(n.has(a.id))return`person "${a.id}" is listed twice`;if(n.add(a.id),a.id===A&&a.role!=="owner")return`the id "${A}" is kept for a person with the owner role`;for(let o of a.identities){let i=ke(o);if(!i)return`identity "${o}" of "${a.id}" must be written channel:id`;let l=`${i.channel}:${i.value}`,u=t.get(l);if(u&&u!==a.id)return`identity "${o}" belongs to both "${u}" and "${a.id}"`;t.set(l,a.id)}}return null}function Bt(r,n,t){let a=D(n),i=(a==="whatsapp"?[t?.id]:[t?.id,t?.username]).filter(l=>typeof l=="string"&&!!l).map(l=>Ee(a,l)).filter(Boolean);return i.length?r.find(l=>l.identities.some(u=>{let f=ke(u);return!!f&&f.channel===a&&i.includes(f.value)}))??null:null}function Ut(r){let n=r.filter(t=>t.role==="owner");return n.length===0?{id:A,role:"owner"}:n.length===1?{id:n[0].id,role:"owner"}:null}function _e(r,n){let t=M(n);if(t)return t.person?{id:t.person}:null;if(!n||B(n)!=="human")return null;let a=String(n.channel??"");if(T.has(D(a)))return xe(n)?Ut(r):null;let o=l=>typeof l=="string"?l:void 0,i=Bt(r,a,{id:o(n.senderId),username:o(n.senderUsername)});return i?{id:i.id,role:i.role}:null}function Ft(r,n){let t=r.agents??[];return r.role==="owner"||t.length===0||t.includes(n)}function rr(r,n,t){let a=_e(r,t);if(!a)return null;let o=r.find(l=>l.id===a.id);if(!o||Ft(o,n))return null;let i=(o.agents??[]).join(", ");return{person:o,note:`${o.name}, you can reach ${i} here, not ${n}. Ask the owner if you need ${n}.`}}function ar(r,n){let t=r.trim().split("*").map(a=>a.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${t}$`,"i").test(n.trim())}function or(r,n){let t=_e(r,n);if(!t)return null;let a=r.find(l=>l.id===t.id);if(!a||a.role==="owner")return null;let o=a.deny?.tools??[],i=a.deny?.skills??[];return!o.length&&!i.length?null:{personId:a.id,name:a.name,tools:[...o],skills:[...i]}}var tr,A,D,Te=m(()=>{"use strict";Fe();pe();Se();tr=["owner","member","client","guest"],A="owner";D=r=>r.toLowerCase().split("@")[0]});var pn={};Be(pn,{INTEGRATION_KINDS:()=>Yt,approvalsConfigSchema:()=>qe,callsSchema:()=>Oe,cameraBotSchema:()=>Le,daemonConfigSchema:()=>Me,eventSubscriptionSchema:()=>Ce,expandEnvVars:()=>C,loadDaemonConfig:()=>mn,membersConfigSchema:()=>De,peopleConfigSchema:()=>$e,personSchema:()=>Ne,requestStatusConfigSchema:()=>Pe,requestsConfigSchema:()=>je,validateWorkspaces:()=>gn});import{z as e}from"zod";import{readFileSync as Ae,existsSync as I}from"fs";import{resolve as v}from"path";function Ht(r){let n=v(r,".env");if(!I(n))return;let t=Ae(n,"utf-8");for(let a of t.split(`
43
- `)){let o=a.trim();if(!o||o.startsWith("#"))continue;let i=o.indexOf("=");if(i===-1)continue;let l=o.slice(0,i).trim(),u=o.slice(i+1).trim();process.env[l]||(process.env[l]=u)}}function C(r){if(typeof r=="string")return r.replace(/\$\{(\w+)\}/g,(n,t)=>process.env[t]||"");if(Array.isArray(r))return r.map(C);if(r!==null&&typeof r=="object"){let n={};for(let[t,a]of Object.entries(r))n[t]=C(a);return n}return r}function fn(r,n){let t=[],a=new Set;for(let o of r){let i=o.path.join("."),l=/^channels\.telegram\.accounts\.([^.]+)\.token$/.exec(i);if(l&&o.message.toLowerCase().includes("required")){let u=l[1],f=`tg:${u}`;if(a.has(f))continue;a.add(f),t.push(`Hint: Telegram account "${u}" is enabled but has no bot token.
44
- Either:
45
- A) Open ${n} and set channels.telegram.accounts.${u}.token to your bot token (or "\${TG_${u.toUpperCase()}_BOT_TOKEN}" + the matching .env entry).
46
- B) If you don't need Telegram on this instance, remove the entire "telegram" block under "channels" (or set channels.telegram.enabled to false AND drop accounts.${u}).`)}}return t}function mn(r){let n=r?[r]:[v(process.cwd(),"agentx.json"),v(process.cwd(),".agentx/config.json")];Ht(process.cwd());let t,a;for(let u of n)if(I(u)){t=Ae(u,"utf-8"),a=u;break}if(!t||!a)throw new Error(`No config found. Create agentx.json or .agentx/config.json
47
- Searched: ${n.join(", ")}`);let o;try{o=JSON.parse(t)}catch(u){throw new Error(`Invalid JSON in ${a}: ${u.message}`)}let i=C(o),l=Me.safeParse(i);if(!l.success){let u=l.error.issues.map(P=>` ${P.path.join(".")}: ${P.message}`).join(`
48
- `),f=fn(l.error.issues,a),b=f.length?`
49
-
50
- ${f.join(`
51
-
52
- `)}`:"";throw new Error(`Config validation failed (${a}):
53
- ${u}${b}`)}return l.data}function gn(r){let n=[];for(let[t,a]of Object.entries(r.agents)){if(!I(a.workspace)){n.push(`Agent "${t}": workspace not found at ${a.workspace}`);continue}if(a.tier==="claude-code"){let l=v(a.workspace,".claude");I(l)||n.push(`Agent "${t}": no .claude/ directory in workspace ${a.workspace}. Claude Code native features (hooks, MCP, skills) won't be available.`)}let o=a.provider||"claude",i=r.providers[o];!["claude-code","codex-cli","opencode"].includes(a.tier)&&(!i||!i.apiKey)&&n.push(`Agent "${t}": provider "${o}" has no API key configured. Set providers.${o}.apiKey in config or use a CLI-backed tier ("claude-code", "codex-cli", or "opencode").`)}for(let[t,a]of Object.entries(r.crons))r.agents[a.agent]||n.push(`Cron "${t}": references unknown agent "${a.agent}"`);if(r.channels.telegram.enabled)for(let[t,a]of Object.entries(r.channels.telegram.accounts))r.agents[a.agentBinding]||n.push(`Telegram account "${t}": references unknown agent "${a.agentBinding}"`);return n}var zt,Wt,Kt,Xt,Zt,Gt,Yt,Re,Ie,R,ve,Ce,Vt,Jt,Le,Qt,en,tn,nn,rn,an,on,sn,ln,Oe,dn,un,cn,je,Ne,$e,De,Pe,qe,Me,bn=m(()=>{z();X();Ue();Y();ee();re();oe();le();Te();zt=e.object({apiKey:e.string().optional(),defaultModel:e.string().optional(),baseUrl:e.string().optional(),thinking:e.boolean().optional()}),Wt=e.object({type:e.literal("stdio").optional(),command:e.string(),args:e.array(e.string()).default([]),env:e.record(e.string(),e.string()).optional()}),Kt=e.object({type:e.literal("http"),url:e.string().url(),headers:e.record(e.string(),e.string()).optional()}),Xt=e.union([Kt,Wt]),Zt=e.object({tokenEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),privateAppTokenEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),apiKeyEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),refreshTokenEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),clientIdEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),clientSecretEnv:e.string().regex(/^[A-Z][A-Z0-9_]*$/).optional(),auth:e.literal("keyring").optional(),sessionDir:e.string().optional()}).strict(),Gt=e.object({kind:e.string().min(1),label:e.string().min(1),credentials:Zt.default({}),metadata:e.record(e.string(),e.union([e.string(),e.number(),e.boolean()])).default({}),enabled:e.boolean().default(!0)}),Yt=["telegram-bot","whatsapp","gitlab-user","github-user","gmail","hotmail","smtp","hubspot","salesforce","pipedrive","odoo","trello","linear","asana","jira","notion","stripe","sentry","vercel","twilio","custom"],Re=e.enum(["system","elevenlabs"]),Ie=e.union([e.string(),e.record(e.string(),e.string())]),R=e.string().superRefine((r,n)=>{let t=G(r);t&&n.addIssue({code:e.ZodIssueCode.custom,message:`shortcut ${t}`})}),ve=e.object({provider:Re.optional(),system:Ie.optional(),fallbacks:e.array(e.string().min(1)).optional(),elevenlabsVoiceId:e.string().optional(),gender:e.enum(["female","male","neutral"]).optional(),style:e.string().optional(),intro:e.string().optional(),narrate:e.enum(["off","on","all"]).optional(),rate:e.number().min(.75).max(1.5).optional(),priority:e.enum(["high","normal","low"]).optional(),hotkey:R.optional()}),Ce=e.object({kinds:e.array(e.string().min(1)).min(1),agents:e.array(e.string().min(1)).optional(),nodes:e.array(e.string().min(1)).optional(),match:e.string().min(1).optional(),delivery:e.enum(["pull","digest","wake"]).default("pull"),maxPerHour:e.number().int().min(1).max(60).default(4)}),Vt=e.object({name:e.string(),workspace:e.string(),tier:e.enum(["claude-code","codex-cli","opencode","sdk","orchestrator"]).default("claude-code"),provider:e.string().optional(),model:e.string().optional(),systemPrompt:e.string().optional(),mentions:e.array(e.string()).default([]),intents:e.array(e.string()).default([]),maxDelegationDepth:e.number().int().min(0).max(50).default(5),mcp:e.record(e.string(),Xt).optional(),codegraph:e.boolean().default(!1),contextStrategy:e.enum(["layered","planner"]).optional(),contextReferences:e.boolean().default(!1),richMessages:e.boolean().default(!0),maxConcurrent:e.number().default(1),maxExecutionMinutes:e.number().int().min(1).max(240).default(20),preSpawnTimeoutSec:e.number().int().min(10).max(3600).default(300),drainTimeoutSeconds:e.number().int().min(0).max(86400).optional(),permissionMode:e.string().default("default"),billing:e.enum(["subscription","api"]).default("subscription"),cloudSessions:e.object({enabled:e.boolean().default(!1),maxPerDay:e.number().int().min(0).default(0),openHours:e.number().min(1).max(168).default(24),launchTimeoutSeconds:e.number().int().min(10).max(600).default(120)}).default({}),toolUseRequired:e.array(e.string()).default([]),gitlabAutoReply:e.boolean().optional(),persistentProcess:e.boolean().default(!1),queueMode:e.enum(["collect","followup","drop"]).default("collect"),heartbeat:e.object({enabled:e.boolean().default(!1),intervalMinutes:e.number().default(30),prompt:e.string().default("Check inbox, pending tasks, and system health. Report anything that needs attention."),channel:e.string().default("heartbeat")}).default({}),access:e.enum(["private","public"]).default("private"),admin:e.boolean().optional(),subscriptions:e.array(Ce).default([]),integrations:e.array(Gt).default([]),voice:ve.optional(),presence:e.object({color:e.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),palette:e.enum(L).optional(),initial:e.string().max(2).optional(),label:e.string().optional(),allowActions:e.boolean().optional()}).optional()}),Jt=e.object({token:e.string(),agentBinding:e.string(),allowFrom:e.array(e.string()).optional(),pollInbound:e.boolean().default(!0)}),Le=e.object({frameIntervalSeconds:e.number().int().min(0).max(3600).default(0),maxSessionMinutes:e.number().int().min(1).max(240).default(10),maxFrameEdge:e.number().int().min(160).max(3840).default(1024),keepFrames:e.boolean().default(!1),streamFrameSeconds:e.number().int().min(2).max(60).default(5),streamMaxSeconds:e.number().int().min(10).max(600).default(60)}).default({}),Qt=e.object({telegram:e.object({enabled:e.boolean().default(!1),accounts:e.record(e.string(),Jt).default({}),policy:e.object({dm:e.enum(["pair","block"]).default("pair"),group:e.enum(["mention-required","all"]).default("mention-required"),allowFrom:e.array(e.string()).optional()}).default({})}).default({}),whatsapp:e.object({enabled:e.boolean().default(!1),sessionDir:e.string().default(".agentx/whatsapp-sessions"),defaultAgent:e.string().optional(),allowFrom:e.array(e.string()).optional(),routes:e.array(e.object({contact:e.string().optional(),group:e.string().optional(),agent:e.string()})).default([]),ingest:e.object({enabled:e.boolean().default(!1),mode:e.enum(["metadata-only","messages"]).default("metadata-only"),allowContacts:e.array(e.string()).default([]),allowGroups:e.array(e.string()).default([]),denyContacts:e.array(e.string()).default([]),denyGroups:e.array(e.string()).default([]),messageCap:e.number().int().min(1).max(500).default(50),historyDays:e.number().int().min(1).max(365).default(30),contactRefreshDays:e.number().int().min(1).max(90).default(7),throttle:e.object({minMsBetweenCalls:e.number().int().min(100).default(1500),maxCallsPerMinute:e.number().int().min(1).default(20),maxChatsPerSweep:e.number().int().min(1).default(25)}).default({}),retentionDays:e.number().int().min(0).default(0)}).default({})}).default({}),gitlab:e.object({enabled:e.boolean().default(!1),webhookPort:e.number().default(18810),webhookSecret:e.string().optional(),host:e.string().default("https://gitlab.com"),token:e.string().optional(),autoReplyLegacy:e.boolean().default(!0),routes:e.array(e.object({project:e.string(),agent:e.string()})).default([]),agentMappings:e.array(e.object({agentId:e.string(),gitlabUsernames:e.array(e.string()).default([]),keywords:e.array(e.string()).default([]),token:e.string().optional(),node:e.string().optional()})).default([]),agentUsernamePrefixes:e.array(e.string().min(1)).default([])}).default({}),github:e.object({enabled:e.boolean().default(!1),autoReplyLegacy:e.boolean().default(!0),cloudSessions:e.boolean().default(!1),token:e.string().optional(),tokenFile:e.string().optional(),appId:e.number().optional(),clientId:e.string().optional(),privateKeyFile:e.string().optional(),webhookSecret:e.string().optional(),routes:e.array(e.object({repo:e.string(),agent:e.string()})).default([]),agentMappings:e.array(e.object({agentId:e.string(),githubUsernames:e.array(e.string()).default([]),token:e.string().optional(),tokenFile:e.string().optional(),node:e.string().optional()})).default([]),issueActions:e.array(e.string().min(1)).default(["opened","reopened","assigned"]),pullRequestActions:e.array(e.string().min(1)).default(["opened","reopened","ready_for_review"]),ignoreOwnChanges:e.boolean().default(!0),debounceSeconds:e.number().min(0).max(3600).default(30)}).default({}),ntfy:e.object({enabled:e.boolean().default(!1),server:e.string().default("https://ntfy.sh"),topic:e.string().optional(),token:e.string().optional(),defaultPriority:e.number().int().min(1).max(5).default(3),defaultTitle:e.string().optional()}).default({}),push:e.object({enabled:e.boolean().default(!1),keysFile:e.string().default(".agentx/push-keys.json"),subject:e.string().regex(/^(mailto:|https:\/\/)/,"must start with mailto: or https://").optional(),relayTo:e.string().optional(),ttlSeconds:e.number().int().min(0).max(2419200).default(86400),keepRecent:e.number().int().min(0).max(1e3).default(50),allowedHosts:e.array(e.string().min(1)).default(["fcm.googleapis.com","push.services.mozilla.com","push.apple.com","notify.windows.com"])}).default({}),webrtc:e.object({enabled:e.boolean().default(!1),stunServers:e.array(e.string()).default(["stun:stun.l.google.com:19302"]),turnServers:e.array(e.object({urls:e.string(),username:e.string().optional(),credential:e.string().optional()})).default([]),allowedCallers:e.array(e.string()).default([]),ringNotify:e.array(e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()})).default([]),callUrlBase:e.string().optional(),bot:e.object({enabled:e.boolean().default(!1),defaultAgentId:e.string().optional(),whisperBackend:e.enum(["auto","mlx","openai"]).default("auto"),whisperModel:e.string().optional(),whisperLanguage:e.string().default("auto"),mlxBinary:e.string().optional(),transcriptChannel:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional(),maxCallMinutes:e.number().int().min(1).max(240).default(30)}).default({}),camera:e.object({width:e.number().int().min(160).max(3840).default(1280),height:e.number().int().min(120).max(2160).default(720),frameRate:e.number().int().min(1).max(60).default(15),maxSeconds:e.number().int().min(10).max(7200).default(600),voiceInput:e.boolean().default(!0),speakAnswers:e.boolean().default(!0),bot:Le}).default({})}).default({})}),en=e.object({enabled:e.boolean().default(!0),schedule:e.string(),timezone:e.string().default("UTC"),agent:e.string(),prompt:e.string().default(""),command:e.string().optional(),timeout:e.number().default(600),model:e.string().optional(),maxOutputTokens:e.number().int().min(50).max(8e3).optional(),autonomy:q.optional(),onError:e.union([e.enum(["log","notify","disable"]),e.array(e.enum(["log","notify","disable"]))]).default("log").transform(r=>Array.isArray(r)?r:[r]),notify:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional(),fireToken:e.string().optional(),createdBy:e.string().optional(),approval:e.object({action:e.enum(["create","delete"]),requestedBy:e.string(),requestedAt:e.string()}).optional()}).refine(r=>!!(r.command?.trim()||r.prompt?.trim()),{message:"a cron needs either a prompt (dispatch an agent) or a command (run it directly)"}).refine(r=>!(r.command?.trim()&&r.autonomy&&r.autonomy!=="act"),{message:"autonomy applies to agent routines; a command cron runs no agent (remove autonomy or the command)"}),tn=e.object({name:e.string(),triggers:e.array(e.object({pattern:e.string(),channel:e.string().optional()})),allowedContacts:e.array(e.string()).optional(),agent:e.string(),prompt:e.string(),schedule:e.string().optional(),timezone:e.string().default("UTC"),notify:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional()}),nn=e.object({url:e.string(),name:e.string(),token:e.string().optional()}),rn=e.object({name:e.string(),agent:e.string(),enabled:e.boolean().default(!0)}),an=e.object({enabled:e.boolean().default(!1),peers:e.array(nn).default([]),inboxes:e.array(rn).default([]),discovery:e.enum(["static","mdns"]).default("static"),healthCheck:e.object({interval:e.number().default(60),timeout:e.number().default(10)}).default({}),feed:e.object({enabled:e.boolean().default(!0),skipTypes:e.array(e.string().min(1)).default(["task:step"])}).default({}),delegation:e.object({asyncWhenHuman:e.boolean().default(!0),timeoutMinutes:e.number().int().min(1).max(240).default(30)}).default({})}),on=e.object({enabled:e.boolean().default(!1),baseDir:e.string().default(".agentx/graph"),draftAgent:e.string().optional(),reviewAgent:e.string().optional(),autoApproveStructure:e.enum(["strict","extend-leaves","any"]).default("extend-leaves"),autoApproveConfidence:e.number().min(0).max(1).default(1),classifierModel:e.string().default("claude-haiku-4-5-20251001"),retrievalWeights:e.object({graph:e.number().min(0).default(.6),bm25:e.number().min(0).default(.4)}).default({})}).default({}),sn=e.object({mode:e.enum(["off","shadow","active"]).default("off"),backend:e.string().optional(),model:e.string().optional(),timeoutMs:e.number().int().min(100).optional(),temperature:e.number().min(.01).default(1),explore:e.number().min(0).max(1).default(.15),holdout:e.number().min(0).max(1).optional()}).default({}),ln=e.object({enabled:e.boolean().default(!1),dbPath:e.string().default(".agentx/decisions/decisions.sqlite"),redactState:e.boolean().default(!1),keepStateRows:e.number().int().min(0).default(2e3),defaultBackend:e.string().default("local"),backends:e.object({local:e.object({provider:e.string().default("claude-code"),model:e.string().default("claude-haiku-4-5-20251001"),structureMode:e.enum(["auto","tool","text"]).default("auto"),normalizeProbabilities:e.boolean().default(!0),nRetryMalformedStructure:e.number().int().min(0).max(3).default(1),maxStateChars:e.number().int().min(500).default(24e3)}).default({}),simpleJev:e.object({baseUrl:e.string().default("http://127.0.0.1:8000/v1"),model:e.string().optional(),apiKeyEnv:e.string().optional(),timeoutMs:e.number().int().min(100).default(3e4),maxStateChars:e.number().int().min(500).default(6e3),maxChoiceOptions:e.number().int().min(2).max(255).default(50)}).default({}),jev:e.object({baseUrl:e.string().default("https://openrouter.ai/api/alpha"),path:e.string().default("/decisions"),model:e.string().default("jev-latest"),apiKeyEnv:e.string().default("OPENROUTER_API_KEY"),timeoutMs:e.number().int().min(100).default(3e4),maxStateChars:e.number().int().min(500).default(9e4),maxChoiceOptions:e.number().int().min(2).max(255).default(255)}).default({}),typesafe:e.object({baseUrl:e.string().default("https://api.typesafe.ai/v1"),path:e.string().default("/systemone"),model:e.string().default("jev-latest"),apiKeyEnv:e.string().default("TYPESAFE_API_KEY"),timeoutMs:e.number().int().min(100).default(3e4),maxStateChars:e.number().int().min(500).default(9e4),maxChoiceOptions:e.number().int().min(2).max(255).default(255)}).default({})}).default({}),seats:e.record(e.string(),sn).default({}),routing:e.object({cheapModel:e.string().optional(),cheapModels:e.object({"claude-code":e.string().optional(),"codex-cli":e.string().optional()}).optional()}).default({})}).default({}),Oe=e.object({allow:e.array(e.string()).default([]),maxPerHour:e.number().int().min(1).max(60).default(3),ringSeconds:e.number().int().min(10).max(300).default(45),maxCallMinutes:e.number().int().min(1).max(240).default(30),ringSound:e.string().regex(/^[\w -]+$/).default("Submarine"),summary:e.boolean().default(!0)}).default({}),dn=e.object({longTaskThreshold:e.number().default(30),destination:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional(),channel:e.string().optional(),on:e.object({taskComplete:e.boolean().default(!0),taskError:e.boolean().default(!0),taskQueued:e.boolean().default(!1)}).default({}),local:e.object({banner:e.boolean().default(!0),sound:e.boolean().default(!0),soundName:e.string().regex(/^[\w -]+$/).default("Glass"),volume:e.number().min(0).max(1).default(.4),icon:e.string().optional()}).default({})}).default({}),un=e.object({x:e.number(),y:e.number(),width:e.number().positive(),height:e.number().positive()}),cn=e.object({maxPixels:e.number().int().positive().default(12e5),timeoutMs:e.number().int().positive().default(5e3),intervalMs:e.number().int().positive().default(100),changeThreshold:e.number().min(0).max(1).default(.015),stableMs:e.number().int().nonnegative().default(400),regions:e.record(e.string().regex(/^[a-z][\w-]*$/),un).default({}),buffer:e.object({enabled:e.boolean().default(!1),seconds:e.number().positive().max(120).default(10),fps:e.number().positive().max(10).default(2),region:e.string().default("screen"),maxPixels:e.number().int().positive().default(3e5)}).default({})}).default({}),je=e.object({enabled:e.boolean().default(!1),channels:e.array(e.string().min(1)).default([]),from:e.array(e.string().regex(/^[a-z0-9_-]+:\S+$/i,"use channel:id, for example telegram:123456789")).default([]),staleAfterHours:e.number().positive().max(24*365).default(24),retentionDays:e.number().positive().max(3650).default(90)}).default({}),Ne=e.object({id:e.string().regex(/^[a-z0-9][a-z0-9_-]{0,39}$/,"lower-case letters, digits, - and _"),name:e.string().min(1).max(80),say:e.string().trim().min(1).max(120).optional(),role:e.enum(["owner","member","client","guest"]).default("member"),identities:e.array(e.string().regex(/^[A-Za-z][\w-]*:\S.*$/,"write it as channel:id")).default([]),agents:e.array(e.string().min(1)).default([]),deny:e.object({tools:e.array(e.string().min(1)).default([]),skills:e.array(e.string().min(1)).default([])}).strict().default({})}),$e=e.array(Ne).default([]).superRefine((r,n)=>{let t=we(r);t&&n.addIssue({code:e.ZodIssueCode.custom,message:t})}),De=e.object({logRetentionDays:e.number().int().min(1).max(3650).default(90)}).default({}),Pe=e.object({channels:e.array(e.string().min(1)).default([])}).default({}),qe=e.object({defaultExpiryDays:e.number().positive().max(365).default(3),maxExpiryDays:e.number().positive().max(365).default(30),laterHours:e.number().positive().max(24*30).default(24),notifyAgent:e.boolean().default(!0),forwardTo:e.string().min(1).optional(),digest:e.object({enabled:e.boolean().default(!0),time:e.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/,"use HH:MM, 24-hour").default("09:00"),timezone:e.string().refine(r=>{try{return new Intl.DateTimeFormat("en-US",{timeZone:r}),!0}catch{return!1}},"unknown timezone").optional(),destination:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional()}).default({}),popup:e.object({enabled:e.boolean().default(!1),style:e.enum(["card","dialog"]).default("card"),theme:e.enum(["system","light","dark"]).default("system"),speak:e.boolean().default(!0),voice:e.string().regex(/^[\w .()-]+$/,"a voice name, as `say -v '?'` lists them").optional(),sound:e.string().regex(/^[\w -]*$/,"a sound name, like chime or Glass").default("chime"),volume:e.number().min(0).max(1).default(.4),timeoutSeconds:e.number().int().min(10).max(3600).default(600)}).default({}),checkin:e.object({enabled:e.boolean().default(!1),times:e.array(e.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/,"use HH:MM, 24-hour")).default(["11:00","14:00","17:00"]),dailyAt:e.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/,"use HH:MM, 24-hour").default("09:00"),timezone:e.string().refine(r=>{try{return new Intl.DateTimeFormat("en-US",{timeZone:r}),!0}catch{return!1}},"unknown timezone").optional(),lists:e.array(e.string().min(1)).default(["Reminders"]),agent:e.string().min(1).optional(),dueWithinHours:e.number().positive().max(24*30).default(24),maxAsksPerPass:e.number().int().min(1).max(20).default(5),composeTimeoutSeconds:e.number().int().min(30).max(3600).default(300)}).default({})}).default({}),Me=e.object({node:e.object({id:e.string(),name:e.string(),bind:e.string().default("127.0.0.1:18800"),defaultAgent:e.string().optional()}),providers:e.record(e.string(),zt).default({}),agents:e.record(e.string(),Vt).default({}),channels:Qt.default({}),crons:e.record(e.string(),en).default({}),services:e.record(e.string(),tn).default({}),notifications:dn,calls:Oe,whatsappTriage:se,approvals:qe,shutdown:e.object({drainTimeoutSeconds:e.number().int().min(0).max(86400).optional(),restart:e.object({allowBy:e.string().optional(),window:e.string().regex(/^\d{1,2}:\d{2}$/,"window must be HH:MM").optional(),windowWaitMinutes:e.number().int().min(1).max(1440).default(180),forbidOnTimeoutRestart:e.boolean().default(!1)}).default({})}).default({}),resume:e.object({enabled:e.boolean().default(!0),maxAgeMinutes:e.number().int().positive().default(30),maxAttempts:e.number().int().min(0).default(1),reportOnlyChannels:e.array(e.string()).default([]),directChannels:e.array(e.string()).default([]),crashLoop:e.object({restarts:e.number().int().positive().default(3),windowMinutes:e.number().positive().default(10)}).default({})}).default({}),requests:je,people:$e,members:De,requestStatus:Pe,reminders:e.object({enabled:e.boolean().default(!1),lists:e.array(e.string().min(1)).default(["AgentX"]),pollSeconds:e.number().int().min(15).default(60),lookbackHours:e.number().positive().default(24),command:e.string().min(1).default("remindctl")}).default({}),app:e.object({android:e.object({packageName:e.string().regex(/^[a-zA-Z][\w]*(\.[a-zA-Z][\w]*)+$/,"must look like com.example.app").default("dev.agentx.phone"),certFingerprints:e.array(e.string().regex(/^([0-9A-Fa-f]{2}:){31}[0-9A-Fa-f]{2}$/,"must be 32 hex pairs separated by colons")).default([])}).default({}),places:e.object({enabled:e.boolean().default(!0),file:e.string().min(1).default(".agentx/places.json"),defaultRadiusMeters:e.number().int().min(50).max(5e4).default(150),minRadiusMeters:e.number().int().min(50).max(5e4).default(100),maxRadiusMeters:e.number().int().min(50).max(5e4).default(5e3),maxPlaces:e.number().int().min(1).max(100).default(50),maxRulesPerPlace:e.number().int().min(1).max(50).default(10),cooldownMinutes:e.number().int().min(0).max(1440).default(10),maxEventAgeMinutes:e.number().int().min(1).max(1440).default(30),syncMinutes:e.number().int().min(15).max(1440).default(60)}).default({})}).default({}),demo:e.object({startupTimeoutSeconds:e.number().int().positive().max(3600).optional()}).default({}),events:e.object({ringSize:e.number().int().min(1).max(1e5).default(1e3)}).default({}),screen:cn,mesh:an.default({}),meshVoices:e.record(e.string(),ve.omit({rate:!0,priority:!0,hotkey:!0}).extend({name:e.string().optional()})).default({}),voice:e.object({provider:Re.default("system"),fallback:e.enum(["system","none"]).default("system"),system:Ie.optional(),locale:e.string().default("en"),listener:e.string().optional(),pronunciations:e.array(e.object({written:e.string().trim().min(1).max(80),spoken:e.string().trim().min(1).max(120),languages:e.array(e.enum(["en","fr","ar"])).optional()}).strict()).max(200).default([]),pointer:e.boolean().default(!0),stt:e.enum(["auto","elevenlabs","local"]).default("auto"),allowUnmeasured:e.boolean().default(!1),spokenMaxChars:e.number().int().min(300).max(1500).default(O),noiseFilter:e.object({enabled:e.boolean().default(!0),markers:e.array(e.string()).default(j)}).default({}),localStt:e.enum(["mlx-whisper","parakeet"]).default("mlx-whisper"),endOfTurn:e.enum(["vad","volume"]).default("vad"),hotkeys:e.object({talk:R.default(E.talk),stop:R.default(E.stop),paste:R.default(E.paste)}).default({}),look:e.enum(V).default("orb"),startReduced:e.boolean().default(!1),stroll:e.boolean().default(!1),animations:e.enum(J).default("sometimes"),palette:e.enum(L).default(k),card:e.object({timeout:e.number().min(0).max(600).default(30),maxHeight:e.number().min(120).max(800).default(320)}).default({})}).default({}),business:H.optional(),boards:W,dashboard:K,graph:on,decisions:ln,workflows:e.object({enabled:e.boolean().default(!1),dir:e.string().default(".agentx/workflows"),n8n:e.object({baseUrl:e.string().default(""),apiKey:e.string().default("")}).default({baseUrl:"",apiKey:""}),matching:e.object({enabled:e.boolean().default(!1),mode:e.enum(["suggest","auto"]).default("suggest"),autoRunThreshold:e.number().min(0).max(1).default(.85),suggestThreshold:e.number().min(0).max(1).default(.65)}).default({}),editor:e.enum(["disabled","readonly","edit"]).default("edit")}).default({}),procedures:e.object({enabled:e.boolean().default(!0),dir:e.string().default(".agentx/procedures"),extraction:e.object({enabled:e.boolean().default(!1),onTaskCompletion:e.boolean().default(!1),minOccurrences:e.number().int().min(2).default(3),sinceDays:e.number().int().min(1).default(7),maxClusters:e.number().int().min(1).default(5),via:e.string().optional()}).default({}),injection:e.object({enabled:e.boolean().default(!0),maxProcedures:e.number().int().min(1).default(2),minScore:e.number().min(0).max(1).default(.5)}).default({})}).default({}),webhooks:e.array(e.object({id:e.string().regex(/^[a-z0-9][a-z0-9_-]*$/,"webhook id must be lowercase slug"),source:e.string().min(1),agentId:e.string(),secretEnv:e.string().optional(),description:e.string().optional(),enabled:e.boolean().default(!0),node:e.string().optional(),triggers:e.record(e.string(),e.string()).optional(),defaultWorkflow:e.string().optional()})).default([]),session:e.object({staleMinutes:e.number().int().min(1).max(1440).default(720),maxTurnsPerSession:e.number().int().min(2).max(200).default(40),tierTwoThresholdTokens:e.number().int().min(5e4).max(2e5).default(18e4),tierTwoThresholdTokensByChannel:e.record(e.number().int().min(5e4).max(2e5)).default({}),contextStrategy:e.enum(["layered","planner"]).default("layered"),maxClaudeCodeDispatchesPerHour:e.number().int().min(0).max(1e4).optional(),maxClaudeCodeDispatchesPer5h:e.number().int().min(0).max(5e4).optional(),continuityStateTurns:e.number().int().min(0).max(5).default(0),profileByChannel:e.record(e.enum(["full","lean"])).default({}),lean:e.object({mcpServers:e.array(e.string().min(1)).default(["agentx"]),settingSources:e.array(e.enum(["user","project","local"])).default(["project","local"]),contextOnDemand:e.boolean().default(!0),tools:e.array(e.string().min(1)).default([]),toolsByChannel:e.record(e.array(e.string().min(1))).default({})}).default({}),triage:e.object({models:e.object({"claude-code":e.string().min(1).optional(),"codex-cli":e.string().min(1).optional()}).default({}),actions:e.array(e.string().min(1)).default(["labeled","unlabeled","closed"])}).default({}),memoryIndexMaxChars:e.number().int().min(0).max(2e5).default(0),observationPack:e.object({enabled:e.boolean().default(!1),limitBytes:e.number().int().min(1024).max(1048576).default(10240),headBytes:e.number().int().min(0).max(65536).default(1024),tailBytes:e.number().int().min(0).max(65536).default(1024),tools:e.array(e.string().min(1)).default(["Bash","Grep","Read","WebFetch","mcp__.*"]),retentionDays:e.number().int().min(0).max(3650).default(0)}).default({})}).default({}),plugins:e.array(e.string()).default([]),processPool:e.object({maxIdleSeconds:e.number().int().min(5).max(86400).default(30),maxAgeSeconds:e.number().int().min(60).max(86400).default(2700),sweepIntervalSeconds:e.number().int().min(1).max(300).default(5)}).default({})})});export{Sn as a,En as b,X as c,ct as d,wn as e,E as f,Y as g,x as h,V as i,J as j,L as k,Tn as l,ee as m,te as n,ne as o,vn as p,re as q,Ln as r,On as s,oe as t,se as u,le as v,y as w,g as x,Pn as y,de as z,ue as A,Bn as B,Un as C,T as D,Fn as E,fe as F,pe as G,Ot as H,Zn as I,xe as J,Gn as K,Dt as L,Yn as M,Se as N,tr as O,A as P,nr as Q,ke as R,Bt as S,Ut as T,_e as U,rr as V,ar as W,or as X,Te as Y,Yt as Z,Ce as _,Le as $,Oe as aa,je as ba,Ne as ca,$e as da,De as ea,Pe as fa,qe as ga,Me as ha,C as ia,mn as ja,gn as ka,pn as la,bn as ma};
54
- //# sourceMappingURL=chunk-FBEMUCBO.js.map