agentix-cli 0.135.0 → 0.136.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 (204) hide show
  1. package/dist/{App-4UVAI5C5.js → App-D6W6IV2L.js} +2 -2
  2. package/dist/{ChatApp-COO67WIR.js → ChatApp-X7TNCFGW.js} +2 -2
  3. package/dist/{absorb-eval-WY3YMLS4.js → absorb-eval-COPVH2M2.js} +2 -2
  4. package/dist/{agent-3R5NY7I3.js → agent-VCGAUBER.js} +2 -2
  5. package/dist/{board-dashboard-U3ZSCO62.js → board-dashboard-JZM3FQNV.js} +4 -4
  6. package/dist/{board-dashboard-U3ZSCO62.js.map → board-dashboard-JZM3FQNV.js.map} +1 -1
  7. package/dist/chunk-4ZWZ42YE.js +5 -0
  8. package/dist/{chunk-KXR6GVL7.js.map → chunk-4ZWZ42YE.js.map} +1 -1
  9. package/dist/{chunk-DYGQF3MI.js → chunk-54OORW5I.js} +2 -2
  10. package/dist/chunk-54OORW5I.js.map +1 -0
  11. package/dist/{chunk-RVEMX5MJ.js → chunk-5J5USW2O.js} +2 -2
  12. package/dist/{chunk-3XVST5XX.js → chunk-5X37CXJF.js} +2 -2
  13. package/dist/{chunk-4XMALK7X.js → chunk-66DPMVUC.js} +2 -2
  14. package/dist/{chunk-SSQMFHSM.js → chunk-AK3XOA5N.js} +2 -2
  15. package/dist/chunk-AKWBDCMU.js +4 -0
  16. package/dist/chunk-AKWBDCMU.js.map +1 -0
  17. package/dist/{chunk-6WF56ME6.js → chunk-C43E3YFT.js} +2 -2
  18. package/dist/{chunk-LU7GDHGD.js → chunk-EVTTAM7S.js} +2 -2
  19. package/dist/{chunk-K445URSN.js → chunk-FQLSV2C4.js} +2 -2
  20. package/dist/{chunk-FWDRBUMS.js → chunk-GL3H7XMI.js} +2 -2
  21. package/dist/{chunk-ZGVVYJIK.js → chunk-H2N7DOPT.js} +2 -2
  22. package/dist/{chunk-BQIWMQNU.js → chunk-H4NSB54D.js} +2 -2
  23. package/dist/{chunk-XOUO4XNA.js → chunk-HEJTE7OC.js} +2 -2
  24. package/dist/{chunk-EEBK4F6E.js → chunk-HH7OFAEM.js} +2 -2
  25. package/dist/{chunk-QDWEM4DG.js → chunk-HZZW35FY.js} +2 -2
  26. package/dist/{chunk-RRGITX5B.js → chunk-IPMXIPTS.js} +2 -2
  27. package/dist/{chunk-MI7WOGH6.js → chunk-K75LFQE3.js} +2 -2
  28. package/dist/{chunk-ZFRXFUP7.js → chunk-KZXQD6ZK.js} +2 -2
  29. package/dist/{chunk-P3I7AATX.js → chunk-M5AHI2PZ.js} +2 -2
  30. package/dist/{chunk-5NT44FKL.js → chunk-M5B4QG6J.js} +2 -2
  31. package/dist/chunk-MTX4UPNB.js +3 -0
  32. package/dist/chunk-MTX4UPNB.js.map +1 -0
  33. package/dist/chunk-MWNCS57L.js +2 -0
  34. package/dist/chunk-MWNCS57L.js.map +1 -0
  35. package/dist/chunk-OISCRNMW.js +105 -0
  36. package/dist/chunk-OISCRNMW.js.map +1 -0
  37. package/dist/{chunk-ERULJ2ZL.js → chunk-OW5EXDVY.js} +2 -2
  38. package/dist/chunk-OWNQ2FD4.js +3 -0
  39. package/dist/chunk-OWNQ2FD4.js.map +1 -0
  40. package/dist/chunk-PE5V2LI7.js +2 -0
  41. package/dist/chunk-PE5V2LI7.js.map +1 -0
  42. package/dist/chunk-PV623BLN.js +55 -0
  43. package/dist/chunk-PV623BLN.js.map +1 -0
  44. package/dist/{chunk-L5UGH4T4.js → chunk-QCUJTAAZ.js} +6 -6
  45. package/dist/{chunk-GSKJ57XY.js → chunk-QTDKNJXD.js} +216 -216
  46. package/dist/chunk-QTDKNJXD.js.map +1 -0
  47. package/dist/{chunk-RGZARSHV.js → chunk-ROLSSYXE.js} +1 -1
  48. package/dist/{chunk-RGZARSHV.js.map → chunk-ROLSSYXE.js.map} +1 -1
  49. package/dist/{chunk-YA3P77LV.js → chunk-SKSYII3K.js} +2 -2
  50. package/dist/chunk-U6EJ53DA.js +16 -0
  51. package/dist/chunk-U6EJ53DA.js.map +1 -0
  52. package/dist/{chunk-WEPON4FP.js → chunk-UNIXYV3U.js} +2 -2
  53. package/dist/{chunk-SMAI7U6H.js → chunk-VA24JS2S.js} +2 -2
  54. package/dist/{chunk-LUYN6RAC.js → chunk-WRJFKA43.js} +2 -2
  55. package/dist/{chunk-H6VWU2HN.js → chunk-ZPJVDX2U.js} +2 -2
  56. package/dist/cli.js +1 -1
  57. package/dist/{client-NFPBE6L4.js → client-SMOWSRJY.js} +2 -2
  58. package/dist/{config-GHMRBRDL.js → config-OGUDWYAA.js} +2 -2
  59. package/dist/{config-mutate-2XV27EFV.js → config-mutate-BH27TMWK.js} +2 -2
  60. package/dist/config-mutator-Q62AS2TR.js +2 -0
  61. package/dist/{contributions-KLRJ4ZXV.js → contributions-H6T65TCY.js} +2 -2
  62. package/dist/{contributions-KLRJ4ZXV.js.map → contributions-H6T65TCY.js.map} +1 -1
  63. package/dist/{doctor-UBXVMGJG.js → doctor-ZOXHT7ZQ.js} +2 -2
  64. package/dist/enrich-R2LIDLPZ.js +2 -0
  65. package/dist/event-levels-WOYYEWSZ.js +3 -0
  66. package/dist/event-levels-WOYYEWSZ.js.map +1 -0
  67. package/dist/fact-proposals-X2O4W7VN.js +2 -0
  68. package/dist/{follow-up-tool-EARVITTS.js → follow-up-tool-GUBBXNEZ.js} +2 -2
  69. package/dist/{grants-HIFE6L5N.js → grants-CEUGZBQ4.js} +2 -2
  70. package/dist/hub-IIW2GBO5.js +2 -0
  71. package/dist/index.d.ts +15 -0
  72. package/dist/index.js +1 -1
  73. package/dist/index.js.map +1 -1
  74. package/dist/ledger-P62U3FHT.js +2 -0
  75. package/dist/load-LQ2I2PQI.js +2 -0
  76. package/dist/model-call-J7JATTMW.js +2 -0
  77. package/dist/{program-U3HJY7E5.js → program-WROQ55F5.js} +233 -231
  78. package/dist/program-WROQ55F5.js.map +1 -0
  79. package/dist/promote-HDLU44MX.js +2 -0
  80. package/dist/push-bridge-325SXDGN.js +1 -1
  81. package/dist/query-6G27CBZQ.js +2 -0
  82. package/dist/query-runs-VXS572PQ.js +6 -0
  83. package/dist/query-runs-VXS572PQ.js.map +1 -0
  84. package/dist/{query-settings-2MGUS6AY.js → query-settings-G4M75LVQ.js} +3 -3
  85. package/dist/registry-3RE5SG22.js +2 -0
  86. package/dist/{request-planner-MFAIVLUQ.js → request-planner-T3VCZVVQ.js} +2 -2
  87. package/dist/{review-candidates-6WMDVVIZ.js → review-candidates-C3O3CENL.js} +2 -2
  88. package/dist/rotation-memo-store-Z4D5KRA6.js +2 -0
  89. package/dist/{rotation-memo-store-A4YW6FSK.js.map → rotation-memo-store-Z4D5KRA6.js.map} +1 -1
  90. package/dist/{routing-OPCLHIYW.js → routing-LD35TJM5.js} +2 -2
  91. package/dist/rules-HUUFXQD6.js +24 -0
  92. package/dist/rules-HUUFXQD6.js.map +1 -0
  93. package/dist/schedule-tool-46TVGEYU.js +2 -0
  94. package/dist/{scheduler-G3WWYETY.js → scheduler-I3QB4GI3.js} +2 -2
  95. package/dist/score-LNJ46A67.js +3 -0
  96. package/dist/score-LNJ46A67.js.map +1 -0
  97. package/dist/{seat-3HM4J7IX.js → seat-4Y3EW3KU.js} +2 -2
  98. package/dist/{select-VEFE2ESF.js → select-LZKN3FER.js} +2 -2
  99. package/dist/{set-enabled-US5BYKFZ.js → set-enabled-WSTOHJDE.js} +2 -2
  100. package/dist/{tool-HUSCHORN.js → tool-AKXO2EJU.js} +2 -2
  101. package/dist/tool-NLMIUOHR.js +4 -0
  102. package/dist/tool-NLMIUOHR.js.map +1 -0
  103. package/dist/types-YZX46RES.js +2 -0
  104. package/dist/wiki-ZS6OHOWQ.js +2 -0
  105. package/dist/wiki-enrich-NGPFWTVA.js +2 -0
  106. package/dist/wiki-enrich-NGPFWTVA.js.map +1 -0
  107. package/package.json +1 -1
  108. package/dist/chunk-AKLZ4YO2.js +0 -4
  109. package/dist/chunk-AKLZ4YO2.js.map +0 -1
  110. package/dist/chunk-DYGQF3MI.js.map +0 -1
  111. package/dist/chunk-GSKJ57XY.js.map +0 -1
  112. package/dist/chunk-JRS5QRZG.js +0 -2
  113. package/dist/chunk-JRS5QRZG.js.map +0 -1
  114. package/dist/chunk-JTDUTCUE.js +0 -3
  115. package/dist/chunk-JTDUTCUE.js.map +0 -1
  116. package/dist/chunk-KA2UIZXG.js +0 -3
  117. package/dist/chunk-KA2UIZXG.js.map +0 -1
  118. package/dist/chunk-KXR6GVL7.js +0 -5
  119. package/dist/chunk-NY7NHGVT.js +0 -105
  120. package/dist/chunk-NY7NHGVT.js.map +0 -1
  121. package/dist/chunk-WWDYDLY2.js +0 -55
  122. package/dist/chunk-WWDYDLY2.js.map +0 -1
  123. package/dist/config-mutator-6ITNU5DT.js +0 -2
  124. package/dist/enrich-ZB5I7KHN.js +0 -16
  125. package/dist/enrich-ZB5I7KHN.js.map +0 -1
  126. package/dist/event-levels-CQWHSLMT.js +0 -3
  127. package/dist/event-levels-CQWHSLMT.js.map +0 -1
  128. package/dist/fact-proposals-LZWS5KFO.js +0 -2
  129. package/dist/hub-TILTOOSS.js +0 -2
  130. package/dist/ledger-CH7R756S.js +0 -2
  131. package/dist/load-EOZUZK7U.js +0 -2
  132. package/dist/model-call-PKV5UAQ7.js +0 -2
  133. package/dist/program-U3HJY7E5.js.map +0 -1
  134. package/dist/promote-RHVZB2QZ.js +0 -2
  135. package/dist/query-OZXZVLO7.js +0 -2
  136. package/dist/query-runs-7VX3YAC3.js +0 -4
  137. package/dist/query-runs-7VX3YAC3.js.map +0 -1
  138. package/dist/registry-LZLIPP7N.js +0 -2
  139. package/dist/rotation-memo-store-A4YW6FSK.js +0 -2
  140. package/dist/schedule-tool-KPVTMYL3.js +0 -2
  141. package/dist/score-DZGPLHCL.js +0 -3
  142. package/dist/score-DZGPLHCL.js.map +0 -1
  143. package/dist/tool-XLWLXGB5.js +0 -4
  144. package/dist/tool-XLWLXGB5.js.map +0 -1
  145. package/dist/types-LJZ2YY5W.js +0 -2
  146. package/dist/wiki-GCRRINW3.js +0 -2
  147. package/dist/wiki-enrich-P5TNWACZ.js +0 -2
  148. /package/dist/{App-4UVAI5C5.js.map → App-D6W6IV2L.js.map} +0 -0
  149. /package/dist/{ChatApp-COO67WIR.js.map → ChatApp-X7TNCFGW.js.map} +0 -0
  150. /package/dist/{absorb-eval-WY3YMLS4.js.map → absorb-eval-COPVH2M2.js.map} +0 -0
  151. /package/dist/{agent-3R5NY7I3.js.map → agent-VCGAUBER.js.map} +0 -0
  152. /package/dist/{chunk-RVEMX5MJ.js.map → chunk-5J5USW2O.js.map} +0 -0
  153. /package/dist/{chunk-3XVST5XX.js.map → chunk-5X37CXJF.js.map} +0 -0
  154. /package/dist/{chunk-4XMALK7X.js.map → chunk-66DPMVUC.js.map} +0 -0
  155. /package/dist/{chunk-SSQMFHSM.js.map → chunk-AK3XOA5N.js.map} +0 -0
  156. /package/dist/{chunk-6WF56ME6.js.map → chunk-C43E3YFT.js.map} +0 -0
  157. /package/dist/{chunk-LU7GDHGD.js.map → chunk-EVTTAM7S.js.map} +0 -0
  158. /package/dist/{chunk-K445URSN.js.map → chunk-FQLSV2C4.js.map} +0 -0
  159. /package/dist/{chunk-FWDRBUMS.js.map → chunk-GL3H7XMI.js.map} +0 -0
  160. /package/dist/{chunk-ZGVVYJIK.js.map → chunk-H2N7DOPT.js.map} +0 -0
  161. /package/dist/{chunk-BQIWMQNU.js.map → chunk-H4NSB54D.js.map} +0 -0
  162. /package/dist/{chunk-XOUO4XNA.js.map → chunk-HEJTE7OC.js.map} +0 -0
  163. /package/dist/{chunk-EEBK4F6E.js.map → chunk-HH7OFAEM.js.map} +0 -0
  164. /package/dist/{chunk-QDWEM4DG.js.map → chunk-HZZW35FY.js.map} +0 -0
  165. /package/dist/{chunk-RRGITX5B.js.map → chunk-IPMXIPTS.js.map} +0 -0
  166. /package/dist/{chunk-MI7WOGH6.js.map → chunk-K75LFQE3.js.map} +0 -0
  167. /package/dist/{chunk-ZFRXFUP7.js.map → chunk-KZXQD6ZK.js.map} +0 -0
  168. /package/dist/{chunk-P3I7AATX.js.map → chunk-M5AHI2PZ.js.map} +0 -0
  169. /package/dist/{chunk-5NT44FKL.js.map → chunk-M5B4QG6J.js.map} +0 -0
  170. /package/dist/{chunk-ERULJ2ZL.js.map → chunk-OW5EXDVY.js.map} +0 -0
  171. /package/dist/{chunk-L5UGH4T4.js.map → chunk-QCUJTAAZ.js.map} +0 -0
  172. /package/dist/{chunk-YA3P77LV.js.map → chunk-SKSYII3K.js.map} +0 -0
  173. /package/dist/{chunk-WEPON4FP.js.map → chunk-UNIXYV3U.js.map} +0 -0
  174. /package/dist/{chunk-SMAI7U6H.js.map → chunk-VA24JS2S.js.map} +0 -0
  175. /package/dist/{chunk-LUYN6RAC.js.map → chunk-WRJFKA43.js.map} +0 -0
  176. /package/dist/{chunk-H6VWU2HN.js.map → chunk-ZPJVDX2U.js.map} +0 -0
  177. /package/dist/{client-NFPBE6L4.js.map → client-SMOWSRJY.js.map} +0 -0
  178. /package/dist/{config-GHMRBRDL.js.map → config-OGUDWYAA.js.map} +0 -0
  179. /package/dist/{config-mutate-2XV27EFV.js.map → config-mutate-BH27TMWK.js.map} +0 -0
  180. /package/dist/{config-mutator-6ITNU5DT.js.map → config-mutator-Q62AS2TR.js.map} +0 -0
  181. /package/dist/{doctor-UBXVMGJG.js.map → doctor-ZOXHT7ZQ.js.map} +0 -0
  182. /package/dist/{fact-proposals-LZWS5KFO.js.map → enrich-R2LIDLPZ.js.map} +0 -0
  183. /package/dist/{grants-HIFE6L5N.js.map → fact-proposals-X2O4W7VN.js.map} +0 -0
  184. /package/dist/{follow-up-tool-EARVITTS.js.map → follow-up-tool-GUBBXNEZ.js.map} +0 -0
  185. /package/dist/{hub-TILTOOSS.js.map → grants-CEUGZBQ4.js.map} +0 -0
  186. /package/dist/{ledger-CH7R756S.js.map → hub-IIW2GBO5.js.map} +0 -0
  187. /package/dist/{load-EOZUZK7U.js.map → ledger-P62U3FHT.js.map} +0 -0
  188. /package/dist/{model-call-PKV5UAQ7.js.map → load-LQ2I2PQI.js.map} +0 -0
  189. /package/dist/{promote-RHVZB2QZ.js.map → model-call-J7JATTMW.js.map} +0 -0
  190. /package/dist/{query-OZXZVLO7.js.map → promote-HDLU44MX.js.map} +0 -0
  191. /package/dist/{registry-LZLIPP7N.js.map → query-6G27CBZQ.js.map} +0 -0
  192. /package/dist/{query-settings-2MGUS6AY.js.map → query-settings-G4M75LVQ.js.map} +0 -0
  193. /package/dist/{routing-OPCLHIYW.js.map → registry-3RE5SG22.js.map} +0 -0
  194. /package/dist/{request-planner-MFAIVLUQ.js.map → request-planner-T3VCZVVQ.js.map} +0 -0
  195. /package/dist/{review-candidates-6WMDVVIZ.js.map → review-candidates-C3O3CENL.js.map} +0 -0
  196. /package/dist/{schedule-tool-KPVTMYL3.js.map → routing-LD35TJM5.js.map} +0 -0
  197. /package/dist/{scheduler-G3WWYETY.js.map → schedule-tool-46TVGEYU.js.map} +0 -0
  198. /package/dist/{seat-3HM4J7IX.js.map → scheduler-I3QB4GI3.js.map} +0 -0
  199. /package/dist/{types-LJZ2YY5W.js.map → seat-4Y3EW3KU.js.map} +0 -0
  200. /package/dist/{select-VEFE2ESF.js.map → select-LZKN3FER.js.map} +0 -0
  201. /package/dist/{set-enabled-US5BYKFZ.js.map → set-enabled-WSTOHJDE.js.map} +0 -0
  202. /package/dist/{tool-HUSCHORN.js.map → tool-AKXO2EJU.js.map} +0 -0
  203. /package/dist/{wiki-GCRRINW3.js.map → types-YZX46RES.js.map} +0 -0
  204. /package/dist/{wiki-enrich-P5TNWACZ.js.map → wiki-ZS6OHOWQ.js.map} +0 -0
@@ -0,0 +1,5 @@
1
+ import{b as F}from"./chunk-PE5V2LI7.js";import{c as u,j as g,k as f}from"./chunk-GQ76J72O.js";import{a as l}from"./chunk-ILEC3IAV.js";import{d}from"./chunk-OWNQ2FD4.js";import{createHash as w}from"crypto";var m=(t,r)=>"fp-"+w("sha1").update(`${t}\0${r.toLowerCase().replace(/\s+/g," ").trim()}`).digest("hex").slice(0,10);function b(t){let r=t.replace(/^[-*•]\s*/,"").replace(/\s*\((?:[^)]*)\)\s*$/,"").trim(),s=r.match(/^(.{2,60}?)\s+(?:is|are|was|were|has been|went|got)\s+(.{1,80})$/i);if(!s)return{};let a=u(r);return{subject:s[1].trim(),attribute:a==="stable"?"state":`${a} status`,value:s[2].trim()}}function y(t,r,s){let a=t.at??new Date().toISOString(),e=f(s),o=u(s);return{id:r,status:"pending",claim:s,...b(s),volatility:o==="stable"?"work-state":o,source:e?.source??`${t.origin} (unchecked summary)`,verifiedAt:e?.verifiedAt??a,verifiedBy:t.agentId,origin:t.origin,agentId:t.agentId,...t.chat?{chat:t.chat}:{},createdAt:a}}function I(t,r){return r.length===0?[]:t.update(s=>{let a=[],e=!1;for(let o of r){let i=o.claim.replace(/^[-*•]\s*/,"").trim();if(!i)continue;let c=m(o.agentId,i),n=s.proposals.find(v=>v.id===c);if(n){a.push(n);continue}let p=y(o,c,i);s.proposals.push(p),a.push(p),e=!0}return{save:e,result:a}})}function A(t,r){return t.load().proposals.filter(s=>!r||s.status===r)}var P=(t,r)=>t.id===r||r.length>=6&&t.id.startsWith(r);function j(t,r){return t.load().proposals.find(s=>P(s,r))}function h(t,r,s){return t.update(a=>{let e=a.proposals.find(o=>P(o,r));if(!e)throw new Error(`no fact proposal "${r}"`);if(e.status!=="pending")throw new Error(`proposal ${e.id} is already ${e.status}`);return Object.assign(e,s),{save:!0,result:e}})}function B(t,r,s,a={}){return l("approve a fact proposal"),d(t.file,()=>$(t,r,s,a))}function $(t,r,s,a){let e=j(t,r);if(!e)throw new Error(`no fact proposal "${r}"`);if(e.status!=="pending")throw new Error(`proposal ${e.id} is already ${e.status}`);let o=a.subject??e.subject,i=a.attribute??e.attribute,c=a.value??e.value;if(!o||!i||!c)throw new Error("could not read a subject, attribute and value from the claim; pass --subject, --attribute and --value");let n=t.write({subject:o,attribute:i,value:c,source:a.source??e.source,verifiedBy:e.verifiedBy,verifiedAt:e.verifiedAt,volatility:e.volatility},{confirmedBy:s});return{proposal:h(t,e.id,{status:"approved",decidedAt:new Date().toISOString(),decidedBy:s}),write:n}}function E(t,r,s,a){return l("reject a fact proposal"),h(t,r,{status:"rejected",decidedAt:new Date().toISOString(),decidedBy:s,...a?{reason:a}:{}})}function C(t,r,s){let{workState:a,claims:e}=g(r);if(e.length===0)return{workState:a.join(`
2
+ `),pinned:r,proposals:[]};let o=[],i;try{o=I(new F(t),e.map(n=>({claim:n,...s})))}catch(n){i=String(n?.message??n)}let c=e.map((n,p)=>`- UNVERIFIED claim (${o[p]?`wiki proposal ${o[p].id}`:"not checked"}): ${n.replace(/^[-*•]\s*/,"")}`);return{workState:a.join(`
3
+ `),pinned:[...a,...c].join(`
4
+ `),proposals:o,...i?{error:i}:{}}}export{b as a,I as b,A as c,B as d,E as e,C as f};
5
+ //# sourceMappingURL=chunk-4ZWZ42YE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/wiki/facts/fact-proposals.ts"],"sourcesContent":["import { createHash } from \"crypto\"\nimport { citedCheck, classifyFact, splitMemo, type FactClass } from \"@/agents/fact-freshness\"\nimport { assertPerson, FactLedger, type FactInput, type WriteResult } from \"./ledger\"\nimport { withLock } from \"./ledger-file\"\n\n// --- Fact proposals: what a session summary claims, waiting for a check ---\n//\n// A rotation or continuity memo is a model's summary of a session. When it\n// says \"the vendor account is past due\", that is a claim nobody checked in\n// this form, and storing it as memory is how a stale note became a stated\n// fact (#273). So memo claims about outside systems come here instead,\n// with where they came from. They reach the ledger only when a person\n// approves one (a confirmation), never on their own.\n\nexport type FactProposalStatus = \"pending\" | \"approved\" | \"rejected\"\n\nexport interface FactProposal {\n id: string\n status: FactProposalStatus\n /** The line as the memo stated it. */\n claim: string\n /** Best guess at the structured fact, editable on approval. */\n subject?: string\n attribute?: string\n value?: string\n volatility: FactClass\n /** The check the memo cited, or where the claim came from. */\n source: string\n /** When that check happened, or when the memo was written. */\n verifiedAt: string\n verifiedBy: string\n /** e.g. \"rotation-memo:tier-2\" or \"continuity-memo\". */\n origin: string\n agentId: string\n chat?: string\n createdAt: string\n decidedAt?: string\n decidedBy?: string\n reason?: string\n}\n\nexport interface ProposalInput {\n claim: string\n agentId: string\n origin: string\n chat?: string\n at?: string\n}\n\nconst proposalId = (agentId: string, claim: string) =>\n \"fp-\" + createHash(\"sha1\").update(`${agentId}\\u0000${claim.toLowerCase().replace(/\\s+/g, \" \").trim()}`).digest(\"hex\").slice(0, 10)\n\n/** \"X is Y\" → subject X, value Y, attribute named after the class. */\nexport function parseClaim(claim: string): { subject?: string; attribute?: string; value?: string } {\n const text = claim.replace(/^[-*•]\\s*/, \"\").replace(/\\s*\\((?:[^)]*)\\)\\s*$/, \"\").trim()\n const m = text.match(/^(.{2,60}?)\\s+(?:is|are|was|were|has been|went|got)\\s+(.{1,80})$/i)\n if (!m) return {}\n const cls = classifyFact(text)\n return { subject: m[1].trim(), attribute: cls === \"stable\" ? \"state\" : `${cls} status`, value: m[2].trim() }\n}\n\nfunction newProposal(it: ProposalInput, id: string, claim: string): FactProposal {\n const at = it.at ?? new Date().toISOString()\n const cited = citedCheck(claim)\n const cls = classifyFact(claim)\n return {\n id, status: \"pending\", claim, ...parseClaim(claim),\n // A summary's claim is never stable: at best it was true that day.\n volatility: cls === \"stable\" ? \"work-state\" : cls,\n source: cited?.source ?? `${it.origin} (unchecked summary)`,\n verifiedAt: cited?.verifiedAt ?? at,\n verifiedBy: it.agentId,\n origin: it.origin, agentId: it.agentId,\n ...(it.chat ? { chat: it.chat } : {}),\n createdAt: at,\n }\n}\n\n/** Queue claims, under the ledger's lock. The same claim from the same\n * agent is kept once. Throws on an unreadable ledger rather than\n * writing over it. */\nexport function proposeFacts(ledger: FactLedger, items: ProposalInput[]): FactProposal[] {\n if (items.length === 0) return []\n return ledger.update((data) => {\n const out: FactProposal[] = []\n let added = false\n for (const it of items) {\n const claim = it.claim.replace(/^[-*•]\\s*/, \"\").trim()\n if (!claim) continue\n const id = proposalId(it.agentId, claim)\n const seen = data.proposals.find((p) => p.id === id)\n if (seen) { out.push(seen); continue }\n const p = newProposal(it, id, claim)\n data.proposals.push(p)\n out.push(p)\n added = true\n }\n return { save: added, result: out }\n })\n}\n\nexport function listFactProposals(ledger: FactLedger, status?: FactProposalStatus): FactProposal[] {\n return ledger.load().proposals.filter((p) => !status || p.status === status)\n}\n\nconst matches = (x: FactProposal, id: string) => x.id === id || (id.length >= 6 && x.id.startsWith(id))\n\nfunction findProposal(ledger: FactLedger, id: string): FactProposal | undefined {\n return ledger.load().proposals.find((x) => matches(x, id))\n}\n\n/** Decide a pending proposal under the ledger's lock. */\nfunction decide(ledger: FactLedger, id: string, fields: Partial<FactProposal>): FactProposal {\n return ledger.update((data) => {\n const p = data.proposals.find((x) => matches(x, id))\n if (!p) throw new Error(`no fact proposal \"${id}\"`)\n if (p.status !== \"pending\") throw new Error(`proposal ${p.id} is already ${p.status}`)\n Object.assign(p, fields)\n return { save: true, result: p }\n })\n}\n\n/**\n * Approve a claim: a person confirms it, so it is written to the ledger\n * with their name, even over a newer-dated value.\n */\nexport function approveFactProposal(\n ledger: FactLedger, id: string, by: string,\n edit: Partial<Pick<FactInput, \"subject\" | \"attribute\" | \"value\" | \"source\">> = {},\n): { proposal: FactProposal; write: WriteResult } {\n assertPerson(\"approve a fact proposal\")\n // One lock for the whole approval: the fact write and the decision\n // land together, or neither does (both re-enter this lock).\n return withLock(ledger.file, () => approveLocked(ledger, id, by, edit))\n}\n\nfunction approveLocked(\n ledger: FactLedger, id: string, by: string,\n edit: Partial<Pick<FactInput, \"subject\" | \"attribute\" | \"value\" | \"source\">>,\n): { proposal: FactProposal; write: WriteResult } {\n const p = findProposal(ledger, id)\n if (!p) throw new Error(`no fact proposal \"${id}\"`)\n if (p.status !== \"pending\") throw new Error(`proposal ${p.id} is already ${p.status}`)\n const subject = edit.subject ?? p.subject\n const attribute = edit.attribute ?? p.attribute\n const value = edit.value ?? p.value\n if (!subject || !attribute || !value) {\n throw new Error(\"could not read a subject, attribute and value from the claim; pass --subject, --attribute and --value\")\n }\n const write = ledger.write(\n { subject, attribute, value, source: edit.source ?? p.source, verifiedBy: p.verifiedBy, verifiedAt: p.verifiedAt, volatility: p.volatility },\n { confirmedBy: by },\n )\n const proposal = decide(ledger, p.id, { status: \"approved\", decidedAt: new Date().toISOString(), decidedBy: by })\n return { proposal, write }\n}\n\nexport function rejectFactProposal(ledger: FactLedger, id: string, by: string, reason?: string): FactProposal {\n assertPerson(\"reject a fact proposal\")\n return decide(ledger, id, { status: \"rejected\", decidedAt: new Date().toISOString(), decidedBy: by, ...(reason ? { reason } : {}) })\n}\n\n/**\n * Route a session memo: claims about outside systems become proposals;\n * the rest is work state. `pinned` is what the next fresh session reads,\n * with each claim marked unverified and pointing at its proposal.\n */\nexport function routeMemo(\n wikiDir: string, memo: string, ctx: { agentId: string; origin: string; chat?: string },\n): { workState: string; pinned: string; proposals: FactProposal[]; error?: string } {\n const { workState, claims } = splitMemo(memo)\n if (claims.length === 0) return { workState: workState.join(\"\\n\"), pinned: memo, proposals: [] }\n let proposals: FactProposal[] = []\n let error: string | undefined\n try {\n proposals = proposeFacts(new FactLedger(wikiDir), claims.map((claim) => ({ claim, ...ctx })))\n } catch (e) {\n // An unwritable wiki must not lose the memo: claims stay out of\n // memory and are pinned for this chat only, still marked.\n error = String((e as Error)?.message ?? e)\n }\n const flagged = claims.map((c, i) =>\n `- UNVERIFIED claim (${proposals[i] ? `wiki proposal ${proposals[i].id}` : \"not checked\"}): ${c.replace(/^[-*•]\\s*/, \"\")}`)\n return { workState: workState.join(\"\\n\"), pinned: [...workState, ...flagged].join(\"\\n\"), proposals, ...(error ? { error } : {}) }\n}\n"],"mappings":"6IAAA,OAAS,cAAAA,MAAkB,SAiD3B,IAAMC,EAAa,CAACC,EAAiBC,IACnC,MAAQC,EAAW,MAAM,EAAE,OAAO,GAAGF,MAAgBC,EAAM,YAAY,EAAE,QAAQ,OAAQ,GAAG,EAAE,KAAK,GAAG,EAAE,OAAO,KAAK,EAAE,MAAM,EAAG,EAAE,EAG5H,SAASE,EAAWF,EAAyE,CAClG,IAAMG,EAAOH,EAAM,QAAQ,YAAa,EAAE,EAAE,QAAQ,uBAAwB,EAAE,EAAE,KAAK,EAC/EI,EAAID,EAAK,MAAM,mEAAmE,EACxF,GAAI,CAACC,EAAG,MAAO,CAAC,EAChB,IAAMC,EAAMC,EAAaH,CAAI,EAC7B,MAAO,CAAE,QAASC,EAAE,CAAC,EAAE,KAAK,EAAG,UAAWC,IAAQ,SAAW,QAAU,GAAGA,WAAc,MAAOD,EAAE,CAAC,EAAE,KAAK,CAAE,CAC7G,CAEA,SAASG,EAAYC,EAAmBC,EAAYT,EAA6B,CAC/E,IAAMU,EAAKF,EAAG,IAAM,IAAI,KAAK,EAAE,YAAY,EACrCG,EAAQC,EAAWZ,CAAK,EACxBK,EAAMC,EAAaN,CAAK,EAC9B,MAAO,CACL,GAAAS,EAAI,OAAQ,UAAW,MAAAT,EAAO,GAAGE,EAAWF,CAAK,EAEjD,WAAYK,IAAQ,SAAW,aAAeA,EAC9C,OAAQM,GAAO,QAAU,GAAGH,EAAG,6BAC/B,WAAYG,GAAO,YAAcD,EACjC,WAAYF,EAAG,QACf,OAAQA,EAAG,OAAQ,QAASA,EAAG,QAC/B,GAAIA,EAAG,KAAO,CAAE,KAAMA,EAAG,IAAK,EAAI,CAAC,EACnC,UAAWE,CACb,CACF,CAKO,SAASG,EAAaC,EAAoBC,EAAwC,CACvF,OAAIA,EAAM,SAAW,EAAU,CAAC,EACzBD,EAAO,OAAQE,GAAS,CAC7B,IAAMC,EAAsB,CAAC,EACzBC,EAAQ,GACZ,QAAWV,KAAMO,EAAO,CACtB,IAAMf,EAAQQ,EAAG,MAAM,QAAQ,YAAa,EAAE,EAAE,KAAK,EACrD,GAAI,CAACR,EAAO,SACZ,IAAMS,EAAKX,EAAWU,EAAG,QAASR,CAAK,EACjCmB,EAAOH,EAAK,UAAU,KAAMI,GAAMA,EAAE,KAAOX,CAAE,EACnD,GAAIU,EAAM,CAAEF,EAAI,KAAKE,CAAI,EAAG,SAC5B,IAAM,EAAIZ,EAAYC,EAAIC,EAAIT,CAAK,EACnCgB,EAAK,UAAU,KAAK,CAAC,EACrBC,EAAI,KAAK,CAAC,EACVC,EAAQ,GAEV,MAAO,CAAE,KAAMA,EAAO,OAAQD,CAAI,CACpC,CAAC,CACH,CAEO,SAASI,EAAkBP,EAAoBQ,EAA6C,CACjG,OAAOR,EAAO,KAAK,EAAE,UAAU,OAAQM,GAAM,CAACE,GAAUF,EAAE,SAAWE,CAAM,CAC7E,CAEA,IAAMC,EAAU,CAACC,EAAiBf,IAAee,EAAE,KAAOf,GAAOA,EAAG,QAAU,GAAKe,EAAE,GAAG,WAAWf,CAAE,EAErG,SAASgB,EAAaX,EAAoBL,EAAsC,CAC9E,OAAOK,EAAO,KAAK,EAAE,UAAU,KAAMU,GAAMD,EAAQC,EAAGf,CAAE,CAAC,CAC3D,CAGA,SAASiB,EAAOZ,EAAoBL,EAAYkB,EAA6C,CAC3F,OAAOb,EAAO,OAAQE,GAAS,CAC7B,IAAMI,EAAIJ,EAAK,UAAU,KAAMQ,GAAMD,EAAQC,EAAGf,CAAE,CAAC,EACnD,GAAI,CAACW,EAAG,MAAM,IAAI,MAAM,qBAAqBX,IAAK,EAClD,GAAIW,EAAE,SAAW,UAAW,MAAM,IAAI,MAAM,YAAYA,EAAE,iBAAiBA,EAAE,QAAQ,EACrF,cAAO,OAAOA,EAAGO,CAAM,EAChB,CAAE,KAAM,GAAM,OAAQP,CAAE,CACjC,CAAC,CACH,CAMO,SAASQ,EACdd,EAAoBL,EAAYoB,EAChCC,EAA+E,CAAC,EAChC,CAChD,OAAAC,EAAa,yBAAyB,EAG/BC,EAASlB,EAAO,KAAM,IAAMmB,EAAcnB,EAAQL,EAAIoB,EAAIC,CAAI,CAAC,CACxE,CAEA,SAASG,EACPnB,EAAoBL,EAAYoB,EAChCC,EACgD,CAChD,IAAMV,EAAIK,EAAaX,EAAQL,CAAE,EACjC,GAAI,CAACW,EAAG,MAAM,IAAI,MAAM,qBAAqBX,IAAK,EAClD,GAAIW,EAAE,SAAW,UAAW,MAAM,IAAI,MAAM,YAAYA,EAAE,iBAAiBA,EAAE,QAAQ,EACrF,IAAMc,EAAUJ,EAAK,SAAWV,EAAE,QAC5Be,EAAYL,EAAK,WAAaV,EAAE,UAChCgB,EAAQN,EAAK,OAASV,EAAE,MAC9B,GAAI,CAACc,GAAW,CAACC,GAAa,CAACC,EAC7B,MAAM,IAAI,MAAM,uGAAuG,EAEzH,IAAMC,EAAQvB,EAAO,MACnB,CAAE,QAAAoB,EAAS,UAAAC,EAAW,MAAAC,EAAO,OAAQN,EAAK,QAAUV,EAAE,OAAQ,WAAYA,EAAE,WAAY,WAAYA,EAAE,WAAY,WAAYA,EAAE,UAAW,EAC3I,CAAE,YAAaS,CAAG,CACpB,EAEA,MAAO,CAAE,SADQH,EAAOZ,EAAQM,EAAE,GAAI,CAAE,OAAQ,WAAY,UAAW,IAAI,KAAK,EAAE,YAAY,EAAG,UAAWS,CAAG,CAAC,EAC7F,MAAAQ,CAAM,CAC3B,CAEO,SAASC,EAAmBxB,EAAoBL,EAAYoB,EAAYU,EAA+B,CAC5G,OAAAR,EAAa,wBAAwB,EAC9BL,EAAOZ,EAAQL,EAAI,CAAE,OAAQ,WAAY,UAAW,IAAI,KAAK,EAAE,YAAY,EAAG,UAAWoB,EAAI,GAAIU,EAAS,CAAE,OAAAA,CAAO,EAAI,CAAC,CAAG,CAAC,CACrI,CAOO,SAASC,EACdC,EAAiBC,EAAcC,EACmD,CAClF,GAAM,CAAE,UAAAC,EAAW,OAAAC,CAAO,EAAIC,EAAUJ,CAAI,EAC5C,GAAIG,EAAO,SAAW,EAAG,MAAO,CAAE,UAAWD,EAAU,KAAK;AAAA,CAAI,EAAG,OAAQF,EAAM,UAAW,CAAC,CAAE,EAC/F,IAAIK,EAA4B,CAAC,EAC7BC,EACJ,GAAI,CACFD,EAAYlC,EAAa,IAAIoC,EAAWR,CAAO,EAAGI,EAAO,IAAK7C,IAAW,CAAE,MAAAA,EAAO,GAAG2C,CAAI,EAAE,CAAC,CAC9F,OAASO,EAAP,CAGAF,EAAQ,OAAQE,GAAa,SAAWA,CAAC,CAC3C,CACA,IAAMC,EAAUN,EAAO,IAAI,CAACO,EAAGC,IAC7B,uBAAuBN,EAAUM,CAAC,EAAI,iBAAiBN,EAAUM,CAAC,EAAE,KAAO,mBAAmBD,EAAE,QAAQ,YAAa,EAAE,GAAG,EAC5H,MAAO,CAAE,UAAWR,EAAU,KAAK;AAAA,CAAI,EAAG,OAAQ,CAAC,GAAGA,EAAW,GAAGO,CAAO,EAAE,KAAK;AAAA,CAAI,EAAG,UAAAJ,EAAW,GAAIC,EAAQ,CAAE,MAAAA,CAAM,EAAI,CAAC,CAAG,CAClI","names":["createHash","proposalId","agentId","claim","createHash","parseClaim","text","m","cls","classifyFact","newProposal","it","id","at","cited","citedCheck","proposeFacts","ledger","items","data","out","added","seen","p","listFactProposals","status","matches","x","findProposal","decide","fields","approveFactProposal","by","edit","assertPerson","withLock","approveLocked","subject","attribute","value","write","rejectFactProposal","reason","routeMemo","wikiDir","memo","ctx","workState","claims","splitMemo","proposals","error","FactLedger","e","flagged","c","i"]}
1
+ {"version":3,"sources":["../src/wiki/facts/fact-proposals.ts"],"sourcesContent":["import { createHash } from \"crypto\"\nimport { citedCheck, classifyFact, splitMemo, type FactClass } from \"@/agents/fact-freshness\"\nimport { assertPerson, FactLedger, type FactInput, type WriteResult } from \"./ledger\"\nimport { withLock } from \"./ledger-file\"\n\n// --- Fact proposals: what a session summary claims, waiting for a check ---\n//\n// A rotation or continuity memo is a model's summary of a session. When it\n// says \"the vendor account is past due\", that is a claim nobody checked in\n// this form, and storing it as memory is how a stale note became a stated\n// fact (#273). So memo claims about outside systems come here instead,\n// with where they came from. They reach the ledger only when a person\n// approves one (a confirmation), never on their own.\n\nexport type FactProposalStatus = \"pending\" | \"approved\" | \"rejected\"\n\nexport interface FactProposal {\n id: string\n status: FactProposalStatus\n /** The line as the memo stated it. */\n claim: string\n /** Best guess at the structured fact, editable on approval. */\n subject?: string\n attribute?: string\n value?: string\n volatility: FactClass\n /** The check the memo cited, or where the claim came from. */\n source: string\n /** When that check happened, or when the memo was written. */\n verifiedAt: string\n verifiedBy: string\n /** e.g. \"rotation-memo:tier-2\" or \"continuity-memo\". */\n origin: string\n agentId: string\n chat?: string\n createdAt: string\n decidedAt?: string\n decidedBy?: string\n reason?: string\n}\n\nexport interface ProposalInput {\n claim: string\n agentId: string\n origin: string\n chat?: string\n at?: string\n}\n\nconst proposalId = (agentId: string, claim: string) =>\n \"fp-\" + createHash(\"sha1\").update(`${agentId}\\u0000${claim.toLowerCase().replace(/\\s+/g, \" \").trim()}`).digest(\"hex\").slice(0, 10)\n\n/** \"X is Y\" → subject X, value Y, attribute named after the class. */\nexport function parseClaim(claim: string): { subject?: string; attribute?: string; value?: string } {\n const text = claim.replace(/^[-*•]\\s*/, \"\").replace(/\\s*\\((?:[^)]*)\\)\\s*$/, \"\").trim()\n const m = text.match(/^(.{2,60}?)\\s+(?:is|are|was|were|has been|went|got)\\s+(.{1,80})$/i)\n if (!m) return {}\n const cls = classifyFact(text)\n return { subject: m[1].trim(), attribute: cls === \"stable\" ? \"state\" : `${cls} status`, value: m[2].trim() }\n}\n\nfunction newProposal(it: ProposalInput, id: string, claim: string): FactProposal {\n const at = it.at ?? new Date().toISOString()\n const cited = citedCheck(claim)\n const cls = classifyFact(claim)\n return {\n id, status: \"pending\", claim, ...parseClaim(claim),\n // A summary's claim is never stable: at best it was true that day.\n volatility: cls === \"stable\" ? \"work-state\" : cls,\n source: cited?.source ?? `${it.origin} (unchecked summary)`,\n verifiedAt: cited?.verifiedAt ?? at,\n verifiedBy: it.agentId,\n origin: it.origin, agentId: it.agentId,\n ...(it.chat ? { chat: it.chat } : {}),\n createdAt: at,\n }\n}\n\n/** Queue claims, under the ledger's lock. The same claim from the same\n * agent is kept once. Throws on an unreadable ledger rather than\n * writing over it. */\nexport function proposeFacts(ledger: FactLedger, items: ProposalInput[]): FactProposal[] {\n if (items.length === 0) return []\n return ledger.update((data) => {\n const out: FactProposal[] = []\n let added = false\n for (const it of items) {\n const claim = it.claim.replace(/^[-*•]\\s*/, \"\").trim()\n if (!claim) continue\n const id = proposalId(it.agentId, claim)\n const seen = data.proposals.find((p) => p.id === id)\n if (seen) { out.push(seen); continue }\n const p = newProposal(it, id, claim)\n data.proposals.push(p)\n out.push(p)\n added = true\n }\n return { save: added, result: out }\n })\n}\n\nexport function listFactProposals(ledger: FactLedger, status?: FactProposalStatus): FactProposal[] {\n return ledger.load().proposals.filter((p) => !status || p.status === status)\n}\n\nconst matches = (x: FactProposal, id: string) => x.id === id || (id.length >= 6 && x.id.startsWith(id))\n\nfunction findProposal(ledger: FactLedger, id: string): FactProposal | undefined {\n return ledger.load().proposals.find((x) => matches(x, id))\n}\n\n/** Decide a pending proposal under the ledger's lock. */\nfunction decide(ledger: FactLedger, id: string, fields: Partial<FactProposal>): FactProposal {\n return ledger.update((data) => {\n const p = data.proposals.find((x) => matches(x, id))\n if (!p) throw new Error(`no fact proposal \"${id}\"`)\n if (p.status !== \"pending\") throw new Error(`proposal ${p.id} is already ${p.status}`)\n Object.assign(p, fields)\n return { save: true, result: p }\n })\n}\n\n/**\n * Approve a claim: a person confirms it, so it is written to the ledger\n * with their name, even over a newer-dated value.\n */\nexport function approveFactProposal(\n ledger: FactLedger, id: string, by: string,\n edit: Partial<Pick<FactInput, \"subject\" | \"attribute\" | \"value\" | \"source\">> = {},\n): { proposal: FactProposal; write: WriteResult } {\n assertPerson(\"approve a fact proposal\")\n // One lock for the whole approval: the fact write and the decision\n // land together, or neither does (both re-enter this lock).\n return withLock(ledger.file, () => approveLocked(ledger, id, by, edit))\n}\n\nfunction approveLocked(\n ledger: FactLedger, id: string, by: string,\n edit: Partial<Pick<FactInput, \"subject\" | \"attribute\" | \"value\" | \"source\">>,\n): { proposal: FactProposal; write: WriteResult } {\n const p = findProposal(ledger, id)\n if (!p) throw new Error(`no fact proposal \"${id}\"`)\n if (p.status !== \"pending\") throw new Error(`proposal ${p.id} is already ${p.status}`)\n const subject = edit.subject ?? p.subject\n const attribute = edit.attribute ?? p.attribute\n const value = edit.value ?? p.value\n if (!subject || !attribute || !value) {\n throw new Error(\"could not read a subject, attribute and value from the claim; pass --subject, --attribute and --value\")\n }\n const write = ledger.write(\n { subject, attribute, value, source: edit.source ?? p.source, verifiedBy: p.verifiedBy, verifiedAt: p.verifiedAt, volatility: p.volatility },\n { confirmedBy: by },\n )\n const proposal = decide(ledger, p.id, { status: \"approved\", decidedAt: new Date().toISOString(), decidedBy: by })\n return { proposal, write }\n}\n\nexport function rejectFactProposal(ledger: FactLedger, id: string, by: string, reason?: string): FactProposal {\n assertPerson(\"reject a fact proposal\")\n return decide(ledger, id, { status: \"rejected\", decidedAt: new Date().toISOString(), decidedBy: by, ...(reason ? { reason } : {}) })\n}\n\n/**\n * Route a session memo: claims about outside systems become proposals;\n * the rest is work state. `pinned` is what the next fresh session reads,\n * with each claim marked unverified and pointing at its proposal.\n */\nexport function routeMemo(\n wikiDir: string, memo: string, ctx: { agentId: string; origin: string; chat?: string },\n): { workState: string; pinned: string; proposals: FactProposal[]; error?: string } {\n const { workState, claims } = splitMemo(memo)\n if (claims.length === 0) return { workState: workState.join(\"\\n\"), pinned: memo, proposals: [] }\n let proposals: FactProposal[] = []\n let error: string | undefined\n try {\n proposals = proposeFacts(new FactLedger(wikiDir), claims.map((claim) => ({ claim, ...ctx })))\n } catch (e) {\n // An unwritable wiki must not lose the memo: claims stay out of\n // memory and are pinned for this chat only, still marked.\n error = String((e as Error)?.message ?? e)\n }\n const flagged = claims.map((c, i) =>\n `- UNVERIFIED claim (${proposals[i] ? `wiki proposal ${proposals[i].id}` : \"not checked\"}): ${c.replace(/^[-*•]\\s*/, \"\")}`)\n return { workState: workState.join(\"\\n\"), pinned: [...workState, ...flagged].join(\"\\n\"), proposals, ...(error ? { error } : {}) }\n}\n"],"mappings":"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","names":["createHash","proposalId","agentId","claim","createHash","parseClaim","text","m","cls","classifyFact","newProposal","it","id","at","cited","citedCheck","proposeFacts","ledger","items","data","out","added","seen","p","listFactProposals","status","matches","x","findProposal","decide","fields","approveFactProposal","by","edit","assertPerson","withLock","approveLocked","subject","attribute","value","write","rejectFactProposal","reason","routeMemo","wikiDir","memo","ctx","workState","claims","splitMemo","proposals","error","FactLedger","e","flagged","c","i"]}
@@ -38,7 +38,7 @@ import{b as U,d as F,h as at}from"./chunk-BRK6M6LA.js";import{l as z,m as H,n as
38
38
  WHERE id = ? AND state NOT IN (${b(p.length)})`).run(t,o,o,t==="done"?i.slice(0,P):null,t==="done"?null:i.slice(0,P),n,...p).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 (${b(x.length)}) ORDER BY created_at, rowid`).all(...x).map(h)}quietSince(n,t){return this.db.prepare(`SELECT * FROM requests WHERE state IN (${b(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
39
  WHERE id = ? AND state = 'needs_attention'`).run(t,t,n).changes>0}handOff(n,t,r,o){return this.db.prepare(`UPDATE requests SET agent_id = ?, state = 'in_progress', updated_at = ?, attention_reason = NULL, notified_at = NULL,
40
40
  question = NULL, pickup_at = ?, owner_note = ?, note_said = NULL, asked_agent = COALESCE(asked_agent, agent_id)
41
- WHERE id = ? AND state IN (${b(x.length)})`).run(t,o,o,r.trim().slice(0,$)||null,n,...x).changes>0}setNoteSaid(n,t,r){this.db.prepare(`UPDATE requests SET note_said = ? WHERE id = ? AND owner_note = ?${r?" AND pickup_at IS NULL":""}`).run(r?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 (${b(p.length)}) AND closed_at < ?`).run(...p,n).changes}}});function oa(a){return Object.assign({channel:pe,chatId:a,sender:"operator"},{[be]:!0})}function ia(a){return!!a&&a[be]===!0}function Pt(a,n,t,r=!1){let o=T(n);if(a.channels.length&&!a.channels.map(T).includes(o))return!1;if(A.has(o))return r&&!Nt.has((t?.name??"").toLowerCase());let i=$t.has(o)?t?.username:t?.id,l=i?fe(o,i):"";return l?a.from.some(d=>{let m=d.trim().toLowerCase(),g=m.indexOf(":");return g>0&&m.slice(0,g)===o&&fe(o,m.slice(g+1))===l}):!1}function sa(a){if(!a)return;let n=r=>typeof r=="string"&&r?r.slice(0,120):void 0,t={name:n(a.sender),id:n(a.senderId),username:n(a.senderUsername)};return t.name||t.id||t.username?t:void 0}function Dt(a){return/\btimed? ?out\b|timeout/i.test(a)?"timed out":"failed"}var pe,be,A,Nt,T,$t,fe,y,S,ge,he=f(()=>{"use strict";me();pe="requests",be=Symbol("requests.pickup");A=new Set(["voice","app","dashboard","webrtc"]),Nt=new Set(["camera"]),T=a=>a.toLowerCase().split("@")[0],$t=new Set(["github","gitlab"]),fe=(a,n)=>a==="whatsapp"?n.replace(/@.*$/,"").replace(/\D/g,""):n.trim().toLowerCase().replace(/^@/,"");y=(a,n=200)=>{let t=a.replace(/\s+/g," ").trim();return t.length>n?`${t.slice(0,n-1)}\u2026`:t},S=(a,n,t)=>`${a}\0${n}\0${t}`,ge=class{constructor(n,t,r,o=Date.now){this.store=n;this.settings=t;this.log=r;this.now=o}live=new Map;guard(n,t){try{t()}catch(r){this.log(`[requests] ${n} failed: ${r?.message??r}`)}}isListedOwner(n){let t=T(n.channel),r=this.settings().channels;return r.length&&!r.map(T).includes(t)?!1:n.person?.role==="owner"&&!A.has(t)}liveRequestId(n,t,r){return this.live.get(S(n,t,r))?.requestId??null}taskStarted(n){n.taskId&&this.guard("capture",()=>{if(!this.settings().enabled)return;let t=this.now(),r=n.resumedFrom?this.store.byLink("run",n.resumedFrom):null,o=S(n.agentId,n.channel,n.chatId);if(r){this.store.link(r.id,"run",n.taskId,t),r.state==="candidate"?this.store.touch(r.id,t):this.store.progress(r.id,t),this.live.set(o,{requestId:r.id,runId:n.taskId});return}let i=n.pickup&&n.channel===pe?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||!(Pt(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 r=this.store.byLink("run",n.taskId);if(!r)return;let o=this.now();if(!n.interrupted){if(n.error&&n.errorKind!=="cancelled"&&!n.stopped&&n.errorKind!=="stopped"){let i=Dt(n.error);this.store.needsAttention(r.id,`${n.agentId} ${i}: ${y(n.error)}`,o)&&this.log(`[requests] ${r.id} needs attention: run ${n.taskId} ${i}`);return}r.state==="candidate"?this.store.discardCandidate(r.id):this.store.touch(r.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 r=this.now();this.store.link(t.requestId,"delegation",n.id,r),this.store.progress(t.requestId,r,"waiting_other")})}delegationDone(n,t,r){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 d={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} ${d}: ${y(r)}`,i)&&this.log(`[requests] ${o.id} needs attention: delegation ${n.id} ${t}`)})}relayFailed(n,t,r){this.guard("delegation relay",()=>{let o=this.store.byLink("delegation",n.id);if(!o)return;let i=n.peer?`${n.callee} on ${n.peer}`:n.callee;this.store.needsAttention(o.id,`The answer from ${i} was not passed on after a restart (${y(r)}). It said: ${y(t)}`,this.now())&&this.log(`[requests] ${o.id} needs attention: delegation ${n.id} answer not relayed`)})}cardRaised(n,t){t&&this.guard("card",()=>{if(!this.settings().enabled)return;let r=this.live.get(S(n.raised_by,t.channel,t.chatId))?.requestId;if(!r)return;let o=this.now();this.store.link(r,"card",n.id,o),this.store.waitOnOwner(r,n.ask,o)})}cardResolved(n){this.guard("card result",()=>{let t=this.store.byLink("card",n.id);if(!t)return;let r=this.now(),o=n.outcome??n.if_silent;n.status==="decided"?t.state==="waiting_owner"&&this.store.progress(t.id,r):this.store.needsAttention(t.id,`Your answer did not come before the card expired (${y(n.ask)}); "${o}" was applied`,r)&&this.log(`[requests] ${t.id} needs attention: card ${n.id} expired unanswered`)})}closingNote(n){try{let t=this.store.byLink("delegation",n);return!t||!x.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 r=this.now();n.decision==="resumed"?t.state==="candidate"?this.store.touch(t.id,r):this.store.progress(t.id,r):(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 (${y(n.reason)})`,r)&&this.log(`[requests] ${t.id} needs attention: run ${n.taskId} cut off by a restart`)})}}});import{randomBytes as qt,timingSafeEqual as ye}from"crypto";import{chmodSync as Mt,existsSync as Bt,mkdirSync as Ut,readFileSync as Ft,writeFileSync as zt}from"fs";import{networkInterfaces as Ht}from"os";import{dirname as Wt,resolve as Kt}from"path";function fa(a){return Object.assign(a,{[ke]:!0})}function we(a){return!!a&&a[ke]===!0}function Zt(a=process.cwd()){return Kt(a,".agentx","operator.key")}function ga(a=process.cwd(),n={}){let t=Zt(a);try{if(Bt(t)){let o=Ft(t,"utf-8").trim();if(o)return o}if(!n.create)return null;let r=qt(32).toString("hex");return Ut(Wt(t),{recursive:!0}),zt(t,r+`
41
+ WHERE id = ? AND state IN (${b(x.length)})`).run(t,o,o,r.trim().slice(0,$)||null,n,...x).changes>0}setNoteSaid(n,t,r){this.db.prepare(`UPDATE requests SET note_said = ? WHERE id = ? AND owner_note = ?${r?" AND pickup_at IS NULL":""}`).run(r?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 (${b(p.length)}) AND closed_at < ?`).run(...p,n).changes}}});function oa(a){return Object.assign({channel:pe,chatId:a,sender:"operator"},{[be]:!0})}function ia(a){return!!a&&a[be]===!0}function Pt(a,n,t,r=!1){let o=T(n);if(a.channels.length&&!a.channels.map(T).includes(o))return!1;if(A.has(o))return r&&!Nt.has((t?.name??"").toLowerCase());let i=$t.has(o)?t?.username:t?.id,l=i?fe(o,i):"";return l?a.from.some(d=>{let m=d.trim().toLowerCase(),g=m.indexOf(":");return g>0&&m.slice(0,g)===o&&fe(o,m.slice(g+1))===l}):!1}function sa(a){if(!a)return;let n=r=>typeof r=="string"&&r?r.slice(0,120):void 0,t={name:n(a.sender),id:n(a.senderId),username:n(a.senderUsername)};return t.name||t.id||t.username?t:void 0}function Dt(a){return/\btimed? ?out\b|timeout/i.test(a)?"timed out":"failed"}var pe,be,A,Nt,T,$t,fe,y,S,ge,he=f(()=>{"use strict";me();pe="requests",be=Symbol("requests.pickup");A=new Set(["voice","app","dashboard","webrtc"]),Nt=new Set(["camera"]),T=a=>a.toLowerCase().split("@")[0],$t=new Set(["github","gitlab"]),fe=(a,n)=>a==="whatsapp"?n.replace(/@.*$/,"").replace(/\D/g,""):n.trim().toLowerCase().replace(/^@/,"");y=(a,n=200)=>{let t=a.replace(/\s+/g," ").trim();return t.length>n?`${t.slice(0,n-1)}\u2026`:t},S=(a,n,t)=>`${a}\0${n}\0${t}`,ge=class{constructor(n,t,r,o=Date.now){this.store=n;this.settings=t;this.log=r;this.now=o}live=new Map;guard(n,t){try{t()}catch(r){this.log(`[requests] ${n} failed: ${r?.message??r}`)}}isListedOwner(n){let t=T(n.channel),r=this.settings().channels;return r.length&&!r.map(T).includes(t)?!1:n.person?.role==="owner"&&!A.has(t)}liveRequestId(n,t,r){return this.live.get(S(n,t,r))?.requestId??null}taskStarted(n){n.taskId&&this.guard("capture",()=>{if(!this.settings().enabled)return;let t=this.now(),r=n.resumedFrom?this.store.byLink("run",n.resumedFrom):null,o=S(n.agentId,n.channel,n.chatId);if(r){this.store.link(r.id,"run",n.taskId,t),r.state==="candidate"?this.store.touch(r.id,t):this.store.progress(r.id,t),this.live.set(o,{requestId:r.id,runId:n.taskId});return}let i=n.pickup&&n.channel===pe?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||!(Pt(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 r=this.store.byLink("run",n.taskId);if(!r)return;let o=this.now();if(!n.interrupted){if(n.error&&n.errorKind!=="cancelled"&&!n.stopped&&n.errorKind!=="stopped"){let i=Dt(n.error);this.store.needsAttention(r.id,`${n.agentId} ${i}: ${y(n.error)}`,o)&&this.log(`[requests] ${r.id} needs attention: run ${n.taskId} ${i}`);return}r.state==="candidate"?this.store.discardCandidate(r.id):this.store.touch(r.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 r=this.now();this.store.link(t.requestId,"delegation",n.id,r),this.store.progress(t.requestId,r,"waiting_other")})}delegationDone(n,t,r){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 d={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} ${d}: ${y(r)}`,i)&&this.log(`[requests] ${o.id} needs attention: delegation ${n.id} ${t}`)})}relayFailed(n,t,r){this.guard("delegation relay",()=>{let o=this.store.byLink("delegation",n.id);if(!o)return;let i=n.peer?`${n.callee} on ${n.peer}`:n.callee;this.store.needsAttention(o.id,`The answer from ${i} was not passed on after a restart (${y(r)}). It said: ${y(t)}`,this.now())&&this.log(`[requests] ${o.id} needs attention: delegation ${n.id} answer not relayed`)})}cardRaised(n,t){t&&this.guard("card",()=>{if(!this.settings().enabled)return;let r=this.live.get(S(n.raised_by,t.channel,t.chatId))?.requestId;if(!r)return;let o=this.now();this.store.link(r,"card",n.id,o),this.store.waitOnOwner(r,n.ask,o)})}cardResolved(n){this.guard("card result",()=>{let t=this.store.byLink("card",n.id);if(!t)return;let r=this.now(),o=n.outcome??n.if_silent;n.status==="decided"||n.status==="resolved"?t.state==="waiting_owner"&&this.store.progress(t.id,r):this.store.needsAttention(t.id,`Your answer did not come before the card expired (${y(n.ask)}); "${o}" was applied`,r)&&this.log(`[requests] ${t.id} needs attention: card ${n.id} expired unanswered`)})}closingNote(n){try{let t=this.store.byLink("delegation",n);return!t||!x.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 r=this.now();n.decision==="resumed"?t.state==="candidate"?this.store.touch(t.id,r):this.store.progress(t.id,r):(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 (${y(n.reason)})`,r)&&this.log(`[requests] ${t.id} needs attention: run ${n.taskId} cut off by a restart`)})}}});import{randomBytes as qt,timingSafeEqual as ye}from"crypto";import{chmodSync as Mt,existsSync as Bt,mkdirSync as Ut,readFileSync as Ft,writeFileSync as zt}from"fs";import{networkInterfaces as Ht}from"os";import{dirname as Wt,resolve as Kt}from"path";function fa(a){return Object.assign(a,{[ke]:!0})}function we(a){return!!a&&a[ke]===!0}function Zt(a=process.cwd()){return Kt(a,".agentx","operator.key")}function ga(a=process.cwd(),n={}){let t=Zt(a);try{if(Bt(t)){let o=Ft(t,"utf-8").trim();if(o)return o}if(!n.create)return null;let r=qt(32).toString("hex");return Ut(Wt(t),{recursive:!0}),zt(t,r+`
42
42
  `,{mode:384}),Mt(t,384),r}catch{return null}}function Gt(a,n){let t=Array.isArray(n)?n[0]:n;if(!a||!t)return!1;let r=Buffer.from(a),o=Buffer.from(t.trim());return r.length===o.length&&ye(r,o)}function Vt(a,n,t,r){if(!a||typeof a!="object")return!1;let o=String(a.channel??"").toLowerCase().split("@")[0];return r.has(o)?Gt(t,n[Xt]):!1}function Jt(a,n){let t=a[Yt];if((Array.isArray(t)?t[0]:t)!=="1")return!1;let r=a.authorization,o=(Array.isArray(r)?r[0]:r)||"",i=o.toLowerCase().startsWith("bearer ")?o.slice(7).trim():"";if(!i)return!1;let l=Buffer.from(i);for(let d of n){if(!d)continue;let m=Buffer.from(d);if(m.length===l.length&&ye(m,l))return!0}return!1}function Qt(a,n=en()){let t=xe(a??"");if(!t||t==="::1"||t.startsWith("127."))return!0;for(let r of n)if(xe(r)===t)return!0;return!1}function en(){return Object.values(Ht()).flatMap(a=>(a??[]).map(n=>n.address))}function pa(a,n,t){if(Vt(a,n.headers,t.key,t.operatorChannels))return!0;if(!a||typeof a!="object")return!1;let r=String(a.channel??"").toLowerCase().split("@")[0];return!t.operatorChannels.has(r)||Qt(n.remoteAddress,t.ownAddresses)?!1:Jt(n.headers,t.peerTokens)}var Xt,ke,Yt,xe,Se=f(()=>{"use strict";Xt="x-agentx-operator",ke=Symbol("requests.operator");Yt="x-agentx-operator-vouch";xe=a=>a.toLowerCase().replace(/^::ffff:/,"").replace(/%.*$/,"")});function wa(a,n){return a.find(t=>t.id===n)?.name??(n===R?"Owner":n)}function _e(a,n){let t=n.trim().toLowerCase();return a==="whatsapp"?t.replace(/@.*$/,"").replace(/\D/g,""):t.replace(/^@/,"")}function Ee(a){let n=a.indexOf(":");if(n<=0||n===a.length-1)return null;let t=D(a.slice(0,n).trim()),r=_e(t,a.slice(n+1));return r?{channel:t,value:r}:null}function Te(a){let n=new Set,t=new Map;for(let r of a){if(n.has(r.id))return`person "${r.id}" is listed twice`;if(n.add(r.id),r.id===R&&r.role!=="owner")return`the id "${R}" is kept for a person with the owner role`;for(let o of r.identities){let i=Ee(o);if(!i)return`identity "${o}" of "${r.id}" must be written channel:id`;let l=`${i.channel}:${i.value}`,d=t.get(l);if(d&&d!==r.id)return`identity "${o}" belongs to both "${d}" and "${r.id}"`;t.set(l,r.id)}}return null}function tn(a,n,t){let r=D(n),i=(r==="whatsapp"?[t?.id]:[t?.id,t?.username]).filter(l=>typeof l=="string"&&!!l).map(l=>_e(r,l)).filter(Boolean);return i.length?a.find(l=>l.identities.some(d=>{let m=Ee(d);return!!m&&m.channel===r&&i.includes(m.value)}))??null:null}function nn(a){let n=a.filter(t=>t.role==="owner");return n.length===0?{id:R,role:"owner"}:n.length===1?{id:n[0].id,role:"owner"}:null}function Ae(a,n){let t=U(n);if(t)return t.person?{id:t.person}:null;if(!n||F(n)!=="human")return null;let r=String(n.channel??"");if(A.has(D(r)))return we(n)?nn(a):null;let o=l=>typeof l=="string"?l:void 0,i=tn(a,r,{id:o(n.senderId),username:o(n.senderUsername)});return i?{id:i.id,role:i.role}:null}function an(a,n){let t=a.agents??[];return a.role==="owner"||t.length===0||t.includes(n)}function Sa(a,n,t){let r=Ae(a,t);if(!r)return null;let o=a.find(l=>l.id===r.id);if(!o||an(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 _a(a,n){let t=a.trim().split("*").map(r=>r.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${t}$`,"i").test(n.trim())}function Ea(a,n){let t=Ae(a,n);if(!t)return null;let r=a.find(l=>l.id===t.id);if(!r||r.role==="owner")return null;let o=r.deny?.tools??[],i=r.deny?.skills??[];return!o.length&&!i.length?null:{personId:r.id,name:r.name,tools:[...o],skills:[...i]}}var ka,R,D,Re=f(()=>{"use strict";at();he();Se();ka=["owner","member","client","guest"],R="owner";D=a=>a.toLowerCase().split("@")[0]});function Ra(a){return typeof a=="string"&&on.includes(a)}function ve(a){let n=new Set(rn);return a.map(t=>t.trim()).filter(t=>t&&!n.has(t))}var rn,on,Aa,Ie=f(()=>{"use strict";rn=["agentx_generate","agentx_inspect","agentx_skill_match","agentx_detect_output_type","agentx_channel_reply","agentx_channel_label","agentx_send","agentx_send_agent","agentx_recent","agentx_events","agentx_signal","agentx_send_contact","agentx_task","agentx_agents","agentx_voice_queue","agentx_call_owner","agentx_camera_ask","agentx_camera_look","agentx_health","agentx_attach_next","agentx_attach_answer","agentx_crons","agentx_schedule","agentx_approval","agentx_request","agentx_workflow","agentx_debug","agentx_wiki_query","agentx_wiki_patch","agentx_wiki_interview","agentx_graph_review"],on=["read","full"],Aa=["agentx_inspect","agentx_skill_match","agentx_detect_output_type","agentx_recent","agentx_events","agentx_agents","agentx_voice_queue","agentx_health","agentx_crons","agentx_wiki_query"]});var Nn={};tt(Nn,{INTEGRATION_KINDS:()=>gn,WIKI_CONTRIBUTE_JOB:()=>Ge,WIKI_CONTRIBUTE_MERGE_JOB:()=>Ye,WIKI_SUMMARIZE_JOB:()=>q,approvalsConfigSchema:()=>Xe,callsSchema:()=>Ue,cameraBotSchema:()=>Me,daemonConfigSchema:()=>Ze,eventSubscriptionSchema:()=>qe,expandEnvVars:()=>j,isCronExpression:()=>Be,loadDaemonConfig:()=>On,membersConfigSchema:()=>We,peopleConfigSchema:()=>He,personSchema:()=>ze,requestStatusConfigSchema:()=>Ke,requestsConfigSchema:()=>Fe,validateWorkspaces:()=>Ln,withContributionJobs:()=>Ve,withSummariesJob:()=>Je});import{z as e}from"zod";import{readFileSync as Ne,existsSync as I}from"fs";import{resolve as C}from"path";function sn(a){let n=C(a,".env");if(!I(n))return;let t=Ne(n,"utf-8");for(let r of t.split(`
43
43
  `)){let o=r.trim();if(!o||o.startsWith("#"))continue;let i=o.indexOf("=");if(i===-1)continue;let l=o.slice(0,i).trim(),d=o.slice(i+1).trim();process.env[l]||(process.env[l]=d)}}function Be(a){let n=[[0,59],[0,23],[1,31],[1,12],[0,6]],t=a.trim().split(/\s+/);return t.length!==5?!1:t.every((r,o)=>r.split(",").every(i=>{let l=/^(\*|(\d+)(?:-(\d+))?)(?:\/(\d+))?$/.exec(i);if(!l)return!1;let[d,m]=n[o],g=l[2]===void 0?d:Number(l[2]),k=l[3]===void 0?g:Number(l[3]),et=l[4]===void 0?1:Number(l[4]);return g>=d&&k<=m&&g<=k&&et>=1}))}function xn(a){try{return new Intl.DateTimeFormat("en-US",{timeZone:a}),!0}catch{return!1}}function j(a){if(typeof a=="string")return a.replace(/\$\{(\w+)\}/g,(n,t)=>process.env[t]||"");if(Array.isArray(a))return a.map(j);if(a!==null&&typeof a=="object"){let n={};for(let[t,r]of Object.entries(a))n[t]=j(r);return n}return a}function jn(a,n){let t=[],r=new Set;for(let o of a){let i=o.path.join("."),l=/^channels\.telegram\.accounts\.([^.]+)\.token$/.exec(i);if(l&&o.message.toLowerCase().includes("required")){let d=l[1],m=`tg:${d}`;if(r.has(m))continue;r.add(m),t.push(`Hint: Telegram account "${d}" is enabled but has no bot token.
44
44
  Either:
@@ -51,4 +51,4 @@ ${m.join(`
51
51
 
52
52
  `)}`:"";throw new Error(`Config validation failed (${r}):
53
53
  ${d}${g}`)}return Je(Ve(l.data))}function Ln(a){let n=[];for(let[t,r]of Object.entries(a.agents)){if(!I(r.workspace)){n.push(`Agent "${t}": workspace not found at ${r.workspace}`);continue}if(r.tier==="claude-code"){let l=C(r.workspace,".claude");I(l)||n.push(`Agent "${t}": no .claude/ directory in workspace ${r.workspace}. Claude Code native features (hooks, MCP, skills) won't be available.`)}let o=r.provider||"claude",i=a.providers[o];!["claude-code","codex-cli","opencode"].includes(r.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,r]of Object.entries(a.crons))a.agents[r.agent]||n.push(`Cron "${t}": references unknown agent "${r.agent}"`);if(a.channels.telegram.enabled)for(let[t,r]of Object.entries(a.channels.telegram.accounts))a.agents[r.agentBinding]||n.push(`Telegram account "${t}": references unknown agent "${r.agentBinding}"`);return n}function Ve(a,n=Qe()){let t=Object.entries(a.agents).filter(([,l])=>l.wiki?.contribute?.enabled).map(([l])=>l).sort();if(t.length===0)return a;let r=a.wiki.contributions,o=(l,d)=>M.parse({schedule:l,timezone:r.timezone,agent:t[0],command:d,timeout:3600,onError:"log"}),i={[Ge]:o(r.schedule,`${n} wiki contribute --all`),[Ye]:o(r.mergeSchedule,`${n} wiki contributions merge`)};return{...a,crons:{...i,...a.crons}}}function Je(a,n=Qe()){let t=a.wiki.summaries,r=t.agent??a.node.defaultAgent??Object.keys(a.agents).sort()[0];if(!t.schedule?.trim()||!r)return a;let o=M.safeParse({schedule:t.schedule,timezone:t.timezone,agent:r,command:`${n} wiki summarize --all`,timeout:3600,onError:"log"});if(!o.success)throw new Error(`wiki.summaries: the ${q} job can't be built: ${o.error.issues.map(i=>i.message).join("; ")}`);return{...a,crons:{[q]:o.data,...a.crons}}}function Qe(){let a=process.argv[1]??"";return/[\\/]cli\.(?:c|m)?js$/.test(a)?`"${process.execPath}" "${a}"`:"agentx"}var Ce,ln,un,dn,cn,mn,fn,gn,$e,Pe,v,De,qe,pn,bn,Me,hn,M,je,Oe,Le,yn,kn,wn,Sn,_n,En,Tn,An,Rn,Ue,vn,In,Cn,Fe,ze,He,We,Ke,Xe,Ze,Ge,Ye,q,$n=f(()=>{K();G();nt();J();ne();oe();se();de();Re();Ie();Ce=e.array(e.string().min(1)).superRefine((a,n)=>{let t=ve(a);t.length&&n.addIssue({code:e.ZodIssueCode.custom,message:`not an agentx tool: ${t.join(", ")}. Use the names the agentx server lists, without "mcp__agentx__".`})}),ln=e.object({apiKey:e.string().optional(),defaultModel:e.string().optional(),baseUrl:e.string().optional(),thinking:e.boolean().optional()}),un=e.object({type:e.literal("stdio").optional(),command:e.string(),args:e.array(e.string()).default([]),env:e.record(e.string(),e.string()).optional()}),dn=e.object({type:e.literal("http"),url:e.string().url(),headers:e.record(e.string(),e.string()).optional()}),cn=e.union([dn,un]),mn=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(),fn=e.object({kind:e.string().min(1),label:e.string().min(1),credentials:mn.default({}),metadata:e.record(e.string(),e.union([e.string(),e.number(),e.boolean()])).default({}),enabled:e.boolean().default(!0)}),gn=["telegram-bot","whatsapp","gitlab-user","github-user","gmail","hotmail","smtp","hubspot","salesforce","pipedrive","odoo","trello","linear","asana","jira","notion","stripe","sentry","vercel","twilio","custom"],$e=e.enum(["system","elevenlabs"]),Pe=e.union([e.string(),e.record(e.string(),e.string())]),v=e.string().superRefine((a,n)=>{let t=V(a);t&&n.addIssue({code:e.ZodIssueCode.custom,message:`shortcut ${t}`})}),De=e.object({provider:$e.optional(),system:Pe.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:v.optional()}),qe=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)}),pn=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(),cn).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(),wiki:e.object({contribute:e.object({enabled:e.boolean().default(!1),maxPatches:e.number().int().min(1).max(200).default(30),maxCostUsd:e.number().min(0).max(20).optional(),model:e.string().optional()}).default({}),absorb:e.object({enabled:e.boolean().default(!0)}).default({}),notes:e.object({dir:e.string().min(1).optional()}).default({})}).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(qe).default([]),integrations:e.array(fn).default([]),voice:De.optional(),presence:e.object({color:e.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),palette:e.enum(O).optional(),initial:e.string().max(2).optional(),label:e.string().optional(),allowActions:e.boolean().optional()}).optional()}),bn=e.object({token:e.string(),agentBinding:e.string(),allowFrom:e.array(e.string()).optional(),pollInbound:e.boolean().default(!0)}),Me=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({}),hn=e.object({telegram:e.object({enabled:e.boolean().default(!1),accounts:e.record(e.string(),bn).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:Me}).default({})}).default({})}),M=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:B.optional(),onError:e.union([e.enum(["log","notify","disable"]),e.array(e.enum(["log","notify","disable"]))]).default("log").transform(a=>Array.isArray(a)?a:[a]),notify:e.object({channel:e.string(),chatId:e.string(),accountId:e.string().optional()}).optional(),deliverResult:e.boolean().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(a=>!!(a.command?.trim()||a.prompt?.trim()),{message:"a cron needs either a prompt (dispatch an agent) or a command (run it directly)"}).refine(a=>!(a.command?.trim()&&a.autonomy&&a.autonomy!=="act"),{message:"autonomy applies to agent routines; a command cron runs no agent (remove autonomy or the command)"});je=e.string().regex(/^(?!.*(?:^|\/)\.+(?:\/|$))[\w.-]+(\/[\w.-]+)+$/,"expected owner/name"),Oe=e.union([je,e.object({repo:je,about:e.string().max(200).optional()})]),Le={tokenEnv:e.string().regex(/^[A-Za-z_][A-Za-z0-9_]*$/).optional(),tokenFile:e.string().optional()},yn=e.discriminatedUnion("type",[e.object({type:e.literal("github"),apiUrl:e.string().url().default("https://api.github.com"),...Le,repos:e.array(Oe).min(1)}),e.object({type:e.literal("gitlab"),url:e.string().url().optional(),...Le,repos:e.array(Oe).min(1)}),e.object({type:e.literal("agentx"),url:e.string().url().optional(),peers:e.boolean().default(!0)})]),kn=e.object({enabled:e.boolean().default(!1),inbox:e.string().min(1).optional(),crons:e.array(e.string().min(1)).default([]),absorbAgent:e.string().min(1).optional(),maxNotesPerRun:e.number().int().min(1).max(100).default(20),maxDeferrals:e.number().int().min(1).max(20).default(3)}).refine(a=>!a.enabled||!!a.inbox,{message:"wikiNotes.enabled needs wikiNotes.inbox: the agent that runs the wiki observe/sweep schedule"}),wn=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()}),Sn=e.object({url:e.string(),name:e.string(),token:e.string().optional()}),_n=e.object({name:e.string(),agent:e.string(),enabled:e.boolean().default(!0)}),En=e.object({enabled:e.boolean().default(!1),peers:e.array(Sn).default([]),inboxes:e.array(_n).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),requeueRelayOnRestart:e.boolean().default(!0)}).default({})}),Tn=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({}),An=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({}),Rn=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(),An).default({}),routing:e.object({cheapModel:e.string().optional(),cheapModels:e.object({"claude-code":e.string().optional(),"codex-cli":e.string().optional()}).optional()}).default({})}).default({}),Ue=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({}),vn=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({}),In=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-]*$/),In).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({}),Fe=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),plans:e.object({enabled:e.boolean().default(!0),stallMinutes:e.number().positive().max(7*24*60).default(30),maxNudges:e.number().int().min(0).max(20).default(3),approveKinds:e.array(e.string().regex(/^[a-z][a-z0-9_-]{0,30}$/,"a step kind: a short lower-case word")).default(["message"]),disabledAgents:e.array(e.string().min(1)).default([])}).default({})}).default({}),ze=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({})}),He=e.array(ze).default([]).superRefine((a,n)=>{let t=Te(a);t&&n.addIssue({code:e.ZodIssueCode.custom,message:t})}),We=e.object({logRetentionDays:e.number().int().min(1).max(3650).default(90)}).default({}),Ke=e.object({channels:e.array(e.string().min(1)).default([])}).default({}),Xe=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(a=>{try{return new Intl.DateTimeFormat("en-US",{timeZone:a}),!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(a=>{try{return new Intl.DateTimeFormat("en-US",{timeZone:a}),!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({}),Ze=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(),ln).default({}),agents:e.record(e.string(),pn).default({}),wiki:e.object({contributions:e.object({schedule:e.string().default("40 22 * * *"),mergeSchedule:e.string().default("20 23 * * *"),timezone:e.string().default("UTC"),maxCostUsd:e.number().min(0).max(20).default(.5),model:e.string().default("sonnet")}).default({}),query:e.object({shared:e.boolean().default(!0),method:e.enum(["auto","summaries","catalog"]).default("auto"),candidates:e.number().int().min(1).max(50).default(12),sharedCandidates:e.number().int().min(0).max(50).default(4),notes:e.object({enabled:e.boolean().default(!1),types:e.array(e.string().min(1)).default(["project","reference"]),candidates:e.number().int().min(1).max(50).default(4)}).default({}),maxPages:e.number().int().min(1).max(10).default(3),pageChars:e.number().int().min(200).max(4e4).default(4e3),linkedPages:e.number().int().min(0).max(10).default(0),linkedChars:e.number().int().min(200).max(4e4).default(6e3),navigatorModel:e.string().min(1).default("haiku"),answerModel:e.string().min(1).default("sonnet"),live:e.object({enabled:e.boolean().default(!0),maxReads:e.number().int().min(0).max(20).default(6),timeoutMs:e.number().int().min(1e3).max(12e4).default(15e3),plannerModel:e.string().min(1).default("haiku"),sources:e.array(yn).default([])}).default({})}).default({}),summaries:e.object({model:e.string().min(1).default("haiku"),batchSize:e.number().int().min(1).max(50).default(20),maxWords:e.number().int().min(5).max(120).default(35),schedule:e.string().refine(a=>a.trim()===""||Be(a),'expected a cron of 5 fields, such as "30 23 * * *"').optional(),timezone:e.string().refine(xn,'expected a time zone such as "UTC" or "Europe/Paris"').default("UTC"),agent:e.string().min(1).optional()}).default({}),curator:e.object({enabled:e.boolean().default(!0),agent:e.string().min(1).optional()}).default({})}).default({}),channels:hn.default({}),crons:e.record(e.string(),M).default({}),wikiNotes:kn.default({}),services:e.record(e.string(),wn).default({}),notifications:vn,calls:Ue,whatsappTriage:ue,approvals:Xe,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({}),signals:e.object({enabled:e.boolean().default(!0),windDownSeconds:e.number().int().min(10).max(1800).default(120),allowAgents:e.array(e.string().min(1)).default([]),allowPeers:e.array(e.string().min(1)).default([]),maxPerRoot:e.number().int().min(1).max(100).default(6)}).default({}),requests:Fe,people:He,members:We,requestStatus:Ke,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:En.default({}),meshVoices:e.record(e.string(),De.omit({rate:!0,priority:!0,hotkey:!0}).extend({name:e.string().optional()})).default({}),voice:e.object({provider:$e.default("system"),fallback:e.enum(["system","none"]).default("system"),system:Pe.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(L),noiseFilter:e.object({enabled:e.boolean().default(!0),markers:e.array(e.string()).default(N)}).default({}),localStt:e.enum(["mlx-whisper","parakeet"]).default("mlx-whisper"),endOfTurn:e.enum(["vad","volume"]).default("vad"),hotkeys:e.object({talk:v.default(_.talk),stop:v.default(_.stop),paste:v.default(_.paste)}).default({}),look:e.enum(Q).default("orb"),startReduced:e.boolean().default(!1),stroll:e.boolean().default(!1),animations:e.enum(ee).default("sometimes"),palette:e.enum(O).default(E),card:e.object({timeout:e.number().min(0).max(600).default(30),maxHeight:e.number().min(120).max(800).default(320)}).default({})}).default({}),business:W.optional(),boards:X,dashboard:Z,graph:Tn,decisions:Rn,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({}),followUp:e.object({enabled:e.boolean().default(!0),agents:e.record(e.boolean()).default({}),stallMinutes:e.number().positive().max(7*24*60).default(30),maxNudges:e.number().int().min(0).max(20).default(2),approval:e.enum(["start","step"]).default("step")}).default({}),required:e.object({enabled:e.boolean().default(!1),agents:e.record(e.boolean()).default({}),exemptQuestions:e.boolean().default(!0),retentionDays:e.number().int().min(0).max(3650).default(30)}).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({}),agentxTools:Ce.default([]),agentxToolsByChannel:e.record(Ce).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),resumeGate:e.object({mode:e.enum(["off","shadow","active"]).default("off"),freshTokens:e.number().int().min(1e3).max(2e5).default(3e4),cacheTtlMinutes:e.number().int().min(1).max(1440).default(60),cacheWriteFactor:e.number().min(1).max(4).default(2),margin:e.number().min(1).max(10).default(1.5)}).default({}),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({})});Ge="wiki-contribute",Ye="wiki-contribute-merge";q="wiki-summarize"});export{Mn as a,Bn as b,G as c,At as d,Fn as e,_ as f,J as g,w as h,Q as i,ee as j,O as k,Hn as l,ne as m,ae as n,re as o,Zn as p,oe as q,Yn as r,Vn as s,se as t,ue as u,de as v,x as w,p as x,$ as y,na as z,ce as A,me as B,oa as C,ia as D,A as E,sa as F,ge as G,he as H,Xt as I,fa as J,we as K,ga as L,Vt as M,pa as N,Se as O,ka as P,R as Q,wa as R,Ee as S,tn as T,nn as U,Ae as V,Sa as W,_a as X,Ea as Y,Re as Z,on as _,Aa as $,Ra as aa,Ie as ba,gn as ca,qe as da,Me as ea,Be as fa,Ue as ga,Fe as ha,ze as ia,He as ja,We as ka,Ke as la,Xe as ma,Ze as na,j as oa,On as pa,Ln as qa,Ge as ra,Ye as sa,Ve as ta,q as ua,Je as va,Nn as wa,$n as xa};
54
- //# sourceMappingURL=chunk-DYGQF3MI.js.map
54
+ //# sourceMappingURL=chunk-54OORW5I.js.map