agentix-cli 0.20.0 → 0.22.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 (82) hide show
  1. package/dist/{agent-57MG4LBM.js → agent-Y4U4R3ZZ.js} +2 -2
  2. package/dist/{board-dashboard-HXDOYGIG.js → board-dashboard-2CPBWFOB.js} +339 -97
  3. package/dist/board-dashboard-2CPBWFOB.js.map +1 -0
  4. package/dist/chunk-2HXSJYAJ.js +15 -0
  5. package/dist/chunk-2HXSJYAJ.js.map +1 -0
  6. package/dist/{chunk-QW2OYR3N.js → chunk-ABVZHJUO.js} +2 -2
  7. package/dist/chunk-BHSPAP4U.js +44 -0
  8. package/dist/chunk-BHSPAP4U.js.map +1 -0
  9. package/dist/chunk-CO4YCIIA.js +13 -0
  10. package/dist/chunk-CO4YCIIA.js.map +1 -0
  11. package/dist/{chunk-4MREHZP5.js → chunk-GOLZ6NEL.js} +2 -2
  12. package/dist/chunk-GOLZ6NEL.js.map +1 -0
  13. package/dist/chunk-GSX4NK2N.js +2 -0
  14. package/dist/chunk-GSX4NK2N.js.map +1 -0
  15. package/dist/chunk-GV7S5BAX.js +2 -0
  16. package/dist/chunk-GV7S5BAX.js.map +1 -0
  17. package/dist/{chunk-WPPUOTY6.js → chunk-KX626FN4.js} +2 -2
  18. package/dist/chunk-OPKQNLGX.js +450 -0
  19. package/dist/chunk-OPKQNLGX.js.map +1 -0
  20. package/dist/chunk-OZOQKPJV.js +102 -0
  21. package/dist/chunk-OZOQKPJV.js.map +1 -0
  22. package/dist/{chunk-DLVOHCTA.js → chunk-P3TJHGO5.js} +2 -2
  23. package/dist/chunk-SZDACK6O.js +2 -0
  24. package/dist/chunk-SZDACK6O.js.map +1 -0
  25. package/dist/{chunk-TC3BSUP7.js → chunk-VYLZ7UYM.js} +2 -2
  26. package/dist/{chunk-WFHIIVLL.js → chunk-WHP4I44J.js} +75 -51
  27. package/dist/chunk-WHP4I44J.js.map +1 -0
  28. package/dist/chunk-X5D5AV5N.js +833 -0
  29. package/dist/chunk-X5D5AV5N.js.map +1 -0
  30. package/dist/cli.js +1 -1
  31. package/dist/cli.js.map +1 -1
  32. package/dist/{config-QXWKEQON.js → config-BLOKGMER.js} +2 -2
  33. package/dist/config-mutator-RG7QY2EL.js +2 -0
  34. package/dist/doctor-ZTECTUHX.js +2 -0
  35. package/dist/index.d.ts +140 -3
  36. package/dist/index.js +1 -1
  37. package/dist/program-GZOJIWTB.js +2 -0
  38. package/dist/registry-QZIUSQ5J.js +2 -0
  39. package/dist/runner-BFYDWPUO.js +2 -0
  40. package/dist/scheduler-B2BQPV4M.js +2 -0
  41. package/dist/store-I3HEWVLQ.js +2 -0
  42. package/dist/store-I3HEWVLQ.js.map +1 -0
  43. package/dist/types-Y6ZCZ52Z.js +2 -0
  44. package/dist/types-Y6ZCZ52Z.js.map +1 -0
  45. package/dist/web/workflow-editor.global.js +12 -10
  46. package/dist/web/workflow-editor.global.js.map +1 -1
  47. package/dist/workspace-setup-DQCZX2NE.js +2 -0
  48. package/dist/workspace-setup-DQCZX2NE.js.map +1 -0
  49. package/package.json +1 -1
  50. package/dist/board-dashboard-HXDOYGIG.js.map +0 -1
  51. package/dist/chunk-23AUU4S2.js +0 -102
  52. package/dist/chunk-23AUU4S2.js.map +0 -1
  53. package/dist/chunk-4MREHZP5.js.map +0 -1
  54. package/dist/chunk-6B74TO2J.js +0 -743
  55. package/dist/chunk-6B74TO2J.js.map +0 -1
  56. package/dist/chunk-7GVXCOLO.js +0 -440
  57. package/dist/chunk-7GVXCOLO.js.map +0 -1
  58. package/dist/chunk-E4ZZILAK.js +0 -15
  59. package/dist/chunk-E4ZZILAK.js.map +0 -1
  60. package/dist/chunk-MBOLXKA2.js +0 -6
  61. package/dist/chunk-MBOLXKA2.js.map +0 -1
  62. package/dist/chunk-WFHIIVLL.js.map +0 -1
  63. package/dist/chunk-ZE2YFX4K.js +0 -45
  64. package/dist/chunk-ZE2YFX4K.js.map +0 -1
  65. package/dist/config-mutator-53XGR2NT.js +0 -2
  66. package/dist/doctor-SEOUFHSL.js +0 -2
  67. package/dist/program-WWCXMRU2.js +0 -2
  68. package/dist/registry-HM4ELSXS.js +0 -2
  69. package/dist/scheduler-XVFIK4XH.js +0 -2
  70. package/dist/workspace-setup-FPGN5VNY.js +0 -2
  71. /package/dist/{agent-57MG4LBM.js.map → agent-Y4U4R3ZZ.js.map} +0 -0
  72. /package/dist/{chunk-QW2OYR3N.js.map → chunk-ABVZHJUO.js.map} +0 -0
  73. /package/dist/{chunk-WPPUOTY6.js.map → chunk-KX626FN4.js.map} +0 -0
  74. /package/dist/{chunk-DLVOHCTA.js.map → chunk-P3TJHGO5.js.map} +0 -0
  75. /package/dist/{chunk-TC3BSUP7.js.map → chunk-VYLZ7UYM.js.map} +0 -0
  76. /package/dist/{config-QXWKEQON.js.map → config-BLOKGMER.js.map} +0 -0
  77. /package/dist/{config-mutator-53XGR2NT.js.map → config-mutator-RG7QY2EL.js.map} +0 -0
  78. /package/dist/{doctor-SEOUFHSL.js.map → doctor-ZTECTUHX.js.map} +0 -0
  79. /package/dist/{program-WWCXMRU2.js.map → program-GZOJIWTB.js.map} +0 -0
  80. /package/dist/{registry-HM4ELSXS.js.map → registry-QZIUSQ5J.js.map} +0 -0
  81. /package/dist/{scheduler-XVFIK4XH.js.map → runner-BFYDWPUO.js.map} +0 -0
  82. /package/dist/{workspace-setup-FPGN5VNY.js.map → scheduler-B2BQPV4M.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import{a as wt}from"./chunk-MTRWXRFF.js";import{a as kt}from"./chunk-NOF4HSGK.js";import{a as S,b as _t,c as Et,d as St,e as U,f as ce,g as De,h as Tt}from"./chunk-WFHIIVLL.js";import{a as A,b as R,g as ft,h as vt,i as j,j as z,k as ve,l as bt,m as xt,n as yt}from"./chunk-CNNLREHD.js";import{a as Ie,b as Le,f as pt,g as ut,h as mt,p as ht}from"./chunk-E4ZZILAK.js";import"./chunk-EW27SCCC.js";import"./chunk-QW2OYR3N.js";import"./chunk-DLVOHCTA.js";import{a as dt,b as ct,e as B}from"./chunk-MBOLXKA2.js";import"./chunk-N67JZAXU.js";import{f as gt}from"./chunk-CDNWCYF7.js";import"./chunk-AFRHKA7B.js";import{a as lt}from"./chunk-5F3J55LG.js";import"./chunk-4MREHZP5.js";import{b as it}from"./chunk-7P5QRX5W.js";import"./chunk-JTJIPNXY.js";import"./chunk-64P4QHSZ.js";import"./chunk-JGXE2YNV.js";import"./chunk-VJUTQAPJ.js";import"./chunk-QOYAX2FT.js";import"./chunk-4YCH6IZV.js";import{createServer as So}from"http";import{appendFileSync as To,existsSync as Da,mkdirSync as Co}from"fs";import{readFile as Ao}from"fs/promises";import{fileURLToPath as $o}from"url";import{dirname as Mo,resolve as ge}from"path";var Ct='/*! Sortable 1.15.2 - MIT | git://github.com/SortableJS/Sortable.git */\n!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function I(o){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?e(Object(i),!0).forEach(function(t){var e,n;e=o,t=i[n=t],n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t}):Object.getOwnPropertyDescriptors?Object.defineProperties(o,Object.getOwnPropertyDescriptors(i)):e(Object(i)).forEach(function(t){Object.defineProperty(o,t,Object.getOwnPropertyDescriptor(i,t))})}return o}function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,o=arguments[e];for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&(t[n]=o[n])}return t}).apply(this,arguments)}function i(t,e){if(null==t)return{};var n,o=function(t,e){if(null==t)return{};for(var n,o={},i=Object.keys(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols)for(var i=Object.getOwnPropertySymbols(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n]);return o}function r(t){return function(t){if(Array.isArray(t))return l(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return l(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Map"===(n="Object"===n&&t.constructor?t.constructor.name:n)||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=new Array(e);n<e;n++)o[n]=t[n];return o}function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var y=t(/(?:Trident.*rv[ :]?11\\.|msie|iemobile|Windows Phone)/i),w=t(/Edge/i),s=t(/firefox/i),u=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),n=t(/iP(ad|od|hone)/i),c=t(/chrome/i)&&t(/android/i),d={capture:!1,passive:!1};function h(t,e,n){t.addEventListener(e,n,!y&&d)}function f(t,e,n){t.removeEventListener(e,n,!y&&d)}function p(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i<r;i++)n(o[i],i);return o}return[]}function O(){var t=document.scrollingElement;return t||document.documentElement}function X(t,e,n,o,i){if(t.getBoundingClientRect||t===window){var r,a,l,s,c,u,d=t!==window&&t.parentNode&&t!==O()?(a=(r=t.getBoundingClientRect()).top,l=r.left,s=r.bottom,c=r.right,u=r.height,r.width):(l=a=0,s=window.innerHeight,c=window.innerWidth,u=window.innerHeight,window.innerWidth);if((e||n)&&t!==window&&(i=i||t.parentNode,!y))do{if(i&&i.getBoundingClientRect&&("none"!==R(i,"transform")||n&&"static"!==R(i,"position"))){var h=i.getBoundingClientRect();a-=h.top+parseInt(R(i,"border-top-width")),l-=h.left+parseInt(R(i,"border-left-width")),s=a+r.height,c=l+r.width;break}}while(i=i.parentNode);return o&&t!==window&&(o=(e=v(i||t))&&e.a,t=e&&e.d,e&&(s=(a/=t)+(u/=t),c=(l/=o)+(d/=o))),{top:a,left:l,bottom:s,right:c,width:d,height:u}}}function Y(t,e,n){for(var o=M(t,!0),i=X(t)[e];o;){var r=X(o)[n];if(!("top"===n||"left"===n?r<=i:i<=r))return o;if(o===O())break;o=M(o,!1)}return!1}function B(t,e,n,o){for(var i=0,r=0,a=t.children;r<a.length;){if("none"!==a[r].style.display&&a[r]!==Ft.ghost&&(o||a[r]!==Ft.dragged)&&P(a[r],n.draggable,t,!1)){if(i===e)return a[r];i++}r++}return null}function F(t,e){for(var n=t.lastElementChild;n&&(n===Ft.ghost||"none"===R(n,"display")||e&&!p(n,e));)n=n.previousElementSibling;return n||null}function j(t,e){var n=0;if(!t||!t.parentNode)return-1;for(;t=t.previousElementSibling;)"TEMPLATE"===t.nodeName.toUpperCase()||t===Ft.clone||e&&!p(t,e)||n++;return n}function E(t){var e=0,n=0,o=O();if(t)do{var i=v(t),r=i.a,i=i.d}while(e+=t.scrollLeft*r,n+=t.scrollTop*i,t!==o&&(t=t.parentNode));return[e,n]}function M(t,e){if(!t||!t.getBoundingClientRect)return O();var n=t,o=!1;do{if(n.clientWidth<n.scrollWidth||n.clientHeight<n.scrollHeight){var i=R(n);if(n.clientWidth<n.scrollWidth&&("auto"==i.overflowX||"scroll"==i.overflowX)||n.clientHeight<n.scrollHeight&&("auto"==i.overflowY||"scroll"==i.overflowY)){if(!n.getBoundingClientRect||n===document.body)return O();if(o||e)return n;o=!0}}}while(n=n.parentNode);return O()}function D(t,e){return Math.round(t.top)===Math.round(e.top)&&Math.round(t.left)===Math.round(e.left)&&Math.round(t.height)===Math.round(e.height)&&Math.round(t.width)===Math.round(e.width)}function S(e,n){return function(){var t;g||(1===(t=arguments).length?e.call(this,t[0]):e.apply(this,t),g=setTimeout(function(){g=void 0},n))}}function H(t,e,n){t.scrollLeft+=e,t.scrollTop+=n}function _(t){var e=window.Polymer,n=window.jQuery||window.Zepto;return e&&e.dom?e.dom(t).cloneNode(!0):n?n(t).clone(!0)[0]:t.cloneNode(!0)}function C(t,e){R(t,"position","absolute"),R(t,"top",e.top),R(t,"left",e.left),R(t,"width",e.width),R(t,"height",e.height)}function T(t){R(t,"position",""),R(t,"top",""),R(t,"left",""),R(t,"width",""),R(t,"height","")}function L(n,o,i){var r={};return Array.from(n.children).forEach(function(t){var e;P(t,o.draggable,n,!1)&&!t.animated&&t!==i&&(e=X(t),r.left=Math.min(null!==(t=r.left)&&void 0!==t?t:1/0,e.left),r.top=Math.min(null!==(t=r.top)&&void 0!==t?t:1/0,e.top),r.right=Math.max(null!==(t=r.right)&&void 0!==t?t:-1/0,e.right),r.bottom=Math.max(null!==(t=r.bottom)&&void 0!==t?t:-1/0,e.bottom))}),r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}var K="Sortable"+(new Date).getTime();function x(){var e,o=[];return{captureAnimationState:function(){o=[],this.options.animation&&[].slice.call(this.el.children).forEach(function(t){var e,n;"none"!==R(t,"display")&&t!==Ft.ghost&&(o.push({target:t,rect:X(t)}),e=I({},o[o.length-1].rect),!t.thisAnimationDuration||(n=v(t,!0))&&(e.top-=n.f,e.left-=n.e),t.fromRect=e)})},addAnimationState:function(t){o.push(t)},removeAnimationState:function(t){o.splice(function(t,e){for(var n in t)if(t.hasOwnProperty(n))for(var o in e)if(e.hasOwnProperty(o)&&e[o]===t[n][o])return Number(n);return-1}(o,{target:t}),1)},animateAll:function(t){var c=this;if(!this.options.animation)return clearTimeout(e),void("function"==typeof t&&t());var u=!1,d=0;o.forEach(function(t){var e=0,n=t.target,o=n.fromRect,i=X(n),r=n.prevFromRect,a=n.prevToRect,l=t.rect,s=v(n,!0);s&&(i.top-=s.f,i.left-=s.e),n.toRect=i,n.thisAnimationDuration&&D(r,i)&&!D(o,i)&&(l.top-i.top)/(l.left-i.left)==(o.top-i.top)/(o.left-i.left)&&(t=l,s=r,r=a,a=c.options,e=Math.sqrt(Math.pow(s.top-t.top,2)+Math.pow(s.left-t.left,2))/Math.sqrt(Math.pow(s.top-r.top,2)+Math.pow(s.left-r.left,2))*a.animation),D(i,o)||(n.prevFromRect=o,n.prevToRect=i,e=e||c.options.animation,c.animate(n,l,i,e)),e&&(u=!0,d=Math.max(d,e),clearTimeout(n.animationResetTimer),n.animationResetTimer=setTimeout(function(){n.animationTime=0,n.prevFromRect=null,n.fromRect=null,n.prevToRect=null,n.thisAnimationDuration=null},e),n.thisAnimationDuration=e)}),clearTimeout(e),u?e=setTimeout(function(){"function"==typeof t&&t()},d):"function"==typeof t&&t(),o=[]},animate:function(t,e,n,o){var i,r;o&&(R(t,"transition",""),R(t,"transform",""),i=(r=v(this.el))&&r.a,r=r&&r.d,i=(e.left-n.left)/(i||1),r=(e.top-n.top)/(r||1),t.animatingX=!!i,t.animatingY=!!r,R(t,"transform","translate3d("+i+"px,"+r+"px,0)"),this.forRepaintDummy=t.offsetWidth,R(t,"transition","transform "+o+"ms"+(this.options.easing?" "+this.options.easing:"")),R(t,"transform","translate3d(0,0,0)"),"number"==typeof t.animated&&clearTimeout(t.animated),t.animated=setTimeout(function(){R(t,"transition",""),R(t,"transform",""),t.animated=!1,t.animatingX=!1,t.animatingY=!1},o))}}}var A=[],N={initializeByDefault:!0},W={mount:function(e){for(var t in N)!N.hasOwnProperty(t)||t in e||(e[t]=N[t]);A.forEach(function(t){if(t.pluginName===e.pluginName)throw"Sortable: Cannot mount plugin ".concat(e.pluginName," more than once")}),A.push(e)},pluginEvent:function(e,n,o){var t=this;this.eventCanceled=!1,o.cancel=function(){t.eventCanceled=!0};var i=e+"Global";A.forEach(function(t){n[t.pluginName]&&(n[t.pluginName][i]&&n[t.pluginName][i](I({sortable:n},o)),n.options[t.pluginName]&&n[t.pluginName][e]&&n[t.pluginName][e](I({sortable:n},o)))})},initializePlugins:function(n,o,i,t){for(var e in A.forEach(function(t){var e=t.pluginName;(n.options[e]||t.initializeByDefault)&&((t=new t(n,o,n.options)).sortable=n,t.options=n.options,n[e]=t,a(i,t.defaults))}),n.options){var r;n.options.hasOwnProperty(e)&&(void 0!==(r=this.modifyOption(n,e,n.options[e]))&&(n.options[e]=r))}},getEventProperties:function(e,n){var o={};return A.forEach(function(t){"function"==typeof t.eventProperties&&a(o,t.eventProperties.call(n[t.pluginName],e))}),o},modifyOption:function(e,n,o){var i;return A.forEach(function(t){e[t.pluginName]&&t.optionListeners&&"function"==typeof t.optionListeners[n]&&(i=t.optionListeners[n].call(e[t.pluginName],o))}),i}};function z(t){var e=t.sortable,n=t.rootEl,o=t.name,i=t.targetEl,r=t.cloneEl,a=t.toEl,l=t.fromEl,s=t.oldIndex,c=t.newIndex,u=t.oldDraggableIndex,d=t.newDraggableIndex,h=t.originalEvent,f=t.putSortable,p=t.extraEventProperties;if(e=e||n&&n[K]){var g,m=e.options,t="on"+o.charAt(0).toUpperCase()+o.substr(1);!window.CustomEvent||y||w?(g=document.createEvent("Event")).initEvent(o,!0,!0):g=new CustomEvent(o,{bubbles:!0,cancelable:!0}),g.to=a||n,g.from=l||n,g.item=i||n,g.clone=r,g.oldIndex=s,g.newIndex=c,g.oldDraggableIndex=u,g.newDraggableIndex=d,g.originalEvent=h,g.pullMode=f?f.lastPutMode:void 0;var v,b=I(I({},p),W.getEventProperties(o,e));for(v in b)g[v]=b[v];n&&n.dispatchEvent(g),m[t]&&m[t].call(e,g)}}function G(t,e){var n=(o=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{}).evt,o=i(o,U);W.pluginEvent.bind(Ft)(t,e,I({dragEl:V,parentEl:Z,ghostEl:$,rootEl:Q,nextEl:J,lastDownEl:tt,cloneEl:et,cloneHidden:nt,dragStarted:gt,putSortable:st,activeSortable:Ft.active,originalEvent:n,oldIndex:ot,oldDraggableIndex:rt,newIndex:it,newDraggableIndex:at,hideGhostForTarget:Rt,unhideGhostForTarget:Xt,cloneNowHidden:function(){nt=!0},cloneNowShown:function(){nt=!1},dispatchSortableEvent:function(t){q({sortable:e,name:t,originalEvent:n})}},o))}var U=["evt"];function q(t){z(I({putSortable:st,cloneEl:et,targetEl:V,rootEl:Q,oldIndex:ot,oldDraggableIndex:rt,newIndex:it,newDraggableIndex:at},t))}var V,Z,$,Q,J,tt,et,nt,ot,it,rt,at,lt,st,ct,ut,dt,ht,ft,pt,gt,mt,vt,bt,yt,wt=!1,Et=!1,Dt=[],St=!1,_t=!1,Ct=[],Tt=!1,xt=[],Ot="undefined"!=typeof document,Mt=n,At=w||y?"cssFloat":"float",Nt=Ot&&!c&&!n&&"draggable"in document.createElement("div"),It=function(){if(Ot){if(y)return!1;var t=document.createElement("x");return t.style.cssText="pointer-events:auto","auto"===t.style.pointerEvents}}(),Pt=function(t,e){var n=R(t),o=parseInt(n.width)-parseInt(n.paddingLeft)-parseInt(n.paddingRight)-parseInt(n.borderLeftWidth)-parseInt(n.borderRightWidth),i=B(t,0,e),r=B(t,1,e),a=i&&R(i),l=r&&R(r),s=a&&parseInt(a.marginLeft)+parseInt(a.marginRight)+X(i).width,t=l&&parseInt(l.marginLeft)+parseInt(l.marginRight)+X(r).width;if("flex"===n.display)return"column"===n.flexDirection||"column-reverse"===n.flexDirection?"vertical":"horizontal";if("grid"===n.display)return n.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal";if(i&&a.float&&"none"!==a.float){e="left"===a.float?"left":"right";return!r||"both"!==l.clear&&l.clear!==e?"horizontal":"vertical"}return i&&("block"===a.display||"flex"===a.display||"table"===a.display||"grid"===a.display||o<=s&&"none"===n[At]||r&&"none"===n[At]&&o<s+t)?"vertical":"horizontal"},kt=function(t){function l(r,a){return function(t,e,n,o){var i=t.options.group.name&&e.options.group.name&&t.options.group.name===e.options.group.name;if(null==r&&(a||i))return!0;if(null==r||!1===r)return!1;if(a&&"clone"===r)return r;if("function"==typeof r)return l(r(t,e,n,o),a)(t,e,n,o);e=(a?t:e).options.group.name;return!0===r||"string"==typeof r&&r===e||r.join&&-1<r.indexOf(e)}}var e={},n=t.group;n&&"object"==o(n)||(n={name:n}),e.name=n.name,e.checkPull=l(n.pull,!0),e.checkPut=l(n.put),e.revertClone=n.revertClone,t.group=e},Rt=function(){!It&&$&&R($,"display","none")},Xt=function(){!It&&$&&R($,"display","")};Ot&&!c&&document.addEventListener("click",function(t){if(Et)return t.preventDefault(),t.stopPropagation&&t.stopPropagation(),t.stopImmediatePropagation&&t.stopImmediatePropagation(),Et=!1},!0);function Yt(t){if(V){t=t.touches?t.touches[0]:t;var e=(i=t.clientX,r=t.clientY,Dt.some(function(t){var e=t[K].options.emptyInsertThreshold;if(e&&!F(t)){var n=X(t),o=i>=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function Bt(t){V&&V.parentNode[K]._isOutsideThisEl(t.target)}function Ft(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Pt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ft.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in W.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in kt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Nt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Dt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function jt(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Ht(t){t.draggable=!1}function Lt(){Tt=!1}function Kt(t){return setTimeout(t,0)}function Wt(t){return clearTimeout(t)}Ft.prototype={constructor:Ft,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(mt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,V):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){xt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&xt.push(o)}}(o),!V&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||tt===l)){if(ot=j(l),rt=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return q({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),G("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return q({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),G("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!V&&n.parentNode===r&&(o=X(n),Q=r,Z=(V=n).parentNode,J=V.nextSibling,tt=n,lt=a.group,ct={target:Ft.dragged=V,clientX:(e||t).clientX,clientY:(e||t).clientY},ft=ct.clientX-o.left,pt=ct.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,V.style["will-change"]="all",o=function(){G("delayEnded",i,{evt:t}),Ft.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(V.draggable=!0),i._triggerDragStart(t,e),q({sortable:i,name:"choose",originalEvent:t}),k(V,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(V,t.trim(),Ht)}),h(l,"dragover",Yt),h(l,"mousemove",Yt),h(l,"touchmove",Yt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,V.draggable=!0),G("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ft.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){V&&Ht(V),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._disableDelayedDrag),f(t,"touchend",this._disableDelayedDrag),f(t,"touchcancel",this._disableDelayedDrag),f(t,"mousemove",this._delayedDragTouchMoveHandler),f(t,"touchmove",this._delayedDragTouchMoveHandler),f(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(V,"dragend",this),h(Q,"dragstart",this._onDragStart));try{document.selection?Kt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;wt=!1,Q&&V?(G("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Bt),n=this.options,t||k(V,n.dragClass,!1),k(V,n.ghostClass,!0),Ft.active=this,t&&this._appendGhost(),q({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ut){this._lastX=ut.clientX,this._lastY=ut.clientY,Rt();for(var t=document.elementFromPoint(ut.clientX,ut.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ut.clientX,ut.clientY))!==e;)e=t;if(V.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:ut.clientX,clientY:ut.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Xt()}},_onTouchMove:function(t){if(ct){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=$&&v($,!0),a=$&&r&&r.a,l=$&&r&&r.d,e=Mt&&yt&&E(yt),a=(i.clientX-ct.clientX+o.x)/(a||1)+(e?e[0]-Ct[0]:0)/(a||1),l=(i.clientY-ct.clientY+o.y)/(l||1)+(e?e[1]-Ct[1]:0)/(l||1);if(!Ft.active&&!wt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))<n)return;this._onDragStart(t,!0)}$&&(r?(r.e+=a-(dt||0),r.f+=l-(ht||0)):r={a:1,b:0,c:0,d:1,e:a,f:l},r="matrix(".concat(r.a,",").concat(r.b,",").concat(r.c,",").concat(r.d,",").concat(r.e,",").concat(r.f,")"),R($,"webkitTransform",r),R($,"mozTransform",r),R($,"msTransform",r),R($,"transform",r),dt=a,ht=l,ut=i),t.cancelable&&t.preventDefault()}},_appendGhost:function(){if(!$){var t=this.options.fallbackOnBody?document.body:Q,e=X(V,!0,Mt,!0,t),n=this.options;if(Mt){for(yt=t;"static"===R(yt,"position")&&"none"===R(yt,"transform")&&yt!==document;)yt=yt.parentNode;yt!==document.body&&yt!==document.documentElement?(yt===document&&(yt=O()),e.top+=yt.scrollTop,e.left+=yt.scrollLeft):yt=O(),Ct=E(yt)}k($=V.cloneNode(!0),n.ghostClass,!1),k($,n.fallbackClass,!0),k($,n.dragClass,!0),R($,"transition",""),R($,"transform",""),R($,"box-sizing","border-box"),R($,"margin",0),R($,"top",e.top),R($,"left",e.left),R($,"width",e.width),R($,"height",e.height),R($,"opacity","0.8"),R($,"position",Mt?"absolute":"fixed"),R($,"zIndex","100000"),R($,"pointerEvents","none"),Ft.ghost=$,t.appendChild($),R($,"transform-origin",ft/parseInt($.style.width)*100+"% "+pt/parseInt($.style.height)*100+"%")}},_onDragStart:function(t,e){var n=this,o=t.dataTransfer,i=n.options;G("dragStart",this,{evt:t}),Ft.eventCanceled?this._onDrop():(G("setupClone",this),Ft.eventCanceled||((et=_(V)).removeAttribute("id"),et.draggable=!1,et.style["will-change"]="",this._hideClone(),k(et,this.options.chosenClass,!1),Ft.clone=et),n.cloneId=Kt(function(){G("clone",n),Ft.eventCanceled||(n.options.removeCloneOnHide||Q.insertBefore(et,V),n._hideClone(),q({sortable:n,name:"clone"}))}),e||k(V,i.dragClass,!0),e?(Et=!0,n._loopId=setInterval(n._emulateDragOver,50)):(f(document,"mouseup",n._onDrop),f(document,"touchend",n._onDrop),f(document,"touchcancel",n._onDrop),o&&(o.effectAllowed="move",i.setData&&i.setData.call(n,o,V)),h(document,"drop",n),R(V,"transform","translateZ(0)")),wt=!0,n._dragStartId=Kt(n._dragStarted.bind(n,e,t)),h(document,"selectstart",n),gt=!0,u&&R(document.body,"user-select","none"))},_onDragOver:function(n){var o,i,r,t,e,a=this.el,l=n.target,s=this.options,c=s.group,u=Ft.active,d=lt===c,h=s.sort,f=st||u,p=this,g=!1;if(!Tt){if(void 0!==n.preventDefault&&n.cancelable&&n.preventDefault(),l=P(l,s.draggable,a,!0),O("dragOver"),Ft.eventCanceled)return g;if(V.contains(n.target)||l.animated&&l.animatingX&&l.animatingY||p._ignoreWhileAnimating===l)return A(!1);if(Et=!1,u&&!s.disabled&&(d?h||(i=Z!==Q):st===this||(this.lastPutMode=lt.checkPull(this,u,V,n))&&c.checkPut(this,u,V,n))){if(r="vertical"===this._getDirection(n,l),o=X(V),O("dragOverValid"),Ft.eventCanceled)return g;if(i)return Z=Q,M(),this._hideClone(),O("revert"),Ft.eventCanceled||(J?Q.insertBefore(V,J):Q.appendChild(V)),A(!0);var m=F(a,s.draggable);if(m&&(S=n,c=r,x=X(F((D=this).el,D.options.draggable)),D=L(D.el,D.options,$),!(c?S.clientX>D.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>D.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,$),e?t.clientX<_.left-10||t.clientY<C.top&&t.clientX<C.right:t.clientY<_.top-10||t.clientY<C.bottom&&t.clientX<C.left)){var v=B(a,0,s,!0);if(v===V)return A(!1);if(E=X(l=v),!1!==jt(Q,a,V,o,l,E,n,!1))return M(),a.insertBefore(V,v),Z=a,N(),A(!0)}else if(l.parentNode===a){var b,y,w,E=X(l),D=V.parentNode!==a,S=(S=V.animated&&V.toRect||o,x=l.animated&&l.toRect||E,_=(e=r)?S.left:S.top,t=e?S.right:S.bottom,C=e?S.width:S.height,v=e?x.left:x.top,S=e?x.right:x.bottom,x=e?x.width:x.height,!(_===v||t===S||_+C/2===v+x/2)),_=r?"top":"left",C=Y(l,"top","top")||Y(V,"top","top"),v=C?C.scrollTop:void 0;if(mt!==l&&(y=E[_],St=!1,_t=!S&&s.invertSwap||D),0!==(b=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,t=o?n.top:n.left,o=o?n.bottom:n.right,n=!1;if(!a)if(l&&bt<c*i){if(St=!St&&(1===vt?t+c*r/2<s:s<o-c*r/2)?!0:St)n=!0;else if(1===vt?s<t+bt:o-bt<s)return-vt}else if(t+c*(1-i)/2<s&&s<o-c*(1-i)/2)return function(t){return j(V)<j(t)?1:-1}(e);if((n=n||a)&&(s<t+c*r/2||o-c*r/2<s))return t+c/2<s?1:-1;return 0}(n,l,E,r,S?1:s.swapThreshold,null==s.invertedSwapThreshold?s.swapThreshold:s.invertedSwapThreshold,_t,mt===l)))for(var T=j(V);(w=Z.children[T-=b])&&("none"===R(w,"display")||w===$););if(0===b||w===l)return A(!1);vt=b;var x=(mt=l).nextElementSibling,D=!1,S=jt(Q,a,V,o,l,E,n,D=1===b);if(!1!==S)return 1!==S&&-1!==S||(D=1===S),Tt=!0,setTimeout(Lt,30),M(),D&&!x?a.appendChild(V):l.parentNode.insertBefore(V,D?x:l),C&&H(C,0,v-C.scrollTop),Z=V.parentNode,void 0===y||_t||(bt=Math.abs(y-X(l)[_])),N(),A(!0)}}else{if(m===V)return A(!1);if((l=m&&a===n.target?m:l)&&(E=X(l)),!1!==jt(Q,a,V,o,l,E,n,!!l))return M(),m&&m.nextSibling?a.insertBefore(V,m.nextSibling):a.appendChild(V),Z=a,N(),A(!0)}if(a.contains(V))return A(!1)}return!1}function O(t,e){G(t,p,I({evt:n,isOwner:d,axis:r?"vertical":"horizontal",revert:i,dragRect:o,targetRect:E,canSort:h,fromSortable:f,target:l,completed:A,onMove:function(t,e){return jt(Q,a,V,o,t,X(t),n,e)},changed:N},e))}function M(){O("dragOverAnimationCapture"),p.captureAnimationState(),p!==f&&f.captureAnimationState()}function A(t){return O("dragOverCompleted",{insertion:t}),t&&(d?u._hideClone():u._showClone(p),p!==f&&(k(V,(st||u).options.ghostClass,!1),k(V,s.ghostClass,!0)),st!==p&&p!==Ft.active?st=p:p===Ft.active&&st&&(st=null),f===p&&(p._ignoreWhileAnimating=l),p.animateAll(function(){O("dragOverAnimationComplete"),p._ignoreWhileAnimating=null}),p!==f&&(f.animateAll(),f._ignoreWhileAnimating=null)),(l===V&&!V.animated||l===a&&!l.animated)&&(mt=null),s.dragoverBubble||n.rootEl||l===document||(V.parentNode[K]._isOutsideThisEl(n.target),t||Yt(n)),!s.dragoverBubble&&n.stopPropagation&&n.stopPropagation(),g=!0}function N(){it=j(V),at=j(V,s.draggable),q({sortable:p,name:"change",toEl:a,newIndex:it,newDraggableIndex:at,originalEvent:n})}},_ignoreWhileAnimating:null,_offMoveEvents:function(){f(document,"mousemove",this._onTouchMove),f(document,"touchmove",this._onTouchMove),f(document,"pointermove",this._onTouchMove),f(document,"dragover",Yt),f(document,"mousemove",Yt),f(document,"touchmove",Yt)},_offUpEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._onDrop),f(t,"touchend",this._onDrop),f(t,"pointerup",this._onDrop),f(t,"touchcancel",this._onDrop),f(document,"selectstart",this)},_onDrop:function(t){var e=this.el,n=this.options;it=j(V),at=j(V,n.draggable),G("drop",this,{evt:t}),Z=V&&V.parentNode,it=j(V),at=j(V,n.draggable),Ft.eventCanceled||(St=_t=wt=!1,clearInterval(this._loopId),clearTimeout(this._dragStartTimer),Wt(this.cloneId),Wt(this._dragStartId),this.nativeDraggable&&(f(document,"drop",this),f(e,"dragstart",this._onDragStart)),this._offMoveEvents(),this._offUpEvents(),u&&R(document.body,"user-select",""),R(V,"transform",""),t&&(gt&&(t.cancelable&&t.preventDefault(),n.dropBubble||t.stopPropagation()),$&&$.parentNode&&$.parentNode.removeChild($),(Q===Z||st&&"clone"!==st.lastPutMode)&&et&&et.parentNode&&et.parentNode.removeChild(et),V&&(this.nativeDraggable&&f(V,"dragend",this),Ht(V),V.style["will-change"]="",gt&&!wt&&k(V,(st||this).options.ghostClass,!1),k(V,this.options.chosenClass,!1),q({sortable:this,name:"unchoose",toEl:Z,newIndex:null,newDraggableIndex:null,originalEvent:t}),Q!==Z?(0<=it&&(q({rootEl:Z,name:"add",toEl:Z,fromEl:Q,originalEvent:t}),q({sortable:this,name:"remove",toEl:Z,originalEvent:t}),q({rootEl:Z,name:"sort",toEl:Z,fromEl:Q,originalEvent:t}),q({sortable:this,name:"sort",toEl:Z,originalEvent:t})),st&&st.save()):it!==ot&&0<=it&&(q({sortable:this,name:"update",toEl:Z,originalEvent:t}),q({sortable:this,name:"sort",toEl:Z,originalEvent:t})),Ft.active&&(null!=it&&-1!==it||(it=ot,at=rt),q({sortable:this,name:"end",toEl:Z,originalEvent:t}),this.save())))),this._nulling()},_nulling:function(){G("nulling",this),Q=V=Z=$=J=et=tt=nt=ct=ut=gt=it=at=ot=rt=mt=vt=st=lt=Ft.dragged=Ft.ghost=Ft.clone=Ft.active=null,xt.forEach(function(t){t.checked=!0}),xt.length=dt=ht=0},handleEvent:function(t){switch(t.type){case"drop":case"dragend":this._onDrop(t);break;case"dragenter":case"dragover":V&&(this._onDragOver(t),function(t){t.dataTransfer&&(t.dataTransfer.dropEffect="move");t.cancelable&&t.preventDefault()}(t));break;case"selectstart":t.preventDefault()}},toArray:function(){for(var t,e=[],n=this.el.children,o=0,i=n.length,r=this.options;o<i;o++)P(t=n[o],r.draggable,this.el,!1)&&e.push(t.getAttribute(r.dataIdAttr)||function(t){var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;for(;n--;)o+=e.charCodeAt(n);return o.toString(36)}(t));return e},sort:function(t,e){var n={},o=this.el;this.toArray().forEach(function(t,e){e=o.children[e];P(e,this.options.draggable,o,!1)&&(n[t]=e)},this),e&&this.captureAnimationState(),t.forEach(function(t){n[t]&&(o.removeChild(n[t]),o.appendChild(n[t]))}),e&&this.animateAll()},save:function(){var t=this.options.store;t&&t.set&&t.set(this)},closest:function(t,e){return P(t,e||this.options.draggable,this.el,!1)},option:function(t,e){var n=this.options;if(void 0===e)return n[t];var o=W.modifyOption(this,t,e);n[t]=void 0!==o?o:e,"group"===t&&kt(n)},destroy:function(){G("destroy",this);var t=this.el;t[K]=null,f(t,"mousedown",this._onTapStart),f(t,"touchstart",this._onTapStart),f(t,"pointerdown",this._onTapStart),this.nativeDraggable&&(f(t,"dragover",this),f(t,"dragenter",this)),Array.prototype.forEach.call(t.querySelectorAll("[draggable]"),function(t){t.removeAttribute("draggable")}),this._onDrop(),this._disableDelayedDragEvents(),Dt.splice(Dt.indexOf(this.el),1),this.el=t=null},_hideClone:function(){nt||(G("hideClone",this),Ft.eventCanceled||(R(et,"display","none"),this.options.removeCloneOnHide&&et.parentNode&&et.parentNode.removeChild(et),nt=!0))},_showClone:function(t){"clone"===t.lastPutMode?nt&&(G("showClone",this),Ft.eventCanceled||(V.parentNode!=Q||this.options.group.revertClone?J?Q.insertBefore(et,J):Q.appendChild(et):Q.insertBefore(et,V),this.options.group.revertClone&&this.animate(V,et),R(et,"display",""),nt=!1)):this._hideClone()}},Ot&&h(document,"touchmove",function(t){(Ft.active||wt)&&t.cancelable&&t.preventDefault()}),Ft.utils={on:h,off:f,css:R,find:b,is:function(t,e){return!!P(t,e,t,!1)},extend:function(t,e){if(t&&e)for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t},throttle:S,closest:P,toggleClass:k,clone:_,index:j,nextTick:Kt,cancelNextTick:Wt,detectDirection:Pt,getChild:B},Ft.get=function(t){return t[K]},Ft.mount=function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];(e=e[0].constructor===Array?e[0]:e).forEach(function(t){if(!t.prototype||!t.prototype.constructor)throw"Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(t));t.utils&&(Ft.utils=I(I({},Ft.utils),t.utils)),W.mount(t)})},Ft.create=function(t,e){return new Ft(t,e)};var zt,Gt,Ut,qt,Vt,Zt,$t=[],Qt=!(Ft.version="1.15.2");function Jt(){$t.forEach(function(t){clearInterval(t.pid)}),$t=[]}function te(){clearInterval(Zt)}var ee,ne=S(function(n,t,e,o){if(t.scroll){var i,r=(n.touches?n.touches[0]:n).clientX,a=(n.touches?n.touches[0]:n).clientY,l=t.scrollSensitivity,s=t.scrollSpeed,c=O(),u=!1;Gt!==e&&(Gt=e,Jt(),zt=t.scroll,i=t.scrollFn,!0===zt&&(zt=M(e,!0)));var d=0,h=zt;do{var f=h,p=X(f),g=p.top,m=p.bottom,v=p.left,b=p.right,y=p.width,w=p.height,E=void 0,D=void 0,S=f.scrollWidth,_=f.scrollHeight,C=R(f),T=f.scrollLeft,p=f.scrollTop,D=f===c?(E=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX||"visible"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY||"visible"===C.overflowY)):(E=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY)),T=E&&(Math.abs(b-r)<=l&&T+y<S)-(Math.abs(v-r)<=l&&!!T),p=D&&(Math.abs(m-a)<=l&&p+w<_)-(Math.abs(g-a)<=l&&!!p);if(!$t[d])for(var x=0;x<=d;x++)$t[x]||($t[x]={});$t[d].vx==T&&$t[d].vy==p&&$t[d].el===f||($t[d].el=f,$t[d].vx=T,$t[d].vy=p,clearInterval($t[d].pid),0==T&&0==p||(u=!0,$t[d].pid=setInterval(function(){o&&0===this.layer&&Ft.active._onTouchMove(Vt);var t=$t[this.layer].vy?$t[this.layer].vy*s:0,e=$t[this.layer].vx?$t[this.layer].vx*s:0;"function"==typeof i&&"continue"!==i.call(Ft.dragged.parentNode[K],e,t,n,Vt,$t[this.layer].el)||H($t[this.layer].el,e,t)}.bind({layer:d}),24))),d++}while(t.bubbleScroll&&h!==c&&(h=M(h,!1)));Qt=u}},30),c=function(t){var e=t.originalEvent,n=t.putSortable,o=t.dragEl,i=t.activeSortable,r=t.dispatchSortableEvent,a=t.hideGhostForTarget,t=t.unhideGhostForTarget;e&&(i=n||i,a(),e=e.changedTouches&&e.changedTouches.length?e.changedTouches[0]:e,e=document.elementFromPoint(e.clientX,e.clientY),t(),i&&!i.el.contains(e)&&(r("spill"),this.onSpill({dragEl:o,putSortable:n})))};function oe(){}function ie(){}oe.prototype={startIndex:null,dragStart:function(t){t=t.oldDraggableIndex;this.startIndex=t},onSpill:function(t){var e=t.dragEl,n=t.putSortable;this.sortable.captureAnimationState(),n&&n.captureAnimationState();t=B(this.sortable.el,this.startIndex,this.options);t?this.sortable.el.insertBefore(e,t):this.sortable.el.appendChild(e),this.sortable.animateAll(),n&&n.animateAll()},drop:c},a(oe,{pluginName:"revertOnSpill"}),ie.prototype={onSpill:function(t){var e=t.dragEl,t=t.putSortable||this.sortable;t.captureAnimationState(),e.parentNode&&e.parentNode.removeChild(e),t.animateAll()},drop:c},a(ie,{pluginName:"removeOnSpill"});var re,ae,le,se,ce,ue=[],de=[],he=!1,fe=!1,pe=!1;function ge(n,o){de.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)})}function me(){ue.forEach(function(t){t!==le&&t.parentNode&&t.parentNode.removeChild(t)})}return Ft.mount(new function(){function t(){for(var t in this.defaults={scroll:!0,forceAutoScrollFallback:!1,scrollSensitivity:30,scrollSpeed:10,bubbleScroll:!0},this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this))}return t.prototype={dragStarted:function(t){t=t.originalEvent;this.sortable.nativeDraggable?h(document,"dragover",this._handleAutoScroll):this.options.supportPointer?h(document,"pointermove",this._handleFallbackAutoScroll):t.touches?h(document,"touchmove",this._handleFallbackAutoScroll):h(document,"mousemove",this._handleFallbackAutoScroll)},dragOverCompleted:function(t){t=t.originalEvent;this.options.dragOverBubble||t.rootEl||this._handleAutoScroll(t)},drop:function(){this.sortable.nativeDraggable?f(document,"dragover",this._handleAutoScroll):(f(document,"pointermove",this._handleFallbackAutoScroll),f(document,"touchmove",this._handleFallbackAutoScroll),f(document,"mousemove",this._handleFallbackAutoScroll)),te(),Jt(),clearTimeout(g),g=void 0},nulling:function(){Vt=Gt=zt=Qt=Zt=Ut=qt=null,$t.length=0},_handleFallbackAutoScroll:function(t){this._handleAutoScroll(t,!0)},_handleAutoScroll:function(e,n){var o,i=this,r=(e.touches?e.touches[0]:e).clientX,a=(e.touches?e.touches[0]:e).clientY,t=document.elementFromPoint(r,a);Vt=e,n||this.options.forceAutoScrollFallback||w||y||u?(ne(e,this.options,t,n),o=M(t,!0),!Qt||Zt&&r===Ut&&a===qt||(Zt&&te(),Zt=setInterval(function(){var t=M(document.elementFromPoint(r,a),!0);t!==o&&(o=t,Jt()),ne(e,i.options,t,n)},10),Ut=r,qt=a)):this.options.bubbleScroll&&M(t,!0)!==O()?ne(e,this.options,M(t,!1),!1):Jt()}},a(t,{pluginName:"scroll",initializeByDefault:!0})}),Ft.mount(ie,oe),Ft.mount(new function(){function t(){this.defaults={swapClass:"sortable-swap-highlight"}}return t.prototype={dragStart:function(t){t=t.dragEl;ee=t},dragOverValid:function(t){var e=t.completed,n=t.target,o=t.onMove,i=t.activeSortable,r=t.changed,a=t.cancel;i.options.swap&&(t=this.sortable.el,i=this.options,n&&n!==t&&(t=ee,ee=!1!==o(n)?(k(n,i.swapClass,!0),n):null,t&&t!==ee&&k(t,i.swapClass,!1)),r(),e(!0),a())},drop:function(t){var e,n,o=t.activeSortable,i=t.putSortable,r=t.dragEl,a=i||this.sortable,l=this.options;ee&&k(ee,l.swapClass,!1),ee&&(l.swap||i&&i.options.swap)&&r!==ee&&(a.captureAnimationState(),a!==o&&o.captureAnimationState(),n=ee,t=(e=r).parentNode,l=n.parentNode,t&&l&&!t.isEqualNode(n)&&!l.isEqualNode(e)&&(i=j(e),r=j(n),t.isEqualNode(l)&&i<r&&r++,t.insertBefore(n,t.children[i]),l.insertBefore(e,l.children[r])),a.animateAll(),a!==o&&o.animateAll())},nulling:function(){ee=null}},a(t,{pluginName:"swap",eventProperties:function(){return{swapItem:ee}}})}),Ft.mount(new function(){function t(o){for(var t in this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this));o.options.avoidImplicitDeselect||(o.options.supportPointer?h(document,"pointerup",this._deselectMultiDrag):(h(document,"mouseup",this._deselectMultiDrag),h(document,"touchend",this._deselectMultiDrag))),h(document,"keydown",this._checkKeyDown),h(document,"keyup",this._checkKeyUp),this.defaults={selectedClass:"sortable-selected",multiDragKey:null,avoidImplicitDeselect:!1,setData:function(t,e){var n="";ue.length&&ae===o?ue.forEach(function(t,e){n+=(e?", ":"")+t.textContent}):n=e.textContent,t.setData("Text",n)}}}return t.prototype={multiDragKeyDown:!1,isMultiDrag:!1,delayStartGlobal:function(t){t=t.dragEl;le=t},delayEnded:function(){this.isMultiDrag=~ue.indexOf(le)},setupClone:function(t){var e=t.sortable,t=t.cancel;if(this.isMultiDrag){for(var n=0;n<ue.length;n++)de.push(_(ue[n])),de[n].sortableIndex=ue[n].sortableIndex,de[n].draggable=!1,de[n].style["will-change"]="",k(de[n],this.options.selectedClass,!1),ue[n]===le&&k(de[n],this.options.chosenClass,!1);e._hideClone(),t()}},clone:function(t){var e=t.sortable,n=t.rootEl,o=t.dispatchSortableEvent,t=t.cancel;this.isMultiDrag&&(this.options.removeCloneOnHide||ue.length&&ae===e&&(ge(!0,n),o("clone"),t()))},showClone:function(t){var e=t.cloneNowShown,n=t.rootEl,t=t.cancel;this.isMultiDrag&&(ge(!1,n),de.forEach(function(t){R(t,"display","")}),e(),ce=!1,t())},hideClone:function(t){var e=this,n=(t.sortable,t.cloneNowHidden),t=t.cancel;this.isMultiDrag&&(de.forEach(function(t){R(t,"display","none"),e.options.removeCloneOnHide&&t.parentNode&&t.parentNode.removeChild(t)}),n(),ce=!0,t())},dragStartGlobal:function(t){t.sortable;!this.isMultiDrag&&ae&&ae.multiDrag._deselectMultiDrag(),ue.forEach(function(t){t.sortableIndex=j(t)}),ue=ue.sort(function(t,e){return t.sortableIndex-e.sortableIndex}),pe=!0},dragStarted:function(t){var e,n=this,t=t.sortable;this.isMultiDrag&&(this.options.sort&&(t.captureAnimationState(),this.options.animation&&(ue.forEach(function(t){t!==le&&R(t,"position","absolute")}),e=X(le,!1,!0,!0),ue.forEach(function(t){t!==le&&C(t,e)}),he=fe=!0)),t.animateAll(function(){he=fe=!1,n.options.animation&&ue.forEach(function(t){T(t)}),n.options.sort&&me()}))},dragOver:function(t){var e=t.target,n=t.completed,t=t.cancel;fe&&~ue.indexOf(e)&&(n(!1),t())},revert:function(t){var n,o,e=t.fromSortable,i=t.rootEl,r=t.sortable,a=t.dragRect;1<ue.length&&(ue.forEach(function(t){r.addAnimationState({target:t,rect:fe?X(t):a}),T(t),t.fromRect=a,e.removeAnimationState(t)}),fe=!1,n=!this.options.removeCloneOnHide,o=i,ue.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)}))},dragOverCompleted:function(t){var e,n=t.sortable,o=t.isOwner,i=t.insertion,r=t.activeSortable,a=t.parentEl,l=t.putSortable,t=this.options;i&&(o&&r._hideClone(),he=!1,t.animation&&1<ue.length&&(fe||!o&&!r.options.sort&&!l)&&(e=X(le,!1,!0,!0),ue.forEach(function(t){t!==le&&(C(t,e),a.appendChild(t))}),fe=!0),o||(fe||me(),1<ue.length?(o=ce,r._showClone(n),r.options.animation&&!ce&&o&&de.forEach(function(t){r.addAnimationState({target:t,rect:se}),t.fromRect=se,t.thisAnimationDuration=null})):r._showClone(n)))},dragOverAnimationCapture:function(t){var e=t.dragRect,n=t.isOwner,t=t.activeSortable;ue.forEach(function(t){t.thisAnimationDuration=null}),t.options.animation&&!n&&t.multiDrag.isMultiDrag&&(se=a({},e),e=v(le,!0),se.top-=e.f,se.left-=e.e)},dragOverAnimationComplete:function(){fe&&(fe=!1,me())},drop:function(t){var e=t.originalEvent,n=t.rootEl,o=t.parentEl,i=t.sortable,r=t.dispatchSortableEvent,a=t.oldIndex,l=t.putSortable,s=l||this.sortable;if(e){var c,u,d,h=this.options,f=o.children;if(!pe)if(h.multiDragKey&&!this.multiDragKeyDown&&this._deselectMultiDrag(),k(le,h.selectedClass,!~ue.indexOf(le)),~ue.indexOf(le))ue.splice(ue.indexOf(le),1),re=null,z({sortable:i,rootEl:n,name:"deselect",targetEl:le,originalEvent:e});else{if(ue.push(le),z({sortable:i,rootEl:n,name:"select",targetEl:le,originalEvent:e}),e.shiftKey&&re&&i.el.contains(re)){var p=j(re),t=j(le);if(~p&&~t&&p!==t)for(var g,m=p<t?(g=p,t):(g=t,p+1);g<m;g++)~ue.indexOf(f[g])||(k(f[g],h.selectedClass,!0),ue.push(f[g]),z({sortable:i,rootEl:n,name:"select",targetEl:f[g],originalEvent:e}))}else re=le;ae=s}pe&&this.isMultiDrag&&(fe=!1,(o[K].options.sort||o!==n)&&1<ue.length&&(c=X(le),u=j(le,":not(."+this.options.selectedClass+")"),!he&&h.animation&&(le.thisAnimationDuration=null),s.captureAnimationState(),he||(h.animation&&(le.fromRect=c,ue.forEach(function(t){var e;t.thisAnimationDuration=null,t!==le&&(e=fe?X(t):c,t.fromRect=e,s.addAnimationState({target:t,rect:e}))})),me(),ue.forEach(function(t){f[u]?o.insertBefore(t,f[u]):o.appendChild(t),u++}),a===j(le)&&(d=!1,ue.forEach(function(t){t.sortableIndex!==j(t)&&(d=!0)}),d&&(r("update"),r("sort")))),ue.forEach(function(t){T(t)}),s.animateAll()),ae=s),(n===o||l&&"clone"!==l.lastPutMode)&&de.forEach(function(t){t.parentNode&&t.parentNode.removeChild(t)})}},nullingGlobal:function(){this.isMultiDrag=pe=!1,de.length=0},destroyGlobal:function(){this._deselectMultiDrag(),f(document,"pointerup",this._deselectMultiDrag),f(document,"mouseup",this._deselectMultiDrag),f(document,"touchend",this._deselectMultiDrag),f(document,"keydown",this._checkKeyDown),f(document,"keyup",this._checkKeyUp)},_deselectMultiDrag:function(t){if(!(void 0!==pe&&pe||ae!==this.sortable||t&&P(t.target,this.options.draggable,this.sortable.el,!1)||t&&0!==t.button))for(;ue.length;){var e=ue[0];k(e,this.options.selectedClass,!1),ue.shift(),z({sortable:this.sortable,rootEl:this.sortable.el,name:"deselect",targetEl:e,originalEvent:t})}},_checkKeyDown:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!0)},_checkKeyUp:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!1)}},a(t,{pluginName:"multiDrag",utils:{select:function(t){var e=t.parentNode[K];e&&e.options.multiDrag&&!~ue.indexOf(t)&&(ae&&ae!==e&&(ae.multiDrag._deselectMultiDrag(),ae=e),k(t,e.options.selectedClass,!0),ue.push(t))},deselect:function(t){var e=t.parentNode[K],n=ue.indexOf(t);e&&e.options.multiDrag&&~n&&(k(t,e.options.selectedClass,!1),ue.splice(n,1))}},eventProperties:function(){var n=this,o=[],i=[];return ue.forEach(function(t){var e;o.push({multiDragElement:t,index:t.sortableIndex}),e=fe&&t!==le?-1:fe?j(t,":not(."+n.options.selectedClass+")"):j(t),i.push({multiDragElement:t,index:e})}),{items:r(ue),clones:[].concat(de),oldIndicies:o,newIndicies:i}},optionListeners:{multiDragKey:function(t){return"ctrl"===(t=t.toLowerCase())?t="Control":1<t.length&&(t=t.charAt(0).toUpperCase()+t.substr(1)),t}}})}),Ft});';import{existsSync as Se,readFileSync as Ot,writeFileSync as Ht,rmSync as ns,mkdirSync as Xa,copyFileSync as Va,readdirSync as Ya}from"fs";import{resolve as oe}from"path";import{existsSync as q,readFileSync as He,writeFileSync as Ne,mkdirSync as be,readdirSync as Oe,rmSync as ja,statSync as F}from"fs";import{resolve as At,relative as za,dirname as Be,join as Q,extname as pe,basename as je}from"path";var O=200*1024,$t=new Set([".md",".markdown",".txt"]),ne=new Set([".md",".markdown",".txt",".json",".jsonc",".yaml",".yml",".toml",".sh",".bash",".zsh",".py",".js",".mjs",".ts",".tsx",".jsx",".css",".html",".lock",".cfg",".ini",".env",".gitignore"]),qa=6,Fa=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function K(t,e){if(!t)throw new Error("Agent workspace is not configured.");let a=At(t);if(q(a)||be(a,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let n=At(a,e);if(za(a,n).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return n}function Mt(t){let e=pe(t).toLowerCase();if(!$t.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function Pe(t,e){let a=t.split(/\r?\n/).find(n=>n.trim().startsWith("#"));return a&&a.replace(/^#+\s*/,"").trim().slice(0,120)||e}function re(t){let e=K(t,"."),a=[],n=new Set,r=[];try{r=Oe(e)}catch{}for(let i of Fa){let l=Q(e,i);if(q(l)&&F(l).isFile()){let d=F(l).size,c=d>0&&d<O?Re(l):"";a.push({path:i,title:Pe(c,i),size:d,exists:!0}),n.add(i)}else a.push({path:i,title:i,size:0,exists:!1}),n.add(i)}for(let i of r){if(n.has(i))continue;let l=Q(e,i);try{let d=F(l);if(!d.isFile()||!$t.has(pe(i).toLowerCase()))continue;let c=d.size>0&&d.size<O?Re(l):"";a.push({path:i,title:Pe(c,i),size:d.size,exists:!0})}catch{}}let o=[],s=Q(e,".claude","skills");if(q(s))try{for(let i of Oe(s)){let l=Q(s,i),d;try{d=F(l)}catch{continue}if(!d.isDirectory())continue;let c=Q(l,"SKILL.md");if(!q(c))continue;let u=F(c),h=u.size<O?Re(c):"";o.push({slug:i,title:Pe(h,i),size:u.size,path:`.claude/skills/${i}/SKILL.md`})}}catch{}return o.sort((i,l)=>i.slug.localeCompare(l.slug)),{identity:a,skills:o,workspace:e}}function Re(t){try{return He(t,"utf-8")}catch{return""}}function xe(t,e){let a=K(t,e);if(Mt(a),!q(a))return{path:e,content:""};if(F(a).size>O)throw new Error(`File is too large to edit in the admin panel (> ${O/1024} KB).`);return{path:e,content:He(a,"utf-8")}}function ye(t,e,a){let n=K(t,e);Mt(n);let r=Buffer.from(a,"utf-8");if(r.length>O)throw new Error(`File too large (${r.length} > ${O} bytes).`);return be(Be(n),{recursive:!0}),Ne(n,r),{path:e,bytes:r.length}}function we(t,e,a={}){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Skill slug must be lowercase (letters, digits, -, _) and start with a letter or digit.");let n=`.claude/skills/${e}/SKILL.md`,r=K(t,n);if(q(r))throw new Error(`Skill "${e}" already exists.`);be(Be(r),{recursive:!0});let o=a.content?.trim()?a.content:Ga(e,a.title);return Ne(r,o),{slug:e,path:n}}function ke(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let a=K(t,`.claude/skills/${e}`);if(!q(a))throw new Error(`Skill "${e}" not found.`);if(!F(a).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return ja(a,{recursive:!0,force:!0}),{slug:e}}function It(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let a=K(t,`.claude/skills/${e}`);if(!q(a))throw new Error(`Skill "${e}" not found.`);let n=[];return r(a,"",0,n),n.sort((o,s)=>o.kind!==s.kind?o.kind==="dir"?-1:1:o.path.localeCompare(s.path)),n;function r(o,s,i,l){if(i>qa)return;let d=[];try{d=Oe(o)}catch{return}for(let c of d){if(c==="node_modules"||c===".git")continue;let u=Q(o,c),h=s?`${s}/${c}`:c,x;try{x=F(u)}catch{continue}if(x.isDirectory())l.push({path:`${h}/`,kind:"dir",size:0,editable:!1}),r(u,h,i+1,l);else if(x.isFile()){let p=pe(c).toLowerCase(),m=ne.has(p)||ne.has(c.toLowerCase());l.push({path:h,kind:"file",size:x.size,editable:m&&x.size<O})}}}}function Lt(t,e,a){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!a||a.includes(".."))throw new Error(`Invalid file path: ${a}`);let n=K(t,`.claude/skills/${e}/${a}`);if(!q(n)||!F(n).isFile())throw new Error(`File not found: ${a}`);let r=pe(n).toLowerCase(),o=je(n).toLowerCase();if(!ne.has(r)&&!ne.has(o))throw new Error(`File type not editable: ${a}`);if(F(n).size>O)throw new Error(`File too large to edit (> ${O/1024} KB): ${a}`);return{path:a,content:He(n,"utf-8")}}function Dt(t,e,a,n){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!a||a.includes(".."))throw new Error(`Invalid file path: ${a}`);let r=K(t,`.claude/skills/${e}/${a}`),o=pe(r).toLowerCase(),s=je(r).toLowerCase();if(!ne.has(o)&&!ne.has(s))throw new Error(`File type not editable: ${a}`);let i=Buffer.from(n,"utf-8");if(i.length>O)throw new Error(`File too large (${i.length} > ${O} bytes).`);return be(Be(r),{recursive:!0}),Ne(r,i),{path:a,bytes:i.length}}function _e(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let a=K(t,`.claude/skills/${e}`);if(!q(a))throw new Error(`Skill "${e}" not found.`);let n=r=>q(Q(a,r));return n("pnpm-lock.yaml")?{manager:"pnpm",file:"pnpm-lock.yaml",command:"pnpm install"}:n("yarn.lock")?{manager:"yarn",file:"yarn.lock",command:"yarn install"}:n("package.json")?{manager:"npm",file:"package.json",command:"npm install"}:n("requirements.txt")?{manager:"pip",file:"requirements.txt",command:"pip install -r requirements.txt"}:n("Gemfile")?{manager:"bundle",file:"Gemfile",command:"bundle install"}:{manager:null,file:null,command:null}}function Ga(t,e){return`# ${e?.trim()||t}
1
+ import{a as kt}from"./chunk-MTRWXRFF.js";import{a as _t}from"./chunk-NOF4HSGK.js";import{a as T,b as Et,c as St,d as Tt,e as Ct,f as U,g as ce,h as De,i as At}from"./chunk-WHP4I44J.js";import{a as A,b as R,g as vt,h as bt,i as H,j as O,k as ve,l as xt,m as yt,n as wt}from"./chunk-CNNLREHD.js";import{a as Ie,b as Le,f as ut,g as mt,h as gt,p as ft}from"./chunk-2HXSJYAJ.js";import"./chunk-N67JZAXU.js";import"./chunk-AFRHKA7B.js";import"./chunk-EW27SCCC.js";import"./chunk-ABVZHJUO.js";import"./chunk-P3TJHGO5.js";import{a as ct,b as pt,e as z}from"./chunk-CO4YCIIA.js";import{f as ht}from"./chunk-CDNWCYF7.js";import{a as dt}from"./chunk-5F3J55LG.js";import"./chunk-GOLZ6NEL.js";import{b as lt}from"./chunk-7P5QRX5W.js";import"./chunk-JTJIPNXY.js";import"./chunk-64P4QHSZ.js";import"./chunk-JGXE2YNV.js";import"./chunk-VJUTQAPJ.js";import"./chunk-QOYAX2FT.js";import"./chunk-4YCH6IZV.js";import{createServer as $o}from"http";import{appendFileSync as Mo,existsSync as Pa,mkdirSync as Io}from"fs";import{readFile as Lo}from"fs/promises";import{fileURLToPath as Do}from"url";import{dirname as Po,resolve as ge}from"path";var $t='/*! Sortable 1.15.2 - MIT | git://github.com/SortableJS/Sortable.git */\n!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function I(o){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?e(Object(i),!0).forEach(function(t){var e,n;e=o,t=i[n=t],n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t}):Object.getOwnPropertyDescriptors?Object.defineProperties(o,Object.getOwnPropertyDescriptors(i)):e(Object(i)).forEach(function(t){Object.defineProperty(o,t,Object.getOwnPropertyDescriptor(i,t))})}return o}function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,o=arguments[e];for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&(t[n]=o[n])}return t}).apply(this,arguments)}function i(t,e){if(null==t)return{};var n,o=function(t,e){if(null==t)return{};for(var n,o={},i=Object.keys(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols)for(var i=Object.getOwnPropertySymbols(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n]);return o}function r(t){return function(t){if(Array.isArray(t))return l(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return l(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Map"===(n="Object"===n&&t.constructor?t.constructor.name:n)||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=new Array(e);n<e;n++)o[n]=t[n];return o}function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var y=t(/(?:Trident.*rv[ :]?11\\.|msie|iemobile|Windows Phone)/i),w=t(/Edge/i),s=t(/firefox/i),u=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),n=t(/iP(ad|od|hone)/i),c=t(/chrome/i)&&t(/android/i),d={capture:!1,passive:!1};function h(t,e,n){t.addEventListener(e,n,!y&&d)}function f(t,e,n){t.removeEventListener(e,n,!y&&d)}function p(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i<r;i++)n(o[i],i);return o}return[]}function O(){var t=document.scrollingElement;return t||document.documentElement}function X(t,e,n,o,i){if(t.getBoundingClientRect||t===window){var r,a,l,s,c,u,d=t!==window&&t.parentNode&&t!==O()?(a=(r=t.getBoundingClientRect()).top,l=r.left,s=r.bottom,c=r.right,u=r.height,r.width):(l=a=0,s=window.innerHeight,c=window.innerWidth,u=window.innerHeight,window.innerWidth);if((e||n)&&t!==window&&(i=i||t.parentNode,!y))do{if(i&&i.getBoundingClientRect&&("none"!==R(i,"transform")||n&&"static"!==R(i,"position"))){var h=i.getBoundingClientRect();a-=h.top+parseInt(R(i,"border-top-width")),l-=h.left+parseInt(R(i,"border-left-width")),s=a+r.height,c=l+r.width;break}}while(i=i.parentNode);return o&&t!==window&&(o=(e=v(i||t))&&e.a,t=e&&e.d,e&&(s=(a/=t)+(u/=t),c=(l/=o)+(d/=o))),{top:a,left:l,bottom:s,right:c,width:d,height:u}}}function Y(t,e,n){for(var o=M(t,!0),i=X(t)[e];o;){var r=X(o)[n];if(!("top"===n||"left"===n?r<=i:i<=r))return o;if(o===O())break;o=M(o,!1)}return!1}function B(t,e,n,o){for(var i=0,r=0,a=t.children;r<a.length;){if("none"!==a[r].style.display&&a[r]!==Ft.ghost&&(o||a[r]!==Ft.dragged)&&P(a[r],n.draggable,t,!1)){if(i===e)return a[r];i++}r++}return null}function F(t,e){for(var n=t.lastElementChild;n&&(n===Ft.ghost||"none"===R(n,"display")||e&&!p(n,e));)n=n.previousElementSibling;return n||null}function j(t,e){var n=0;if(!t||!t.parentNode)return-1;for(;t=t.previousElementSibling;)"TEMPLATE"===t.nodeName.toUpperCase()||t===Ft.clone||e&&!p(t,e)||n++;return n}function E(t){var e=0,n=0,o=O();if(t)do{var i=v(t),r=i.a,i=i.d}while(e+=t.scrollLeft*r,n+=t.scrollTop*i,t!==o&&(t=t.parentNode));return[e,n]}function M(t,e){if(!t||!t.getBoundingClientRect)return O();var n=t,o=!1;do{if(n.clientWidth<n.scrollWidth||n.clientHeight<n.scrollHeight){var i=R(n);if(n.clientWidth<n.scrollWidth&&("auto"==i.overflowX||"scroll"==i.overflowX)||n.clientHeight<n.scrollHeight&&("auto"==i.overflowY||"scroll"==i.overflowY)){if(!n.getBoundingClientRect||n===document.body)return O();if(o||e)return n;o=!0}}}while(n=n.parentNode);return O()}function D(t,e){return Math.round(t.top)===Math.round(e.top)&&Math.round(t.left)===Math.round(e.left)&&Math.round(t.height)===Math.round(e.height)&&Math.round(t.width)===Math.round(e.width)}function S(e,n){return function(){var t;g||(1===(t=arguments).length?e.call(this,t[0]):e.apply(this,t),g=setTimeout(function(){g=void 0},n))}}function H(t,e,n){t.scrollLeft+=e,t.scrollTop+=n}function _(t){var e=window.Polymer,n=window.jQuery||window.Zepto;return e&&e.dom?e.dom(t).cloneNode(!0):n?n(t).clone(!0)[0]:t.cloneNode(!0)}function C(t,e){R(t,"position","absolute"),R(t,"top",e.top),R(t,"left",e.left),R(t,"width",e.width),R(t,"height",e.height)}function T(t){R(t,"position",""),R(t,"top",""),R(t,"left",""),R(t,"width",""),R(t,"height","")}function L(n,o,i){var r={};return Array.from(n.children).forEach(function(t){var e;P(t,o.draggable,n,!1)&&!t.animated&&t!==i&&(e=X(t),r.left=Math.min(null!==(t=r.left)&&void 0!==t?t:1/0,e.left),r.top=Math.min(null!==(t=r.top)&&void 0!==t?t:1/0,e.top),r.right=Math.max(null!==(t=r.right)&&void 0!==t?t:-1/0,e.right),r.bottom=Math.max(null!==(t=r.bottom)&&void 0!==t?t:-1/0,e.bottom))}),r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}var K="Sortable"+(new Date).getTime();function x(){var e,o=[];return{captureAnimationState:function(){o=[],this.options.animation&&[].slice.call(this.el.children).forEach(function(t){var e,n;"none"!==R(t,"display")&&t!==Ft.ghost&&(o.push({target:t,rect:X(t)}),e=I({},o[o.length-1].rect),!t.thisAnimationDuration||(n=v(t,!0))&&(e.top-=n.f,e.left-=n.e),t.fromRect=e)})},addAnimationState:function(t){o.push(t)},removeAnimationState:function(t){o.splice(function(t,e){for(var n in t)if(t.hasOwnProperty(n))for(var o in e)if(e.hasOwnProperty(o)&&e[o]===t[n][o])return Number(n);return-1}(o,{target:t}),1)},animateAll:function(t){var c=this;if(!this.options.animation)return clearTimeout(e),void("function"==typeof t&&t());var u=!1,d=0;o.forEach(function(t){var e=0,n=t.target,o=n.fromRect,i=X(n),r=n.prevFromRect,a=n.prevToRect,l=t.rect,s=v(n,!0);s&&(i.top-=s.f,i.left-=s.e),n.toRect=i,n.thisAnimationDuration&&D(r,i)&&!D(o,i)&&(l.top-i.top)/(l.left-i.left)==(o.top-i.top)/(o.left-i.left)&&(t=l,s=r,r=a,a=c.options,e=Math.sqrt(Math.pow(s.top-t.top,2)+Math.pow(s.left-t.left,2))/Math.sqrt(Math.pow(s.top-r.top,2)+Math.pow(s.left-r.left,2))*a.animation),D(i,o)||(n.prevFromRect=o,n.prevToRect=i,e=e||c.options.animation,c.animate(n,l,i,e)),e&&(u=!0,d=Math.max(d,e),clearTimeout(n.animationResetTimer),n.animationResetTimer=setTimeout(function(){n.animationTime=0,n.prevFromRect=null,n.fromRect=null,n.prevToRect=null,n.thisAnimationDuration=null},e),n.thisAnimationDuration=e)}),clearTimeout(e),u?e=setTimeout(function(){"function"==typeof t&&t()},d):"function"==typeof t&&t(),o=[]},animate:function(t,e,n,o){var i,r;o&&(R(t,"transition",""),R(t,"transform",""),i=(r=v(this.el))&&r.a,r=r&&r.d,i=(e.left-n.left)/(i||1),r=(e.top-n.top)/(r||1),t.animatingX=!!i,t.animatingY=!!r,R(t,"transform","translate3d("+i+"px,"+r+"px,0)"),this.forRepaintDummy=t.offsetWidth,R(t,"transition","transform "+o+"ms"+(this.options.easing?" "+this.options.easing:"")),R(t,"transform","translate3d(0,0,0)"),"number"==typeof t.animated&&clearTimeout(t.animated),t.animated=setTimeout(function(){R(t,"transition",""),R(t,"transform",""),t.animated=!1,t.animatingX=!1,t.animatingY=!1},o))}}}var A=[],N={initializeByDefault:!0},W={mount:function(e){for(var t in N)!N.hasOwnProperty(t)||t in e||(e[t]=N[t]);A.forEach(function(t){if(t.pluginName===e.pluginName)throw"Sortable: Cannot mount plugin ".concat(e.pluginName," more than once")}),A.push(e)},pluginEvent:function(e,n,o){var t=this;this.eventCanceled=!1,o.cancel=function(){t.eventCanceled=!0};var i=e+"Global";A.forEach(function(t){n[t.pluginName]&&(n[t.pluginName][i]&&n[t.pluginName][i](I({sortable:n},o)),n.options[t.pluginName]&&n[t.pluginName][e]&&n[t.pluginName][e](I({sortable:n},o)))})},initializePlugins:function(n,o,i,t){for(var e in A.forEach(function(t){var e=t.pluginName;(n.options[e]||t.initializeByDefault)&&((t=new t(n,o,n.options)).sortable=n,t.options=n.options,n[e]=t,a(i,t.defaults))}),n.options){var r;n.options.hasOwnProperty(e)&&(void 0!==(r=this.modifyOption(n,e,n.options[e]))&&(n.options[e]=r))}},getEventProperties:function(e,n){var o={};return A.forEach(function(t){"function"==typeof t.eventProperties&&a(o,t.eventProperties.call(n[t.pluginName],e))}),o},modifyOption:function(e,n,o){var i;return A.forEach(function(t){e[t.pluginName]&&t.optionListeners&&"function"==typeof t.optionListeners[n]&&(i=t.optionListeners[n].call(e[t.pluginName],o))}),i}};function z(t){var e=t.sortable,n=t.rootEl,o=t.name,i=t.targetEl,r=t.cloneEl,a=t.toEl,l=t.fromEl,s=t.oldIndex,c=t.newIndex,u=t.oldDraggableIndex,d=t.newDraggableIndex,h=t.originalEvent,f=t.putSortable,p=t.extraEventProperties;if(e=e||n&&n[K]){var g,m=e.options,t="on"+o.charAt(0).toUpperCase()+o.substr(1);!window.CustomEvent||y||w?(g=document.createEvent("Event")).initEvent(o,!0,!0):g=new CustomEvent(o,{bubbles:!0,cancelable:!0}),g.to=a||n,g.from=l||n,g.item=i||n,g.clone=r,g.oldIndex=s,g.newIndex=c,g.oldDraggableIndex=u,g.newDraggableIndex=d,g.originalEvent=h,g.pullMode=f?f.lastPutMode:void 0;var v,b=I(I({},p),W.getEventProperties(o,e));for(v in b)g[v]=b[v];n&&n.dispatchEvent(g),m[t]&&m[t].call(e,g)}}function G(t,e){var n=(o=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{}).evt,o=i(o,U);W.pluginEvent.bind(Ft)(t,e,I({dragEl:V,parentEl:Z,ghostEl:$,rootEl:Q,nextEl:J,lastDownEl:tt,cloneEl:et,cloneHidden:nt,dragStarted:gt,putSortable:st,activeSortable:Ft.active,originalEvent:n,oldIndex:ot,oldDraggableIndex:rt,newIndex:it,newDraggableIndex:at,hideGhostForTarget:Rt,unhideGhostForTarget:Xt,cloneNowHidden:function(){nt=!0},cloneNowShown:function(){nt=!1},dispatchSortableEvent:function(t){q({sortable:e,name:t,originalEvent:n})}},o))}var U=["evt"];function q(t){z(I({putSortable:st,cloneEl:et,targetEl:V,rootEl:Q,oldIndex:ot,oldDraggableIndex:rt,newIndex:it,newDraggableIndex:at},t))}var V,Z,$,Q,J,tt,et,nt,ot,it,rt,at,lt,st,ct,ut,dt,ht,ft,pt,gt,mt,vt,bt,yt,wt=!1,Et=!1,Dt=[],St=!1,_t=!1,Ct=[],Tt=!1,xt=[],Ot="undefined"!=typeof document,Mt=n,At=w||y?"cssFloat":"float",Nt=Ot&&!c&&!n&&"draggable"in document.createElement("div"),It=function(){if(Ot){if(y)return!1;var t=document.createElement("x");return t.style.cssText="pointer-events:auto","auto"===t.style.pointerEvents}}(),Pt=function(t,e){var n=R(t),o=parseInt(n.width)-parseInt(n.paddingLeft)-parseInt(n.paddingRight)-parseInt(n.borderLeftWidth)-parseInt(n.borderRightWidth),i=B(t,0,e),r=B(t,1,e),a=i&&R(i),l=r&&R(r),s=a&&parseInt(a.marginLeft)+parseInt(a.marginRight)+X(i).width,t=l&&parseInt(l.marginLeft)+parseInt(l.marginRight)+X(r).width;if("flex"===n.display)return"column"===n.flexDirection||"column-reverse"===n.flexDirection?"vertical":"horizontal";if("grid"===n.display)return n.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal";if(i&&a.float&&"none"!==a.float){e="left"===a.float?"left":"right";return!r||"both"!==l.clear&&l.clear!==e?"horizontal":"vertical"}return i&&("block"===a.display||"flex"===a.display||"table"===a.display||"grid"===a.display||o<=s&&"none"===n[At]||r&&"none"===n[At]&&o<s+t)?"vertical":"horizontal"},kt=function(t){function l(r,a){return function(t,e,n,o){var i=t.options.group.name&&e.options.group.name&&t.options.group.name===e.options.group.name;if(null==r&&(a||i))return!0;if(null==r||!1===r)return!1;if(a&&"clone"===r)return r;if("function"==typeof r)return l(r(t,e,n,o),a)(t,e,n,o);e=(a?t:e).options.group.name;return!0===r||"string"==typeof r&&r===e||r.join&&-1<r.indexOf(e)}}var e={},n=t.group;n&&"object"==o(n)||(n={name:n}),e.name=n.name,e.checkPull=l(n.pull,!0),e.checkPut=l(n.put),e.revertClone=n.revertClone,t.group=e},Rt=function(){!It&&$&&R($,"display","none")},Xt=function(){!It&&$&&R($,"display","")};Ot&&!c&&document.addEventListener("click",function(t){if(Et)return t.preventDefault(),t.stopPropagation&&t.stopPropagation(),t.stopImmediatePropagation&&t.stopImmediatePropagation(),Et=!1},!0);function Yt(t){if(V){t=t.touches?t.touches[0]:t;var e=(i=t.clientX,r=t.clientY,Dt.some(function(t){var e=t[K].options.emptyInsertThreshold;if(e&&!F(t)){var n=X(t),o=i>=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function Bt(t){V&&V.parentNode[K]._isOutsideThisEl(t.target)}function Ft(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Pt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ft.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in W.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in kt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Nt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Dt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function jt(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Ht(t){t.draggable=!1}function Lt(){Tt=!1}function Kt(t){return setTimeout(t,0)}function Wt(t){return clearTimeout(t)}Ft.prototype={constructor:Ft,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(mt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,V):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){xt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&xt.push(o)}}(o),!V&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||tt===l)){if(ot=j(l),rt=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return q({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),G("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return q({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),G("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!V&&n.parentNode===r&&(o=X(n),Q=r,Z=(V=n).parentNode,J=V.nextSibling,tt=n,lt=a.group,ct={target:Ft.dragged=V,clientX:(e||t).clientX,clientY:(e||t).clientY},ft=ct.clientX-o.left,pt=ct.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,V.style["will-change"]="all",o=function(){G("delayEnded",i,{evt:t}),Ft.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(V.draggable=!0),i._triggerDragStart(t,e),q({sortable:i,name:"choose",originalEvent:t}),k(V,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(V,t.trim(),Ht)}),h(l,"dragover",Yt),h(l,"mousemove",Yt),h(l,"touchmove",Yt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,V.draggable=!0),G("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ft.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){V&&Ht(V),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._disableDelayedDrag),f(t,"touchend",this._disableDelayedDrag),f(t,"touchcancel",this._disableDelayedDrag),f(t,"mousemove",this._delayedDragTouchMoveHandler),f(t,"touchmove",this._delayedDragTouchMoveHandler),f(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(V,"dragend",this),h(Q,"dragstart",this._onDragStart));try{document.selection?Kt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;wt=!1,Q&&V?(G("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Bt),n=this.options,t||k(V,n.dragClass,!1),k(V,n.ghostClass,!0),Ft.active=this,t&&this._appendGhost(),q({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ut){this._lastX=ut.clientX,this._lastY=ut.clientY,Rt();for(var t=document.elementFromPoint(ut.clientX,ut.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ut.clientX,ut.clientY))!==e;)e=t;if(V.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:ut.clientX,clientY:ut.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Xt()}},_onTouchMove:function(t){if(ct){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=$&&v($,!0),a=$&&r&&r.a,l=$&&r&&r.d,e=Mt&&yt&&E(yt),a=(i.clientX-ct.clientX+o.x)/(a||1)+(e?e[0]-Ct[0]:0)/(a||1),l=(i.clientY-ct.clientY+o.y)/(l||1)+(e?e[1]-Ct[1]:0)/(l||1);if(!Ft.active&&!wt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))<n)return;this._onDragStart(t,!0)}$&&(r?(r.e+=a-(dt||0),r.f+=l-(ht||0)):r={a:1,b:0,c:0,d:1,e:a,f:l},r="matrix(".concat(r.a,",").concat(r.b,",").concat(r.c,",").concat(r.d,",").concat(r.e,",").concat(r.f,")"),R($,"webkitTransform",r),R($,"mozTransform",r),R($,"msTransform",r),R($,"transform",r),dt=a,ht=l,ut=i),t.cancelable&&t.preventDefault()}},_appendGhost:function(){if(!$){var t=this.options.fallbackOnBody?document.body:Q,e=X(V,!0,Mt,!0,t),n=this.options;if(Mt){for(yt=t;"static"===R(yt,"position")&&"none"===R(yt,"transform")&&yt!==document;)yt=yt.parentNode;yt!==document.body&&yt!==document.documentElement?(yt===document&&(yt=O()),e.top+=yt.scrollTop,e.left+=yt.scrollLeft):yt=O(),Ct=E(yt)}k($=V.cloneNode(!0),n.ghostClass,!1),k($,n.fallbackClass,!0),k($,n.dragClass,!0),R($,"transition",""),R($,"transform",""),R($,"box-sizing","border-box"),R($,"margin",0),R($,"top",e.top),R($,"left",e.left),R($,"width",e.width),R($,"height",e.height),R($,"opacity","0.8"),R($,"position",Mt?"absolute":"fixed"),R($,"zIndex","100000"),R($,"pointerEvents","none"),Ft.ghost=$,t.appendChild($),R($,"transform-origin",ft/parseInt($.style.width)*100+"% "+pt/parseInt($.style.height)*100+"%")}},_onDragStart:function(t,e){var n=this,o=t.dataTransfer,i=n.options;G("dragStart",this,{evt:t}),Ft.eventCanceled?this._onDrop():(G("setupClone",this),Ft.eventCanceled||((et=_(V)).removeAttribute("id"),et.draggable=!1,et.style["will-change"]="",this._hideClone(),k(et,this.options.chosenClass,!1),Ft.clone=et),n.cloneId=Kt(function(){G("clone",n),Ft.eventCanceled||(n.options.removeCloneOnHide||Q.insertBefore(et,V),n._hideClone(),q({sortable:n,name:"clone"}))}),e||k(V,i.dragClass,!0),e?(Et=!0,n._loopId=setInterval(n._emulateDragOver,50)):(f(document,"mouseup",n._onDrop),f(document,"touchend",n._onDrop),f(document,"touchcancel",n._onDrop),o&&(o.effectAllowed="move",i.setData&&i.setData.call(n,o,V)),h(document,"drop",n),R(V,"transform","translateZ(0)")),wt=!0,n._dragStartId=Kt(n._dragStarted.bind(n,e,t)),h(document,"selectstart",n),gt=!0,u&&R(document.body,"user-select","none"))},_onDragOver:function(n){var o,i,r,t,e,a=this.el,l=n.target,s=this.options,c=s.group,u=Ft.active,d=lt===c,h=s.sort,f=st||u,p=this,g=!1;if(!Tt){if(void 0!==n.preventDefault&&n.cancelable&&n.preventDefault(),l=P(l,s.draggable,a,!0),O("dragOver"),Ft.eventCanceled)return g;if(V.contains(n.target)||l.animated&&l.animatingX&&l.animatingY||p._ignoreWhileAnimating===l)return A(!1);if(Et=!1,u&&!s.disabled&&(d?h||(i=Z!==Q):st===this||(this.lastPutMode=lt.checkPull(this,u,V,n))&&c.checkPut(this,u,V,n))){if(r="vertical"===this._getDirection(n,l),o=X(V),O("dragOverValid"),Ft.eventCanceled)return g;if(i)return Z=Q,M(),this._hideClone(),O("revert"),Ft.eventCanceled||(J?Q.insertBefore(V,J):Q.appendChild(V)),A(!0);var m=F(a,s.draggable);if(m&&(S=n,c=r,x=X(F((D=this).el,D.options.draggable)),D=L(D.el,D.options,$),!(c?S.clientX>D.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>D.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,$),e?t.clientX<_.left-10||t.clientY<C.top&&t.clientX<C.right:t.clientY<_.top-10||t.clientY<C.bottom&&t.clientX<C.left)){var v=B(a,0,s,!0);if(v===V)return A(!1);if(E=X(l=v),!1!==jt(Q,a,V,o,l,E,n,!1))return M(),a.insertBefore(V,v),Z=a,N(),A(!0)}else if(l.parentNode===a){var b,y,w,E=X(l),D=V.parentNode!==a,S=(S=V.animated&&V.toRect||o,x=l.animated&&l.toRect||E,_=(e=r)?S.left:S.top,t=e?S.right:S.bottom,C=e?S.width:S.height,v=e?x.left:x.top,S=e?x.right:x.bottom,x=e?x.width:x.height,!(_===v||t===S||_+C/2===v+x/2)),_=r?"top":"left",C=Y(l,"top","top")||Y(V,"top","top"),v=C?C.scrollTop:void 0;if(mt!==l&&(y=E[_],St=!1,_t=!S&&s.invertSwap||D),0!==(b=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,t=o?n.top:n.left,o=o?n.bottom:n.right,n=!1;if(!a)if(l&&bt<c*i){if(St=!St&&(1===vt?t+c*r/2<s:s<o-c*r/2)?!0:St)n=!0;else if(1===vt?s<t+bt:o-bt<s)return-vt}else if(t+c*(1-i)/2<s&&s<o-c*(1-i)/2)return function(t){return j(V)<j(t)?1:-1}(e);if((n=n||a)&&(s<t+c*r/2||o-c*r/2<s))return t+c/2<s?1:-1;return 0}(n,l,E,r,S?1:s.swapThreshold,null==s.invertedSwapThreshold?s.swapThreshold:s.invertedSwapThreshold,_t,mt===l)))for(var T=j(V);(w=Z.children[T-=b])&&("none"===R(w,"display")||w===$););if(0===b||w===l)return A(!1);vt=b;var x=(mt=l).nextElementSibling,D=!1,S=jt(Q,a,V,o,l,E,n,D=1===b);if(!1!==S)return 1!==S&&-1!==S||(D=1===S),Tt=!0,setTimeout(Lt,30),M(),D&&!x?a.appendChild(V):l.parentNode.insertBefore(V,D?x:l),C&&H(C,0,v-C.scrollTop),Z=V.parentNode,void 0===y||_t||(bt=Math.abs(y-X(l)[_])),N(),A(!0)}}else{if(m===V)return A(!1);if((l=m&&a===n.target?m:l)&&(E=X(l)),!1!==jt(Q,a,V,o,l,E,n,!!l))return M(),m&&m.nextSibling?a.insertBefore(V,m.nextSibling):a.appendChild(V),Z=a,N(),A(!0)}if(a.contains(V))return A(!1)}return!1}function O(t,e){G(t,p,I({evt:n,isOwner:d,axis:r?"vertical":"horizontal",revert:i,dragRect:o,targetRect:E,canSort:h,fromSortable:f,target:l,completed:A,onMove:function(t,e){return jt(Q,a,V,o,t,X(t),n,e)},changed:N},e))}function M(){O("dragOverAnimationCapture"),p.captureAnimationState(),p!==f&&f.captureAnimationState()}function A(t){return O("dragOverCompleted",{insertion:t}),t&&(d?u._hideClone():u._showClone(p),p!==f&&(k(V,(st||u).options.ghostClass,!1),k(V,s.ghostClass,!0)),st!==p&&p!==Ft.active?st=p:p===Ft.active&&st&&(st=null),f===p&&(p._ignoreWhileAnimating=l),p.animateAll(function(){O("dragOverAnimationComplete"),p._ignoreWhileAnimating=null}),p!==f&&(f.animateAll(),f._ignoreWhileAnimating=null)),(l===V&&!V.animated||l===a&&!l.animated)&&(mt=null),s.dragoverBubble||n.rootEl||l===document||(V.parentNode[K]._isOutsideThisEl(n.target),t||Yt(n)),!s.dragoverBubble&&n.stopPropagation&&n.stopPropagation(),g=!0}function N(){it=j(V),at=j(V,s.draggable),q({sortable:p,name:"change",toEl:a,newIndex:it,newDraggableIndex:at,originalEvent:n})}},_ignoreWhileAnimating:null,_offMoveEvents:function(){f(document,"mousemove",this._onTouchMove),f(document,"touchmove",this._onTouchMove),f(document,"pointermove",this._onTouchMove),f(document,"dragover",Yt),f(document,"mousemove",Yt),f(document,"touchmove",Yt)},_offUpEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._onDrop),f(t,"touchend",this._onDrop),f(t,"pointerup",this._onDrop),f(t,"touchcancel",this._onDrop),f(document,"selectstart",this)},_onDrop:function(t){var e=this.el,n=this.options;it=j(V),at=j(V,n.draggable),G("drop",this,{evt:t}),Z=V&&V.parentNode,it=j(V),at=j(V,n.draggable),Ft.eventCanceled||(St=_t=wt=!1,clearInterval(this._loopId),clearTimeout(this._dragStartTimer),Wt(this.cloneId),Wt(this._dragStartId),this.nativeDraggable&&(f(document,"drop",this),f(e,"dragstart",this._onDragStart)),this._offMoveEvents(),this._offUpEvents(),u&&R(document.body,"user-select",""),R(V,"transform",""),t&&(gt&&(t.cancelable&&t.preventDefault(),n.dropBubble||t.stopPropagation()),$&&$.parentNode&&$.parentNode.removeChild($),(Q===Z||st&&"clone"!==st.lastPutMode)&&et&&et.parentNode&&et.parentNode.removeChild(et),V&&(this.nativeDraggable&&f(V,"dragend",this),Ht(V),V.style["will-change"]="",gt&&!wt&&k(V,(st||this).options.ghostClass,!1),k(V,this.options.chosenClass,!1),q({sortable:this,name:"unchoose",toEl:Z,newIndex:null,newDraggableIndex:null,originalEvent:t}),Q!==Z?(0<=it&&(q({rootEl:Z,name:"add",toEl:Z,fromEl:Q,originalEvent:t}),q({sortable:this,name:"remove",toEl:Z,originalEvent:t}),q({rootEl:Z,name:"sort",toEl:Z,fromEl:Q,originalEvent:t}),q({sortable:this,name:"sort",toEl:Z,originalEvent:t})),st&&st.save()):it!==ot&&0<=it&&(q({sortable:this,name:"update",toEl:Z,originalEvent:t}),q({sortable:this,name:"sort",toEl:Z,originalEvent:t})),Ft.active&&(null!=it&&-1!==it||(it=ot,at=rt),q({sortable:this,name:"end",toEl:Z,originalEvent:t}),this.save())))),this._nulling()},_nulling:function(){G("nulling",this),Q=V=Z=$=J=et=tt=nt=ct=ut=gt=it=at=ot=rt=mt=vt=st=lt=Ft.dragged=Ft.ghost=Ft.clone=Ft.active=null,xt.forEach(function(t){t.checked=!0}),xt.length=dt=ht=0},handleEvent:function(t){switch(t.type){case"drop":case"dragend":this._onDrop(t);break;case"dragenter":case"dragover":V&&(this._onDragOver(t),function(t){t.dataTransfer&&(t.dataTransfer.dropEffect="move");t.cancelable&&t.preventDefault()}(t));break;case"selectstart":t.preventDefault()}},toArray:function(){for(var t,e=[],n=this.el.children,o=0,i=n.length,r=this.options;o<i;o++)P(t=n[o],r.draggable,this.el,!1)&&e.push(t.getAttribute(r.dataIdAttr)||function(t){var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;for(;n--;)o+=e.charCodeAt(n);return o.toString(36)}(t));return e},sort:function(t,e){var n={},o=this.el;this.toArray().forEach(function(t,e){e=o.children[e];P(e,this.options.draggable,o,!1)&&(n[t]=e)},this),e&&this.captureAnimationState(),t.forEach(function(t){n[t]&&(o.removeChild(n[t]),o.appendChild(n[t]))}),e&&this.animateAll()},save:function(){var t=this.options.store;t&&t.set&&t.set(this)},closest:function(t,e){return P(t,e||this.options.draggable,this.el,!1)},option:function(t,e){var n=this.options;if(void 0===e)return n[t];var o=W.modifyOption(this,t,e);n[t]=void 0!==o?o:e,"group"===t&&kt(n)},destroy:function(){G("destroy",this);var t=this.el;t[K]=null,f(t,"mousedown",this._onTapStart),f(t,"touchstart",this._onTapStart),f(t,"pointerdown",this._onTapStart),this.nativeDraggable&&(f(t,"dragover",this),f(t,"dragenter",this)),Array.prototype.forEach.call(t.querySelectorAll("[draggable]"),function(t){t.removeAttribute("draggable")}),this._onDrop(),this._disableDelayedDragEvents(),Dt.splice(Dt.indexOf(this.el),1),this.el=t=null},_hideClone:function(){nt||(G("hideClone",this),Ft.eventCanceled||(R(et,"display","none"),this.options.removeCloneOnHide&&et.parentNode&&et.parentNode.removeChild(et),nt=!0))},_showClone:function(t){"clone"===t.lastPutMode?nt&&(G("showClone",this),Ft.eventCanceled||(V.parentNode!=Q||this.options.group.revertClone?J?Q.insertBefore(et,J):Q.appendChild(et):Q.insertBefore(et,V),this.options.group.revertClone&&this.animate(V,et),R(et,"display",""),nt=!1)):this._hideClone()}},Ot&&h(document,"touchmove",function(t){(Ft.active||wt)&&t.cancelable&&t.preventDefault()}),Ft.utils={on:h,off:f,css:R,find:b,is:function(t,e){return!!P(t,e,t,!1)},extend:function(t,e){if(t&&e)for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t},throttle:S,closest:P,toggleClass:k,clone:_,index:j,nextTick:Kt,cancelNextTick:Wt,detectDirection:Pt,getChild:B},Ft.get=function(t){return t[K]},Ft.mount=function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];(e=e[0].constructor===Array?e[0]:e).forEach(function(t){if(!t.prototype||!t.prototype.constructor)throw"Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(t));t.utils&&(Ft.utils=I(I({},Ft.utils),t.utils)),W.mount(t)})},Ft.create=function(t,e){return new Ft(t,e)};var zt,Gt,Ut,qt,Vt,Zt,$t=[],Qt=!(Ft.version="1.15.2");function Jt(){$t.forEach(function(t){clearInterval(t.pid)}),$t=[]}function te(){clearInterval(Zt)}var ee,ne=S(function(n,t,e,o){if(t.scroll){var i,r=(n.touches?n.touches[0]:n).clientX,a=(n.touches?n.touches[0]:n).clientY,l=t.scrollSensitivity,s=t.scrollSpeed,c=O(),u=!1;Gt!==e&&(Gt=e,Jt(),zt=t.scroll,i=t.scrollFn,!0===zt&&(zt=M(e,!0)));var d=0,h=zt;do{var f=h,p=X(f),g=p.top,m=p.bottom,v=p.left,b=p.right,y=p.width,w=p.height,E=void 0,D=void 0,S=f.scrollWidth,_=f.scrollHeight,C=R(f),T=f.scrollLeft,p=f.scrollTop,D=f===c?(E=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX||"visible"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY||"visible"===C.overflowY)):(E=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY)),T=E&&(Math.abs(b-r)<=l&&T+y<S)-(Math.abs(v-r)<=l&&!!T),p=D&&(Math.abs(m-a)<=l&&p+w<_)-(Math.abs(g-a)<=l&&!!p);if(!$t[d])for(var x=0;x<=d;x++)$t[x]||($t[x]={});$t[d].vx==T&&$t[d].vy==p&&$t[d].el===f||($t[d].el=f,$t[d].vx=T,$t[d].vy=p,clearInterval($t[d].pid),0==T&&0==p||(u=!0,$t[d].pid=setInterval(function(){o&&0===this.layer&&Ft.active._onTouchMove(Vt);var t=$t[this.layer].vy?$t[this.layer].vy*s:0,e=$t[this.layer].vx?$t[this.layer].vx*s:0;"function"==typeof i&&"continue"!==i.call(Ft.dragged.parentNode[K],e,t,n,Vt,$t[this.layer].el)||H($t[this.layer].el,e,t)}.bind({layer:d}),24))),d++}while(t.bubbleScroll&&h!==c&&(h=M(h,!1)));Qt=u}},30),c=function(t){var e=t.originalEvent,n=t.putSortable,o=t.dragEl,i=t.activeSortable,r=t.dispatchSortableEvent,a=t.hideGhostForTarget,t=t.unhideGhostForTarget;e&&(i=n||i,a(),e=e.changedTouches&&e.changedTouches.length?e.changedTouches[0]:e,e=document.elementFromPoint(e.clientX,e.clientY),t(),i&&!i.el.contains(e)&&(r("spill"),this.onSpill({dragEl:o,putSortable:n})))};function oe(){}function ie(){}oe.prototype={startIndex:null,dragStart:function(t){t=t.oldDraggableIndex;this.startIndex=t},onSpill:function(t){var e=t.dragEl,n=t.putSortable;this.sortable.captureAnimationState(),n&&n.captureAnimationState();t=B(this.sortable.el,this.startIndex,this.options);t?this.sortable.el.insertBefore(e,t):this.sortable.el.appendChild(e),this.sortable.animateAll(),n&&n.animateAll()},drop:c},a(oe,{pluginName:"revertOnSpill"}),ie.prototype={onSpill:function(t){var e=t.dragEl,t=t.putSortable||this.sortable;t.captureAnimationState(),e.parentNode&&e.parentNode.removeChild(e),t.animateAll()},drop:c},a(ie,{pluginName:"removeOnSpill"});var re,ae,le,se,ce,ue=[],de=[],he=!1,fe=!1,pe=!1;function ge(n,o){de.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)})}function me(){ue.forEach(function(t){t!==le&&t.parentNode&&t.parentNode.removeChild(t)})}return Ft.mount(new function(){function t(){for(var t in this.defaults={scroll:!0,forceAutoScrollFallback:!1,scrollSensitivity:30,scrollSpeed:10,bubbleScroll:!0},this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this))}return t.prototype={dragStarted:function(t){t=t.originalEvent;this.sortable.nativeDraggable?h(document,"dragover",this._handleAutoScroll):this.options.supportPointer?h(document,"pointermove",this._handleFallbackAutoScroll):t.touches?h(document,"touchmove",this._handleFallbackAutoScroll):h(document,"mousemove",this._handleFallbackAutoScroll)},dragOverCompleted:function(t){t=t.originalEvent;this.options.dragOverBubble||t.rootEl||this._handleAutoScroll(t)},drop:function(){this.sortable.nativeDraggable?f(document,"dragover",this._handleAutoScroll):(f(document,"pointermove",this._handleFallbackAutoScroll),f(document,"touchmove",this._handleFallbackAutoScroll),f(document,"mousemove",this._handleFallbackAutoScroll)),te(),Jt(),clearTimeout(g),g=void 0},nulling:function(){Vt=Gt=zt=Qt=Zt=Ut=qt=null,$t.length=0},_handleFallbackAutoScroll:function(t){this._handleAutoScroll(t,!0)},_handleAutoScroll:function(e,n){var o,i=this,r=(e.touches?e.touches[0]:e).clientX,a=(e.touches?e.touches[0]:e).clientY,t=document.elementFromPoint(r,a);Vt=e,n||this.options.forceAutoScrollFallback||w||y||u?(ne(e,this.options,t,n),o=M(t,!0),!Qt||Zt&&r===Ut&&a===qt||(Zt&&te(),Zt=setInterval(function(){var t=M(document.elementFromPoint(r,a),!0);t!==o&&(o=t,Jt()),ne(e,i.options,t,n)},10),Ut=r,qt=a)):this.options.bubbleScroll&&M(t,!0)!==O()?ne(e,this.options,M(t,!1),!1):Jt()}},a(t,{pluginName:"scroll",initializeByDefault:!0})}),Ft.mount(ie,oe),Ft.mount(new function(){function t(){this.defaults={swapClass:"sortable-swap-highlight"}}return t.prototype={dragStart:function(t){t=t.dragEl;ee=t},dragOverValid:function(t){var e=t.completed,n=t.target,o=t.onMove,i=t.activeSortable,r=t.changed,a=t.cancel;i.options.swap&&(t=this.sortable.el,i=this.options,n&&n!==t&&(t=ee,ee=!1!==o(n)?(k(n,i.swapClass,!0),n):null,t&&t!==ee&&k(t,i.swapClass,!1)),r(),e(!0),a())},drop:function(t){var e,n,o=t.activeSortable,i=t.putSortable,r=t.dragEl,a=i||this.sortable,l=this.options;ee&&k(ee,l.swapClass,!1),ee&&(l.swap||i&&i.options.swap)&&r!==ee&&(a.captureAnimationState(),a!==o&&o.captureAnimationState(),n=ee,t=(e=r).parentNode,l=n.parentNode,t&&l&&!t.isEqualNode(n)&&!l.isEqualNode(e)&&(i=j(e),r=j(n),t.isEqualNode(l)&&i<r&&r++,t.insertBefore(n,t.children[i]),l.insertBefore(e,l.children[r])),a.animateAll(),a!==o&&o.animateAll())},nulling:function(){ee=null}},a(t,{pluginName:"swap",eventProperties:function(){return{swapItem:ee}}})}),Ft.mount(new function(){function t(o){for(var t in this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this));o.options.avoidImplicitDeselect||(o.options.supportPointer?h(document,"pointerup",this._deselectMultiDrag):(h(document,"mouseup",this._deselectMultiDrag),h(document,"touchend",this._deselectMultiDrag))),h(document,"keydown",this._checkKeyDown),h(document,"keyup",this._checkKeyUp),this.defaults={selectedClass:"sortable-selected",multiDragKey:null,avoidImplicitDeselect:!1,setData:function(t,e){var n="";ue.length&&ae===o?ue.forEach(function(t,e){n+=(e?", ":"")+t.textContent}):n=e.textContent,t.setData("Text",n)}}}return t.prototype={multiDragKeyDown:!1,isMultiDrag:!1,delayStartGlobal:function(t){t=t.dragEl;le=t},delayEnded:function(){this.isMultiDrag=~ue.indexOf(le)},setupClone:function(t){var e=t.sortable,t=t.cancel;if(this.isMultiDrag){for(var n=0;n<ue.length;n++)de.push(_(ue[n])),de[n].sortableIndex=ue[n].sortableIndex,de[n].draggable=!1,de[n].style["will-change"]="",k(de[n],this.options.selectedClass,!1),ue[n]===le&&k(de[n],this.options.chosenClass,!1);e._hideClone(),t()}},clone:function(t){var e=t.sortable,n=t.rootEl,o=t.dispatchSortableEvent,t=t.cancel;this.isMultiDrag&&(this.options.removeCloneOnHide||ue.length&&ae===e&&(ge(!0,n),o("clone"),t()))},showClone:function(t){var e=t.cloneNowShown,n=t.rootEl,t=t.cancel;this.isMultiDrag&&(ge(!1,n),de.forEach(function(t){R(t,"display","")}),e(),ce=!1,t())},hideClone:function(t){var e=this,n=(t.sortable,t.cloneNowHidden),t=t.cancel;this.isMultiDrag&&(de.forEach(function(t){R(t,"display","none"),e.options.removeCloneOnHide&&t.parentNode&&t.parentNode.removeChild(t)}),n(),ce=!0,t())},dragStartGlobal:function(t){t.sortable;!this.isMultiDrag&&ae&&ae.multiDrag._deselectMultiDrag(),ue.forEach(function(t){t.sortableIndex=j(t)}),ue=ue.sort(function(t,e){return t.sortableIndex-e.sortableIndex}),pe=!0},dragStarted:function(t){var e,n=this,t=t.sortable;this.isMultiDrag&&(this.options.sort&&(t.captureAnimationState(),this.options.animation&&(ue.forEach(function(t){t!==le&&R(t,"position","absolute")}),e=X(le,!1,!0,!0),ue.forEach(function(t){t!==le&&C(t,e)}),he=fe=!0)),t.animateAll(function(){he=fe=!1,n.options.animation&&ue.forEach(function(t){T(t)}),n.options.sort&&me()}))},dragOver:function(t){var e=t.target,n=t.completed,t=t.cancel;fe&&~ue.indexOf(e)&&(n(!1),t())},revert:function(t){var n,o,e=t.fromSortable,i=t.rootEl,r=t.sortable,a=t.dragRect;1<ue.length&&(ue.forEach(function(t){r.addAnimationState({target:t,rect:fe?X(t):a}),T(t),t.fromRect=a,e.removeAnimationState(t)}),fe=!1,n=!this.options.removeCloneOnHide,o=i,ue.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)}))},dragOverCompleted:function(t){var e,n=t.sortable,o=t.isOwner,i=t.insertion,r=t.activeSortable,a=t.parentEl,l=t.putSortable,t=this.options;i&&(o&&r._hideClone(),he=!1,t.animation&&1<ue.length&&(fe||!o&&!r.options.sort&&!l)&&(e=X(le,!1,!0,!0),ue.forEach(function(t){t!==le&&(C(t,e),a.appendChild(t))}),fe=!0),o||(fe||me(),1<ue.length?(o=ce,r._showClone(n),r.options.animation&&!ce&&o&&de.forEach(function(t){r.addAnimationState({target:t,rect:se}),t.fromRect=se,t.thisAnimationDuration=null})):r._showClone(n)))},dragOverAnimationCapture:function(t){var e=t.dragRect,n=t.isOwner,t=t.activeSortable;ue.forEach(function(t){t.thisAnimationDuration=null}),t.options.animation&&!n&&t.multiDrag.isMultiDrag&&(se=a({},e),e=v(le,!0),se.top-=e.f,se.left-=e.e)},dragOverAnimationComplete:function(){fe&&(fe=!1,me())},drop:function(t){var e=t.originalEvent,n=t.rootEl,o=t.parentEl,i=t.sortable,r=t.dispatchSortableEvent,a=t.oldIndex,l=t.putSortable,s=l||this.sortable;if(e){var c,u,d,h=this.options,f=o.children;if(!pe)if(h.multiDragKey&&!this.multiDragKeyDown&&this._deselectMultiDrag(),k(le,h.selectedClass,!~ue.indexOf(le)),~ue.indexOf(le))ue.splice(ue.indexOf(le),1),re=null,z({sortable:i,rootEl:n,name:"deselect",targetEl:le,originalEvent:e});else{if(ue.push(le),z({sortable:i,rootEl:n,name:"select",targetEl:le,originalEvent:e}),e.shiftKey&&re&&i.el.contains(re)){var p=j(re),t=j(le);if(~p&&~t&&p!==t)for(var g,m=p<t?(g=p,t):(g=t,p+1);g<m;g++)~ue.indexOf(f[g])||(k(f[g],h.selectedClass,!0),ue.push(f[g]),z({sortable:i,rootEl:n,name:"select",targetEl:f[g],originalEvent:e}))}else re=le;ae=s}pe&&this.isMultiDrag&&(fe=!1,(o[K].options.sort||o!==n)&&1<ue.length&&(c=X(le),u=j(le,":not(."+this.options.selectedClass+")"),!he&&h.animation&&(le.thisAnimationDuration=null),s.captureAnimationState(),he||(h.animation&&(le.fromRect=c,ue.forEach(function(t){var e;t.thisAnimationDuration=null,t!==le&&(e=fe?X(t):c,t.fromRect=e,s.addAnimationState({target:t,rect:e}))})),me(),ue.forEach(function(t){f[u]?o.insertBefore(t,f[u]):o.appendChild(t),u++}),a===j(le)&&(d=!1,ue.forEach(function(t){t.sortableIndex!==j(t)&&(d=!0)}),d&&(r("update"),r("sort")))),ue.forEach(function(t){T(t)}),s.animateAll()),ae=s),(n===o||l&&"clone"!==l.lastPutMode)&&de.forEach(function(t){t.parentNode&&t.parentNode.removeChild(t)})}},nullingGlobal:function(){this.isMultiDrag=pe=!1,de.length=0},destroyGlobal:function(){this._deselectMultiDrag(),f(document,"pointerup",this._deselectMultiDrag),f(document,"mouseup",this._deselectMultiDrag),f(document,"touchend",this._deselectMultiDrag),f(document,"keydown",this._checkKeyDown),f(document,"keyup",this._checkKeyUp)},_deselectMultiDrag:function(t){if(!(void 0!==pe&&pe||ae!==this.sortable||t&&P(t.target,this.options.draggable,this.sortable.el,!1)||t&&0!==t.button))for(;ue.length;){var e=ue[0];k(e,this.options.selectedClass,!1),ue.shift(),z({sortable:this.sortable,rootEl:this.sortable.el,name:"deselect",targetEl:e,originalEvent:t})}},_checkKeyDown:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!0)},_checkKeyUp:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!1)}},a(t,{pluginName:"multiDrag",utils:{select:function(t){var e=t.parentNode[K];e&&e.options.multiDrag&&!~ue.indexOf(t)&&(ae&&ae!==e&&(ae.multiDrag._deselectMultiDrag(),ae=e),k(t,e.options.selectedClass,!0),ue.push(t))},deselect:function(t){var e=t.parentNode[K],n=ue.indexOf(t);e&&e.options.multiDrag&&~n&&(k(t,e.options.selectedClass,!1),ue.splice(n,1))}},eventProperties:function(){var n=this,o=[],i=[];return ue.forEach(function(t){var e;o.push({multiDragElement:t,index:t.sortableIndex}),e=fe&&t!==le?-1:fe?j(t,":not(."+n.options.selectedClass+")"):j(t),i.push({multiDragElement:t,index:e})}),{items:r(ue),clones:[].concat(de),oldIndicies:o,newIndicies:i}},optionListeners:{multiDragKey:function(t){return"ctrl"===(t=t.toLowerCase())?t="Control":1<t.length&&(t=t.charAt(0).toUpperCase()+t.substr(1)),t}}})}),Ft});';import{existsSync as Se,readFileSync as Ot,writeFileSync as Nt,rmSync as is,mkdirSync as Va,copyFileSync as Ya,readdirSync as Qa}from"fs";import{resolve as oe}from"path";import{existsSync as q,readFileSync as Oe,writeFileSync as Ne,mkdirSync as be,readdirSync as He,rmSync as za,statSync as W}from"fs";import{resolve as Mt,relative as qa,dirname as Be,join as Q,extname as pe,basename as je}from"path";var N=200*1024,It=new Set([".md",".markdown",".txt"]),ne=new Set([".md",".markdown",".txt",".json",".jsonc",".yaml",".yml",".toml",".sh",".bash",".zsh",".py",".js",".mjs",".ts",".tsx",".jsx",".css",".html",".lock",".cfg",".ini",".env",".gitignore"]),Fa=6,Wa=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function K(t,e){if(!t)throw new Error("Agent workspace is not configured.");let a=Mt(t);if(q(a)||be(a,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let n=Mt(a,e);if(qa(a,n).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return n}function Lt(t){let e=pe(t).toLowerCase();if(!It.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function Pe(t,e){let a=t.split(/\r?\n/).find(n=>n.trim().startsWith("#"));return a&&a.replace(/^#+\s*/,"").trim().slice(0,120)||e}function re(t){let e=K(t,"."),a=[],n=new Set,r=[];try{r=He(e)}catch{}for(let i of Wa){let l=Q(e,i);if(q(l)&&W(l).isFile()){let d=W(l).size,c=d>0&&d<N?Re(l):"";a.push({path:i,title:Pe(c,i),size:d,exists:!0}),n.add(i)}else a.push({path:i,title:i,size:0,exists:!1}),n.add(i)}for(let i of r){if(n.has(i))continue;let l=Q(e,i);try{let d=W(l);if(!d.isFile()||!It.has(pe(i).toLowerCase()))continue;let c=d.size>0&&d.size<N?Re(l):"";a.push({path:i,title:Pe(c,i),size:d.size,exists:!0})}catch{}}let o=[],s=Q(e,".claude","skills");if(q(s))try{for(let i of He(s)){let l=Q(s,i),d;try{d=W(l)}catch{continue}if(!d.isDirectory())continue;let c=Q(l,"SKILL.md");if(!q(c))continue;let u=W(c),h=u.size<N?Re(c):"";o.push({slug:i,title:Pe(h,i),size:u.size,path:`.claude/skills/${i}/SKILL.md`})}}catch{}return o.sort((i,l)=>i.slug.localeCompare(l.slug)),{identity:a,skills:o,workspace:e}}function Re(t){try{return Oe(t,"utf-8")}catch{return""}}function xe(t,e){let a=K(t,e);if(Lt(a),!q(a))return{path:e,content:""};if(W(a).size>N)throw new Error(`File is too large to edit in the admin panel (> ${N/1024} KB).`);return{path:e,content:Oe(a,"utf-8")}}function ye(t,e,a){let n=K(t,e);Lt(n);let r=Buffer.from(a,"utf-8");if(r.length>N)throw new Error(`File too large (${r.length} > ${N} bytes).`);return be(Be(n),{recursive:!0}),Ne(n,r),{path:e,bytes:r.length}}function we(t,e,a={}){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Skill slug must be lowercase (letters, digits, -, _) and start with a letter or digit.");let n=`.claude/skills/${e}/SKILL.md`,r=K(t,n);if(q(r))throw new Error(`Skill "${e}" already exists.`);be(Be(r),{recursive:!0});let o=a.content?.trim()?a.content:Ga(e,a.title);return Ne(r,o),{slug:e,path:n}}function ke(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let a=K(t,`.claude/skills/${e}`);if(!q(a))throw new Error(`Skill "${e}" not found.`);if(!W(a).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return za(a,{recursive:!0,force:!0}),{slug:e}}function Dt(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let a=K(t,`.claude/skills/${e}`);if(!q(a))throw new Error(`Skill "${e}" not found.`);let n=[];return r(a,"",0,n),n.sort((o,s)=>o.kind!==s.kind?o.kind==="dir"?-1:1:o.path.localeCompare(s.path)),n;function r(o,s,i,l){if(i>Fa)return;let d=[];try{d=He(o)}catch{return}for(let c of d){if(c==="node_modules"||c===".git")continue;let u=Q(o,c),h=s?`${s}/${c}`:c,y;try{y=W(u)}catch{continue}if(y.isDirectory())l.push({path:`${h}/`,kind:"dir",size:0,editable:!1}),r(u,h,i+1,l);else if(y.isFile()){let p=pe(c).toLowerCase(),m=ne.has(p)||ne.has(c.toLowerCase());l.push({path:h,kind:"file",size:y.size,editable:m&&y.size<N})}}}}function Pt(t,e,a){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!a||a.includes(".."))throw new Error(`Invalid file path: ${a}`);let n=K(t,`.claude/skills/${e}/${a}`);if(!q(n)||!W(n).isFile())throw new Error(`File not found: ${a}`);let r=pe(n).toLowerCase(),o=je(n).toLowerCase();if(!ne.has(r)&&!ne.has(o))throw new Error(`File type not editable: ${a}`);if(W(n).size>N)throw new Error(`File too large to edit (> ${N/1024} KB): ${a}`);return{path:a,content:Oe(n,"utf-8")}}function Rt(t,e,a,n){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!a||a.includes(".."))throw new Error(`Invalid file path: ${a}`);let r=K(t,`.claude/skills/${e}/${a}`),o=pe(r).toLowerCase(),s=je(r).toLowerCase();if(!ne.has(o)&&!ne.has(s))throw new Error(`File type not editable: ${a}`);let i=Buffer.from(n,"utf-8");if(i.length>N)throw new Error(`File too large (${i.length} > ${N} bytes).`);return be(Be(r),{recursive:!0}),Ne(r,i),{path:a,bytes:i.length}}function _e(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let a=K(t,`.claude/skills/${e}`);if(!q(a))throw new Error(`Skill "${e}" not found.`);let n=r=>q(Q(a,r));return n("pnpm-lock.yaml")?{manager:"pnpm",file:"pnpm-lock.yaml",command:"pnpm install"}:n("yarn.lock")?{manager:"yarn",file:"yarn.lock",command:"yarn install"}:n("package.json")?{manager:"npm",file:"package.json",command:"npm install"}:n("requirements.txt")?{manager:"pip",file:"requirements.txt",command:"pip install -r requirements.txt"}:n("Gemfile")?{manager:"bundle",file:"Gemfile",command:"bundle install"}:{manager:null,file:null,command:null}}function Ga(t,e){return`# ${e?.trim()||t}
2
2
 
3
3
  Describe what this skill does and when the agent should use it. Keep it under ~5 lines \u2014 the agent reads this to decide whether to invoke the skill.
4
4
 
@@ -13,10 +13,10 @@ Document the arguments, commands, or files the skill expects. Example:
13
13
  # Example invocation
14
14
  claude-code ${je(t)} --arg value
15
15
  \`\`\`
16
- `}var G={agents:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="2"/><path d="M12 7v4M8 16h.01M16 16h.01"/></svg>',channels:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>',schedules:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>',webhooks:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10 12a3 3 0 1 0 3-3m-8 11a3 3 0 1 0 2.6-1.5L10 12m7 3a3 3 0 1 0-2-5.5"/></svg>',mesh:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="18" r="2"/><circle cx="12" cy="12" r="2"/><path d="M7.4 7.4l3.2 3.2M13.4 13.4l3.2 3.2M16.6 7.4l-3.2 3.2M10.6 13.4l-3.2 3.2"/></svg>',tokens:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-8 8a4 4 0 1 1-6 6m6-6l5-5 3 3-5 5m-3-3l3 3"/></svg>',advanced:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4h8l4 4v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M9 13l2 2 4-4"/></svg>'};function Pt(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=ft({kicker:"Settings",title:"Your team's control room",lead:`Manage the agents, the places they answer from, and who's allowed to reach them. Everything here writes to <span class="mono muted">agentx.json</span> on your machine \u2014 nothing leaves.`})+vt([{kind:"off",num:"\u2014",label:"Agents online"},{kind:"off",num:"\u2014",label:"Channels connected"},{kind:"off",num:"0",label:"Needs attention"},{kind:"off",num:"\u2014",label:"Active tokens"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="ax-health">');return A({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+Ua+bt,css:Ka,scripts:`${e}<script>${xt}
17
- ${yt}
18
- ${Wa}
19
- ${Ja}</script>`})}var Wa=`
16
+ `}var F={agents:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="2"/><path d="M12 7v4M8 16h.01M16 16h.01"/></svg>',channels:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>',schedules:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>',webhooks:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10 12a3 3 0 1 0 3-3m-8 11a3 3 0 1 0 2.6-1.5L10 12m7 3a3 3 0 1 0-2-5.5"/></svg>',mesh:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="18" r="2"/><circle cx="12" cy="12" r="2"/><path d="M7.4 7.4l3.2 3.2M13.4 13.4l3.2 3.2M16.6 7.4l-3.2 3.2M10.6 13.4l-3.2 3.2"/></svg>',tokens:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-8 8a4 4 0 1 1-6 6m6-6l5-5 3 3-5 5m-3-3l3 3"/></svg>',advanced:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4h8l4 4v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M9 13l2 2 4-4"/></svg>',actions:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>'};function Ht(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=vt({kicker:"Settings",title:"Your team's control room",lead:`Manage the agents, the places they answer from, and who's allowed to reach them. Everything here writes to <span class="mono muted">agentx.json</span> on your machine \u2014 nothing leaves.`})+bt([{kind:"off",num:"\u2014",label:"Agents online"},{kind:"off",num:"\u2014",label:"Channels connected"},{kind:"off",num:"0",label:"Needs attention"},{kind:"off",num:"\u2014",label:"Active tokens"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="ax-health">');return A({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+Ka+xt,css:Ja,scripts:`${e}<script>${yt}
17
+ ${wt}
18
+ ${Ua}
19
+ ${Xa}</script>`})}var Ua=`
20
20
  (function(){
21
21
  function fmt(n) { return n == null ? '\u2014' : String(n); }
22
22
  async function refresh() {
@@ -77,7 +77,7 @@ ${Ja}</script>`})}var Wa=`
77
77
  refresh();
78
78
  // Refresh again after the main admin script has had a chance to mutate config.
79
79
  document.addEventListener('ax-config-saved', refresh);
80
- })();`,Ua=`
80
+ })();`,Ka=`
81
81
  <div id="peer-banner" class="peer-banner">
82
82
  <span class="label">Managing</span>
83
83
  <span class="name" id="peer-banner-name">\u2014</span>
@@ -94,6 +94,7 @@ ${Ja}</script>`})}var Wa=`
94
94
  <button data-tab="team">Team</button>
95
95
  <button data-tab="business">Business</button>
96
96
  <button data-tab="boards-cfg">Boards</button>
97
+ <button data-tab="actions">Actions</button>
97
98
  <button data-tab="tokens">Tokens</button>
98
99
  <button data-tab="advanced">Advanced</button>
99
100
  </nav>
@@ -221,8 +222,8 @@ ${Ja}</script>`})}var Wa=`
221
222
  <div id="global-msg" class="msg"></div>
222
223
 
223
224
  <section id="tab-agents" class="tab active">
224
- ${z({icon:G.agents,title:"Your agents",lead:"Each agent is a role with its own trigger words and workspace. Delete removes the config only \u2014 the folder on disk stays."})}
225
- ${j({persistKey:"agents",bodyHtml:`<b>What's an agent, exactly?</b> Think of it as a specialised teammate. A sales agent handles pricing questions, a support agent answers tickets, a reports agent sends a weekly summary. You decide what they do and what to say to wake them up (their "trigger words", like <code>@support</code>).`})}
225
+ ${O({icon:F.agents,title:"Your agents",lead:"Each agent is a role with its own trigger words and workspace. Delete removes the config only \u2014 the folder on disk stays."})}
226
+ ${H({persistKey:"agents",bodyHtml:`<b>What's an agent, exactly?</b> Think of it as a specialised teammate. A sales agent handles pricing questions, a support agent answers tickets, a reports agent sends a weekly summary. You decide what they do and what to say to wake them up (their "trigger words", like <code>@support</code>).`})}
226
227
  <div id="agent-list" class="ax-stack"></div>
227
228
  <div class="add-form">
228
229
  <h3>Add a new agent</h3>
@@ -244,8 +245,8 @@ ${Ja}</script>`})}var Wa=`
244
245
  </section>
245
246
 
246
247
  <section id="tab-channels" class="tab">
247
- ${z({icon:G.channels,title:"Where your agents show up",lead:"Connect a chat app, and your agents can answer from there. Set up once \u2014 they'll keep working in the background."})}
248
- ${j({persistKey:"channels",bodyHtml:`<b>How does this work?</b> We give each channel a small "bridge" that forwards messages to AgentX. For chat apps (Telegram, Slack, Discord) you'll paste a bot token \u2014 we keep the value in your <code>.env</code> file and never send it over the network. For webhook-style sources (GitHub, GitLab) we hand you a URL to paste into their dashboard.`})}
248
+ ${O({icon:F.channels,title:"Where your agents show up",lead:"Connect a chat app, and your agents can answer from there. Set up once \u2014 they'll keep working in the background."})}
249
+ ${H({persistKey:"channels",bodyHtml:`<b>How does this work?</b> We give each channel a small "bridge" that forwards messages to AgentX. For chat apps (Telegram, Slack, Discord) you'll paste a bot token \u2014 we keep the value in your <code>.env</code> file and never send it over the network. For webhook-style sources (GitHub, GitLab) we hand you a URL to paste into their dashboard.`})}
249
250
 
250
251
  <details class="add-form" style="margin-top:14px;margin-bottom:18px" id="notif-section">
251
252
  <summary class="primary">\u2699 Notifications routing</summary>
@@ -295,8 +296,8 @@ ${Ja}</script>`})}var Wa=`
295
296
  </section>
296
297
 
297
298
  <section id="tab-crons" class="tab">
298
- ${z({icon:G.schedules,title:"Schedules",lead:"Make an agent do something on a timer \u2014 no one has to ask. Daily summaries, weekly reports, hourly health checks."})}
299
- ${j({persistKey:"crons",bodyHtml:"<b>What's a good schedule?</b> Anything recurring. A <i>Reports agent</i> sending Monday-morning numbers, a <i>Health agent</i> pinging you at 3am if a server's down, a <i>Standup agent</i> reminding the team. Pick a time below."})}
299
+ ${O({icon:F.schedules,title:"Schedules",lead:"Make an agent do something on a timer \u2014 no one has to ask. Daily summaries, weekly reports, hourly health checks."})}
300
+ ${H({persistKey:"crons",bodyHtml:"<b>What's a good schedule?</b> Anything recurring. A <i>Reports agent</i> sending Monday-morning numbers, a <i>Health agent</i> pinging you at 3am if a server's down, a <i>Standup agent</i> reminding the team. Pick a time below."})}
300
301
  <div id="cron-list" class="ax-stack" style="margin-bottom:22px"></div>
301
302
 
302
303
  <div class="ax-builder">
@@ -393,8 +394,8 @@ ${Ja}</script>`})}var Wa=`
393
394
  </section>
394
395
 
395
396
  <section id="tab-webhooks" class="tab">
396
- ${z({icon:G.webhooks,title:"Webhooks",lead:"A URL you give to another service. When something happens there \u2014 a PR is merged, an error fires \u2014 they POST to that URL, and we forward it to your agent as a readable message."})}
397
- ${j({persistKey:"webhooks",bodyHtml:`<b>Not sure you need this?</b> If a service you use has a "webhooks" setting (GitHub, Stripe, Sentry, Typeform\u2026), you probably do. It's how those services tell AgentX when something's worth looking at.`})}
397
+ ${O({icon:F.webhooks,title:"Webhooks",lead:"A URL you give to another service. When something happens there \u2014 a PR is merged, an error fires \u2014 they POST to that URL, and we forward it to your agent as a readable message."})}
398
+ ${H({persistKey:"webhooks",bodyHtml:`<b>Not sure you need this?</b> If a service you use has a "webhooks" setting (GitHub, Stripe, Sentry, Typeform\u2026), you probably do. It's how those services tell AgentX when something's worth looking at.`})}
398
399
  <div id="webhook-list" class="ax-stack"></div>
399
400
  <div class="add-form">
400
401
  <h3>Add a webhook</h3>
@@ -413,9 +414,9 @@ ${Ja}</script>`})}var Wa=`
413
414
  </section>
414
415
 
415
416
  <section id="tab-mesh" class="tab">
416
- ${z({icon:G.mesh,title:"Mesh",lead:"Link this AgentX to other machines so they share work. Good for teams running AgentX on multiple laptops or a mix of laptop + server."})}
417
+ ${O({icon:F.mesh,title:"Mesh",lead:"Link this AgentX to other machines so they share work. Good for teams running AgentX on multiple laptops or a mix of laptop + server."})}
417
418
  <div id="mesh-hero" class="ax-mesh-hero"></div>
418
- ${j({persistKey:"mesh",bodyHtml:"<b>Do I need mesh?</b> Only if you're running AgentX in more than one place. Solo users on one laptop can skip this entirely."})}
419
+ ${H({persistKey:"mesh",bodyHtml:"<b>Do I need mesh?</b> Only if you're running AgentX in more than one place. Solo users on one laptop can skip this entirely."})}
419
420
  ${ve({label:"Connected peers"})}
420
421
  <div id="mesh-peers" class="ax-stack"></div>
421
422
  <div class="add-form">
@@ -443,8 +444,8 @@ ${Ja}</script>`})}var Wa=`
443
444
  </section>
444
445
 
445
446
  <section id="tab-team" class="tab">
446
- ${z({icon:G.tokens,title:"Actors & Roles",lead:"Humans (Actors) and groups of humans (Roles) that workflow user-tasks can be assigned to. Mirrors <code>agentx actor</code> and <code>agentx role</code>."})}
447
- ${j({persistKey:"team",bodyHtml:"<b>Actors</b> are people. They carry one or more channel handles (Telegram, WhatsApp, Slack, Discord, email) so user-tasks land in a place they actually read. <b>Roles</b> are named groups \u2014 assigning a userTask to a role lets the engine pick a member by strategy (first-available, round-robin, all). Assignees in workflow YAML are referenced as <code>actor:&lt;id&gt;</code> or <code>role:&lt;id&gt;</code>."})}
447
+ ${O({icon:F.tokens,title:"Actors & Roles",lead:"Humans (Actors) and groups of humans (Roles) that workflow user-tasks can be assigned to. Mirrors <code>agentx actor</code> and <code>agentx role</code>."})}
448
+ ${H({persistKey:"team",bodyHtml:"<b>Actors</b> are people. They carry one or more channel handles (Telegram, WhatsApp, Slack, Discord, email) so user-tasks land in a place they actually read. <b>Roles</b> are named groups \u2014 assigning a userTask to a role lets the engine pick a member by strategy (first-available, round-robin, all). Assignees in workflow YAML are referenced as <code>actor:&lt;id&gt;</code> or <code>role:&lt;id&gt;</code>."})}
448
449
 
449
450
  <div class="ax-stack" style="margin-top:14px">
450
451
  <h3 style="margin:0 0 6px;font-size:13px">Actors</h3>
@@ -490,8 +491,8 @@ ${Ja}</script>`})}var Wa=`
490
491
  </section>
491
492
 
492
493
  <section id="tab-business" class="tab">
493
- ${z({icon:G.tokens,title:"Business layer",lead:"Org chart, projects, and contact map \u2014 the data that drives PM gating and activity-graph attribution. Mirrors <code>agentx business</code>."})}
494
- ${j({persistKey:"business",bodyHtml:'<b>Three concepts.</b> The <b>org chart</b> is who reports to whom (<code>reportsTo</code>). <b>Projects</b> map an id to a PM and client (drives the PM gate and lets the activity graph attribute work to the right client). The <b>contact map</b> tells the activity graph which client a Telegram/WhatsApp chat belongs to \u2014 without it, free-text channels fall into the catch-all "internal" bucket. Editing here writes to <code>agentx.json</code>; restart the daemon (or POST /reload) for the change to take effect.'})}
494
+ ${O({icon:F.tokens,title:"Business layer",lead:"Org chart, projects, and contact map \u2014 the data that drives PM gating and activity-graph attribution. Mirrors <code>agentx business</code>."})}
495
+ ${H({persistKey:"business",bodyHtml:'<b>Three concepts.</b> The <b>org chart</b> is who reports to whom (<code>reportsTo</code>). <b>Projects</b> map an id to a PM and client (drives the PM gate and lets the activity graph attribute work to the right client). The <b>contact map</b> tells the activity graph which client a Telegram/WhatsApp chat belongs to \u2014 without it, free-text channels fall into the catch-all "internal" bucket. Editing here writes to <code>agentx.json</code>; restart the daemon (or POST /reload) for the change to take effect.'})}
495
496
 
496
497
  <div class="ax-stack" style="margin-top:14px">
497
498
  <h3 style="margin:0 0 6px;font-size:13px">Org chart</h3>
@@ -556,8 +557,8 @@ ${Ja}</script>`})}var Wa=`
556
557
  </section>
557
558
 
558
559
  <section id="tab-boards-cfg" class="tab">
559
- ${z({icon:G.tokens,title:"Kanban boards",lead:"Configure the boards rendered on the home page. Mirrors <code>agentx board add/edit/remove</code> + <code>agentx board column</code>. Source is GitLab today; backlog/wiki sources land when the schema unlocks them."})}
560
- ${j({persistKey:"boards-cfg",bodyHtml:'<b>Two layers.</b> A board points to one or more GitLab projects (<code>source.projects</code>) and optionally filters by a primary tool label. Inside each board, <b>columns</b> map drag-drop actions to scoped-labels (e.g. dropping a card on "Doing" adds <code>Status::Doing</code>). The default flow is Open \u2192 To Do \u2192 Doing \u2192 On Hold \u2192 Review \u2192 Closed; override per-board with the column controls below.'})}
560
+ ${O({icon:F.tokens,title:"Kanban boards",lead:"Configure the boards rendered on the home page. Mirrors <code>agentx board add/edit/remove</code> + <code>agentx board column</code>. Source is GitLab today; backlog/wiki sources land when the schema unlocks them."})}
561
+ ${H({persistKey:"boards-cfg",bodyHtml:'<b>Two layers.</b> A board points to one or more GitLab projects (<code>source.projects</code>) and optionally filters by a primary tool label. Inside each board, <b>columns</b> map drag-drop actions to scoped-labels (e.g. dropping a card on "Doing" adds <code>Status::Doing</code>). The default flow is Open \u2192 To Do \u2192 Doing \u2192 On Hold \u2192 Review \u2192 Closed; override per-board with the column controls below.'})}
561
562
 
562
563
  <div class="ax-stack" style="margin-top:14px">
563
564
  <h3 style="margin:0 0 6px;font-size:13px">Boards</h3>
@@ -580,9 +581,65 @@ ${Ja}</script>`})}var Wa=`
580
581
  </div>
581
582
  </section>
582
583
 
584
+ <section id="tab-actions" class="tab">
585
+ ${O({icon:F.actions,title:"Action registry",lead:"Reusable shell commands and HTTP calls. Workflows invoke them by id; the dashboard runs them on demand for smoke-tests. Mirrors <code>agentx actions</code>."})}
586
+ ${H({persistKey:"actions",bodyHtml:"<b>Two flavors.</b> <code>shell</code> runs a templated command on the daemon host (cwd + extra env vars supported). <code>http</code> calls a URL with templated method/headers/body. Inputs are typed (string / number / boolean) and fill <code>{{name}}</code> markers; <code>$VAR</code> resolves against the daemon's process env. Output capped at 32KB."})}
587
+
588
+ <div class="ax-stack" style="margin-top:14px">
589
+ <h3 style="margin:0 0 6px;font-size:13px">Registered actions</h3>
590
+ <div id="actions-list"></div>
591
+ <details class="add-form" style="margin-top:10px">
592
+ <summary class="primary">+ Add or update action</summary>
593
+ <div style="margin-top:10px">
594
+ <label>Id<span class="hint">(unique slug \u2014 e.g. <code>deploy-staging</code>)</span></label>
595
+ <input id="ac-id" placeholder="deploy-staging" />
596
+ <label>Title</label>
597
+ <input id="ac-title" placeholder="Deploy staging" />
598
+ <label>Description<span class="hint">(optional)</span></label>
599
+ <input id="ac-desc" placeholder="Build, push, restart staging" />
600
+ <label>Kind</label>
601
+ <select id="ac-kind">
602
+ <option value="shell">shell</option>
603
+ <option value="http">http</option>
604
+ </select>
605
+
606
+ <div id="ac-shell-fields">
607
+ <label>Command<span class="hint">(supports <code>{{input}}</code> + <code>$ENV</code>)</span></label>
608
+ <input id="ac-command" placeholder="git pull && pnpm deploy --version={{version}}" />
609
+ <label>Working directory<span class="hint">(optional)</span></label>
610
+ <input id="ac-cwd" placeholder="/srv/staging" />
611
+ </div>
612
+
613
+ <div id="ac-http-fields" style="display:none">
614
+ <label>URL</label>
615
+ <input id="ac-url" placeholder="https://api.example.com/deploy" />
616
+ <label>Method</label>
617
+ <select id="ac-method">
618
+ <option value="POST">POST</option>
619
+ <option value="GET">GET</option>
620
+ <option value="PUT">PUT</option>
621
+ <option value="PATCH">PATCH</option>
622
+ <option value="DELETE">DELETE</option>
623
+ </select>
624
+ <label>Headers<span class="hint">(JSON object, optional)</span></label>
625
+ <input id="ac-headers" placeholder='{"Authorization":"Bearer $TOKEN"}' />
626
+ <label>Body<span class="hint">(template \u2014 JSON or text, skipped on GET/DELETE)</span></label>
627
+ <textarea id="ac-body" rows="3" placeholder='{"version":"{{version}}"}'></textarea>
628
+ </div>
629
+
630
+ <label>Inputs<span class="hint">(comma-separated <code>name:type[!]</code> \u2014 <code>!</code> = required. e.g. <code>version:string!,dryRun:boolean</code>)</span></label>
631
+ <input id="ac-inputs" placeholder="version:string!,dryRun:boolean" />
632
+ <label>Timeout (ms)</label>
633
+ <input id="ac-timeout" type="number" min="100" max="600000" value="30000" />
634
+ <div class="actions"><button class="primary" onclick="upsertAction()">Save action</button><div id="ac-msg" class="msg"></div></div>
635
+ </div>
636
+ </details>
637
+ </div>
638
+ </section>
639
+
583
640
  <section id="tab-tokens" class="tab">
584
- ${z({icon:G.tokens,title:"Access tokens",lead:"Passwords, but for software. Anything that wants to talk to AgentX from outside (a Slack bridge, another AgentX machine, a script) uses one."})}
585
- ${j({persistKey:"tokens",bodyHtml:"<b>Tokens get scopes.</b> A scope is what the token is allowed to do. Give the narrowest one that works \u2014 a Slack bridge only needs to send messages, it doesn't need to edit settings. You can't recover a token after you close this page, so copy it immediately."})}
641
+ ${O({icon:F.tokens,title:"Access tokens",lead:"Passwords, but for software. Anything that wants to talk to AgentX from outside (a Slack bridge, another AgentX machine, a script) uses one."})}
642
+ ${H({persistKey:"tokens",bodyHtml:"<b>Tokens get scopes.</b> A scope is what the token is allowed to do. Give the narrowest one that works \u2014 a Slack bridge only needs to send messages, it doesn't need to edit settings. You can't recover a token after you close this page, so copy it immediately."})}
586
643
  <div id="token-list" class="ax-stack"></div>
587
644
  <div class="add-form">
588
645
  <h3>Mint a new token</h3>
@@ -601,8 +658,8 @@ ${Ja}</script>`})}var Wa=`
601
658
  </section>
602
659
 
603
660
  <section id="tab-advanced" class="tab">
604
- ${z({icon:G.advanced,title:"Raw configuration",lead:"Everything on the other tabs writes to this file. Edit here for bulk changes, diffs, or fields we haven't put in the UI yet. Saving creates a timestamped backup."})}
605
- ${j({persistKey:"advanced",bodyHtml:`<b>Safe to look, careful editing.</b> We've pretty-printed and annotated each section so you can read it. Click any <span class="mono" style="color:var(--ax-muted)">\u25B8</span> to fold. Switch to <b>Edit</b> to change values \u2014 invalid JSON is refused before saving.`})}
661
+ ${O({icon:F.advanced,title:"Raw configuration",lead:"Everything on the other tabs writes to this file. Edit here for bulk changes, diffs, or fields we haven't put in the UI yet. Saving creates a timestamped backup."})}
662
+ ${H({persistKey:"advanced",bodyHtml:`<b>Safe to look, careful editing.</b> We've pretty-printed and annotated each section so you can read it. Click any <span class="mono" style="color:var(--ax-muted)">\u25B8</span> to fold. Switch to <b>Edit</b> to change values \u2014 invalid JSON is refused before saving.`})}
606
663
 
607
664
  <div class="ax-jv-toolbar">
608
665
  <input class="ax-jv-search" id="jv-search" placeholder="Search keys & values\u2026" />
@@ -628,7 +685,7 @@ ${Ja}</script>`})}var Wa=`
628
685
  <div class="hint-block">The schema is documented at <code>docs/reference/config-schema.md</code>. Invalid JSON is refused; schema-level errors only surface after the daemon tries to use the new config.</div>
629
686
  </section>
630
687
  </main>
631
- `,Ka=`
688
+ `,Ja=`
632
689
 
633
690
  /* --- Inner tabs (Agents / Channels / Schedules / \u2026) --- */
634
691
  nav.tabs{display:flex;gap:4px;padding:14px 24px 0;background:var(--ax-bg-elev);
@@ -836,7 +893,7 @@ textarea.raw{min-height:480px;font-family:var(--ax-mono);font-size:12px;line-hei
836
893
  .peer-banner button{background:transparent;border:1px solid currentColor;color:var(--ax-accent);
837
894
  padding:4px 10px;border-radius:4px;font:inherit;font-size:11px;cursor:pointer}
838
895
  .peer-banner button:hover{background:color-mix(in oklch,var(--ax-accent) 12%,transparent)}
839
- `,Ja=`
896
+ `,Xa=`
840
897
  const $ = (id) => document.getElementById(id);
841
898
  let state = null;
842
899
 
@@ -891,6 +948,9 @@ async function refresh() {
891
948
  renderBoardsCfg();
892
949
  wireBoardsCfgHandlers();
893
950
  renderNotifications();
951
+ renderActions();
952
+ wireActionsHandlers();
953
+ wireActionKindToggle();
894
954
  wireWebhookTriggerHandlers();
895
955
  initScheduleBuilder();
896
956
  initScheduleExpertAgentSelect();
@@ -1564,6 +1624,188 @@ window.clearNotificationsDestination = async function() {
1564
1624
  } catch (e) { showMsg($('notif-msg'), 'err', e.message); }
1565
1625
  }
1566
1626
 
1627
+ // ---------------- Action registry ----------------
1628
+
1629
+ function renderActions() {
1630
+ const list = $('actions-list');
1631
+ if (!list) return;
1632
+ const items = state.actions || [];
1633
+ if (items.length === 0) {
1634
+ list.innerHTML = '<div class="ax-empty-card" style="text-align:center;padding:24px;background:var(--ax-surface);border:1px dashed var(--ax-border-2);border-radius:6px;color:var(--ax-muted);font-size:12px">no actions yet \u2014 add one below or via <code>agentx actions add</code></div>';
1635
+ return;
1636
+ }
1637
+ list.innerHTML = items.map(function(a) {
1638
+ const target = a.kind === 'shell'
1639
+ ? '<span class="muted">shell:</span> <code>' + escapeHtml(String(a.command || '').slice(0, 90)) + '</code>'
1640
+ : '<span class="muted">' + escapeHtml(a.method || 'POST') + '</span> <code>' + escapeHtml(String(a.url || '').slice(0, 90)) + '</code>';
1641
+ const inputPills = (a.inputs || []).map(function(inp) {
1642
+ const req = inp.required ? '<span style="color:var(--ax-warn)">*</span>' : '';
1643
+ return '<span class="ax-pill" style="font-size:10px;padding:2px 6px;margin-right:4px">' + escapeHtml(inp.name) + req + ':' + escapeHtml(inp.type) + '</span>';
1644
+ }).join('');
1645
+ const inputForm = (a.inputs || []).map(function(inp) {
1646
+ const ph = inp.description ? escapeHtml(inp.description) : escapeHtml(inp.name);
1647
+ const t = inp.type === 'number' ? 'number' : inp.type === 'boolean' ? 'checkbox' : 'text';
1648
+ const def = inp.defaultValue !== undefined ? String(inp.defaultValue) : '';
1649
+ const valAttr = t === 'checkbox'
1650
+ ? (def === 'true' ? ' checked' : '')
1651
+ : (def ? ' value="' + escapeHtml(def) + '"' : '');
1652
+ return '<label style="display:block;margin:4px 0;font-size:11px"><span style="display:inline-block;min-width:120px;color:var(--ax-muted)">' + escapeHtml(inp.name) + '</span>'
1653
+ + '<input data-ac-input data-name="' + escapeHtml(inp.name) + '" type="' + t + '" placeholder="' + ph + '"' + valAttr + ' style="width:60%" />'
1654
+ + '</label>';
1655
+ }).join('');
1656
+ return '<div class="ax-row-card" style="padding:10px 14px;border:1px solid var(--ax-border);border-radius:6px;margin-bottom:8px" data-ac-card="' + escapeHtml(a.id) + '">'
1657
+ + '<div style="display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;justify-content:space-between">'
1658
+ + '<div><b>' + escapeHtml(a.title) + '</b> <code style="font-size:10px;color:var(--ax-muted)">' + escapeHtml(a.id) + '</code> '
1659
+ + '<span class="ax-pill" style="font-size:10px;padding:2px 6px;margin-left:4px">' + escapeHtml(a.kind) + '</span></div>'
1660
+ + '<div style="display:flex;gap:4px">'
1661
+ + '<button class="ghost" data-act="ac-edit" data-id="' + escapeHtml(a.id) + '">Edit</button>'
1662
+ + '<button class="ghost danger" data-act="ac-rm" data-id="' + escapeHtml(a.id) + '">Remove</button>'
1663
+ + '</div>'
1664
+ + '</div>'
1665
+ + '<div style="margin-top:6px;font-size:11px">' + target + '</div>'
1666
+ + (a.description ? '<div style="margin-top:4px;font-size:11px;color:var(--ax-muted)">' + escapeHtml(a.description) + '</div>' : '')
1667
+ + (inputPills ? '<div style="margin-top:6px">' + inputPills + '</div>' : '')
1668
+ + '<details style="margin-top:8px;padding-top:8px;border-top:1px dashed var(--ax-border)">'
1669
+ + '<summary style="font-size:11px;cursor:pointer;color:var(--ax-accent)">\u25B6 Run</summary>'
1670
+ + '<div style="margin-top:8px">'
1671
+ + (inputForm || '<div style="font-size:11px;color:var(--ax-muted);margin-bottom:6px">no inputs \u2014 invokes verbatim</div>')
1672
+ + '<div style="margin-top:6px;display:flex;gap:6px;align-items:center">'
1673
+ + '<button class="primary" data-act="ac-run" data-id="' + escapeHtml(a.id) + '">Run now</button>'
1674
+ + '<span class="msg" data-ac-msg style="margin:0;padding:4px 8px"></span>'
1675
+ + '</div>'
1676
+ + '<pre data-ac-output style="display:none;margin-top:8px;padding:8px;background:var(--ax-bg);border:1px solid var(--ax-border);border-radius:4px;font-family:var(--ax-mono);font-size:11px;line-height:1.5;white-space:pre-wrap;max-height:280px;overflow:auto"></pre>'
1677
+ + '</div>'
1678
+ + '</details>'
1679
+ + '</div>';
1680
+ }).join('');
1681
+ }
1682
+
1683
+ function wireActionKindToggle() {
1684
+ if (window.__acKindWired) return;
1685
+ window.__acKindWired = true;
1686
+ const sel = $('ac-kind');
1687
+ if (!sel) return;
1688
+ const apply = () => {
1689
+ const k = sel.value;
1690
+ const sh = $('ac-shell-fields'); if (sh) sh.style.display = k === 'shell' ? '' : 'none';
1691
+ const ht = $('ac-http-fields'); if (ht) ht.style.display = k === 'http' ? '' : 'none';
1692
+ };
1693
+ sel.addEventListener('change', apply);
1694
+ apply();
1695
+ }
1696
+
1697
+ function wireActionsHandlers() {
1698
+ if (window.__actionsWired) return;
1699
+ window.__actionsWired = true;
1700
+ document.addEventListener('click', async (ev) => {
1701
+ const t = ev.target.closest('[data-act^="ac-"]');
1702
+ if (!t) return;
1703
+ const act = t.getAttribute('data-act');
1704
+ const id = t.getAttribute('data-id');
1705
+ if (act === 'ac-rm') {
1706
+ if (!confirm('Remove action ' + id + '?')) return;
1707
+ try { await req('DELETE', '/api/admin/actions', { id }); await refresh(); }
1708
+ catch (e) { showMsg($('global-msg'), 'err', e.message); }
1709
+ } else if (act === 'ac-edit') {
1710
+ const a = (state.actions || []).find(x => x.id === id);
1711
+ if (!a) return;
1712
+ $('ac-id').value = a.id;
1713
+ $('ac-title').value = a.title || '';
1714
+ $('ac-desc').value = a.description || '';
1715
+ $('ac-kind').value = a.kind;
1716
+ $('ac-kind').dispatchEvent(new Event('change'));
1717
+ if (a.kind === 'shell') {
1718
+ $('ac-command').value = a.command || '';
1719
+ $('ac-cwd').value = a.cwd || '';
1720
+ } else {
1721
+ $('ac-url').value = a.url || '';
1722
+ $('ac-method').value = a.method || 'POST';
1723
+ }
1724
+ $('ac-inputs').value = (a.inputs || []).map(i => i.name + ':' + i.type + (i.required ? '!' : '')).join(',');
1725
+ $('ac-timeout').value = a.timeoutMs ?? 30000;
1726
+ const details = document.querySelector('#tab-actions .add-form');
1727
+ if (details) { details.open = true; details.scrollIntoView({ behavior: 'smooth' }); }
1728
+ } else if (act === 'ac-run') {
1729
+ const card = t.closest('[data-ac-card]');
1730
+ if (!card) return;
1731
+ const inputs = {};
1732
+ card.querySelectorAll('[data-ac-input]').forEach(el => {
1733
+ const name = el.getAttribute('data-name');
1734
+ if (el.type === 'checkbox') inputs[name] = el.checked;
1735
+ else if (el.value !== '') inputs[name] = el.value;
1736
+ });
1737
+ const msgEl = card.querySelector('[data-ac-msg]');
1738
+ const outEl = card.querySelector('[data-ac-output]');
1739
+ if (msgEl) { msgEl.className = 'msg warn'; msgEl.textContent = 'running\u2026'; msgEl.style.display = 'inline-block'; }
1740
+ try {
1741
+ const r = await req('POST', '/api/admin/actions/run', { id, inputs });
1742
+ const result = r.result || {};
1743
+ if (msgEl) {
1744
+ msgEl.className = 'msg ' + (result.ok ? 'ok' : 'err');
1745
+ msgEl.textContent = (result.ok ? 'ok' : 'failed') + ' \xB7 status=' + result.status + ' \xB7 ' + result.durationMs + 'ms';
1746
+ }
1747
+ if (outEl) {
1748
+ let text = '';
1749
+ if (result.output) text += result.output;
1750
+ if (result.errors) text += (text ? '\\n--- stderr ---\\n' : '') + result.errors;
1751
+ outEl.textContent = text || '(no output)';
1752
+ outEl.style.display = 'block';
1753
+ }
1754
+ } catch (e) {
1755
+ if (msgEl) { msgEl.className = 'msg err'; msgEl.textContent = e.message; }
1756
+ if (outEl) outEl.style.display = 'none';
1757
+ }
1758
+ }
1759
+ });
1760
+ }
1761
+
1762
+ window.upsertAction = async function() {
1763
+ const id = $('ac-id').value.trim();
1764
+ const title = $('ac-title').value.trim();
1765
+ const kind = $('ac-kind').value;
1766
+ if (!id) { showMsg($('ac-msg'), 'err', 'id required'); return; }
1767
+ if (!title) { showMsg($('ac-msg'), 'err', 'title required'); return; }
1768
+ const inputsCsv = $('ac-inputs').value.trim();
1769
+ const inputs = inputsCsv ? inputsCsv.split(',').map(s => s.trim()).filter(Boolean).map(part => {
1770
+ const required = part.endsWith('!');
1771
+ const clean = required ? part.slice(0, -1) : part;
1772
+ const colon = clean.indexOf(':');
1773
+ const name = colon >= 0 ? clean.slice(0, colon) : clean;
1774
+ const type = colon >= 0 ? clean.slice(colon + 1) : 'string';
1775
+ return { name, type, required };
1776
+ }) : [];
1777
+ const body = {
1778
+ id, title, kind, inputs,
1779
+ timeoutMs: parseInt($('ac-timeout').value, 10) || 30000,
1780
+ };
1781
+ const desc = $('ac-desc').value.trim();
1782
+ if (desc) body.description = desc;
1783
+ if (kind === 'shell') {
1784
+ const cmd = $('ac-command').value.trim();
1785
+ if (!cmd) { showMsg($('ac-msg'), 'err', 'command required for shell'); return; }
1786
+ body.command = cmd;
1787
+ const cwd = $('ac-cwd').value.trim();
1788
+ if (cwd) body.cwd = cwd;
1789
+ } else if (kind === 'http') {
1790
+ const url = $('ac-url').value.trim();
1791
+ if (!url) { showMsg($('ac-msg'), 'err', 'url required for http'); return; }
1792
+ body.url = url;
1793
+ body.method = $('ac-method').value;
1794
+ const headers = $('ac-headers').value.trim();
1795
+ if (headers) {
1796
+ try { body.headers = JSON.parse(headers); }
1797
+ catch { showMsg($('ac-msg'), 'err', 'headers must be valid JSON'); return; }
1798
+ }
1799
+ const reqBody = $('ac-body').value;
1800
+ if (reqBody) body.body = reqBody;
1801
+ }
1802
+ try {
1803
+ await req('POST', '/api/admin/actions', body);
1804
+ showMsg($('ac-msg'), 'ok', 'saved');
1805
+ await refresh();
1806
+ } catch (e) { showMsg($('ac-msg'), 'err', e.message); }
1807
+ }
1808
+
1567
1809
  function wireWebhookTriggerHandlers() {
1568
1810
  if (window.__whTrigWired) return;
1569
1811
  window.__whTrigWired = true;
@@ -3087,7 +3329,7 @@ const JV_HINTS = {
3087
3329
  'agents[].id': 'lowercase handle, used in logs',
3088
3330
  'agents[].tier': 'which AI engine runs this agent (claude-code / sdk / orchestrator)',
3089
3331
  'agents[].mentions': 'trigger words that wake this agent',
3090
- 'channels.telegram.accounts[].botToken': 'reference to an env-var, not the token itself',
3332
+ 'channels.telegram.accounts[].token': 'reference to an env-var, not the token itself',
3091
3333
  'channels.telegram.accounts[].agentBinding': 'which agent answers messages to this bot',
3092
3334
  'crons[].schedule': 'standard five-field cron',
3093
3335
  'mesh.peers[].url': 'full URL including port',
@@ -3341,11 +3583,11 @@ for (const btn of document.querySelectorAll('nav.tabs button')) {
3341
3583
  })();
3342
3584
 
3343
3585
  refresh();
3344
- `;function Nt(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Pt({peers:a,localToken:n}))}async function Bt(t,e){let a=Fe();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function jt(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await un(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await Qa(t),r={"GET /api/admin/state":()=>Za(),"POST /api/admin/agents":()=>on(n),"PATCH /api/admin/agents":()=>sn(n),"DELETE /api/admin/agents":()=>ln(n),"POST /api/admin/agents/access":()=>en(n),"POST /api/admin/channels/telegram":()=>dn(n),"DELETE /api/admin/channels/telegram":()=>In(n),"POST /api/admin/channels/telegram/toggle":()=>Ln(n),"POST /api/admin/crons":()=>Dn(n),"DELETE /api/admin/crons":()=>Pn(n),"POST /api/admin/config/raw":()=>Rn(n),"GET /api/admin/tokens":()=>tn(),"POST /api/admin/tokens":()=>an(n),"DELETE /api/admin/tokens":()=>nn(n),"POST /api/admin/agents/test":()=>rn(n),"PATCH /api/admin/channels/telegram":()=>cn(n),"POST /api/admin/channels/slack":()=>En(n),"POST /api/admin/channels/slack/toggle":()=>Sn(n),"POST /api/admin/channels/discord":()=>Tn(n),"POST /api/admin/channels/discord/toggle":()=>Cn(n),"POST /api/admin/channels/gitlab":()=>An(n),"POST /api/admin/channels/gitlab/toggle":()=>$n(n),"GET /api/admin/channels/whatsapp/state":()=>Ee("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>Ee("/webrtc/history"),"GET /api/admin/channels/whatsapp/chats":()=>Ee("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>Ee("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>pn("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>Mn(n),"POST /api/admin/webhooks":()=>bn(n),"PATCH /api/admin/webhooks":()=>xn(n),"DELETE /api/admin/webhooks":()=>_n(n),"POST /api/admin/mesh/peers":()=>yn(n),"DELETE /api/admin/mesh/peers":()=>wn(n),"POST /api/admin/mesh/toggle":()=>kn(n),"GET /api/admin/files":()=>mn(t),"GET /api/admin/files/read":()=>gn(t),"PUT /api/admin/files":()=>hn(n),"POST /api/admin/files/skill":()=>fn(n),"DELETE /api/admin/files/skill":()=>vn(n),"POST /api/admin/actors":()=>On(n),"DELETE /api/admin/actors":()=>Hn(n),"POST /api/admin/roles":()=>Nn(n),"DELETE /api/admin/roles":()=>Bn(n),"POST /api/admin/roles/grant":()=>jn(n),"POST /api/admin/roles/revoke":()=>zn(n),"POST /api/admin/business/orgchart":()=>qn(n),"DELETE /api/admin/business/orgchart":()=>Fn(n),"POST /api/admin/business/project":()=>Gn(n),"DELETE /api/admin/business/project":()=>Wn(n),"POST /api/admin/business/contact":()=>Un(n),"DELETE /api/admin/business/contact":()=>Kn(n),"POST /api/admin/boards":()=>Jn(n),"DELETE /api/admin/boards":()=>Xn(n),"POST /api/admin/boards/columns":()=>Vn(n),"DELETE /api/admin/boards/columns":()=>Yn(n),"POST /api/admin/notifications":()=>Zn(n),"POST /api/admin/webhooks/triggers":()=>er(n),"POST /api/admin/mesh/health":()=>Qn(n)},o=`${t.method} ${a}`,s=r[o];if(!s){ze(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();ze(e,200,i)}catch(n){ze(e,400,{error:n.message||"admin op failed"})}}function ze(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Qa(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}function Rt(t){let e=oe(process.cwd(),t);if(!Se(e))return[];let a=[];for(let n of Ya(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(Ot(oe(e,n.name),"utf-8")))}catch{}return a}function Fe(){let t=oe(process.cwd(),"agentx.json");return Se(t)?JSON.parse(Ot(t,"utf-8")):null}function Za(){let t=Fe();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([g,v])=>({id:g,name:v.name,tier:v.tier,model:v.model,mentions:v.mentions||[],workspace:v.workspace,access:v.access||"private",systemPrompt:v.systemPrompt||"",maxConcurrent:v.maxConcurrent??1,maxExecutionMinutes:v.maxExecutionMinutes??20,permissionMode:v.permissionMode||"default"})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([g,v])=>({id:g,botUsername:v.botUsername||"",agentBinding:v.agentBinding||"",botTokenRef:v.botToken||""}))},r={enabled:!!t.channels?.slack?.enabled,botTokenRef:t.channels?.slack?.botToken||"",appTokenRef:t.channels?.slack?.appToken||"",agentBinding:t.channels?.slack?.agentBinding||""},o={enabled:!!t.channels?.discord?.enabled,tokenRef:t.channels?.discord?.token||"",agentBinding:t.channels?.discord?.agentBinding||""},s={enabled:!!t.channels?.gitlab?.enabled,host:t.channels?.gitlab?.host||"",webhookPort:t.channels?.gitlab?.webhookPort||18810,tokenRef:t.channels?.gitlab?.token||"",routeCount:Array.isArray(t.channels?.gitlab?.routes)?t.channels.gitlab.routes.length:0,agentMappingCount:Array.isArray(t.channels?.gitlab?.agentMappings)?t.channels.gitlab.agentMappings.length:0},i={enabled:!!t.channels?.whatsapp?.enabled,sessionDir:t.channels?.whatsapp?.sessionDir||".agentx/whatsapp-sessions",routeCount:Array.isArray(t.channels?.whatsapp?.routes)?t.channels.whatsapp.routes.length:0},l=Object.entries(t.crons||{}).map(([g,v])=>({id:g,schedule:v.schedule,agent:v.agent,prompt:(v.prompt||"").slice(0,200),enabled:v.enabled!==!1})),d=Array.isArray(t.webhooks)?t.webhooks.map(g=>({id:g.id,source:g.source,agentId:g.agentId,secretEnv:g.secretEnv||"",description:g.description||"",enabled:g.enabled!==!1,triggers:g.triggers&&typeof g.triggers=="object"?g.triggers:{},defaultWorkflow:g.defaultWorkflow||""})):[],c={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(g=>({url:g.url,name:g.name,hasToken:!!g.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},u=t.dashboard?.daemonUrl||"http://localhost:18800",h=Rt(".agentx/actors").map(g=>({id:g.id,name:g.name,email:g.email,channels:Array.isArray(g.channels)?g.channels.map(v=>({channel:v.channel,handle:v.handle,preferredForTasks:!!v.preferredForTasks})):[],timezone:g.timezone})).sort((g,v)=>g.id.localeCompare(v.id)),x=Rt(".agentx/roles").map(g=>({id:g.id,name:g.name,members:Array.isArray(g.members)?g.members:[],assignmentStrategy:g.assignmentStrategy||"first-available"})).sort((g,v)=>g.id.localeCompare(v.id)),p=t.business||{},m={enabled:!!p.enabled,timezone:p.timezone||"UTC",orgChart:p.orgChart||{},projects:Array.isArray(p.projects)?p.projects:[],contactMap:Array.isArray(p.contactMap)?p.contactMap:[]},f=t.notifications||{},w={longTaskThreshold:f.longTaskThreshold??30,destination:f.destination||null,on:{taskComplete:f.on?.taskComplete!==!1,taskError:f.on?.taskError!==!1,taskQueued:!!f.on?.taskQueued}},b=(Array.isArray(t.boards)?t.boards:[]).map(g=>({id:g.id,name:g.name,source:g.source||{type:"gitlab",projects:[]},primaryToolLabel:g.primaryToolLabel||"",timeRangeDays:g.timeRangeDays??30,closedWindowDays:g.closedWindowDays??30,columns:Array.isArray(g.columns)?g.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:i,crons:l,webhooks:d,mesh:c,daemonUrl:u,nodeName:t.node?.name,actors:h,roles:x,business:m,boards:b,notifications:w}}function en(t){let e=String(t?.id||"").trim(),a=t?.access==="public"?"public":"private";if(!e)throw new Error("Agent id is required.");let{summary:n}=S(r=>{if(!r.agents?.[e])throw new Error(`Agent "${e}" not found.`);return r.agents[e].access=a,`agent "${e}" is now ${a}`});return{summary:n}}function tn(){return new U().list().map(t=>({id:t.id,name:t.name,prefix:t.prefix,scopes:t.scopes,createdAt:t.createdAt,expiresAt:t.expiresAt,revokedAt:t.revokedAt,lastUsedAt:t.lastUsedAt}))}function an(t){let e=String(t?.name||"").trim(),a=Array.isArray(t?.scopes)?t.scopes.map(String):[],n=t?.expiresInDays?Number(t.expiresInDays):void 0,{token:r,record:o}=new U().create({name:e,scopes:a,expiresInDays:n});return{summary:`created token "${e}"`,token:r,record:o}}function nn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Token id is required.");let a=new U().revoke(e);if(!a)throw new Error(`Token "${e}" not found.`);return{summary:`revoked token ${e} (${a.name})`}}async function rn(t){let e=String(t?.agent||t?.id||"").trim(),a=String(t?.message||"").trim(),n=String(t?.chatId||"").trim()||`admin-${Date.now()}`;if(!e)throw new Error("Agent id is required.");if(!a)throw new Error("Message is required.");let r="http://127.0.0.1:18800",o;try{let c=B();r=c.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=c.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),l=await i.text(),d;try{d=JSON.parse(l)}catch{d={content:l}}if(!i.ok)throw new Error(d?.error||`daemon HTTP ${i.status}`);return{chatId:n,response:d}}function on(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=t?.tier==="sdk"?"sdk":"claude-code",r=qt(t?.triggerWords),o=t?.model?String(t.model).trim():void 0,s=t?.personality?String(t.personality).trim():void 0;if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Agent id must be lowercase (letters, digits, -, _).");if(!a)throw new Error("Agent name is required.");if(r.length===0)throw new Error("At least one trigger word is required.");let i=oe(process.cwd(),"agents",e),{summary:l}=S(c=>{if(c.agents=c.agents||{},c.agents[e])throw new Error(`Agent "${e}" already exists.`);let u={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(u.model=o),s&&(u.systemPrompt=s.slice(0,400)),c.agents[e]=u,`added agent "${e}"`}),d=oe(i,"CLAUDE.md");if(!Se(d))try{Xa(i,{recursive:!0}),Ht(d,`# ${a}
3586
+ `;function Bt(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ht({peers:a,localToken:n}))}async function jt(t,e){let a=We();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function zt(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await mn(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await Za(t),r={"GET /api/admin/state":()=>en(),"POST /api/admin/agents":()=>sn(n),"PATCH /api/admin/agents":()=>ln(n),"DELETE /api/admin/agents":()=>dn(n),"POST /api/admin/agents/access":()=>tn(n),"POST /api/admin/channels/telegram":()=>cn(n),"DELETE /api/admin/channels/telegram":()=>Ln(n),"POST /api/admin/channels/telegram/toggle":()=>Dn(n),"POST /api/admin/crons":()=>Pn(n),"DELETE /api/admin/crons":()=>Rn(n),"POST /api/admin/config/raw":()=>Hn(n),"GET /api/admin/tokens":()=>an(),"POST /api/admin/tokens":()=>nn(n),"DELETE /api/admin/tokens":()=>rn(n),"POST /api/admin/agents/test":()=>on(n),"PATCH /api/admin/channels/telegram":()=>pn(n),"POST /api/admin/channels/slack":()=>Sn(n),"POST /api/admin/channels/slack/toggle":()=>Tn(n),"POST /api/admin/channels/discord":()=>Cn(n),"POST /api/admin/channels/discord/toggle":()=>An(n),"POST /api/admin/channels/gitlab":()=>$n(n),"POST /api/admin/channels/gitlab/toggle":()=>Mn(n),"GET /api/admin/channels/whatsapp/state":()=>Ee("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>Ee("/webrtc/history"),"POST /api/admin/actions":()=>Zn(n),"DELETE /api/admin/actions":()=>er(n),"POST /api/admin/actions/run":()=>tr(n),"GET /api/admin/channels/whatsapp/chats":()=>Ee("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>Ee("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>un("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>In(n),"POST /api/admin/webhooks":()=>xn(n),"PATCH /api/admin/webhooks":()=>yn(n),"DELETE /api/admin/webhooks":()=>En(n),"POST /api/admin/mesh/peers":()=>wn(n),"DELETE /api/admin/mesh/peers":()=>kn(n),"POST /api/admin/mesh/toggle":()=>_n(n),"GET /api/admin/files":()=>gn(t),"GET /api/admin/files/read":()=>hn(t),"PUT /api/admin/files":()=>fn(n),"POST /api/admin/files/skill":()=>vn(n),"DELETE /api/admin/files/skill":()=>bn(n),"POST /api/admin/actors":()=>On(n),"DELETE /api/admin/actors":()=>Nn(n),"POST /api/admin/roles":()=>Bn(n),"DELETE /api/admin/roles":()=>jn(n),"POST /api/admin/roles/grant":()=>zn(n),"POST /api/admin/roles/revoke":()=>qn(n),"POST /api/admin/business/orgchart":()=>Fn(n),"DELETE /api/admin/business/orgchart":()=>Wn(n),"POST /api/admin/business/project":()=>Gn(n),"DELETE /api/admin/business/project":()=>Un(n),"POST /api/admin/business/contact":()=>Kn(n),"DELETE /api/admin/business/contact":()=>Jn(n),"POST /api/admin/boards":()=>Xn(n),"DELETE /api/admin/boards":()=>Vn(n),"POST /api/admin/boards/columns":()=>Yn(n),"DELETE /api/admin/boards/columns":()=>Qn(n),"POST /api/admin/notifications":()=>nr(n),"POST /api/admin/webhooks/triggers":()=>rr(n),"POST /api/admin/mesh/health":()=>ar(n)},o=`${t.method} ${a}`,s=r[o];if(!s){ze(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();ze(e,200,i)}catch(n){ze(e,400,{error:n.message||"admin op failed"})}}function ze(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Za(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}function qe(t){let e=oe(process.cwd(),t);if(!Se(e))return[];let a=[];for(let n of Qa(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(Ot(oe(e,n.name),"utf-8")))}catch{}return a}function We(){let t=oe(process.cwd(),"agentx.json");return Se(t)?JSON.parse(Ot(t,"utf-8")):null}function en(){let t=We();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([g,v])=>({id:g,name:v.name,tier:v.tier,model:v.model,mentions:v.mentions||[],workspace:v.workspace,access:v.access||"private",systemPrompt:v.systemPrompt||"",maxConcurrent:v.maxConcurrent??1,maxExecutionMinutes:v.maxExecutionMinutes??20,permissionMode:v.permissionMode||"default"})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([g,v])=>({id:g,botUsername:v.botUsername||"",agentBinding:v.agentBinding||"",botTokenRef:v.token||""}))},r={enabled:!!t.channels?.slack?.enabled,botTokenRef:t.channels?.slack?.botToken||"",appTokenRef:t.channels?.slack?.appToken||"",agentBinding:t.channels?.slack?.agentBinding||""},o={enabled:!!t.channels?.discord?.enabled,tokenRef:t.channels?.discord?.token||"",agentBinding:t.channels?.discord?.agentBinding||""},s={enabled:!!t.channels?.gitlab?.enabled,host:t.channels?.gitlab?.host||"",webhookPort:t.channels?.gitlab?.webhookPort||18810,tokenRef:t.channels?.gitlab?.token||"",routeCount:Array.isArray(t.channels?.gitlab?.routes)?t.channels.gitlab.routes.length:0,agentMappingCount:Array.isArray(t.channels?.gitlab?.agentMappings)?t.channels.gitlab.agentMappings.length:0},i={enabled:!!t.channels?.whatsapp?.enabled,sessionDir:t.channels?.whatsapp?.sessionDir||".agentx/whatsapp-sessions",routeCount:Array.isArray(t.channels?.whatsapp?.routes)?t.channels.whatsapp.routes.length:0},l=Object.entries(t.crons||{}).map(([g,v])=>({id:g,schedule:v.schedule,agent:v.agent,prompt:(v.prompt||"").slice(0,200),enabled:v.enabled!==!1})),d=Array.isArray(t.webhooks)?t.webhooks.map(g=>({id:g.id,source:g.source,agentId:g.agentId,secretEnv:g.secretEnv||"",description:g.description||"",enabled:g.enabled!==!1,triggers:g.triggers&&typeof g.triggers=="object"?g.triggers:{},defaultWorkflow:g.defaultWorkflow||""})):[],c={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(g=>({url:g.url,name:g.name,hasToken:!!g.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},u=t.dashboard?.daemonUrl||"http://localhost:18800",h=qe(".agentx/actors").map(g=>({id:g.id,name:g.name,email:g.email,channels:Array.isArray(g.channels)?g.channels.map(v=>({channel:v.channel,handle:v.handle,preferredForTasks:!!v.preferredForTasks})):[],timezone:g.timezone})).sort((g,v)=>g.id.localeCompare(v.id)),y=qe(".agentx/roles").map(g=>({id:g.id,name:g.name,members:Array.isArray(g.members)?g.members:[],assignmentStrategy:g.assignmentStrategy||"first-available"})).sort((g,v)=>g.id.localeCompare(v.id)),p=t.business||{},m={enabled:!!p.enabled,timezone:p.timezone||"UTC",orgChart:p.orgChart||{},projects:Array.isArray(p.projects)?p.projects:[],contactMap:Array.isArray(p.contactMap)?p.contactMap:[]},f=t.notifications||{},k={longTaskThreshold:f.longTaskThreshold??30,destination:f.destination||null,on:{taskComplete:f.on?.taskComplete!==!1,taskError:f.on?.taskError!==!1,taskQueued:!!f.on?.taskQueued}},b=[];try{b=qe(".agentx/actions").filter(v=>v&&typeof v=="object"&&v.id).map(v=>({id:v.id,title:v.title,kind:v.kind,description:v.description||"",inputs:Array.isArray(v.inputs)?v.inputs:[],timeoutMs:v.timeoutMs??3e4,command:v.kind==="shell"?v.command:void 0,url:v.kind==="http"?v.url:void 0,method:v.kind==="http"?v.method:void 0})).sort((v,x)=>v.id.localeCompare(x.id))}catch{}let w=(Array.isArray(t.boards)?t.boards:[]).map(g=>({id:g.id,name:g.name,source:g.source||{type:"gitlab",projects:[]},primaryToolLabel:g.primaryToolLabel||"",timeRangeDays:g.timeRangeDays??30,closedWindowDays:g.closedWindowDays??30,columns:Array.isArray(g.columns)?g.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:i,crons:l,webhooks:d,mesh:c,daemonUrl:u,nodeName:t.node?.name,actors:h,roles:y,business:m,boards:w,notifications:k,actions:b}}function tn(t){let e=String(t?.id||"").trim(),a=t?.access==="public"?"public":"private";if(!e)throw new Error("Agent id is required.");let{summary:n}=T(r=>{if(!r.agents?.[e])throw new Error(`Agent "${e}" not found.`);return r.agents[e].access=a,`agent "${e}" is now ${a}`});return{summary:n}}function an(){return new U().list().map(t=>({id:t.id,name:t.name,prefix:t.prefix,scopes:t.scopes,createdAt:t.createdAt,expiresAt:t.expiresAt,revokedAt:t.revokedAt,lastUsedAt:t.lastUsedAt}))}function nn(t){let e=String(t?.name||"").trim(),a=Array.isArray(t?.scopes)?t.scopes.map(String):[],n=t?.expiresInDays?Number(t.expiresInDays):void 0,{token:r,record:o}=new U().create({name:e,scopes:a,expiresInDays:n});return{summary:`created token "${e}"`,token:r,record:o}}function rn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Token id is required.");let a=new U().revoke(e);if(!a)throw new Error(`Token "${e}" not found.`);return{summary:`revoked token ${e} (${a.name})`}}async function on(t){let e=String(t?.agent||t?.id||"").trim(),a=String(t?.message||"").trim(),n=String(t?.chatId||"").trim()||`admin-${Date.now()}`;if(!e)throw new Error("Agent id is required.");if(!a)throw new Error("Message is required.");let r="http://127.0.0.1:18800",o;try{let c=z();r=c.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=c.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),l=await i.text(),d;try{d=JSON.parse(l)}catch{d={content:l}}if(!i.ok)throw new Error(d?.error||`daemon HTTP ${i.status}`);return{chatId:n,response:d}}function sn(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=t?.tier==="sdk"?"sdk":"claude-code",r=Ft(t?.triggerWords),o=t?.model?String(t.model).trim():void 0,s=t?.personality?String(t.personality).trim():void 0;if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Agent id must be lowercase (letters, digits, -, _).");if(!a)throw new Error("Agent name is required.");if(r.length===0)throw new Error("At least one trigger word is required.");let i=oe(process.cwd(),"agents",e),{summary:l}=T(c=>{if(c.agents=c.agents||{},c.agents[e])throw new Error(`Agent "${e}" already exists.`);let u={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(u.model=o),s&&(u.systemPrompt=s.slice(0,400)),c.agents[e]=u,`added agent "${e}"`}),d=oe(i,"CLAUDE.md");if(!Se(d))try{Va(i,{recursive:!0}),Nt(d,`# ${a}
3345
3587
 
3346
3588
  ${s||"You are "+a+"."}
3347
- `)}catch{}return{summary:l}}function sn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let a=t?.patch||{},{summary:n}=S(r=>{if(!r.agents?.[e])throw new Error(`Agent "${e}" not found.`);let o=r.agents[e];return typeof a.name=="string"&&a.name.trim()&&(o.name=a.name.trim()),typeof a.model=="string"&&(o.model=a.model.trim()||void 0),typeof a.tier=="string"&&["claude-code","sdk","orchestrator"].includes(a.tier)&&(o.tier=a.tier),typeof a.systemPrompt=="string"&&(o.systemPrompt=a.systemPrompt.trim()||void 0),Array.isArray(a.mentions)?o.mentions=a.mentions.map(s=>String(s).trim()).filter(Boolean):typeof a.triggerWords=="string"&&(o.mentions=qt(a.triggerWords)),typeof a.maxConcurrent=="number"&&a.maxConcurrent>=1&&(o.maxConcurrent=a.maxConcurrent),typeof a.maxExecutionMinutes=="number"&&a.maxExecutionMinutes>=1&&a.maxExecutionMinutes<=240&&(o.maxExecutionMinutes=a.maxExecutionMinutes),typeof a.permissionMode=="string"&&(o.permissionMode=a.permissionMode),(a.access==="public"||a.access==="private")&&(o.access=a.access),`updated agent "${e}"`});return{summary:n}}function ln(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let{summary:a}=S(n=>{if(!n.agents||!n.agents[e])throw new Error(`Agent "${e}" not found.`);if(delete n.agents[e],n.channels?.telegram?.accounts)for(let r of Object.keys(n.channels.telegram.accounts))n.channels.telegram.accounts[r]?.agentBinding===e&&(n.channels.telegram.accounts[r].agentBinding="");return`removed agent "${e}"`});return{summary:a}}function dn(t){let e=String(t?.id||"").trim(),a=String(t?.agentBinding||"").trim(),n=String(t?.botUsername||"").trim(),r=String(t?.botTokenEnv||"").trim();if(!e)throw new Error("Account id is required.");if(!a)throw new Error("Choose an agent to bind this account to.");if(!r)throw new Error("Bot token env-var name is required (e.g. TG_SUPPORT_BOT_TOKEN).");let{summary:o}=S(s=>{if(s.channels=s.channels||{},s.channels.telegram=s.channels.telegram||{enabled:!0,accounts:{},policy:{dm:"pair",group:"mention-required"}},s.channels.telegram.enabled=!0,s.channels.telegram.accounts=s.channels.telegram.accounts||{},s.channels.telegram.accounts[e])throw new Error(`Telegram account "${e}" already exists.`);if(!s.agents?.[a])throw new Error(`Unknown agent "${a}".`);return s.channels.telegram.accounts[e]={botToken:"${"+r+"}",botUsername:n,agentBinding:a},`added telegram account "${e}"`});return{summary:o,hint:`Add ${r}=<bot-token> to your .env file.`}}function cn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let a=t?.patch||{},{summary:n}=S(r=>{let o=r.channels?.telegram?.accounts?.[e];if(!o)throw new Error(`Account "${e}" not found.`);if(typeof a.agentBinding=="string"&&a.agentBinding.trim()){if(!r.agents?.[a.agentBinding])throw new Error(`Unknown agent "${a.agentBinding}".`);o.agentBinding=a.agentBinding.trim()}return typeof a.botUsername=="string"&&(o.botUsername=a.botUsername.trim()),typeof a.botTokenEnv=="string"&&a.botTokenEnv.trim()&&(o.botToken="${"+a.botTokenEnv.trim()+"}"),`updated telegram account "${e}"`});return{summary:n}}async function Ee(t){let{url:e,headers:a}=Ge(),n=await fetch(e+t,{headers:a}),r=await n.text();if(!n.ok)throw new Error(`daemon ${n.status}: ${r.slice(0,200)}`);try{return JSON.parse(r)}catch{return{raw:r}}}async function pn(t,e){let{url:a,headers:n}=Ge(),r=await fetch(a+t,{method:"POST",headers:{...n,"Content-Type":"application/json"},body:JSON.stringify(e||{})}),o=await r.text();if(!r.ok)throw new Error(`daemon ${r.status}: ${o.slice(0,200)}`);try{return JSON.parse(o)}catch{return{raw:o}}}async function un(t,e){try{let{url:a,headers:n}=Ge(),r=await fetch(a+e,{headers:n}),o=await r.text();t.writeHead(r.status,{"Content-Type":r.headers.get("content-type")||"image/svg+xml","Cache-Control":"no-store"}),t.end(o)}catch(a){t.writeHead(502,{"Content-Type":"text/plain; charset=utf-8"}),t.end("daemon unreachable: "+(a?.message||"unknown"))}}function Ge(){let t="http://127.0.0.1:18800",e={};try{let a=B();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function ue(t){let a=Fe()?.agents?.[t];if(!a)throw new Error(`Unknown agent "${t}".`);if(!a.workspace)throw new Error(`Agent "${t}" has no workspace configured.`);return a.workspace}function qe(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function mn(t){let e=qe(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=re(ue(e));return{agentId:e,...a}}function gn(t){let e=qe(t,"agent").trim(),a=qe(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return xe(ue(e),a)}function hn(t){let e=String(t?.agent||"").trim(),a=String(t?.path||"").trim(),n=typeof t?.content=="string"?t.content:"";if(!e||!a)throw new Error("agent and path are required.");let r=ye(ue(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function fn(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim(),n=t?.title?String(t.title):void 0,r=t?.content?String(t.content):void 0;if(!e)throw new Error("agent is required.");let o=we(ue(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function vn(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim();if(!e||!a)throw new Error("agent and slug are required.");let n=ke(ue(e),a);return{summary:`removed skill "${a}"`,...n}}var zt=["gitlab","github","sentry","stripe","discord","slack","custom"];function bn(t){let e=String(t?.id||"").trim(),a=String(t?.source||"").trim(),n=String(t?.agentId||"").trim(),r=String(t?.secretEnv||"").trim(),o=String(t?.description||"").trim();if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Webhook id must be lowercase (letters, digits, -, _).");if(!zt.includes(a))throw new Error(`Unknown source: ${a}`);if(!n)throw new Error("Pick an agent to bind the webhook to.");let{summary:s}=S(i=>{if(!i.agents?.[n])throw new Error(`Unknown agent "${n}".`);if(i.webhooks=Array.isArray(i.webhooks)?i.webhooks:[],i.webhooks.find(d=>d.id===e))throw new Error(`Webhook "${e}" already exists.`);let l={id:e,source:a,agentId:n,enabled:!0};return r&&(l.secretEnv=r),o&&(l.description=o),i.webhooks.push(l),`added webhook "${e}" (${a} \u2192 ${n})`});return{summary:s}}function xn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let a=t?.patch||{},{summary:n}=S(r=>{let o=(r.webhooks||[]).find(s=>s.id===e);if(!o)throw new Error(`Webhook "${e}" not found.`);if(typeof a.source=="string"&&zt.includes(a.source)&&(o.source=a.source),typeof a.agentId=="string"&&a.agentId.trim()){if(!r.agents?.[a.agentId])throw new Error(`Unknown agent "${a.agentId}".`);o.agentId=a.agentId.trim()}return typeof a.secretEnv=="string"&&(o.secretEnv=a.secretEnv.trim()||void 0),typeof a.description=="string"&&(o.description=a.description.trim()||void 0),typeof a.enabled=="boolean"&&(o.enabled=a.enabled),`updated webhook "${e}"`});return{summary:n}}function yn(t){let e=String(t?.url||"").trim().replace(/\/+$/,""),a=String(t?.name||"").trim(),n=String(t?.token||"").trim()||void 0;if(!e||!/^https?:\/\//.test(e))throw new Error("Peer URL must start with http:// or https://");if(!a)throw new Error("Peer name is required.");let{summary:r}=S(o=>{if(o.mesh=o.mesh||{enabled:!0,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},o.mesh.enabled=!0,o.mesh.peers=Array.isArray(o.mesh.peers)?o.mesh.peers:[],o.mesh.peers.find(i=>i.url===e))throw new Error(`Peer at ${e} already registered.`);let s={url:e,name:a};return n&&(s.token=n),o.mesh.peers.push(s),`added mesh peer "${a}"`});return{summary:r}}function wn(t){let e=String(t?.url||"").trim().replace(/\/+$/,"");if(!e)throw new Error("Peer URL is required.");let{summary:a}=S(n=>{let r=(n.mesh?.peers||[]).length;if(n.mesh=n.mesh||{enabled:!1,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},n.mesh.peers=(n.mesh.peers||[]).filter(o=>o.url.replace(/\/+$/,"")!==e),n.mesh.peers.length===r)throw new Error(`Peer at ${e} not found.`);return`removed mesh peer ${e}`});return{summary:a}}function kn(t){let e=!!t?.enabled,{summary:a}=S(n=>(n.mesh=n.mesh||{enabled:e,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},n.mesh.enabled=e,`mesh ${e?"enabled":"disabled"}`));return{summary:a}}function _n(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let{summary:a}=S(n=>{let r=(n.webhooks||[]).length;if(n.webhooks=(n.webhooks||[]).filter(o=>o.id!==e),n.webhooks.length===r)throw new Error(`Webhook "${e}" not found.`);return`removed webhook "${e}"`});return{summary:a}}function En(t){let e=String(t?.botTokenEnv||"").trim(),a=String(t?.appTokenEnv||"").trim(),n=String(t?.agentBinding||"").trim();if(!e)throw new Error("Bot token env-var name is required (e.g. SLACK_BOT_TOKEN).");if(!a)throw new Error("App-level token env-var name is required (e.g. SLACK_APP_TOKEN).");let{summary:r}=S(o=>{if(o.channels=o.channels||{},o.channels.slack=o.channels.slack||{enabled:!1},o.channels.slack.enabled=!0,o.channels.slack.botToken="${"+e+"}",o.channels.slack.appToken="${"+a+"}",n){if(!o.agents?.[n])throw new Error(`Unknown agent "${n}".`);o.channels.slack.agentBinding=n}return"configured slack connector"});return{summary:r,hint:`Add ${e}=xoxb-\u2026 and ${a}=xapp-\u2026 to your .env.`}}function Sn(t){let e=!!t?.enabled,{summary:a}=S(n=>(n.channels=n.channels||{},n.channels.slack=n.channels.slack||{enabled:!1},n.channels.slack.enabled=e,`slack ${e?"enabled":"disabled"}`));return{summary:a}}function Tn(t){let e=String(t?.tokenEnv||"").trim(),a=String(t?.agentBinding||"").trim();if(!e)throw new Error("Bot token env-var name is required (e.g. DISCORD_BOT_TOKEN).");let{summary:n}=S(r=>{if(r.channels=r.channels||{},r.channels.discord=r.channels.discord||{enabled:!1},r.channels.discord.enabled=!0,r.channels.discord.token="${"+e+"}",a){if(!r.agents?.[a])throw new Error(`Unknown agent "${a}".`);r.channels.discord.agentBinding=a}return"configured discord connector"});return{summary:n,hint:`Add ${e}=<bot-token> to your .env.`}}function Cn(t){let e=!!t?.enabled,{summary:a}=S(n=>(n.channels=n.channels||{},n.channels.discord=n.channels.discord||{enabled:!1},n.channels.discord.enabled=e,`discord ${e?"enabled":"disabled"}`));return{summary:a}}function An(t){let e=String(t?.host||"").trim().replace(/\/+$/,""),a=String(t?.tokenEnv||"").trim(),n=parseInt(String(t?.webhookPort||"18810"),10);if(!e||!/^https?:\/\//.test(e))throw new Error("Host must start with http:// or https://");if(!a)throw new Error("Admin token env-var name is required (e.g. GITLAB_TOKEN).");if(!Number.isFinite(n)||n<1||n>65535)throw new Error("Webhook port must be between 1 and 65535.");let{summary:r}=S(o=>(o.channels=o.channels||{},o.channels.gitlab=o.channels.gitlab||{enabled:!1,routes:[],agentMappings:[]},o.channels.gitlab.enabled=!0,o.channels.gitlab.host=e,o.channels.gitlab.token="${"+a+"}",o.channels.gitlab.webhookPort=n,"configured gitlab connector"));return{summary:r,hint:`Add ${a}=<personal-access-token> to your .env. Per-project routes + per-agent tokens stay in the Advanced JSON editor.`}}function $n(t){let e=!!t?.enabled,{summary:a}=S(n=>(n.channels=n.channels||{},n.channels.gitlab=n.channels.gitlab||{enabled:!1,routes:[],agentMappings:[]},n.channels.gitlab.enabled=e,`gitlab ${e?"enabled":"disabled"}`));return{summary:a}}async function Mn(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-XVFIK4XH.js"),n;try{n=(await import("cronstrue")).default.toString(e,{use24HourTimeFormat:!1})}catch(i){throw new Error(`Invalid cron: ${i.message||"unknown"}`)}let r=Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC",o=[],s=new Date;try{for(let i=0;i<3;i++)s=a(e,s,r),o.push(s.toISOString())}catch(i){throw new Error(`Cron preview failed: ${i.message}`)}return{human:n,next:o,timezone:r}}function In(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let{summary:a}=S(n=>{if(!n.channels?.telegram?.accounts?.[e])throw new Error(`Account "${e}" not found.`);return delete n.channels.telegram.accounts[e],`removed telegram account "${e}"`});return{summary:a}}function Ln(t){let e=!!t?.enabled,{summary:a}=S(n=>(n.channels=n.channels||{},n.channels.telegram=n.channels.telegram||{enabled:!1,accounts:{},policy:{dm:"pair",group:"mention-required"}},n.channels.telegram.enabled=e,`telegram ${e?"enabled":"disabled"}`));return{summary:a}}function Dn(t){let e=String(t?.id||"").trim(),a=String(t?.schedule||"").trim(),n=String(t?.agent||"").trim(),r=String(t?.prompt||"").trim();if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Cron id must be lowercase (letters, digits, -, _).");if(!a)throw new Error("Cron expression is required (e.g. '0 9 * * 1' for Mondays at 9am).");if(!n)throw new Error("Pick an agent to run this schedule.");if(!r)throw new Error("A prompt is required (what should the agent do?).");let{summary:o}=S(s=>{if(s.crons=s.crons||{},s.crons[e])throw new Error(`Cron "${e}" already exists.`);if(!s.agents?.[n])throw new Error(`Unknown agent "${n}".`);return s.crons[e]={schedule:a,agent:n,prompt:r,enabled:!0},`added cron "${e}"`});return{summary:o}}function Pn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Cron id is required.");let{summary:a}=S(n=>{if(!n.crons?.[e])throw new Error(`Cron "${e}" not found.`);return delete n.crons[e],`removed cron "${e}"`});return{summary:a}}function Rn(t){let e=String(t?.raw||"");if(!e.trim())throw new Error("Config body is empty.");let a;try{a=JSON.parse(e)}catch(o){throw new Error(`Invalid JSON: ${o.message}`)}let n=oe(process.cwd(),"agentx.json"),r=`${n}.bak.${Date.now()}`;if(Se(n))try{Va(n,r)}catch{}Ht(n,JSON.stringify(a,null,2)+`
3348
- `,"utf-8");try{let s=B().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${s}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:r}}function qt(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function se(){let{ActorStore:t}=await import("./store-BAPDZHXE.js");return new t}async function On(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim();if(!e.startsWith("actor:"))throw new Error("id must start with 'actor:'");if(!a)throw new Error("name required");let n=Array.isArray(t?.channels)?t.channels:[];if(n.length===0)throw new Error("at least one channel handle required");let o=(await se()).saveActor({id:e,name:a,email:t?.email||void 0,channels:n.map(s=>({channel:s.channel,handle:String(s.handle||"").trim(),preferredForTasks:!!s.preferredForTasks})).filter(s=>s.handle),timezone:t?.timezone||void 0});return{summary:`Actor ${o.id} saved`,actor:o}}async function Hn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");if(!(await se()).deleteActor(e))throw new Error(`actor ${e} not found`);return{summary:`Actor ${e} deleted`}}async function Nn(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim();if(!e.startsWith("role:"))throw new Error("id must start with 'role:'");if(!a)throw new Error("name required");let n=t?.assignmentStrategy||"first-available",r=await se(),o=r.getRole(e),s=r.saveRole({id:e,name:a,members:Array.isArray(t?.members)?t.members:o?.members||[],assignmentStrategy:n,rotationCursor:o?.rotationCursor??0});return{summary:`Role ${s.id} saved`,role:s}}async function Bn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");if(!(await se()).deleteRole(e))throw new Error(`role ${e} not found`);return{summary:`Role ${e} deleted`}}async function jn(t){let e=String(t?.role||"").trim(),a=String(t?.member||"").trim();if(!e.startsWith("role:"))throw new Error("role required");if(!a.startsWith("actor:")&&!a.startsWith("role:"))throw new Error("member must be actor:<id> or role:<id>");let n=await se(),r=n.getRole(e);if(!r)throw new Error(`role ${e} not found`);let o=a.startsWith("actor:")?{actor:a}:{role:a};if(r.members.some(l=>("actor"in l?l.actor:l.role)===a))return{summary:`${a} already in ${e}`,role:r};let i=n.saveRole({...r,members:[...r.members,o]});return{summary:`${a} granted to ${e}`,role:i}}async function zn(t){let e=String(t?.role||"").trim(),a=String(t?.member||"").trim();if(!e.startsWith("role:"))throw new Error("role required");let n=await se(),r=n.getRole(e);if(!r)throw new Error(`role ${e} not found`);let o=r.members.filter(i=>("actor"in i?i.actor:i.role)!==a);if(o.length===r.members.length)return{summary:`${a} not in ${e}`,role:r};let s=n.saveRole({...r,members:o});return{summary:`${a} revoked from ${e}`,role:s}}async function qn(t){let e=String(t?.agentId||"").trim(),a=String(t?.role||"").trim();if(!e)throw new Error("agentId required");if(!a)throw new Error("role required");let n=Array.isArray(t?.days)&&t.days.length>0?t.days:["mon","tue","wed","thu","fri"],r=String(t?.start||"09:00"),o=String(t?.end||"17:00"),s=t?.reportsTo?String(t.reportsTo).trim():"",i=typeof t?.utilizationTarget=="number"?t.utilizationTarget:.8,{summary:l}=S(d=>(d.business=d.business||{},d.business.orgChart=d.business.orgChart||{},d.business.orgChart[e]={role:a,...s?{reportsTo:s}:{},schedule:{days:n,start:r,end:o},utilizationTarget:i},`orgChart "${e}" upserted`));return{summary:l}}async function Fn(t){let e=String(t?.agentId||"").trim();if(!e)throw new Error("agentId required");let{summary:a}=S(n=>{if(!n.business?.orgChart||!(e in n.business.orgChart))throw new Error(`no orgChart entry for "${e}"`);return delete n.business.orgChart[e],`orgChart "${e}" removed`});return{summary:a}}async function Gn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let a=t?.pm?String(t.pm).trim():"",n=t?.client?String(t.client).trim():"",{summary:r}=S(o=>{o.business=o.business||{},o.business.projects=o.business.projects||[];let s=o.business.projects.findIndex(l=>l.id===e),i={id:e,...a?{pm:a}:{},...n?{client:n}:{}};return s>=0?o.business.projects[s]={...o.business.projects[s],...i}:o.business.projects.push(i),s>=0?`project "${e}" updated`:`project "${e}" added`});return{summary:r}}async function Wn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let{summary:a}=S(n=>{let r=n.business?.projects||[],o=r.length;if(n.business.projects=r.filter(s=>s.id!==e),n.business.projects.length===o)throw new Error(`no project "${e}"`);return`project "${e}" removed`});return{summary:a}}async function Un(t){let e=String(t?.client||"").trim();if(!e)throw new Error("client required");if(!t?.chatId&&!t?.username&&!t?.senderId)throw new Error("one of chatId / username / senderId required");let{summary:a}=S(n=>{n.business=n.business||{},n.business.contactMap=n.business.contactMap||[];let r={client:e};t?.channel&&(r.channel=String(t.channel)),t?.chatId&&(r.chatId=String(t.chatId)),t?.username&&(r.username=String(t.username)),t?.senderId&&(r.senderId=String(t.senderId)),t?.project&&(r.project=String(t.project)),t?.displayName&&(r.displayName=String(t.displayName)),n.business.contactMap.push(r);let o=r.chatId||r.username||r.senderId;return`contact ${r.channel?r.channel+"/":""}${o} \u2192 ${e} added`});return{summary:a}}async function Kn(t){let a=["channel","chatId","username","senderId"].filter(r=>t?.[r]);if(a.length===0)throw new Error("at least one filter (channel/chatId/username/senderId) required");let{summary:n}=S(r=>{let o=r.business?.contactMap||[],s=o.length;if(r.business.contactMap=o.filter(i=>{for(let l of a)if(i[l]!==t[l])return!0;return!1}),r.business.contactMap.length===s)throw new Error("no matching contact entry");return`${s-r.business.contactMap.length} contact entry/entries removed`});return{summary:n}}async function Jn(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=String(t?.projects||"").split(/[,\n]/).map(l=>l.trim()).filter(Boolean);if(!e)throw new Error("id required");if(!a)throw new Error("name required");if(n.length===0)throw new Error("at least one project path required");let r=t?.primaryToolLabel?String(t.primaryToolLabel).trim():"",o=Number.isFinite(Number(t?.timeRangeDays))?Number(t.timeRangeDays):30,s=Number.isFinite(Number(t?.closedWindowDays))?Number(t.closedWindowDays):30,{summary:i}=S(l=>{l.boards=Array.isArray(l.boards)?l.boards:[];let d=l.boards.findIndex(u=>u.id===e),c={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(c.primaryToolLabel=r),d>=0){let u=l.boards[d];return l.boards[d]={...u,...c,columns:u.columns,labels:u.labels},`board "${e}" updated`}return l.boards.push(c),`board "${e}" added`});return{summary:i}}async function Xn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");let{summary:a}=S(n=>{let r=Array.isArray(n.boards)?n.boards:[],o=r.length;if(n.boards=r.filter(s=>s.id!==e),n.boards.length===o)throw new Error(`board "${e}" not found`);return`board "${e}" removed`});return{summary:a}}async function Vn(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"-"),n=String(t?.title||"").trim(),r=String(t?.kind||"scoped-label");if(!e)throw new Error("boardId required");if(!a)throw new Error("columnId required");if(!n)throw new Error("title required");if(!["open-backlog","scoped-label","closed","label"].includes(r))throw new Error("kind must be open-backlog | scoped-label | closed | label");let{summary:o}=S(s=>{let l=(Array.isArray(s.boards)?s.boards:[]).find(u=>u.id===e);if(!l)throw new Error(`board "${e}" not found`);l.columns=Array.isArray(l.columns)?l.columns:[];let d={id:a,title:n,kind:r,scopedPrefix:t?.scopedPrefix||"Status"};if(r==="scoped-label"){if(!t?.scopedLabel)throw new Error("scopedLabel required for kind=scoped-label");d.scopedLabel=String(t.scopedLabel)}if(r==="label"){if(!t?.mapsToLabel)throw new Error("mapsToLabel required for kind=label");d.mapsToLabel=String(t.mapsToLabel)}t?.accent&&(d.accent=String(t.accent));let c=l.columns.findIndex(u=>u.id===a);return c>=0?(l.columns[c]={...l.columns[c],...d},`column "${a}" updated`):(l.columns.push(d),`column "${a}" added to board "${e}"`)});return{summary:o}}async function Yn(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim();if(!e||!a)throw new Error("boardId and columnId required");let{summary:n}=S(r=>{let s=(Array.isArray(r.boards)?r.boards:[]).find(l=>l.id===e);if(!s)throw new Error(`board "${e}" not found`);let i=(s.columns||[]).length;if(s.columns=(s.columns||[]).filter(l=>l.id!==a),s.columns.length===i)throw new Error(`column "${a}" not found`);return`column "${a}" removed from board "${e}"`});return{summary:n}}async function Qn(t){let e=t?.interval!==void 0?Number(t.interval):void 0,a=t?.timeout!==void 0?Number(t.timeout):void 0;if(e!==void 0&&(!Number.isFinite(e)||e<5||e>3600))throw new Error("interval must be 5..3600 seconds");if(a!==void 0&&(!Number.isFinite(a)||a<1||a>60))throw new Error("timeout must be 1..60 seconds");if(e===void 0&&a===void 0)throw new Error("nothing to update");let{summary:n}=S(r=>(r.mesh=r.mesh||{},r.mesh.healthCheck=r.mesh.healthCheck||{},e!==void 0&&(r.mesh.healthCheck.interval=e),a!==void 0&&(r.mesh.healthCheck.timeout=a),`mesh.healthCheck updated (interval=${r.mesh.healthCheck.interval}s, timeout=${r.mesh.healthCheck.timeout}s)`));return{summary:n}}async function Zn(t){let{summary:e}=S(a=>{a.notifications=a.notifications||{};let n=[];if(t&&typeof t=="object"){if("destination"in t)if(!t.destination)delete a.notifications.destination,n.push("destination cleared");else if(t.destination.channel&&t.destination.chatId)a.notifications.destination={channel:String(t.destination.channel),chatId:String(t.destination.chatId),...t.destination.accountId?{accountId:String(t.destination.accountId)}:{}},n.push(`destination=${t.destination.channel}:${t.destination.chatId}`);else throw new Error("destination requires channel + chatId");if("on"in t&&t.on&&typeof t.on=="object"){a.notifications.on=a.notifications.on||{};for(let r of["taskComplete","taskError","taskQueued"])r in t.on&&(a.notifications.on[r]=!!t.on[r]);n.push("on="+JSON.stringify(a.notifications.on))}if("longTaskThreshold"in t){let r=Number(t.longTaskThreshold);if(!Number.isFinite(r)||r<0)throw new Error("longTaskThreshold must be a non-negative number");a.notifications.longTaskThreshold=r,n.push(`threshold=${r}s`)}}if(n.length===0)throw new Error("nothing to update");return`notifications updated (${n.join(", ")})`});return{summary:e}}async function er(t){let e=String(t?.id||"").trim();if(!e)throw new Error("webhook id required");let{summary:a}=S(n=>{let o=(Array.isArray(n.webhooks)?n.webhooks:[]).find(s=>s.id===e);if(!o)throw new Error(`webhook "${e}" not found`);if("triggers"in t){if(t.triggers===null||typeof t.triggers=="object"&&Object.keys(t.triggers).length===0)delete o.triggers;else if(typeof t.triggers=="object"){let s={};for(let[i,l]of Object.entries(t.triggers))typeof l=="string"&&l.trim()&&(s[String(i)]=l.trim());Object.keys(s).length===0?delete o.triggers:o.triggers=s}}return"defaultWorkflow"in t&&(t.defaultWorkflow?o.defaultWorkflow=String(t.defaultWorkflow).trim():delete o.defaultWorkflow),`webhook "${e}" triggers/defaultWorkflow updated`});return{summary:a}}import{resolve as nr}from"path";function Ft(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
3589
+ `)}catch{}return{summary:l}}function ln(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let a=t?.patch||{},{summary:n}=T(r=>{if(!r.agents?.[e])throw new Error(`Agent "${e}" not found.`);let o=r.agents[e];return typeof a.name=="string"&&a.name.trim()&&(o.name=a.name.trim()),typeof a.model=="string"&&(o.model=a.model.trim()||void 0),typeof a.tier=="string"&&["claude-code","sdk","orchestrator"].includes(a.tier)&&(o.tier=a.tier),typeof a.systemPrompt=="string"&&(o.systemPrompt=a.systemPrompt.trim()||void 0),Array.isArray(a.mentions)?o.mentions=a.mentions.map(s=>String(s).trim()).filter(Boolean):typeof a.triggerWords=="string"&&(o.mentions=Ft(a.triggerWords)),typeof a.maxConcurrent=="number"&&a.maxConcurrent>=1&&(o.maxConcurrent=a.maxConcurrent),typeof a.maxExecutionMinutes=="number"&&a.maxExecutionMinutes>=1&&a.maxExecutionMinutes<=240&&(o.maxExecutionMinutes=a.maxExecutionMinutes),typeof a.permissionMode=="string"&&(o.permissionMode=a.permissionMode),(a.access==="public"||a.access==="private")&&(o.access=a.access),`updated agent "${e}"`});return{summary:n}}function dn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let{summary:a}=T(n=>{if(!n.agents||!n.agents[e])throw new Error(`Agent "${e}" not found.`);if(delete n.agents[e],n.channels?.telegram?.accounts)for(let r of Object.keys(n.channels.telegram.accounts))n.channels.telegram.accounts[r]?.agentBinding===e&&(n.channels.telegram.accounts[r].agentBinding="");return`removed agent "${e}"`});return{summary:a}}function cn(t){let e=String(t?.id||"").trim(),a=String(t?.agentBinding||"").trim(),n=String(t?.botUsername||"").trim(),r=String(t?.botTokenEnv||"").trim();if(!e)throw new Error("Account id is required.");if(!a)throw new Error("Choose an agent to bind this account to.");if(!r)throw new Error("Bot token env-var name is required (e.g. TG_SUPPORT_BOT_TOKEN).");let{summary:o}=T(s=>{if(s.channels=s.channels||{},s.channels.telegram=s.channels.telegram||{enabled:!0,accounts:{},policy:{dm:"pair",group:"mention-required"}},s.channels.telegram.enabled=!0,s.channels.telegram.accounts=s.channels.telegram.accounts||{},s.channels.telegram.accounts[e])throw new Error(`Telegram account "${e}" already exists.`);if(!s.agents?.[a])throw new Error(`Unknown agent "${a}".`);return s.channels.telegram.accounts[e]={token:"${"+r+"}",agentBinding:a},`added telegram account "${e}"`});return{summary:o,hint:`Add ${r}=<bot-token> to your .env file.`}}function pn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let a=t?.patch||{},{summary:n}=T(r=>{let o=r.channels?.telegram?.accounts?.[e];if(!o)throw new Error(`Account "${e}" not found.`);if(typeof a.agentBinding=="string"&&a.agentBinding.trim()){if(!r.agents?.[a.agentBinding])throw new Error(`Unknown agent "${a.agentBinding}".`);o.agentBinding=a.agentBinding.trim()}return typeof a.botUsername=="string"&&(o.botUsername=a.botUsername.trim()),typeof a.botTokenEnv=="string"&&a.botTokenEnv.trim()&&(o.token="${"+a.botTokenEnv.trim()+"}"),`updated telegram account "${e}"`});return{summary:n}}async function Ee(t){let{url:e,headers:a}=Ge(),n=await fetch(e+t,{headers:a}),r=await n.text();if(!n.ok)throw new Error(`daemon ${n.status}: ${r.slice(0,200)}`);try{return JSON.parse(r)}catch{return{raw:r}}}async function un(t,e){let{url:a,headers:n}=Ge(),r=await fetch(a+t,{method:"POST",headers:{...n,"Content-Type":"application/json"},body:JSON.stringify(e||{})}),o=await r.text();if(!r.ok)throw new Error(`daemon ${r.status}: ${o.slice(0,200)}`);try{return JSON.parse(o)}catch{return{raw:o}}}async function mn(t,e){try{let{url:a,headers:n}=Ge(),r=await fetch(a+e,{headers:n}),o=await r.text();t.writeHead(r.status,{"Content-Type":r.headers.get("content-type")||"image/svg+xml","Cache-Control":"no-store"}),t.end(o)}catch(a){t.writeHead(502,{"Content-Type":"text/plain; charset=utf-8"}),t.end("daemon unreachable: "+(a?.message||"unknown"))}}function Ge(){let t="http://127.0.0.1:18800",e={};try{let a=z();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function ue(t){let a=We()?.agents?.[t];if(!a)throw new Error(`Unknown agent "${t}".`);if(!a.workspace)throw new Error(`Agent "${t}" has no workspace configured.`);return a.workspace}function Fe(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function gn(t){let e=Fe(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=re(ue(e));return{agentId:e,...a}}function hn(t){let e=Fe(t,"agent").trim(),a=Fe(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return xe(ue(e),a)}function fn(t){let e=String(t?.agent||"").trim(),a=String(t?.path||"").trim(),n=typeof t?.content=="string"?t.content:"";if(!e||!a)throw new Error("agent and path are required.");let r=ye(ue(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function vn(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim(),n=t?.title?String(t.title):void 0,r=t?.content?String(t.content):void 0;if(!e)throw new Error("agent is required.");let o=we(ue(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function bn(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim();if(!e||!a)throw new Error("agent and slug are required.");let n=ke(ue(e),a);return{summary:`removed skill "${a}"`,...n}}var qt=["gitlab","github","sentry","stripe","discord","slack","custom"];function xn(t){let e=String(t?.id||"").trim(),a=String(t?.source||"").trim(),n=String(t?.agentId||"").trim(),r=String(t?.secretEnv||"").trim(),o=String(t?.description||"").trim();if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Webhook id must be lowercase (letters, digits, -, _).");if(!qt.includes(a))throw new Error(`Unknown source: ${a}`);if(!n)throw new Error("Pick an agent to bind the webhook to.");let{summary:s}=T(i=>{if(!i.agents?.[n])throw new Error(`Unknown agent "${n}".`);if(i.webhooks=Array.isArray(i.webhooks)?i.webhooks:[],i.webhooks.find(d=>d.id===e))throw new Error(`Webhook "${e}" already exists.`);let l={id:e,source:a,agentId:n,enabled:!0};return r&&(l.secretEnv=r),o&&(l.description=o),i.webhooks.push(l),`added webhook "${e}" (${a} \u2192 ${n})`});return{summary:s}}function yn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let a=t?.patch||{},{summary:n}=T(r=>{let o=(r.webhooks||[]).find(s=>s.id===e);if(!o)throw new Error(`Webhook "${e}" not found.`);if(typeof a.source=="string"&&qt.includes(a.source)&&(o.source=a.source),typeof a.agentId=="string"&&a.agentId.trim()){if(!r.agents?.[a.agentId])throw new Error(`Unknown agent "${a.agentId}".`);o.agentId=a.agentId.trim()}return typeof a.secretEnv=="string"&&(o.secretEnv=a.secretEnv.trim()||void 0),typeof a.description=="string"&&(o.description=a.description.trim()||void 0),typeof a.enabled=="boolean"&&(o.enabled=a.enabled),`updated webhook "${e}"`});return{summary:n}}function wn(t){let e=String(t?.url||"").trim().replace(/\/+$/,""),a=String(t?.name||"").trim(),n=String(t?.token||"").trim()||void 0;if(!e||!/^https?:\/\//.test(e))throw new Error("Peer URL must start with http:// or https://");if(!a)throw new Error("Peer name is required.");let{summary:r}=T(o=>{if(o.mesh=o.mesh||{enabled:!0,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},o.mesh.enabled=!0,o.mesh.peers=Array.isArray(o.mesh.peers)?o.mesh.peers:[],o.mesh.peers.find(i=>i.url===e))throw new Error(`Peer at ${e} already registered.`);let s={url:e,name:a};return n&&(s.token=n),o.mesh.peers.push(s),`added mesh peer "${a}"`});return{summary:r}}function kn(t){let e=String(t?.url||"").trim().replace(/\/+$/,"");if(!e)throw new Error("Peer URL is required.");let{summary:a}=T(n=>{let r=(n.mesh?.peers||[]).length;if(n.mesh=n.mesh||{enabled:!1,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},n.mesh.peers=(n.mesh.peers||[]).filter(o=>o.url.replace(/\/+$/,"")!==e),n.mesh.peers.length===r)throw new Error(`Peer at ${e} not found.`);return`removed mesh peer ${e}`});return{summary:a}}function _n(t){let e=!!t?.enabled,{summary:a}=T(n=>(n.mesh=n.mesh||{enabled:e,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},n.mesh.enabled=e,`mesh ${e?"enabled":"disabled"}`));return{summary:a}}function En(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let{summary:a}=T(n=>{let r=(n.webhooks||[]).length;if(n.webhooks=(n.webhooks||[]).filter(o=>o.id!==e),n.webhooks.length===r)throw new Error(`Webhook "${e}" not found.`);return`removed webhook "${e}"`});return{summary:a}}function Sn(t){let e=String(t?.botTokenEnv||"").trim(),a=String(t?.appTokenEnv||"").trim(),n=String(t?.agentBinding||"").trim();if(!e)throw new Error("Bot token env-var name is required (e.g. SLACK_BOT_TOKEN).");if(!a)throw new Error("App-level token env-var name is required (e.g. SLACK_APP_TOKEN).");let{summary:r}=T(o=>{if(o.channels=o.channels||{},o.channels.slack=o.channels.slack||{enabled:!1},o.channels.slack.enabled=!0,o.channels.slack.botToken="${"+e+"}",o.channels.slack.appToken="${"+a+"}",n){if(!o.agents?.[n])throw new Error(`Unknown agent "${n}".`);o.channels.slack.agentBinding=n}return"configured slack connector"});return{summary:r,hint:`Add ${e}=xoxb-\u2026 and ${a}=xapp-\u2026 to your .env.`}}function Tn(t){let e=!!t?.enabled,{summary:a}=T(n=>(n.channels=n.channels||{},n.channels.slack=n.channels.slack||{enabled:!1},n.channels.slack.enabled=e,`slack ${e?"enabled":"disabled"}`));return{summary:a}}function Cn(t){let e=String(t?.tokenEnv||"").trim(),a=String(t?.agentBinding||"").trim();if(!e)throw new Error("Bot token env-var name is required (e.g. DISCORD_BOT_TOKEN).");let{summary:n}=T(r=>{if(r.channels=r.channels||{},r.channels.discord=r.channels.discord||{enabled:!1},r.channels.discord.enabled=!0,r.channels.discord.token="${"+e+"}",a){if(!r.agents?.[a])throw new Error(`Unknown agent "${a}".`);r.channels.discord.agentBinding=a}return"configured discord connector"});return{summary:n,hint:`Add ${e}=<bot-token> to your .env.`}}function An(t){let e=!!t?.enabled,{summary:a}=T(n=>(n.channels=n.channels||{},n.channels.discord=n.channels.discord||{enabled:!1},n.channels.discord.enabled=e,`discord ${e?"enabled":"disabled"}`));return{summary:a}}function $n(t){let e=String(t?.host||"").trim().replace(/\/+$/,""),a=String(t?.tokenEnv||"").trim(),n=parseInt(String(t?.webhookPort||"18810"),10);if(!e||!/^https?:\/\//.test(e))throw new Error("Host must start with http:// or https://");if(!a)throw new Error("Admin token env-var name is required (e.g. GITLAB_TOKEN).");if(!Number.isFinite(n)||n<1||n>65535)throw new Error("Webhook port must be between 1 and 65535.");let{summary:r}=T(o=>(o.channels=o.channels||{},o.channels.gitlab=o.channels.gitlab||{enabled:!1,routes:[],agentMappings:[]},o.channels.gitlab.enabled=!0,o.channels.gitlab.host=e,o.channels.gitlab.token="${"+a+"}",o.channels.gitlab.webhookPort=n,"configured gitlab connector"));return{summary:r,hint:`Add ${a}=<personal-access-token> to your .env. Per-project routes + per-agent tokens stay in the Advanced JSON editor.`}}function Mn(t){let e=!!t?.enabled,{summary:a}=T(n=>(n.channels=n.channels||{},n.channels.gitlab=n.channels.gitlab||{enabled:!1,routes:[],agentMappings:[]},n.channels.gitlab.enabled=e,`gitlab ${e?"enabled":"disabled"}`));return{summary:a}}async function In(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-B2BQPV4M.js"),n;try{n=(await import("cronstrue")).default.toString(e,{use24HourTimeFormat:!1})}catch(i){throw new Error(`Invalid cron: ${i.message||"unknown"}`)}let r=Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC",o=[],s=new Date;try{for(let i=0;i<3;i++)s=a(e,s,r),o.push(s.toISOString())}catch(i){throw new Error(`Cron preview failed: ${i.message}`)}return{human:n,next:o,timezone:r}}function Ln(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let{summary:a}=T(n=>{if(!n.channels?.telegram?.accounts?.[e])throw new Error(`Account "${e}" not found.`);return delete n.channels.telegram.accounts[e],`removed telegram account "${e}"`});return{summary:a}}function Dn(t){let e=!!t?.enabled,{summary:a}=T(n=>(n.channels=n.channels||{},n.channels.telegram=n.channels.telegram||{enabled:!1,accounts:{},policy:{dm:"pair",group:"mention-required"}},n.channels.telegram.enabled=e,`telegram ${e?"enabled":"disabled"}`));return{summary:a}}function Pn(t){let e=String(t?.id||"").trim(),a=String(t?.schedule||"").trim(),n=String(t?.agent||"").trim(),r=String(t?.prompt||"").trim();if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Cron id must be lowercase (letters, digits, -, _).");if(!a)throw new Error("Cron expression is required (e.g. '0 9 * * 1' for Mondays at 9am).");if(!n)throw new Error("Pick an agent to run this schedule.");if(!r)throw new Error("A prompt is required (what should the agent do?).");let{summary:o}=T(s=>{if(s.crons=s.crons||{},s.crons[e])throw new Error(`Cron "${e}" already exists.`);if(!s.agents?.[n])throw new Error(`Unknown agent "${n}".`);return s.crons[e]={schedule:a,agent:n,prompt:r,enabled:!0},`added cron "${e}"`});return{summary:o}}function Rn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Cron id is required.");let{summary:a}=T(n=>{if(!n.crons?.[e])throw new Error(`Cron "${e}" not found.`);return delete n.crons[e],`removed cron "${e}"`});return{summary:a}}function Hn(t){let e=String(t?.raw||"");if(!e.trim())throw new Error("Config body is empty.");let a;try{a=JSON.parse(e)}catch(o){throw new Error(`Invalid JSON: ${o.message}`)}let n=oe(process.cwd(),"agentx.json"),r=`${n}.bak.${Date.now()}`;if(Se(n))try{Ya(n,r)}catch{}Nt(n,JSON.stringify(a,null,2)+`
3590
+ `,"utf-8");try{let s=z().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${s}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:r}}function Ft(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function se(){let{ActorStore:t}=await import("./store-BAPDZHXE.js");return new t}async function On(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim();if(!e.startsWith("actor:"))throw new Error("id must start with 'actor:'");if(!a)throw new Error("name required");let n=Array.isArray(t?.channels)?t.channels:[];if(n.length===0)throw new Error("at least one channel handle required");let o=(await se()).saveActor({id:e,name:a,email:t?.email||void 0,channels:n.map(s=>({channel:s.channel,handle:String(s.handle||"").trim(),preferredForTasks:!!s.preferredForTasks})).filter(s=>s.handle),timezone:t?.timezone||void 0});return{summary:`Actor ${o.id} saved`,actor:o}}async function Nn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");if(!(await se()).deleteActor(e))throw new Error(`actor ${e} not found`);return{summary:`Actor ${e} deleted`}}async function Bn(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim();if(!e.startsWith("role:"))throw new Error("id must start with 'role:'");if(!a)throw new Error("name required");let n=t?.assignmentStrategy||"first-available",r=await se(),o=r.getRole(e),s=r.saveRole({id:e,name:a,members:Array.isArray(t?.members)?t.members:o?.members||[],assignmentStrategy:n,rotationCursor:o?.rotationCursor??0});return{summary:`Role ${s.id} saved`,role:s}}async function jn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");if(!(await se()).deleteRole(e))throw new Error(`role ${e} not found`);return{summary:`Role ${e} deleted`}}async function zn(t){let e=String(t?.role||"").trim(),a=String(t?.member||"").trim();if(!e.startsWith("role:"))throw new Error("role required");if(!a.startsWith("actor:")&&!a.startsWith("role:"))throw new Error("member must be actor:<id> or role:<id>");let n=await se(),r=n.getRole(e);if(!r)throw new Error(`role ${e} not found`);let o=a.startsWith("actor:")?{actor:a}:{role:a};if(r.members.some(l=>("actor"in l?l.actor:l.role)===a))return{summary:`${a} already in ${e}`,role:r};let i=n.saveRole({...r,members:[...r.members,o]});return{summary:`${a} granted to ${e}`,role:i}}async function qn(t){let e=String(t?.role||"").trim(),a=String(t?.member||"").trim();if(!e.startsWith("role:"))throw new Error("role required");let n=await se(),r=n.getRole(e);if(!r)throw new Error(`role ${e} not found`);let o=r.members.filter(i=>("actor"in i?i.actor:i.role)!==a);if(o.length===r.members.length)return{summary:`${a} not in ${e}`,role:r};let s=n.saveRole({...r,members:o});return{summary:`${a} revoked from ${e}`,role:s}}async function Fn(t){let e=String(t?.agentId||"").trim(),a=String(t?.role||"").trim();if(!e)throw new Error("agentId required");if(!a)throw new Error("role required");let n=Array.isArray(t?.days)&&t.days.length>0?t.days:["mon","tue","wed","thu","fri"],r=String(t?.start||"09:00"),o=String(t?.end||"17:00"),s=t?.reportsTo?String(t.reportsTo).trim():"",i=typeof t?.utilizationTarget=="number"?t.utilizationTarget:.8,{summary:l}=T(d=>(d.business=d.business||{},d.business.orgChart=d.business.orgChart||{},d.business.orgChart[e]={role:a,...s?{reportsTo:s}:{},schedule:{days:n,start:r,end:o},utilizationTarget:i},`orgChart "${e}" upserted`));return{summary:l}}async function Wn(t){let e=String(t?.agentId||"").trim();if(!e)throw new Error("agentId required");let{summary:a}=T(n=>{if(!n.business?.orgChart||!(e in n.business.orgChart))throw new Error(`no orgChart entry for "${e}"`);return delete n.business.orgChart[e],`orgChart "${e}" removed`});return{summary:a}}async function Gn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let a=t?.pm?String(t.pm).trim():"",n=t?.client?String(t.client).trim():"",{summary:r}=T(o=>{o.business=o.business||{},o.business.projects=o.business.projects||[];let s=o.business.projects.findIndex(l=>l.id===e),i={id:e,...a?{pm:a}:{},...n?{client:n}:{}};return s>=0?o.business.projects[s]={...o.business.projects[s],...i}:o.business.projects.push(i),s>=0?`project "${e}" updated`:`project "${e}" added`});return{summary:r}}async function Un(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let{summary:a}=T(n=>{let r=n.business?.projects||[],o=r.length;if(n.business.projects=r.filter(s=>s.id!==e),n.business.projects.length===o)throw new Error(`no project "${e}"`);return`project "${e}" removed`});return{summary:a}}async function Kn(t){let e=String(t?.client||"").trim();if(!e)throw new Error("client required");if(!t?.chatId&&!t?.username&&!t?.senderId)throw new Error("one of chatId / username / senderId required");let{summary:a}=T(n=>{n.business=n.business||{},n.business.contactMap=n.business.contactMap||[];let r={client:e};t?.channel&&(r.channel=String(t.channel)),t?.chatId&&(r.chatId=String(t.chatId)),t?.username&&(r.username=String(t.username)),t?.senderId&&(r.senderId=String(t.senderId)),t?.project&&(r.project=String(t.project)),t?.displayName&&(r.displayName=String(t.displayName)),n.business.contactMap.push(r);let o=r.chatId||r.username||r.senderId;return`contact ${r.channel?r.channel+"/":""}${o} \u2192 ${e} added`});return{summary:a}}async function Jn(t){let a=["channel","chatId","username","senderId"].filter(r=>t?.[r]);if(a.length===0)throw new Error("at least one filter (channel/chatId/username/senderId) required");let{summary:n}=T(r=>{let o=r.business?.contactMap||[],s=o.length;if(r.business.contactMap=o.filter(i=>{for(let l of a)if(i[l]!==t[l])return!0;return!1}),r.business.contactMap.length===s)throw new Error("no matching contact entry");return`${s-r.business.contactMap.length} contact entry/entries removed`});return{summary:n}}async function Xn(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=String(t?.projects||"").split(/[,\n]/).map(l=>l.trim()).filter(Boolean);if(!e)throw new Error("id required");if(!a)throw new Error("name required");if(n.length===0)throw new Error("at least one project path required");let r=t?.primaryToolLabel?String(t.primaryToolLabel).trim():"",o=Number.isFinite(Number(t?.timeRangeDays))?Number(t.timeRangeDays):30,s=Number.isFinite(Number(t?.closedWindowDays))?Number(t.closedWindowDays):30,{summary:i}=T(l=>{l.boards=Array.isArray(l.boards)?l.boards:[];let d=l.boards.findIndex(u=>u.id===e),c={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(c.primaryToolLabel=r),d>=0){let u=l.boards[d];return l.boards[d]={...u,...c,columns:u.columns,labels:u.labels},`board "${e}" updated`}return l.boards.push(c),`board "${e}" added`});return{summary:i}}async function Vn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");let{summary:a}=T(n=>{let r=Array.isArray(n.boards)?n.boards:[],o=r.length;if(n.boards=r.filter(s=>s.id!==e),n.boards.length===o)throw new Error(`board "${e}" not found`);return`board "${e}" removed`});return{summary:a}}async function Yn(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"-"),n=String(t?.title||"").trim(),r=String(t?.kind||"scoped-label");if(!e)throw new Error("boardId required");if(!a)throw new Error("columnId required");if(!n)throw new Error("title required");if(!["open-backlog","scoped-label","closed","label"].includes(r))throw new Error("kind must be open-backlog | scoped-label | closed | label");let{summary:o}=T(s=>{let l=(Array.isArray(s.boards)?s.boards:[]).find(u=>u.id===e);if(!l)throw new Error(`board "${e}" not found`);l.columns=Array.isArray(l.columns)?l.columns:[];let d={id:a,title:n,kind:r,scopedPrefix:t?.scopedPrefix||"Status"};if(r==="scoped-label"){if(!t?.scopedLabel)throw new Error("scopedLabel required for kind=scoped-label");d.scopedLabel=String(t.scopedLabel)}if(r==="label"){if(!t?.mapsToLabel)throw new Error("mapsToLabel required for kind=label");d.mapsToLabel=String(t.mapsToLabel)}t?.accent&&(d.accent=String(t.accent));let c=l.columns.findIndex(u=>u.id===a);return c>=0?(l.columns[c]={...l.columns[c],...d},`column "${a}" updated`):(l.columns.push(d),`column "${a}" added to board "${e}"`)});return{summary:o}}async function Qn(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim();if(!e||!a)throw new Error("boardId and columnId required");let{summary:n}=T(r=>{let s=(Array.isArray(r.boards)?r.boards:[]).find(l=>l.id===e);if(!s)throw new Error(`board "${e}" not found`);let i=(s.columns||[]).length;if(s.columns=(s.columns||[]).filter(l=>l.id!==a),s.columns.length===i)throw new Error(`column "${a}" not found`);return`column "${a}" removed from board "${e}"`});return{summary:n}}async function Zn(t){let{ActionStore:e}=await import("./store-I3HEWVLQ.js"),{actionSchema:a}=await import("./types-Y6ZCZ52Z.js");if(!t||typeof t!="object")throw new Error("body required");let n=a.safeParse(t);if(!n.success){let o=n.error.issues[0];throw new Error(`${o.path.join(".")||"<root>"}: ${o.message}`)}let r=new e().save(n.data);return{summary:`action "${r.id}" saved (${r.kind})`,action:r}}async function er(t){let{ActionStore:e}=await import("./store-I3HEWVLQ.js"),a=String(t?.id||"").trim();if(!a)throw new Error("id required");if(!new e().delete(a))throw new Error(`action "${a}" not found`);return{summary:`action "${a}" removed`}}async function tr(t){let{ActionStore:e}=await import("./store-I3HEWVLQ.js"),{runAction:a}=await import("./runner-BFYDWPUO.js"),n=String(t?.id||"").trim();if(!n)throw new Error("id required");let r=new e().get(n);if(!r)throw new Error(`action "${n}" not found`);let o=t?.inputs&&typeof t.inputs=="object"?t.inputs:{},s=await a(r,o);return{summary:`action "${n}" ${s.ok?"ok":"failed"} (${s.durationMs}ms)`,result:s}}async function ar(t){let e=t?.interval!==void 0?Number(t.interval):void 0,a=t?.timeout!==void 0?Number(t.timeout):void 0;if(e!==void 0&&(!Number.isFinite(e)||e<5||e>3600))throw new Error("interval must be 5..3600 seconds");if(a!==void 0&&(!Number.isFinite(a)||a<1||a>60))throw new Error("timeout must be 1..60 seconds");if(e===void 0&&a===void 0)throw new Error("nothing to update");let{summary:n}=T(r=>(r.mesh=r.mesh||{},r.mesh.healthCheck=r.mesh.healthCheck||{},e!==void 0&&(r.mesh.healthCheck.interval=e),a!==void 0&&(r.mesh.healthCheck.timeout=a),`mesh.healthCheck updated (interval=${r.mesh.healthCheck.interval}s, timeout=${r.mesh.healthCheck.timeout}s)`));return{summary:n}}async function nr(t){let{summary:e}=T(a=>{a.notifications=a.notifications||{};let n=[];if(t&&typeof t=="object"){if("destination"in t)if(!t.destination)delete a.notifications.destination,n.push("destination cleared");else if(t.destination.channel&&t.destination.chatId)a.notifications.destination={channel:String(t.destination.channel),chatId:String(t.destination.chatId),...t.destination.accountId?{accountId:String(t.destination.accountId)}:{}},n.push(`destination=${t.destination.channel}:${t.destination.chatId}`);else throw new Error("destination requires channel + chatId");if("on"in t&&t.on&&typeof t.on=="object"){a.notifications.on=a.notifications.on||{};for(let r of["taskComplete","taskError","taskQueued"])r in t.on&&(a.notifications.on[r]=!!t.on[r]);n.push("on="+JSON.stringify(a.notifications.on))}if("longTaskThreshold"in t){let r=Number(t.longTaskThreshold);if(!Number.isFinite(r)||r<0)throw new Error("longTaskThreshold must be a non-negative number");a.notifications.longTaskThreshold=r,n.push(`threshold=${r}s`)}}if(n.length===0)throw new Error("nothing to update");return`notifications updated (${n.join(", ")})`});return{summary:e}}async function rr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("webhook id required");let{summary:a}=T(n=>{let o=(Array.isArray(n.webhooks)?n.webhooks:[]).find(s=>s.id===e);if(!o)throw new Error(`webhook "${e}" not found`);if("triggers"in t){if(t.triggers===null||typeof t.triggers=="object"&&Object.keys(t.triggers).length===0)delete o.triggers;else if(typeof t.triggers=="object"){let s={};for(let[i,l]of Object.entries(t.triggers))typeof l=="string"&&l.trim()&&(s[String(i)]=l.trim());Object.keys(s).length===0?delete o.triggers:o.triggers=s}}return"defaultWorkflow"in t&&(t.defaultWorkflow?o.defaultWorkflow=String(t.defaultWorkflow).trim():delete o.defaultWorkflow),`webhook "${e}" triggers/defaultWorkflow updated`});return{summary:a}}import{resolve as ir}from"path";function Wt(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
3349
3591
 
3350
3592
  <div id="disabled-banner" class="banner warn" style="display:none">
3351
3593
  <b>Graph is disabled.</b> Set <code class="mono">graph.enabled: true</code>
@@ -3400,7 +3642,7 @@ ${s||"You are "+a+"."}
3400
3642
  <h2>Recent classifications</h2>
3401
3643
  <p class="muted">Last 25 log rows, newest first \u2014 approved / pending / rejected.</p>
3402
3644
  <div id="recent"></div>
3403
- </section>`;return A({title:"AgentX \xB7 Intent Graph",activeTab:"graph",subtitle:"Intent Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:tr,scripts:`${e}<script>${ar}</script>`})}var tr=`
3645
+ </section>`;return A({title:"AgentX \xB7 Intent Graph",activeTab:"graph",subtitle:"Intent Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:or,scripts:`${e}<script>${sr}</script>`})}var or=`
3404
3646
  main { max-width: 1200px; margin: 0 auto; padding: 24px 20px 60px; }
3405
3647
  h2 { margin: 0 0 12px; font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
3406
3648
  .grid { display: grid; gap: 20px; grid-template-columns: 1fr; }
@@ -3504,7 +3746,7 @@ details {
3504
3746
  border-radius: 4px; padding: 8px 12px; margin-top: 8px;
3505
3747
  }
3506
3748
  details summary { cursor: pointer; font-size: 11px; color: var(--ax-muted); user-select: none; }
3507
- details[open] summary { margin-bottom: 8px; }`,ar=`
3749
+ details[open] summary { margin-bottom: 8px; }`,sr=`
3508
3750
  const $ = (id) => document.getElementById(id);
3509
3751
  const state = { schema: null, nodes: [], pending: [], recent: [] };
3510
3752
 
@@ -3724,7 +3966,7 @@ $('btn-save-schema').addEventListener('click', async () => {
3724
3966
  $('btn-reload-schema').addEventListener('click', refresh);
3725
3967
 
3726
3968
  refresh();
3727
- `;function Wt(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ft({peers:a,localToken:n}))}async function Ut(t,e,a){try{let n=t.method==="GET"?void 0:await ur(t),r=rr(),o={"GET /api/admin/graph/state":()=>or(r),"POST /api/admin/graph/classifications/approve":()=>sr(r,n),"POST /api/admin/graph/classifications/reject":()=>ir(r,n),"POST /api/admin/graph/nodes":()=>lr(r,n),"PATCH /api/admin/graph/nodes":()=>dr(r,n),"DELETE /api/admin/graph/nodes":()=>cr(r,n),"PUT /api/admin/graph/schema":()=>pr(r,n)},s=`${t.method} ${a}`,i=o[s];if(!i){We(e,404,{error:`unknown graph endpoint: ${s}`});return}let l=await i();We(e,200,l)}catch(n){We(e,400,{error:n?.message||"graph op failed"})}}function rr(){let t=B(),e=nr(process.cwd(),t.graph.baseDir);return new it({baseDir:e})}function or(t){let e=B(),a=t.loadSchema(),n=t.loadNodes().nodes,r=t.readRecentClassifications(100),o=t.loadIndex().entries,s=new Map;for(let l of r)s.has(l.msgHash)||s.set(l.msgHash,l);let i=[];for(let l of s.values())l.status==="pending"&&!o[l.msgHash]&&i.push(l);return{enabled:e.graph.enabled,schema:a,nodes:n,pending:i,recent:r.slice(0,25),counts:{nodes:n.length,pending:i.length,fingerprints:Object.keys(o).length}}}function sr(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Kt(t,a);return Array.isArray(e?.path)&&e.path.length>0&&(n.path=e.path.map(r=>String(r))),e?.proposedAxes&&typeof e.proposedAxes=="object"&&(n.proposedAxes=Ue(e.proposedAxes)),t.approveClassification(n),{summary:`Approved ${n.msgHash}`}}function ir(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Kt(t,a);return t.rejectClassification(n),{summary:`Rejected ${n.msgHash}`}}function Kt(t,e){let n=t.readRecentClassifications(500).find(r=>r.msgHash===e);if(!n)throw new Error(`No classification found for ${e}`);return n}function lr(t,e){let a=Gt(String(e?.id||"")),n=String(e?.level||"").trim(),r=e?.parentId?Gt(String(e.parentId)):null,o=Ue({[a]:e?.axes||{}})[a]||{};if(!a)throw new Error("id is required");if(!n)throw new Error("level is required");let s={id:a,level:n,parentId:r,axes:o,createdAt:new Date().toISOString(),createdBy:"admin-ui"};return t.addNode(s),{node:s}}function dr(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");let n=Ue({[a]:e?.axes||{}})[a]||{};return{node:t.updateNodeAxes(a,n)}}function cr(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");return t.deleteNode(a),{summary:`Deleted ${a}`}}function pr(t,e){if(!e?.schema||typeof e.schema!="object")throw new Error("schema object is required");return t.saveSchema(e.schema),{summary:"Schema saved"}}function Ue(t){let e={};for(let[a,n]of Object.entries(t||{})){if(!n||typeof n!="object")continue;let r={};for(let[o,s]of Object.entries(n))typeof s=="string"&&(r[o]=s);e[a]=r}return e}function Gt(t){return t.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")}function We(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function ur(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}import{resolve as hr}from"path";import{existsSync as fr}from"fs";import vr from"better-sqlite3";function Jt(t={}){let e=`<div class="ax-obs">
3969
+ `;function Ut(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Wt({peers:a,localToken:n}))}async function Kt(t,e,a){try{let n=t.method==="GET"?void 0:await fr(t),r=lr(),o={"GET /api/admin/graph/state":()=>dr(r),"POST /api/admin/graph/classifications/approve":()=>cr(r,n),"POST /api/admin/graph/classifications/reject":()=>pr(r,n),"POST /api/admin/graph/nodes":()=>ur(r,n),"PATCH /api/admin/graph/nodes":()=>mr(r,n),"DELETE /api/admin/graph/nodes":()=>gr(r,n),"PUT /api/admin/graph/schema":()=>hr(r,n)},s=`${t.method} ${a}`,i=o[s];if(!i){Ue(e,404,{error:`unknown graph endpoint: ${s}`});return}let l=await i();Ue(e,200,l)}catch(n){Ue(e,400,{error:n?.message||"graph op failed"})}}function lr(){let t=z(),e=ir(process.cwd(),t.graph.baseDir);return new lt({baseDir:e})}function dr(t){let e=z(),a=t.loadSchema(),n=t.loadNodes().nodes,r=t.readRecentClassifications(100),o=t.loadIndex().entries,s=new Map;for(let l of r)s.has(l.msgHash)||s.set(l.msgHash,l);let i=[];for(let l of s.values())l.status==="pending"&&!o[l.msgHash]&&i.push(l);return{enabled:e.graph.enabled,schema:a,nodes:n,pending:i,recent:r.slice(0,25),counts:{nodes:n.length,pending:i.length,fingerprints:Object.keys(o).length}}}function cr(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Jt(t,a);return Array.isArray(e?.path)&&e.path.length>0&&(n.path=e.path.map(r=>String(r))),e?.proposedAxes&&typeof e.proposedAxes=="object"&&(n.proposedAxes=Ke(e.proposedAxes)),t.approveClassification(n),{summary:`Approved ${n.msgHash}`}}function pr(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Jt(t,a);return t.rejectClassification(n),{summary:`Rejected ${n.msgHash}`}}function Jt(t,e){let n=t.readRecentClassifications(500).find(r=>r.msgHash===e);if(!n)throw new Error(`No classification found for ${e}`);return n}function ur(t,e){let a=Gt(String(e?.id||"")),n=String(e?.level||"").trim(),r=e?.parentId?Gt(String(e.parentId)):null,o=Ke({[a]:e?.axes||{}})[a]||{};if(!a)throw new Error("id is required");if(!n)throw new Error("level is required");let s={id:a,level:n,parentId:r,axes:o,createdAt:new Date().toISOString(),createdBy:"admin-ui"};return t.addNode(s),{node:s}}function mr(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");let n=Ke({[a]:e?.axes||{}})[a]||{};return{node:t.updateNodeAxes(a,n)}}function gr(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");return t.deleteNode(a),{summary:`Deleted ${a}`}}function hr(t,e){if(!e?.schema||typeof e.schema!="object")throw new Error("schema object is required");return t.saveSchema(e.schema),{summary:"Schema saved"}}function Ke(t){let e={};for(let[a,n]of Object.entries(t||{})){if(!n||typeof n!="object")continue;let r={};for(let[o,s]of Object.entries(n))typeof s=="string"&&(r[o]=s);e[a]=r}return e}function Gt(t){return t.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")}function Ue(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function fr(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}import{resolve as xr}from"path";import{existsSync as yr}from"fs";import wr from"better-sqlite3";function Xt(t={}){let e=`<div class="ax-obs">
3728
3970
  <header class="ax-obs__head">
3729
3971
  <h1>Health</h1>
3730
3972
  <p class="ax-obs__sub">Platform-health view: what each agent ran, what failed, and how the router decided. <span class="ax-obs__sub-link">Spend lives on the <a href="/admin/cost">Cost</a> page.</span></p>
@@ -3846,7 +4088,7 @@ refresh();
3846
4088
  </div>
3847
4089
  <div id="obs-doctor-body" class="ax-obs__doctor-body"></div>
3848
4090
  </section>
3849
- </div>`;return A({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:mr,scripts:`<script>${gr}</script>`})}var mr=`
4091
+ </div>`;return A({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:vr,scripts:`<script>${br}</script>`})}var vr=`
3850
4092
  .ax-obs { padding: 16px 24px; }
3851
4093
  .ax-obs__head { margin-bottom: 16px; }
3852
4094
  .ax-obs__head h1 { margin: 0 0 4px; font-size: 18px; }
@@ -3963,7 +4205,7 @@ refresh();
3963
4205
  .ax-obs__doctor-title { font-size: 12px; font-weight: 500; }
3964
4206
  .ax-obs__doctor-detail { font-size: 11px; color: var(--ax-muted); margin-top: 2px; font-family: 'IBM Plex Mono', monospace; word-break: break-word; }
3965
4207
  .ax-obs__doctor-fix { font-size: 11px; color: var(--ax-accent, #3a7bd5); margin-top: 2px; }
3966
- `,gr=`
4208
+ `,br=`
3967
4209
  (function(){
3968
4210
  var panes = document.querySelectorAll('.ax-obs__pane');
3969
4211
  var tabs = document.querySelectorAll('.ax-obs__tab');
@@ -4347,7 +4589,7 @@ refresh();
4347
4589
 
4348
4590
  load(current);
4349
4591
  })();
4350
- `;var Xt={opus:{input:15,output:75,cacheRead:1.5,cacheCreate:18.75},sonnet:{input:3,output:15,cacheRead:.3,cacheCreate:3.75},haiku:{input:.25,output:1.25,cacheRead:.025,cacheCreate:.3125}};function Vt(t){let e=(t||"").toLowerCase();return e.includes("opus")?"opus":e.includes("haiku")?"haiku":"sonnet"}function Ke(t){let e=Xt[Vt(t.model)],a=t.input_tokens/1e6*e.input+t.output_tokens/1e6*e.output+t.cache_read_tokens/1e6*e.cacheRead+t.cache_create_tokens/1e6*e.cacheCreate,n=(t.tier2_input_tokens??0)/1e6*e.input*.5+(t.tier2_output_tokens??0)/1e6*e.output*.5+(t.tier2_cache_read_tokens??0)/1e6*e.cacheRead*.5+(t.tier2_cache_create_tokens??0)/1e6*e.cacheCreate*.5;return a+n}function br(){let t=hr(process.cwd(),".agentx/db.sqlite");if(!fr(t))return null;try{let e=new vr(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch{return null}}function Yt(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Jt({peers:a}))}function xr(t){let e=new URL(t.url||"/","http://_"),a=parseInt(e.searchParams.get("limit")||"50",10),n=Number.isFinite(a)?Math.max(1,Math.min(500,a)):50,r=e.searchParams.get("agent")||void 0;return{limit:n,agent:r&&r.length>0?r:void 0}}function J(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function Qt(t,e,a){if(!a.startsWith("/api/admin/observability/"))return!1;let n=a.replace(/^\/api\/admin\/observability\//,"").split("?")[0],r=br();if(!r)return J(e,503,{error:"operational SQLite not available",rows:[]}),!0;try{let{limit:o,agent:s}=xr(t);if(n==="routing"){let i=[],l={limit:o};s&&(i.push("agent_id = @agent"),l.agent=s);let d=`
4592
+ `;var Vt={opus:{input:15,output:75,cacheRead:1.5,cacheCreate:18.75},sonnet:{input:3,output:15,cacheRead:.3,cacheCreate:3.75},haiku:{input:.25,output:1.25,cacheRead:.025,cacheCreate:.3125}};function Yt(t){let e=(t||"").toLowerCase();return e.includes("opus")?"opus":e.includes("haiku")?"haiku":"sonnet"}function Je(t){let e=Vt[Yt(t.model)],a=t.input_tokens/1e6*e.input+t.output_tokens/1e6*e.output+t.cache_read_tokens/1e6*e.cacheRead+t.cache_create_tokens/1e6*e.cacheCreate,n=(t.tier2_input_tokens??0)/1e6*e.input*.5+(t.tier2_output_tokens??0)/1e6*e.output*.5+(t.tier2_cache_read_tokens??0)/1e6*e.cacheRead*.5+(t.tier2_cache_create_tokens??0)/1e6*e.cacheCreate*.5;return a+n}function kr(){let t=xr(process.cwd(),".agentx/db.sqlite");if(!yr(t))return null;try{let e=new wr(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch{return null}}function Qt(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Xt({peers:a}))}function _r(t){let e=new URL(t.url||"/","http://_"),a=parseInt(e.searchParams.get("limit")||"50",10),n=Number.isFinite(a)?Math.max(1,Math.min(500,a)):50,r=e.searchParams.get("agent")||void 0;return{limit:n,agent:r&&r.length>0?r:void 0}}function J(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function Zt(t,e,a){if(!a.startsWith("/api/admin/observability/"))return!1;let n=a.replace(/^\/api\/admin\/observability\//,"").split("?")[0],r=kr();if(!r)return J(e,503,{error:"operational SQLite not available",rows:[]}),!0;try{let{limit:o,agent:s}=_r(t);if(n==="routing"){let i=[],l={limit:o};s&&(i.push("agent_id = @agent"),l.agent=s);let d=`
4351
4593
  SELECT at, channel, chat_id, account_id, kind, deciding_stage, agent_id, reason
4352
4594
  FROM route_traces
4353
4595
  ${i.length?"WHERE "+i.join(" AND "):""}
@@ -4362,8 +4604,8 @@ refresh();
4362
4604
  FROM task_history
4363
4605
  WHERE ${i.join(" AND ")}
4364
4606
  ORDER BY started_at DESC LIMIT @limit
4365
- `,u=r.db.prepare(d).all(l).map(h=>({...h,plain:Zt(h.error)}));return J(e,200,{rows:u}),!0}return n==="summary"||n==="overview"?(J(e,200,yr(r.db)),!0):n==="activity"?(J(e,200,wr(r.db,{agent:s})),!0):n==="cost"?(J(e,200,kr(r.db)),!0):(J(e,404,{error:"unknown observability slice",rows:[]}),!0)}catch(o){return J(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function Zt(t){let e=String(t||"");return e?/timed out|SIGTERM|exit 143|maxExecutionMinutes/i.test(e)?"Agent ran past its time limit":/ECONNREFUSED|fetch failed|getaddrinfo|ENOTFOUND/i.test(e)?"Couldn't reach a service over the network":/401|403|Unauthorized|Forbidden|invalid token|missing scope/i.test(e)?"Authentication or permission denied":/rate limit|429|too many requests/i.test(e)?"Hit a rate limit (too many calls)":/quota|insufficient_quota/i.test(e)?"Provider account out of quota or credits":/tier-?2|tier two|200K|200,000/i.test(e)?"Hit Anthropic tier-2 billing threshold":/JSON|parse|unexpected token/i.test(e)?"Got a response in the wrong shape":/permission denied|EACCES|EPERM/i.test(e)?"File permission denied":/ENOENT|no such file/i.test(e)?"Expected file is missing":/abort|cancel/i.test(e)?"Task was cancelled before it finished":e.split(`
4366
- `)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function yr(t){let e=new Date,a=new Date(e.getFullYear(),e.getMonth(),e.getDate()).toISOString(),n=new Date(e.getTime()-864e5),r=new Date(n.getFullYear(),n.getMonth(),n.getDate()).toISOString(),o=new Date(e.getTime()-864e5).toISOString(),s=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ?").get(a).n,i=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ? AND started_at < ?").get(r,a).n,l=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE status='error' AND started_at >= ?").get(a).n,d=t.prepare("SELECT AVG(duration_ms) AS d FROM task_history WHERE status='ok' AND started_at >= ?").get(a).d??0,c=t.prepare("SELECT duration_ms FROM task_history WHERE status='ok' AND started_at >= ? AND duration_ms IS NOT NULL ORDER BY duration_ms ASC").all(a),u=T=>c.length?c[Math.min(c.length-1,Math.floor(c.length*T))].duration_ms:0,h=u(.5),x=u(.95),m=t.prepare("SELECT * FROM usage_daily WHERE day = date('now')").all().reduce((T,M)=>T+Ke(M),0),f=t.prepare("SELECT * FROM usage_daily WHERE day = date('now', '-1 day')").all().reduce((T,M)=>T+Ke(M),0),w=t.prepare(`
4607
+ `,u=r.db.prepare(d).all(l).map(h=>({...h,plain:ea(h.error)}));return J(e,200,{rows:u}),!0}return n==="summary"||n==="overview"?(J(e,200,Er(r.db)),!0):n==="activity"?(J(e,200,Sr(r.db,{agent:s})),!0):n==="cost"?(J(e,200,Tr(r.db)),!0):(J(e,404,{error:"unknown observability slice",rows:[]}),!0)}catch(o){return J(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function ea(t){let e=String(t||"");return e?/timed out|SIGTERM|exit 143|maxExecutionMinutes/i.test(e)?"Agent ran past its time limit":/ECONNREFUSED|fetch failed|getaddrinfo|ENOTFOUND/i.test(e)?"Couldn't reach a service over the network":/401|403|Unauthorized|Forbidden|invalid token|missing scope/i.test(e)?"Authentication or permission denied":/rate limit|429|too many requests/i.test(e)?"Hit a rate limit (too many calls)":/quota|insufficient_quota/i.test(e)?"Provider account out of quota or credits":/tier-?2|tier two|200K|200,000/i.test(e)?"Hit Anthropic tier-2 billing threshold":/JSON|parse|unexpected token/i.test(e)?"Got a response in the wrong shape":/permission denied|EACCES|EPERM/i.test(e)?"File permission denied":/ENOENT|no such file/i.test(e)?"Expected file is missing":/abort|cancel/i.test(e)?"Task was cancelled before it finished":e.split(`
4608
+ `)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function Er(t){let e=new Date,a=new Date(e.getFullYear(),e.getMonth(),e.getDate()).toISOString(),n=new Date(e.getTime()-864e5),r=new Date(n.getFullYear(),n.getMonth(),n.getDate()).toISOString(),o=new Date(e.getTime()-864e5).toISOString(),s=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ?").get(a).n,i=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ? AND started_at < ?").get(r,a).n,l=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE status='error' AND started_at >= ?").get(a).n,d=t.prepare("SELECT AVG(duration_ms) AS d FROM task_history WHERE status='ok' AND started_at >= ?").get(a).d??0,c=t.prepare("SELECT duration_ms FROM task_history WHERE status='ok' AND started_at >= ? AND duration_ms IS NOT NULL ORDER BY duration_ms ASC").all(a),u=C=>c.length?c[Math.min(c.length-1,Math.floor(c.length*C))].duration_ms:0,h=u(.5),y=u(.95),m=t.prepare("SELECT * FROM usage_daily WHERE day = date('now')").all().reduce((C,M)=>C+Je(M),0),f=t.prepare("SELECT * FROM usage_daily WHERE day = date('now', '-1 day')").all().reduce((C,M)=>C+Je(M),0),k=t.prepare(`
4367
4609
  SELECT agent_id,
4368
4610
  COUNT(*) AS tasks,
4369
4611
  SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors,
@@ -4381,12 +4623,12 @@ refresh();
4381
4623
  WHERE started_at >= ?
4382
4624
  GROUP BY channel
4383
4625
  ORDER BY tasks DESC
4384
- `).all(a),g=t.prepare("SELECT DISTINCT agent_id FROM usage_daily WHERE day >= date('now', '-7 day')").all().map(T=>T.agent_id),v=new Set(t.prepare("SELECT DISTINCT agent_id FROM task_history WHERE started_at >= ?").all(o).map(T=>T.agent_id)),C=g.filter(T=>!v.has(T)),_=t.prepare(`
4626
+ `).all(a),w=t.prepare("SELECT DISTINCT agent_id FROM usage_daily WHERE day >= date('now', '-7 day')").all().map(C=>C.agent_id),g=new Set(t.prepare("SELECT DISTINCT agent_id FROM task_history WHERE started_at >= ?").all(o).map(C=>C.agent_id)),v=w.filter(C=>!g.has(C)),E=t.prepare(`
4385
4627
  SELECT started_at, agent_id, channel, message_preview, error
4386
4628
  FROM task_history
4387
4629
  WHERE status='error' AND started_at >= ?
4388
4630
  ORDER BY started_at DESC LIMIT 5
4389
- `).all(o).map(T=>({...T,plain:Zt(T.error)}));return{kpis:{tasksToday:s,tasksDelta:s-i,errorsToday:l,errorRate:s>0?l/s:0,avgDurationMs:Math.round(d),p50DurationMs:h,p95DurationMs:x,spendToday:m,spendDelta:m-f,idleAgentCount:C.length},perAgent:w,perChannel:b,idleAgents:C,recentErrors:_}}function wr(t,e){let a=new Date(Date.now()-864e5).toISOString(),n=new Date(Date.now()-7*864e5).toISOString(),r=e.agent?"AND agent_id = @agent":"",o=e.agent?{agent:e.agent}:{},s=t.prepare(`
4631
+ `).all(o).map(C=>({...C,plain:ea(C.error)}));return{kpis:{tasksToday:s,tasksDelta:s-i,errorsToday:l,errorRate:s>0?l/s:0,avgDurationMs:Math.round(d),p50DurationMs:h,p95DurationMs:y,spendToday:m,spendDelta:m-f,idleAgentCount:v.length},perAgent:k,perChannel:b,idleAgents:v,recentErrors:E}}function Sr(t,e){let a=new Date(Date.now()-864e5).toISOString(),n=new Date(Date.now()-7*864e5).toISOString(),r=e.agent?"AND agent_id = @agent":"",o=e.agent?{agent:e.agent}:{},s=t.prepare(`
4390
4632
  SELECT strftime('%Y-%m-%dT%H:00', started_at) AS hour,
4391
4633
  COUNT(*) AS tasks,
4392
4634
  SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors
@@ -4413,7 +4655,7 @@ refresh();
4413
4655
  WHERE started_at >= @since
4414
4656
  GROUP BY agent_id
4415
4657
  ORDER BY tasks_24h DESC, tasks_7d DESC
4416
- `).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function kr(t){let e=t.prepare(`
4658
+ `).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function Tr(t){let e=t.prepare(`
4417
4659
  SELECT day, agent_id, model,
4418
4660
  input_tokens, output_tokens, cache_read_tokens, cache_create_tokens,
4419
4661
  tier2_input_tokens, tier2_output_tokens, tier2_cache_read_tokens, tier2_cache_create_tokens,
@@ -4421,17 +4663,17 @@ refresh();
4421
4663
  FROM usage_daily
4422
4664
  WHERE day >= date('now', '-30 day')
4423
4665
  ORDER BY day
4424
- `).all(),a=new Date().toISOString().slice(0,10),n=new Date(Date.now()-864e5).toISOString().slice(0,10),r=new Date(Date.now()-7*864e5).toISOString().slice(0,10),o=0,s=0,i=0,l=0,d=0,c=0,u={},h={};for(let m of e){let f=Ke(m);l+=f,m.day>=r&&(i+=f),m.day===a&&(o+=f),m.day===n&&(s+=f),u[m.day]=(u[m.day]||0)+f;let w=Vt(m.model),b=Xt[w],g=(m.tier2_input_tokens||0)/1e6*b.input*.5+(m.tier2_output_tokens||0)/1e6*b.output*.5+(m.tier2_cache_read_tokens||0)/1e6*b.cacheRead*.5+(m.tier2_cache_create_tokens||0)/1e6*b.cacheCreate*.5;m.day===a&&(d+=g),m.day>=r&&(c+=g);let v=h[m.agent_id]||(h[m.agent_id]={spend:0,tasks:0,tier2:0});v.spend+=f,v.tasks+=m.tasks||0,v.tier2+=g}let x=Object.entries(h).map(([m,f])=>({agent_id:m,spend:f.spend,tasks:f.tasks,tier2:f.tier2})).sort((m,f)=>f.spend-m.spend),p=Object.entries(u).map(([m,f])=>({day:m,spend:f})).sort((m,f)=>m.day<f.day?-1:1);return{kpis:{spendToday:o,spendYesterday:s,spend7d:i,spend30d:l,tier2Today:d,tier2_7d:c,tier2PctToday:o>0?d/o:0},trend:p,perAgent:x}}import{resolve as _r}from"path";import{existsSync as Er}from"fs";import Sr from"better-sqlite3";function Tr(){let t=_r(process.cwd(),".agentx/intent/ledger.sqlite");if(!Er(t))return null;try{let e=new Sr(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch{return null}}function Z(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Cr(t){if(!t)return;let e=String(t).trim().match(/^(\d+)\s*(s|m|h|d|w)?$/i);if(!e)return;let a=parseInt(e[1],10),n=(e[2]||"h").toLowerCase(),r=n==="s"?1e3:n==="m"?6e4:n==="h"?36e5:n==="d"?864e5:n==="w"?7*864e5:0;return Date.now()-a*r}async function ea(t,e,a){if(!a.startsWith("/api/admin/ledger/"))return!1;let n=a.replace(/^\/api\/admin\/ledger\//,"").split("?")[0],r=Tr();if(!r)return Z(e,503,{error:"intent ledger not available",rows:[]}),!0;try{let o=new URL(t.url||"/","http://_"),s=Cr(o.searchParams.get("since")),i=o.searchParams.get("source")||"",l=o.searchParams.get("project")||"",d=parseInt(o.searchParams.get("limit")||"50",10),c=Number.isFinite(d)?Math.max(1,Math.min(500,d)):50;if(n==="stats"){let u=s!==void 0?"WHERE ts >= @since":"",h=s!==void 0?"WHERE decided_at >= @since":"",x=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_events ${u} GROUP BY source ORDER BY n DESC`).all({since:s}),p=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_decisions ${h}`).get({since:s}).n,m=r.db.prepare(`SELECT outcome, COUNT(*) AS n FROM intent_decisions ${h} GROUP BY outcome ORDER BY n DESC`).all({since:s}),f=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_divergences ${u}`).get({since:s}).n,w=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_divergences ${u} GROUP BY source ORDER BY n DESC`).all({since:s}),b=r.db.prepare(`
4666
+ `).all(),a=new Date().toISOString().slice(0,10),n=new Date(Date.now()-864e5).toISOString().slice(0,10),r=new Date(Date.now()-7*864e5).toISOString().slice(0,10),o=0,s=0,i=0,l=0,d=0,c=0,u={},h={};for(let m of e){let f=Je(m);l+=f,m.day>=r&&(i+=f),m.day===a&&(o+=f),m.day===n&&(s+=f),u[m.day]=(u[m.day]||0)+f;let k=Yt(m.model),b=Vt[k],w=(m.tier2_input_tokens||0)/1e6*b.input*.5+(m.tier2_output_tokens||0)/1e6*b.output*.5+(m.tier2_cache_read_tokens||0)/1e6*b.cacheRead*.5+(m.tier2_cache_create_tokens||0)/1e6*b.cacheCreate*.5;m.day===a&&(d+=w),m.day>=r&&(c+=w);let g=h[m.agent_id]||(h[m.agent_id]={spend:0,tasks:0,tier2:0});g.spend+=f,g.tasks+=m.tasks||0,g.tier2+=w}let y=Object.entries(h).map(([m,f])=>({agent_id:m,spend:f.spend,tasks:f.tasks,tier2:f.tier2})).sort((m,f)=>f.spend-m.spend),p=Object.entries(u).map(([m,f])=>({day:m,spend:f})).sort((m,f)=>m.day<f.day?-1:1);return{kpis:{spendToday:o,spendYesterday:s,spend7d:i,spend30d:l,tier2Today:d,tier2_7d:c,tier2PctToday:o>0?d/o:0},trend:p,perAgent:y}}import{resolve as Cr}from"path";import{existsSync as Ar}from"fs";import $r from"better-sqlite3";function Mr(){let t=Cr(process.cwd(),".agentx/intent/ledger.sqlite");if(!Ar(t))return null;try{let e=new $r(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch{return null}}function Z(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Ir(t){if(!t)return;let e=String(t).trim().match(/^(\d+)\s*(s|m|h|d|w)?$/i);if(!e)return;let a=parseInt(e[1],10),n=(e[2]||"h").toLowerCase(),r=n==="s"?1e3:n==="m"?6e4:n==="h"?36e5:n==="d"?864e5:n==="w"?7*864e5:0;return Date.now()-a*r}async function ta(t,e,a){if(!a.startsWith("/api/admin/ledger/"))return!1;let n=a.replace(/^\/api\/admin\/ledger\//,"").split("?")[0],r=Mr();if(!r)return Z(e,503,{error:"intent ledger not available",rows:[]}),!0;try{let o=new URL(t.url||"/","http://_"),s=Ir(o.searchParams.get("since")),i=o.searchParams.get("source")||"",l=o.searchParams.get("project")||"",d=parseInt(o.searchParams.get("limit")||"50",10),c=Number.isFinite(d)?Math.max(1,Math.min(500,d)):50;if(n==="stats"){let u=s!==void 0?"WHERE ts >= @since":"",h=s!==void 0?"WHERE decided_at >= @since":"",y=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_events ${u} GROUP BY source ORDER BY n DESC`).all({since:s}),p=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_decisions ${h}`).get({since:s}).n,m=r.db.prepare(`SELECT outcome, COUNT(*) AS n FROM intent_decisions ${h} GROUP BY outcome ORDER BY n DESC`).all({since:s}),f=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_divergences ${u}`).get({since:s}).n,k=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_divergences ${u} GROUP BY source ORDER BY n DESC`).all({since:s}),b=r.db.prepare(`
4425
4667
  SELECT COUNT(*) AS n FROM intent_decisions d
4426
4668
  LEFT JOIN intent_resolutions r
4427
4669
  ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
4428
4670
  WHERE d.outcome = 'dispatched' AND r.decision_event_id IS NULL
4429
- `).get().n;return Z(e,200,{since:s??null,eventsBySource:x,totalDecisions:p,decisionsByOutcome:m,totalDivergences:f,divergencesBySource:w,inFlight:b}),!0}if(n==="events"){let u=[],h={limit:c};s!==void 0&&(u.push("ts >= @since"),h.since=s),i&&(u.push("source = @source"),h.source=i),l&&(u.push("project = @project"),h.project=l);let x=`
4671
+ `).get().n;return Z(e,200,{since:s??null,eventsBySource:y,totalDecisions:p,decisionsByOutcome:m,totalDivergences:f,divergencesBySource:k,inFlight:b}),!0}if(n==="events"){let u=[],h={limit:c};s!==void 0&&(u.push("ts >= @since"),h.since=s),i&&(u.push("source = @source"),h.source=i),l&&(u.push("project = @project"),h.project=l);let y=`
4430
4672
  SELECT id, ts, source, source_event_id, project, subject, intent
4431
4673
  FROM intent_events
4432
4674
  ${u.length?"WHERE "+u.join(" AND "):""}
4433
4675
  ORDER BY ts DESC LIMIT @limit
4434
- `;return Z(e,200,{rows:r.db.prepare(x).all(h)}),!0}if(n==="divergences"){let u=[],h={limit:c};s!==void 0&&(u.push("ts >= @since"),h.since=s),i&&(u.push("source = @source"),h.source=i);let x=`
4676
+ `;return Z(e,200,{rows:r.db.prepare(y).all(h)}),!0}if(n==="divergences"){let u=[],h={limit:c};s!==void 0&&(u.push("ts >= @since"),h.since=s),i&&(u.push("source = @source"),h.source=i);let y=`
4435
4677
  SELECT ts, source, decided_by,
4436
4678
  legacy_agent_id, legacy_outcome, legacy_reason,
4437
4679
  ledger_agent_id, ledger_outcome, ledger_reason,
@@ -4439,7 +4681,7 @@ refresh();
4439
4681
  FROM intent_divergences
4440
4682
  ${u.length?"WHERE "+u.join(" AND "):""}
4441
4683
  ORDER BY ts DESC LIMIT @limit
4442
- `;return Z(e,200,{rows:r.db.prepare(x).all(h)}),!0}if(n==="active"){let u=["d.outcome = 'dispatched'","r.decision_event_id IS NULL"],h={limit:c};i&&(u.push("e.source = @source"),h.source=i);let x=`
4684
+ `;return Z(e,200,{rows:r.db.prepare(y).all(h)}),!0}if(n==="active"){let u=["d.outcome = 'dispatched'","r.decision_event_id IS NULL"],h={limit:c};i&&(u.push("e.source = @source"),h.source=i);let y=`
4443
4685
  SELECT e.id AS event_id, e.ts, e.source, e.project, e.subject, e.intent,
4444
4686
  d.decided_by, d.decided_at, d.agent_id, d.reason
4445
4687
  FROM intent_decisions d
@@ -4448,7 +4690,7 @@ refresh();
4448
4690
  ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
4449
4691
  WHERE ${u.join(" AND ")}
4450
4692
  ORDER BY d.decided_at DESC LIMIT @limit
4451
- `;return Z(e,200,{rows:r.db.prepare(x).all(h)}),!0}return Z(e,404,{error:"unknown ledger slice",rows:[]}),!0}catch(o){return Z(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function ta(t={}){return A({title:"AgentX \xB7 Ledger",activeTab:"graph",subtitle:"Ledger",body:`<div class="ax-led">
4693
+ `;return Z(e,200,{rows:r.db.prepare(y).all(h)}),!0}return Z(e,404,{error:"unknown ledger slice",rows:[]}),!0}catch(o){return Z(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function aa(t={}){return A({title:"AgentX \xB7 Ledger",activeTab:"graph",subtitle:"Ledger",body:`<div class="ax-led">
4452
4694
  <header class="ax-led__head">
4453
4695
  <h1>Intent ledger</h1>
4454
4696
  <p class="ax-led__sub">Read-only view over <code>.agentx/intent/ledger.sqlite</code> \u2014 same source as <code>agentx ledger</code>. Replay and lineage live in the CLI for now.</p>
@@ -4653,7 +4895,7 @@ refresh();
4653
4895
  }
4654
4896
  load();
4655
4897
  })();
4656
- </script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function aa(t={}){return A({title:"AgentX \xB7 Cost",activeTab:"cost",subtitle:"Cost",body:`<div class="ax-cost">
4898
+ </script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function na(t={}){return A({title:"AgentX \xB7 Cost",activeTab:"cost",subtitle:"Cost",body:`<div class="ax-cost">
4657
4899
  <header class="ax-cost__head">
4658
4900
  <h1>Cost</h1>
4659
4901
  <p class="ax-cost__sub">Anthropic spend across all agents over the last 30 days. Rates: Opus $15/$75 per M, Sonnet $3/$15, Haiku $0.25/$1.25 (input/output).</p>
@@ -4768,7 +5010,7 @@ refresh();
4768
5010
  load();
4769
5011
  setInterval(load, 30000);
4770
5012
  })();
4771
- </script>`,peers:t.peers,currentPeerId:t.currentPeerId})}import{resolve as Xe,join as $r}from"path";import{existsSync as Ve,readdirSync as Mr,readFileSync as Ir}from"fs";import Lr from"better-sqlite3";function na(t={}){let e='<div id="ax-fleet-root"></div>';return A({title:"AgentX \xB7 Activity Graph",activeTab:"graph",subtitle:"Activity Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Ar,scripts:'<script src="/assets/activity-graph.global.js" defer></script>',noMain:!0})}var Ar=`
5013
+ </script>`,peers:t.peers,currentPeerId:t.currentPeerId})}import{resolve as Ve,join as Dr}from"path";import{existsSync as Ye,readdirSync as Pr,readFileSync as Rr}from"fs";import Hr from"better-sqlite3";function ra(t={}){let e='<div id="ax-fleet-root"></div>';return A({title:"AgentX \xB7 Activity Graph",activeTab:"graph",subtitle:"Activity Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Lr,scripts:'<script src="/assets/activity-graph.global.js" defer></script>',noMain:!0})}var Lr=`
4772
5014
  html, body { height: 100%; }
4773
5015
  body { margin: 0; }
4774
5016
  #ax-fleet-root { height: calc(100vh - 48px); }
@@ -4780,22 +5022,22 @@ body { margin: 0; }
4780
5022
  font: 13px/1 -apple-system, BlinkMacSystemFont, sans-serif;
4781
5023
  text-align: center;
4782
5024
  }
4783
- `;function Te(){let t=Xe(process.cwd(),".agentx/intent/ledger.sqlite");if(!Ve(t))return null;try{let e=new Lr(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch{return null}}function X(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function sa(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(na({peers:a}))}var ie={gitlab:{label:"GitLab",color:"#fc6d26"},github:{label:"GitHub",color:"#6e7681"},telegram:{label:"Telegram",color:"#0088cc"},whatsapp:{label:"WhatsApp",color:"#25d366"},slack:{label:"Slack",color:"#4a154b"},discord:{label:"Discord",color:"#5865f2"},mesh:{label:"Mesh (a2a)",color:"#bf8700"},a2a:{label:"Agent \u2192 Agent",color:"#bf8700"},cron:{label:"Cron",color:"#6b7280"},workflow:{label:"Workflow",color:"#9333ea"},api:{label:"API",color:"#3a7bd5"}};function Dr(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in ie)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in ie)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in ie)return r;let o=n?.issueEvent||n?.webhookEvent;if(o){if(o.user?.username||o.project?.path_with_namespace)return"gitlab";if(o.sender?.login)return"github"}if(e.startsWith("workflow.")){let s=e.slice(9).split("-")[0];if(s in ie)return s}return"workflow"}return t}function Pr(t){let e={mtgl:"#e07a3a",ksi:"#3a7bd5",noqta:"#10b981",hasanah:"#bc8cff","hasanah-lab":"#bc8cff",hexastack:"#06b6d4",hackathonat:"#ec775c",internal:"#6b7280",unmapped:"#d29922"};if(e[t])return e[t];let a=["#e07a3a","#3a7bd5","#10b981","#bc8cff","#ec775c","#bf8700","#5865f2","#cf222e"],n=0;for(let r=0;r<t.length;r++)n=n*31+t.charCodeAt(r)|0;return a[Math.abs(n)%a.length]}function Rr(t,e){if(!t)return!1;let a=e?.agents?.[t];return a&&typeof a.system=="boolean"?a.system:!!(t==="graph-agent"||t==="intent-classifier"||/-classifier$/.test(t))}function ia(t,e){if(!t)return"unmapped";if(e){let n=e.find(r=>r.id===t);if(n?.client)return n.client}let a=t.indexOf("/");return a>0?t.slice(0,a):t}function la(t){let e=new Map;if(!t)return e;let a=t.business;if(!a)return e;let n=a.projects??[],r=a.orgChart??{};for(let s of n){if(!s.pm)continue;let i=s.client||(s.id.includes("/")?s.id.slice(0,s.id.indexOf("/")):s.id);e.has(s.pm)||e.set(s.pm,i)}function o(s,i=new Set){if(e.has(s))return e.get(s);if(i.has(s))return;i.add(s);let l=r[s];if(!l?.reportsTo)return;let d=o(l.reportsTo,i);return d&&e.set(s,d),d}for(let s of Object.keys(r))o(s);return e}function da(t,e,a){if(!a.length)return;let n=String(e?.chatId??e?.message?.chat?.id??""),r=String(e?.sender?.username??e?.message?.from?.username??""),o=String(e?.sender?.id??e?.message?.from?.id??""),s=a.filter(i=>!i.channel||i.channel===t);for(let i of s)if(i.chatId&&n&&i.chatId===n)return i;for(let i of s)if(i.username&&r&&i.username===r)return i;for(let i of s)if(i.senderId&&o&&i.senderId===o)return i;for(let i of s)if(!i.chatId&&!i.username&&!i.senderId&&i.channel===t)return i}function Or(t,e,a){if(!a||typeof a!="object")return null;if(t==="mesh"){if(typeof a.senderAgentId=="string"&&a.senderAgentId.trim()){let r=a.senderAgentId.trim();return{id:r,name:r,avatar:L(r),kind:"a2a"}}let n=a.context&&typeof a.context=="object"?a.context:null;if(n){let r=typeof n.senderUsername=="string"?n.senderUsername:null,o=typeof n.sender=="string"?n.sender:null,s=typeof n.senderId=="string"?n.senderId:null;if(o&&o.startsWith("agent:")){let l=o.slice(6);if(l&&!Je(l))return{id:l,name:l,avatar:L(l),kind:"a2a"}}let i=o||r||s;if(i&&!Je(r||o||"")){let l=r||o||s,d=e==="mesh.github"?"github":e==="mesh.gitlab"?"gitlab":e==="mesh.a2a"?"a2a":"mesh";return{id:l,name:o||r||l,avatar:L(i),kind:d}}}return e==="mesh.task"||e==="mesh.a2a"?{id:"__a2a",name:"Internal (A2A)",avatar:"\u21BB",kind:"a2a"}:null}if(t==="cron"){let n=typeof a.jobId=="string"?a.jobId:null;if(n)return{id:`cron:${n}`,name:`Cron: ${n}`,avatar:"\u23F1",kind:"cron"}}if(t==="workflow"){let n=a.event?.payload;if(n&&typeof n=="object"){if(n.sender&&typeof n.sender=="object"){let s=n.sender,i=typeof s.username=="string"?s.username:null,l=typeof s.name=="string"?s.name:null,d=i||(s.id!=null?String(s.id):null)||l;if(d&&!Je(i||l||"")){let c=typeof n.channel=="string"?n.channel:"",u=ra(c);return{id:d,name:l||i||d,avatar:L(l||i||d),kind:u}}}let o=n.issueEvent||n.webhookEvent;if(o&&typeof o=="object"){let s=o.user;if(s&&typeof s=="object"&&(s.username||s.name)){let l=s.username||s.name,d=s.name||s.username;return{id:l,name:d,avatar:L(d),kind:"gitlab"}}let i=o.sender;if(i?.login)return{id:i.login,name:i.login,avatar:L(i.login),kind:"github"}}}let r=typeof a.workflowId=="string"&&a.workflowId||typeof a.runId=="string"&&a.runId||typeof a.workflow=="string"&&a.workflow||typeof a.event?.id=="string"&&a.event.id.split(":")[0];if(r)return{id:`workflow:${r}`,name:`Workflow: ${r}`,avatar:"\u25B6",kind:"workflow"}}if(a.sender&&typeof a.sender=="object"){let n=a.sender,r=typeof n.username=="string"?n.username:null,o=typeof n.name=="string"?n.name:null,s=r||(n.id!=null?String(n.id):null)||o;if(s){let i=o||r||s;return{id:s,name:i,avatar:L(i),kind:ra(t)}}}if(t==="gitlab"){let n=a.user||a.payload?.user;if(n&&typeof n=="object"&&(n.username||n.name)){let r=n.username||n.name,o=n.name||n.username;return{id:r,name:o,avatar:L(o),kind:"gitlab"}}}if(t==="github"){let n=a.sender||a.payload?.sender;if(n?.login)return{id:n.login,name:n.login,avatar:L(n.login),kind:"github"}}if(t==="telegram"){let n=a.message?.from||a.from;if(n?.username){let r=n.first_name||n.username;return{id:n.username,name:r,avatar:L(r),kind:"telegram"}}if(n?.id)return{id:String(n.id),name:n.first_name||`tg:${n.id}`,avatar:L(n.first_name||`tg${n.id}`),kind:"telegram"}}if(t==="whatsapp"){let n=a.from||a.payload?.from;if(n){let r=String(n),o=r.replace(/@.*$/,"");return{id:r,name:o,avatar:L(o),kind:"whatsapp"}}}return null}function ra(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function Je(t){if(!t)return!1;let e=t.toLowerCase();return e==="graph-classifier"||e==="graph-agent"||e.startsWith("system:")||e.startsWith("internal:")||e.endsWith("-system")}function L(t){let e=String(t||"?").trim().split(/\s+/).filter(Boolean);return e.length>=2?(e[0][0]+e[1][0]).toUpperCase():String(t||"?").slice(0,2).toUpperCase()}function ca(t,e){if(!e||typeof e!="object")return"";let a=[];if(typeof e.text=="string"&&a.push(e.text),e.message?.text&&a.push(e.message.text),e.message?.caption&&a.push(e.message.caption),e.object_attributes?.note&&a.push(e.object_attributes.note),e.object_attributes?.title){let n=e.object_attributes.title,r=e.object_attributes.description;a.push(r?`${n}
5025
+ `;function Te(){let t=Ve(process.cwd(),".agentx/intent/ledger.sqlite");if(!Ye(t))return null;try{let e=new Hr(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch{return null}}function X(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function ia(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ra({peers:a}))}var ie={gitlab:{label:"GitLab",color:"#fc6d26"},github:{label:"GitHub",color:"#6e7681"},telegram:{label:"Telegram",color:"#0088cc"},whatsapp:{label:"WhatsApp",color:"#25d366"},slack:{label:"Slack",color:"#4a154b"},discord:{label:"Discord",color:"#5865f2"},mesh:{label:"Mesh (a2a)",color:"#bf8700"},a2a:{label:"Agent \u2192 Agent",color:"#bf8700"},cron:{label:"Cron",color:"#6b7280"},workflow:{label:"Workflow",color:"#9333ea"},api:{label:"API",color:"#3a7bd5"}};function Or(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in ie)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in ie)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in ie)return r;let o=n?.issueEvent||n?.webhookEvent;if(o){if(o.user?.username||o.project?.path_with_namespace)return"gitlab";if(o.sender?.login)return"github"}if(e.startsWith("workflow.")){let s=e.slice(9).split("-")[0];if(s in ie)return s}return"workflow"}return t}function Nr(t){let e={mtgl:"#e07a3a",ksi:"#3a7bd5",noqta:"#10b981",hasanah:"#bc8cff","hasanah-lab":"#bc8cff",hexastack:"#06b6d4",hackathonat:"#ec775c",internal:"#6b7280",unmapped:"#d29922"};if(e[t])return e[t];let a=["#e07a3a","#3a7bd5","#10b981","#bc8cff","#ec775c","#bf8700","#5865f2","#cf222e"],n=0;for(let r=0;r<t.length;r++)n=n*31+t.charCodeAt(r)|0;return a[Math.abs(n)%a.length]}function Br(t,e){if(!t)return!1;let a=e?.agents?.[t];return a&&typeof a.system=="boolean"?a.system:!!(t==="graph-agent"||t==="intent-classifier"||/-classifier$/.test(t))}function la(t,e){if(!t)return"unmapped";if(e){let n=e.find(r=>r.id===t);if(n?.client)return n.client}let a=t.indexOf("/");return a>0?t.slice(0,a):t}function da(t){let e=new Map;if(!t)return e;let a=t.business;if(!a)return e;let n=a.projects??[],r=a.orgChart??{};for(let s of n){if(!s.pm)continue;let i=s.client||(s.id.includes("/")?s.id.slice(0,s.id.indexOf("/")):s.id);e.has(s.pm)||e.set(s.pm,i)}function o(s,i=new Set){if(e.has(s))return e.get(s);if(i.has(s))return;i.add(s);let l=r[s];if(!l?.reportsTo)return;let d=o(l.reportsTo,i);return d&&e.set(s,d),d}for(let s of Object.keys(r))o(s);return e}function ca(t,e,a){if(!a.length)return;let n=String(e?.chatId??e?.message?.chat?.id??""),r=String(e?.sender?.username??e?.message?.from?.username??""),o=String(e?.sender?.id??e?.message?.from?.id??""),s=a.filter(i=>!i.channel||i.channel===t);for(let i of s)if(i.chatId&&n&&i.chatId===n)return i;for(let i of s)if(i.username&&r&&i.username===r)return i;for(let i of s)if(i.senderId&&o&&i.senderId===o)return i;for(let i of s)if(!i.chatId&&!i.username&&!i.senderId&&i.channel===t)return i}function jr(t,e,a){if(!a||typeof a!="object")return null;if(t==="mesh"){if(typeof a.senderAgentId=="string"&&a.senderAgentId.trim()){let r=a.senderAgentId.trim();return{id:r,name:r,avatar:L(r),kind:"a2a"}}let n=a.context&&typeof a.context=="object"?a.context:null;if(n){let r=typeof n.senderUsername=="string"?n.senderUsername:null,o=typeof n.sender=="string"?n.sender:null,s=typeof n.senderId=="string"?n.senderId:null;if(o&&o.startsWith("agent:")){let l=o.slice(6);if(l&&!Xe(l))return{id:l,name:l,avatar:L(l),kind:"a2a"}}let i=o||r||s;if(i&&!Xe(r||o||"")){let l=r||o||s,d=e==="mesh.github"?"github":e==="mesh.gitlab"?"gitlab":e==="mesh.a2a"?"a2a":"mesh";return{id:l,name:o||r||l,avatar:L(i),kind:d}}}return e==="mesh.task"||e==="mesh.a2a"?{id:"__a2a",name:"Internal (A2A)",avatar:"\u21BB",kind:"a2a"}:null}if(t==="cron"){let n=typeof a.jobId=="string"?a.jobId:null;if(n)return{id:`cron:${n}`,name:`Cron: ${n}`,avatar:"\u23F1",kind:"cron"}}if(t==="workflow"){let n=a.event?.payload;if(n&&typeof n=="object"){if(n.sender&&typeof n.sender=="object"){let s=n.sender,i=typeof s.username=="string"?s.username:null,l=typeof s.name=="string"?s.name:null,d=i||(s.id!=null?String(s.id):null)||l;if(d&&!Xe(i||l||"")){let c=typeof n.channel=="string"?n.channel:"",u=oa(c);return{id:d,name:l||i||d,avatar:L(l||i||d),kind:u}}}let o=n.issueEvent||n.webhookEvent;if(o&&typeof o=="object"){let s=o.user;if(s&&typeof s=="object"&&(s.username||s.name)){let l=s.username||s.name,d=s.name||s.username;return{id:l,name:d,avatar:L(d),kind:"gitlab"}}let i=o.sender;if(i?.login)return{id:i.login,name:i.login,avatar:L(i.login),kind:"github"}}}let r=typeof a.workflowId=="string"&&a.workflowId||typeof a.runId=="string"&&a.runId||typeof a.workflow=="string"&&a.workflow||typeof a.event?.id=="string"&&a.event.id.split(":")[0];if(r)return{id:`workflow:${r}`,name:`Workflow: ${r}`,avatar:"\u25B6",kind:"workflow"}}if(a.sender&&typeof a.sender=="object"){let n=a.sender,r=typeof n.username=="string"?n.username:null,o=typeof n.name=="string"?n.name:null,s=r||(n.id!=null?String(n.id):null)||o;if(s){let i=o||r||s;return{id:s,name:i,avatar:L(i),kind:oa(t)}}}if(t==="gitlab"){let n=a.user||a.payload?.user;if(n&&typeof n=="object"&&(n.username||n.name)){let r=n.username||n.name,o=n.name||n.username;return{id:r,name:o,avatar:L(o),kind:"gitlab"}}}if(t==="github"){let n=a.sender||a.payload?.sender;if(n?.login)return{id:n.login,name:n.login,avatar:L(n.login),kind:"github"}}if(t==="telegram"){let n=a.message?.from||a.from;if(n?.username){let r=n.first_name||n.username;return{id:n.username,name:r,avatar:L(r),kind:"telegram"}}if(n?.id)return{id:String(n.id),name:n.first_name||`tg:${n.id}`,avatar:L(n.first_name||`tg${n.id}`),kind:"telegram"}}if(t==="whatsapp"){let n=a.from||a.payload?.from;if(n){let r=String(n),o=r.replace(/@.*$/,"");return{id:r,name:o,avatar:L(o),kind:"whatsapp"}}}return null}function oa(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function Xe(t){if(!t)return!1;let e=t.toLowerCase();return e==="graph-classifier"||e==="graph-agent"||e.startsWith("system:")||e.startsWith("internal:")||e.endsWith("-system")}function L(t){let e=String(t||"?").trim().split(/\s+/).filter(Boolean);return e.length>=2?(e[0][0]+e[1][0]).toUpperCase():String(t||"?").slice(0,2).toUpperCase()}function pa(t,e){if(!e||typeof e!="object")return"";let a=[];if(typeof e.text=="string"&&a.push(e.text),e.message?.text&&a.push(e.message.text),e.message?.caption&&a.push(e.message.caption),e.object_attributes?.note&&a.push(e.object_attributes.note),e.object_attributes?.title){let n=e.object_attributes.title,r=e.object_attributes.description;a.push(r?`${n}
4784
5026
  ${r}`:n)}e.comment?.body&&a.push(e.comment.body),e.issue?.title&&a.push(e.issue.title+(e.issue.body?`
4785
- ${e.issue.body}`:"")),e.pull_request?.title&&a.push(e.pull_request.title),typeof e.message=="string"&&a.push(e.message),typeof e.prompt=="string"&&a.push(e.prompt),typeof e.input=="string"&&a.push(e.input),e.payload&&typeof e.payload.text=="string"&&a.push(e.payload.text),e.payload&&typeof e.payload.message=="string"&&a.push(e.payload.message);for(let n of a)if(typeof n=="string"&&n.trim().length>0){let r=n.trim();return r.length>220?r.slice(0,217)+"\u2026":r}return""}function Hr(t){if(!t)return"(no subject)";let e;return(e=t.match(/^merge_request:(\d+)(?::note:(\d+))?/))?e[2]?`MR #${e[1]} \xB7 note ${e[2]}`:`MR #${e[1]}`:(e=t.match(/^issue:(\d+)(?::note:(\d+))?/))?e[2]?`Issue #${e[1]} \xB7 note ${e[2]}`:`Issue #${e[1]}`:(e=t.match(/^chat:(.+?):(.+)$/))?`${e[1]} \xB7 ${e[2].slice(0,40)}`:(e=t.match(/^mesh:agent:(.+)$/))?`\u2192 ${e[1]}`:(e=t.match(/^workflow:([^:]+):(.+)$/))?`${e[1]} \xB7 ${e[2].slice(0,30)}`:t.length>60?t.slice(0,57)+"\u2026":t}function Ye(t,e,a){let n=Date.now(),r=n-a*3600*1e3,o=t.prepare(`
5027
+ ${e.issue.body}`:"")),e.pull_request?.title&&a.push(e.pull_request.title),typeof e.message=="string"&&a.push(e.message),typeof e.prompt=="string"&&a.push(e.prompt),typeof e.input=="string"&&a.push(e.input),e.payload&&typeof e.payload.text=="string"&&a.push(e.payload.text),e.payload&&typeof e.payload.message=="string"&&a.push(e.payload.message);for(let n of a)if(typeof n=="string"&&n.trim().length>0){let r=n.trim();return r.length>220?r.slice(0,217)+"\u2026":r}return""}function zr(t){if(!t)return"(no subject)";let e;return(e=t.match(/^merge_request:(\d+)(?::note:(\d+))?/))?e[2]?`MR #${e[1]} \xB7 note ${e[2]}`:`MR #${e[1]}`:(e=t.match(/^issue:(\d+)(?::note:(\d+))?/))?e[2]?`Issue #${e[1]} \xB7 note ${e[2]}`:`Issue #${e[1]}`:(e=t.match(/^chat:(.+?):(.+)$/))?`${e[1]} \xB7 ${e[2].slice(0,40)}`:(e=t.match(/^mesh:agent:(.+)$/))?`\u2192 ${e[1]}`:(e=t.match(/^workflow:([^:]+):(.+)$/))?`${e[1]} \xB7 ${e[2].slice(0,30)}`:t.length>60?t.slice(0,57)+"\u2026":t}function Qe(t,e,a){let n=Date.now(),r=n-a*3600*1e3,o=t.prepare(`
4786
5028
  SELECT id, ts, source, project, subject, intent, raw_json
4787
5029
  FROM intent_events WHERE ts >= ? ORDER BY ts ASC
4788
- `).all(r),s=new Map,i=new Map;if(o.length>0){let y=o.map($=>$.id),_=y.map(($,V)=>`@id${V}`).join(","),T=Object.fromEntries(y.map(($,V)=>[`id${V}`,$])),M=t.prepare(`
5030
+ `).all(r),s=new Map,i=new Map;if(o.length>0){let x=o.map($=>$.id),E=x.map(($,V)=>`@id${V}`).join(","),C=Object.fromEntries(x.map(($,V)=>[`id${V}`,$])),M=t.prepare(`
4789
5031
  SELECT event_id, decided_at, decided_by, agent_id, outcome, reason
4790
- FROM intent_decisions WHERE event_id IN (${_}) ORDER BY decided_at ASC
4791
- `).all(T);for(let $ of M)s.has($.event_id)||s.set($.event_id,[]),s.get($.event_id).push($);let I=t.prepare(`
5032
+ FROM intent_decisions WHERE event_id IN (${E}) ORDER BY decided_at ASC
5033
+ `).all(C);for(let $ of M)s.has($.event_id)||s.set($.event_id,[]),s.get($.event_id).push($);let I=t.prepare(`
4792
5034
  SELECT decision_event_id, decision_decided_by, resolved_at, status, duration_ms, result_summary
4793
- FROM intent_resolutions WHERE decision_event_id IN (${_})
4794
- `).all(T);for(let $ of I)i.set(`${$.decision_event_id}|${$.decision_decided_by}`,$)}let l=new Map,d=new Map,c=new Map,u=new Map,h=[],x=e?.business?.projects??[],p=e?.business?.contactMap??[],m=la(e);for(let y of o){let _=null;try{_=JSON.parse(y.raw_json)}catch{}let T=da(y.source,_,p),M=null,I=null;T?(M=T.client,I=T.project||`${T.client}/_chat`):y.project&&(M=ia(y.project,x),I=y.project);let $=Dr(y.source,y.intent||"",_),V=ie[$]||{label:$,color:"#6b7280"};c.has($)||c.set($,{id:$,label:V.label,color:V.color});let ae="__system",he,Y=Or(y.source,y.intent||"",_);if(Y){ae=Y.id,he=Y.kind;let N=T?.displayName||Y.name;(!u.has(Y.id)||T?.displayName)&&u.set(Y.id,{id:Y.id,name:N,avatar:L(N),kind:Y.kind})}else u.has("__system")||u.set("__system",{id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});let Oa=ca(y.source,_);for(let N of s.get(y.id)??[]){if(N.outcome!=="dispatched"||!N.agent_id)continue;let Ha=`${y.id}|${N.decided_by}`,fe=i.get(Ha),ot=N.decided_at,st=fe?.resolved_at??null,$e=st===null,Na=fe?.duration_ms??($e?n-ot:0),Ba=$e?"active":fe?.status==="error"||fe?.status==="fail"?"error":"completed",P,de;if(M)P=M,de=I;else{let Me=m.get(N.agent_id);Me?(P=Me,de=`${Me}/_${y.source}`):(P="unmapped",de=`unmapped/_${y.source}`)}l.has(P)||l.set(P,{id:P,name:P,color:Pr(P),projects:[]}),d.has(P)||d.set(P,new Set),d.get(P).add(de),h.push({id:`${y.id}|${N.decided_by}`,agentId:N.agent_id,clientId:P,projectId:de,channelId:$,initiatorId:ae,initiatorKind:he,subject:Hr(y.subject),intent:y.intent||"",startedAt:ot,resolvedAt:st,duration:Na,active:$e,outcome:Ba,tokens:0,inputPreview:Oa,system:Rr(N.agent_id,e)})}}let f=[...l.values()].map(y=>({...y,projects:[...d.get(y.id)||[]].sort()})).sort((y,_)=>y.id.localeCompare(_.id)),w=[],b=new Set;if(e)for(let[y,_]of Object.entries(e.agents||{})){let T={id:y,name:_.name||y,tier:_.tier==="claude-code"?"lead":"worker",model:_.model||"",role:_.systemPrompt?_.systemPrompt.split(/[.\n]/)[0].slice(0,60):_.tier||""};w.push(T),b.add(y)}for(let y of h)b.has(y.agentId)||(w.push({id:y.agentId,name:y.agentId,tier:"worker",model:"",role:""}),b.add(y.agentId));w.sort((y,_)=>y.id.localeCompare(_.id));let g=[],v=new Set;for(let[y,_]of Object.entries(ie))g.push({id:y,label:_.label,color:_.color}),v.add(y);for(let y of c.values())v.has(y.id)||g.push(y);let C=[...u.values()];return C.find(y=>y.id==="__system")||C.push({id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"}),{now:n,windowH:a,clients:f,agents:w,channels:g,initiators:C,dispatches:h}}function pa(t){let e=Te();if(!e)return null;try{return Ye(e.db,ee,t)}finally{e.close()}}function ua(t){let e=new Map,a=new Map,n=new Map,r=new Map,o=[],s=0,i=0;for(let{nodeId:l,snap:d}of t){d.now>s&&(s=d.now),d.windowH>i&&(i=d.windowH);for(let c of d.clients){let u=e.get(c.id);if(!u)e.set(c.id,{...c,projects:[...c.projects]});else{let h=Array.from(new Set([...u.projects,...c.projects])).sort();e.set(c.id,{...u,projects:h})}}for(let c of d.agents)a.has(c.id)||a.set(c.id,c);for(let c of d.channels)n.has(c.id)||n.set(c.id,c);for(let c of d.initiators)r.has(c.id)||r.set(c.id,c);for(let c of d.dispatches)o.push({...c,nodeId:l,id:`${l}::${c.id}`})}return{now:s||Date.now(),windowH:i||6,clients:[...e.values()].sort((l,d)=>l.id.localeCompare(d.id)),agents:[...a.values()].sort((l,d)=>l.id.localeCompare(d.id)),channels:[...n.values()],initiators:[...r.values()],dispatches:o.sort((l,d)=>d.startedAt-l.startedAt)}}var ee=null;function ma(t){ee=t}async function ga(t,e,a){if(a!=="/api/admin/activity-graph"&&!a.startsWith("/api/admin/activity-graph?"))return!1;let n=Te();if(!n)return X(e,503,{error:"intent ledger not available",clients:[],agents:[],channels:[],initiators:[],dispatches:[]}),!0;try{let r=new URL(t.url||"/","http://_"),o=fa(parseInt(r.searchParams.get("hours")||"6",10));X(e,200,Ye(n.db,ee,o))}catch(r){X(e,500,{error:r?.message??String(r)})}finally{n.close()}return!0}var Nr=5e3;async function ha(t,e,a){if(a!=="/api/admin/activity-graph/stream"&&!a.startsWith("/api/admin/activity-graph/stream?"))return!1;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`: connected
5035
+ FROM intent_resolutions WHERE decision_event_id IN (${E})
5036
+ `).all(C);for(let $ of I)i.set(`${$.decision_event_id}|${$.decision_decided_by}`,$)}let l=new Map,d=new Map,c=new Map,u=new Map,h=[],y=e?.business?.projects??[],p=e?.business?.contactMap??[],m=da(e);for(let x of o){let E=null;try{E=JSON.parse(x.raw_json)}catch{}let C=ca(x.source,E,p),M=null,I=null;C?(M=C.client,I=C.project||`${C.client}/_chat`):x.project&&(M=la(x.project,y),I=x.project);let $=Or(x.source,x.intent||"",E),V=ie[$]||{label:$,color:"#6b7280"};c.has($)||c.set($,{id:$,label:V.label,color:V.color});let ae="__system",he,Y=jr(x.source,x.intent||"",E);if(Y){ae=Y.id,he=Y.kind;let j=C?.displayName||Y.name;(!u.has(Y.id)||C?.displayName)&&u.set(Y.id,{id:Y.id,name:j,avatar:L(j),kind:Y.kind})}else u.has("__system")||u.set("__system",{id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});let Oa=pa(x.source,E);for(let j of s.get(x.id)??[]){if(j.outcome!=="dispatched"||!j.agent_id)continue;let Na=`${x.id}|${j.decided_by}`,fe=i.get(Na),st=j.decided_at,it=fe?.resolved_at??null,$e=it===null,Ba=fe?.duration_ms??($e?n-st:0),ja=$e?"active":fe?.status==="error"||fe?.status==="fail"?"error":"completed",P,de;if(M)P=M,de=I;else{let Me=m.get(j.agent_id);Me?(P=Me,de=`${Me}/_${x.source}`):(P="unmapped",de=`unmapped/_${x.source}`)}l.has(P)||l.set(P,{id:P,name:P,color:Nr(P),projects:[]}),d.has(P)||d.set(P,new Set),d.get(P).add(de),h.push({id:`${x.id}|${j.decided_by}`,agentId:j.agent_id,clientId:P,projectId:de,channelId:$,initiatorId:ae,initiatorKind:he,subject:zr(x.subject),intent:x.intent||"",startedAt:st,resolvedAt:it,duration:Ba,active:$e,outcome:ja,tokens:0,inputPreview:Oa,system:Br(j.agent_id,e)})}}let f=[...l.values()].map(x=>({...x,projects:[...d.get(x.id)||[]].sort()})).sort((x,E)=>x.id.localeCompare(E.id)),k=[],b=new Set;if(e)for(let[x,E]of Object.entries(e.agents||{})){let C={id:x,name:E.name||x,tier:E.tier==="claude-code"?"lead":"worker",model:E.model||"",role:E.systemPrompt?E.systemPrompt.split(/[.\n]/)[0].slice(0,60):E.tier||""};k.push(C),b.add(x)}for(let x of h)b.has(x.agentId)||(k.push({id:x.agentId,name:x.agentId,tier:"worker",model:"",role:""}),b.add(x.agentId));k.sort((x,E)=>x.id.localeCompare(E.id));let w=[],g=new Set;for(let[x,E]of Object.entries(ie))w.push({id:x,label:E.label,color:E.color}),g.add(x);for(let x of c.values())g.has(x.id)||w.push(x);let v=[...u.values()];return v.find(x=>x.id==="__system")||v.push({id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"}),{now:n,windowH:a,clients:f,agents:k,channels:w,initiators:v,dispatches:h}}function ua(t){let e=Te();if(!e)return null;try{return Qe(e.db,ee,t)}finally{e.close()}}function ma(t){let e=new Map,a=new Map,n=new Map,r=new Map,o=[],s=0,i=0;for(let{nodeId:l,snap:d}of t){d.now>s&&(s=d.now),d.windowH>i&&(i=d.windowH);for(let c of d.clients){let u=e.get(c.id);if(!u)e.set(c.id,{...c,projects:[...c.projects]});else{let h=Array.from(new Set([...u.projects,...c.projects])).sort();e.set(c.id,{...u,projects:h})}}for(let c of d.agents)a.has(c.id)||a.set(c.id,c);for(let c of d.channels)n.has(c.id)||n.set(c.id,c);for(let c of d.initiators)r.has(c.id)||r.set(c.id,c);for(let c of d.dispatches)o.push({...c,nodeId:l,id:`${l}::${c.id}`})}return{now:s||Date.now(),windowH:i||6,clients:[...e.values()].sort((l,d)=>l.id.localeCompare(d.id)),agents:[...a.values()].sort((l,d)=>l.id.localeCompare(d.id)),channels:[...n.values()],initiators:[...r.values()],dispatches:o.sort((l,d)=>d.startedAt-l.startedAt)}}var ee=null;function ga(t){ee=t}async function ha(t,e,a){if(a!=="/api/admin/activity-graph"&&!a.startsWith("/api/admin/activity-graph?"))return!1;let n=Te();if(!n)return X(e,503,{error:"intent ledger not available",clients:[],agents:[],channels:[],initiators:[],dispatches:[]}),!0;try{let r=new URL(t.url||"/","http://_"),o=va(parseInt(r.searchParams.get("hours")||"6",10));X(e,200,Qe(n.db,ee,o))}catch(r){X(e,500,{error:r?.message??String(r)})}finally{n.close()}return!0}var qr=5e3;async function fa(t,e,a){if(a!=="/api/admin/activity-graph/stream"&&!a.startsWith("/api/admin/activity-graph/stream?"))return!1;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`: connected
4795
5037
 
4796
- `);let n=new URL(t.url||"/","http://_"),r=fa(parseInt(n.searchParams.get("hours")||"6",10)),o=!1,s=()=>{o=!0};t.on("close",s),t.on("error",s),e.on("close",s),e.on("error",s);let i=setInterval(()=>{if(!o)try{e.write(`: hb
5038
+ `);let n=new URL(t.url||"/","http://_"),r=va(parseInt(n.searchParams.get("hours")||"6",10)),o=!1,s=()=>{o=!0};t.on("close",s),t.on("error",s),e.on("close",s),e.on("error",s);let i=setInterval(()=>{if(!o)try{e.write(`: hb
4797
5039
 
4798
- `)}catch{s()}},25e3);try{for(;!o;){let l=Te();if(l)try{let c=Ye(l.db,ee,r);e.write(`event: snapshot
5040
+ `)}catch{s()}},25e3);try{for(;!o;){let l=Te();if(l)try{let c=Qe(l.db,ee,r);e.write(`event: snapshot
4799
5041
  `),e.write(`data: ${JSON.stringify(c)}
4800
5042
 
4801
5043
  `)}catch(c){e.write(`event: error
@@ -4804,7 +5046,7 @@ data: ${JSON.stringify({error:c?.message??String(c)})}
4804
5046
  `)}finally{l.close()}else e.write(`event: error
4805
5047
  data: ${JSON.stringify({error:"ledger not available"})}
4806
5048
 
4807
- `);let d=Date.now();for(;!o&&Date.now()-d<Nr;)await new Promise(c=>setTimeout(c,200))}}finally{clearInterval(i);try{e.end()}catch{}}return!0}function fa(t){return!Number.isFinite(t)||t<1?6:Math.min(720,Math.max(1,t))}function Br(t,e,a=5e3){let n=new Date(e).toISOString().slice(0,10),r=Xe(process.cwd(),".agentx/task-history",t,n);if(!Ve(r)){let o=new Date(e-864e5).toISOString().slice(0,10),s=Xe(process.cwd(),".agentx/task-history",t,o);return Ve(s)?oa(s,e,a):null}return oa(r,e,a)}function oa(t,e,a){let n=null,r=1/0;for(let o of Mr(t)){if(!o.endsWith(".json"))continue;let s;try{s=JSON.parse(Ir($r(t,o),"utf-8"))}catch{continue}let i=s.startedAt,l;if(typeof i=="number")l=i;else if(typeof i=="string"){let c=Date.parse(i);if(!Number.isFinite(c))continue;l=c}else continue;let d=Math.abs(l-e);d<r&&d<=a&&(n=s,r=d)}return n}async function va(t,e,a){let n=a.match(/^\/api\/admin\/activity-graph\/dispatch\/([^/?]+)(?:\?.*)?$/);if(!n)return!1;let r=decodeURIComponent(n[1]),o=r.indexOf("|");if(o<0)return X(e,400,{error:"invalid dispatch id"}),!0;let s=r.slice(0,o),i=r.slice(o+1),l=Te();if(!l)return X(e,503,{error:"ledger not available"}),!0;try{let d=l.db.prepare("SELECT id, ts, source, project, subject, intent, raw_json FROM intent_events WHERE id = ?").get(s);if(!d)return X(e,404,{error:"event not found"}),!0;let c=l.db.prepare("SELECT decided_at, decided_by, agent_id, outcome, reason FROM intent_decisions WHERE event_id = ? AND decided_by = ?").get(s,i);if(!c)return X(e,404,{error:"decision not found"}),!0;let u=l.db.prepare("SELECT resolved_at, status, duration_ms, result_summary FROM intent_resolutions WHERE decision_event_id = ? AND decision_decided_by = ?").get(s,i),h=null;try{h=JSON.parse(d.raw_json)}catch{}let x=ca(d.source,h),p=h&&typeof h=="object"&&(h.text||h.message?.text||h.message?.caption||h.object_attributes?.note||h.object_attributes?.description||h.comment?.body||h.issue?.body||(typeof h.message=="string"?h.message:null)||(typeof h.prompt=="string"?h.prompt:null)||null)||x,m=null,f=null;if(c.agent_id){let y=Br(c.agent_id,c.decided_at);if(y){typeof y.responseText=="string"&&(m=y.responseText);let _=y.transcript;Array.isArray(_)&&(f=_.length)}}let w=ee?.business?.projects??[],b=ee?.business?.contactMap??[],g=la(ee),v={client:"unmapped",project:`unmapped/_${d.source}`,via:"fallback"},C=da(d.source,h,b);if(C)v={client:C.client,project:C.project||`${C.client}/_chat`,via:`contactMap (channel=${C.channel??"*"}${C.username?` username=${C.username}`:""}${C.chatId?` chatId=${C.chatId}`:""})`};else if(d.project)v={client:ia(d.project,w),project:d.project,via:`project namespace prefix (${d.project})`};else if(c.agent_id){let y=g.get(c.agent_id);y&&(v={client:y,project:`${y}/_${d.source}`,via:`orgChart fallback (agent ${c.agent_id} reports up to a PM whose project belongs to ${y})`})}X(e,200,{id:r,eventId:s,source:d.source,subject:d.subject,intent:d.intent,project:d.project,decidedBy:c.decided_by,agentId:c.agent_id,outcome:c.outcome,reason:c.reason,startedAt:c.decided_at,resolvedAt:u?.resolved_at??null,durationMs:u?.duration_ms??null,input:p,response:m,transcriptLen:f,resolutionStatus:u?.status??null,resultSummary:u?.result_summary??null,attribution:v})}catch(d){X(e,500,{error:d?.message??String(d)})}finally{l.close()}return!0}import{existsSync as Fr,readFileSync as Gr}from"fs";import{resolve as xa}from"path";function ba(t){let e=t.agentId,a=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",n=`<script>window.AGENT_ID = ${JSON.stringify(e)};</script>`,r=jr.replace(/__AGENT_ID__/g,R(e));return A({title:`AgentX \xB7 ${R(e)}`,activeTab:"admin",subtitle:`Agent \xB7 ${R(e)}`,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:r,css:zr,headExtras:'<link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css">',scripts:`${n}${a}<script src="https://unpkg.com/easymde/dist/easymde.min.js"></script><script>${qr}</script>`})}var jr=`
5049
+ `);let d=Date.now();for(;!o&&Date.now()-d<qr;)await new Promise(c=>setTimeout(c,200))}}finally{clearInterval(i);try{e.end()}catch{}}return!0}function va(t){return!Number.isFinite(t)||t<1?6:Math.min(720,Math.max(1,t))}function Fr(t,e,a=5e3){let n=new Date(e).toISOString().slice(0,10),r=Ve(process.cwd(),".agentx/task-history",t,n);if(!Ye(r)){let o=new Date(e-864e5).toISOString().slice(0,10),s=Ve(process.cwd(),".agentx/task-history",t,o);return Ye(s)?sa(s,e,a):null}return sa(r,e,a)}function sa(t,e,a){let n=null,r=1/0;for(let o of Pr(t)){if(!o.endsWith(".json"))continue;let s;try{s=JSON.parse(Rr(Dr(t,o),"utf-8"))}catch{continue}let i=s.startedAt,l;if(typeof i=="number")l=i;else if(typeof i=="string"){let c=Date.parse(i);if(!Number.isFinite(c))continue;l=c}else continue;let d=Math.abs(l-e);d<r&&d<=a&&(n=s,r=d)}return n}async function ba(t,e,a){let n=a.match(/^\/api\/admin\/activity-graph\/dispatch\/([^/?]+)(?:\?.*)?$/);if(!n)return!1;let r=decodeURIComponent(n[1]),o=r.indexOf("|");if(o<0)return X(e,400,{error:"invalid dispatch id"}),!0;let s=r.slice(0,o),i=r.slice(o+1),l=Te();if(!l)return X(e,503,{error:"ledger not available"}),!0;try{let d=l.db.prepare("SELECT id, ts, source, project, subject, intent, raw_json FROM intent_events WHERE id = ?").get(s);if(!d)return X(e,404,{error:"event not found"}),!0;let c=l.db.prepare("SELECT decided_at, decided_by, agent_id, outcome, reason FROM intent_decisions WHERE event_id = ? AND decided_by = ?").get(s,i);if(!c)return X(e,404,{error:"decision not found"}),!0;let u=l.db.prepare("SELECT resolved_at, status, duration_ms, result_summary FROM intent_resolutions WHERE decision_event_id = ? AND decision_decided_by = ?").get(s,i),h=null;try{h=JSON.parse(d.raw_json)}catch{}let y=pa(d.source,h),p=h&&typeof h=="object"&&(h.text||h.message?.text||h.message?.caption||h.object_attributes?.note||h.object_attributes?.description||h.comment?.body||h.issue?.body||(typeof h.message=="string"?h.message:null)||(typeof h.prompt=="string"?h.prompt:null)||null)||y,m=null,f=null;if(c.agent_id){let x=Fr(c.agent_id,c.decided_at);if(x){typeof x.responseText=="string"&&(m=x.responseText);let E=x.transcript;Array.isArray(E)&&(f=E.length)}}let k=ee?.business?.projects??[],b=ee?.business?.contactMap??[],w=da(ee),g={client:"unmapped",project:`unmapped/_${d.source}`,via:"fallback"},v=ca(d.source,h,b);if(v)g={client:v.client,project:v.project||`${v.client}/_chat`,via:`contactMap (channel=${v.channel??"*"}${v.username?` username=${v.username}`:""}${v.chatId?` chatId=${v.chatId}`:""})`};else if(d.project)g={client:la(d.project,k),project:d.project,via:`project namespace prefix (${d.project})`};else if(c.agent_id){let x=w.get(c.agent_id);x&&(g={client:x,project:`${x}/_${d.source}`,via:`orgChart fallback (agent ${c.agent_id} reports up to a PM whose project belongs to ${x})`})}X(e,200,{id:r,eventId:s,source:d.source,subject:d.subject,intent:d.intent,project:d.project,decidedBy:c.decided_by,agentId:c.agent_id,outcome:c.outcome,reason:c.reason,startedAt:c.decided_at,resolvedAt:u?.resolved_at??null,durationMs:u?.duration_ms??null,input:p,response:m,transcriptLen:f,resolutionStatus:u?.status??null,resultSummary:u?.result_summary??null,attribution:g})}catch(d){X(e,500,{error:d?.message??String(d)})}finally{l.close()}return!0}import{existsSync as Kr,readFileSync as Jr}from"fs";import{resolve as ya}from"path";function xa(t){let e=t.agentId,a=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",n=`<script>window.AGENT_ID = ${JSON.stringify(e)};</script>`,r=Wr.replace(/__AGENT_ID__/g,R(e));return A({title:`AgentX \xB7 ${R(e)}`,activeTab:"admin",subtitle:`Agent \xB7 ${R(e)}`,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:r,css:Gr,headExtras:'<link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css">',scripts:`${n}${a}<script src="https://unpkg.com/easymde/dist/easymde.min.js"></script><script>${Ur}</script>`})}var Wr=`
4808
5050
  <!-- Breadcrumb -->
4809
5051
  <div class="ax-crumb">
4810
5052
  <a href="/admin">Settings</a>
@@ -5391,7 +5633,7 @@ data: ${JSON.stringify({error:"ledger not available"})}
5391
5633
  </div>
5392
5634
  </div>
5393
5635
  </div>
5394
- `,zr=`
5636
+ `,Gr=`
5395
5637
  /* Agent-specific layout + legacy styles for bits the migration left in
5396
5638
  * place (EasyMDE theming, skills tree, plain-editor). Shared chrome + tab
5397
5639
  * primitives live in components.css.ts. */
@@ -5510,7 +5752,7 @@ textarea.inp.mono { font-family: var(--ax-mono); }
5510
5752
 
5511
5753
  /* Agent-specific button variant used in rail context (no ax-btn wrapper) */
5512
5754
  .ax-btn.lg { padding: 9px 16px; font-size: 13px; }
5513
- `,qr=`
5755
+ `,Ur=`
5514
5756
  const $ = (id) => document.getElementById(id);
5515
5757
  const state = { agent: null, activeSkill: null, activeSkillFile: null, identityPath: null };
5516
5758
 
@@ -6334,9 +6576,9 @@ document.addEventListener('keydown', (e) => {
6334
6576
  /* ===== Boot ===== */
6335
6577
  initOptsToggles();
6336
6578
  loadAgent();
6337
- `;function ya(t,e,a,n=[],r){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ba({agentId:a,peers:n,localToken:r}))}async function wa(t,e,a){try{let n=t.method==="GET"?void 0:await mo(t),r=new URL(t.url||"/","http://localhost"),o=Object.fromEntries(r.searchParams),s=a.match(/^\/api\/admin\/agent\/([a-z0-9][a-z0-9_-]*)(?:\/(.+))?$/);if(!s){Ce(e,404,{error:`unknown agent endpoint: ${a}`});return}let i=s[1],l=s[2]||"",d=`${t.method} ${l}`,u={"GET ":()=>me(i),"PATCH ":()=>Wr(i,n),"PATCH capability":()=>Jr(i,n),"POST mcp":()=>Ur(i,n),"DELETE mcp":()=>Kr(i,n),"GET identity":()=>Xr(i),"GET identity/file":()=>Vr(i,String(o.path||"")),"PUT identity/file":()=>Yr(i,n),"GET skills":()=>Qr(i),"POST skills":()=>Zr(i,n),"DELETE skills":()=>eo(i,n),"GET skills/tree":()=>to(i,String(o.slug||"")),"GET skills/file":()=>ao(i,String(o.slug||""),String(o.path||"")),"PUT skills/file":()=>no(i,n),"GET skills/deps":()=>ro(i,String(o.slug||"")),"POST skills/install":()=>oo(i,n,t),"POST skills/deps":()=>so(i,n,t),"GET channels":()=>io(i),"GET activity":()=>lo(i,t),"GET handovers":()=>co(i),"POST handovers":()=>po(i,n),"DELETE handovers":()=>uo(n)}[d];if(!u){Ce(e,404,{error:`unknown agent sub-endpoint: ${d}`});return}let h=await u();Ce(e,200,h)}catch(n){Ce(e,400,{error:n?.message||"agent op failed"})}}function ka(){let t=xa(process.cwd(),"agentx.json");return Fr(t)?JSON.parse(Gr(t,"utf-8")):null}function D(t){let e=ka();if(!e)throw new Error("agentx.json not found");let a=e.agents?.[t];if(!a)throw new Error(`Agent "${t}" not found`);return{def:a,cfg:e}}function me(t){let{def:e,cfg:a}=D(t),n=e.workspace?re(e.workspace):null;return{id:t,name:e.name||t,tier:e.tier,model:e.model,workspace:e.workspace,systemPrompt:e.systemPrompt||"",mentions:e.mentions||[],access:e.access||"private",maxConcurrent:e.maxConcurrent??1,maxExecutionMinutes:e.maxExecutionMinutes??20,permissionMode:e.permissionMode||"default",intents:Array.isArray(e.intents)?e.intents:[],maxDelegationDepth:e.maxDelegationDepth??5,contextReferences:!!e.contextReferences,contextStrategy:e.contextStrategy||"",mcp:e.mcp&&typeof e.mcp=="object"?e.mcp:{},overview:n,defaultWorker:a.node?.defaultAgent,draftAgent:a.dashboard?.draftAgent}}function Wr(t,e){let a={};for(let r of["name","tier","model","systemPrompt","mentions","access","maxConcurrent","maxExecutionMinutes","permissionMode"])e?.[r]!==void 0&&(a[r]=e[r]);let{summary:n}=S(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);return r.agents[t]={...r.agents[t],...a},`agent "${t}" updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:me(t)}}function Ur(t,e){let a=String(e?.name||"").trim(),n=String(e?.command||"").trim();if(!a)throw new Error("name required");if(!/^[a-zA-Z0-9_-]+$/.test(a))throw new Error("name must be identifier-safe (alnum, _, -)");if(!n)throw new Error("command required");let r=Array.isArray(e?.args)?e.args.map(i=>String(i)):[],o;if(e?.env&&typeof e.env=="object"){o={};for(let[i,l]of Object.entries(e.env))typeof l=="string"&&(o[i]=l);Object.keys(o).length===0&&(o=void 0)}let{summary:s}=S(i=>{if(!i.agents?.[t])throw new Error(`Agent "${t}" not found`);return i.agents[t].mcp=i.agents[t].mcp||{},i.agents[t].mcp[a]={command:n,args:r,...o?{env:o}:{}},`agent "${t}" mcp.${a} upserted`});return{summary:s,agent:me(t)}}function Kr(t,e){let a=String(e?.name||"").trim();if(!a)throw new Error("name required");let{summary:n}=S(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);if(!r.agents[t].mcp||!(a in r.agents[t].mcp))throw new Error(`no mcp.${a} on "${t}"`);return delete r.agents[t].mcp[a],Object.keys(r.agents[t].mcp).length===0&&delete r.agents[t].mcp,`agent "${t}" mcp.${a} removed`});return{summary:n,agent:me(t)}}function Jr(t,e){let a={};if(Array.isArray(e?.intents)&&(a.intents=e.intents.map(r=>String(r)).filter(Boolean)),e?.maxDelegationDepth!==void 0){let r=Number(e.maxDelegationDepth);if(!Number.isFinite(r)||r<0||r>50)throw new Error("maxDelegationDepth must be 0..50");a.maxDelegationDepth=r}if(e?.contextReferences!==void 0&&(a.contextReferences=!!e.contextReferences),e?.contextStrategy!==void 0){if(e.contextStrategy&&!["layered","planner"].includes(e.contextStrategy))throw new Error("contextStrategy must be layered|planner|empty");e.contextStrategy?a.contextStrategy=e.contextStrategy:a.contextStrategy=void 0}if(e?.maxExecutionMinutes!==void 0){let r=Number(e.maxExecutionMinutes);if(!Number.isFinite(r)||r<1||r>240)throw new Error("maxExecutionMinutes must be 1..240");a.maxExecutionMinutes=r}if(Object.keys(a).length===0)throw new Error("nothing to update");let{summary:n}=S(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);let o={...r.agents[t]};for(let[s,i]of Object.entries(a))i===void 0?delete o[s]:o[s]=i;return r.agents[t]=o,`agent "${t}" capability updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:me(t)}}function Xr(t){let{def:e}=D(t);return re(e.workspace)}function Vr(t,e){if(!e)throw new Error("path query param required");let{def:a}=D(t);return xe(a.workspace,e)}function Yr(t,e){let a=String(e?.path||"");if(!a)throw new Error("path required");let{def:n}=D(t);return ye(n.workspace,a,String(e?.content??""))}function Qr(t){let{def:e}=D(t),a=re(e.workspace);return{skills:a.skills,workspace:a.workspace}}function Zr(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=D(t);return we(n.workspace,a,{title:e?.title,content:e?.content})}function eo(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=D(t);return ke(n.workspace,a)}function to(t,e){if(!e)throw new Error("slug query param required");let{def:a}=D(t),n=It(a.workspace,e),r=_e(a.workspace,e);return{slug:e,tree:n,deps:r}}function ao(t,e,a){if(!e||!a)throw new Error("slug and path query params required");let{def:n}=D(t);return Lt(n.workspace,e,a)}function no(t,e){let a=String(e?.slug||""),n=String(e?.path||"");if(!a||!n)throw new Error("slug and path required");let{def:r}=D(t);return Dt(r.workspace,a,n,String(e?.content??""))}function ro(t,e){if(!e)throw new Error("slug query param required");let{def:a}=D(t);return _e(a.workspace,e)}async function oo(t,e,a){let n=String(e?.package||"").trim();if(!n||!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)?$/.test(n))throw new Error("package must be in 'owner/repo' or 'owner/repo/skill' form");let r=_a(e?.worker),{def:o}=D(t),s=[`Install the skills.sh package "${n}" into agent "${t}".`,`Workspace: ${o.workspace}`,`Run: cd ${o.workspace} && npx -y skills add ${n}`,`If that fails, fall back to: agentx skill install ${n}`,`Skills should land under ${o.workspace}/.claude/skills/. Report what was installed and any errors.`].join(`
6338
- `);return Ea(a,r,s,`install-${n}:${Date.now()}`)}async function so(t,e,a){let n=String(e?.slug||"").trim();if(!n)throw new Error("slug required");let r=_a(e?.worker),{def:o}=D(t),s=_e(o.workspace,n);if(!s.manager)throw new Error(`No dependency manifest detected in .claude/skills/${n}. Expected one of: package.json, requirements.txt, Gemfile.`);let i=xa(o.workspace,".claude","skills",n),l=[`Install dependencies for skill "${n}" in agent "${t}".`,`cd to: ${i}`,`Detected manifest: ${s.file}`,`Run: ${s.command}`,"Stream the install output. On success, summarise the packages installed.","On failure, report the exit code and the last 20 lines of output."].join(`
6339
- `);return Ea(a,r,l,`deps-${t}-${n}:${Date.now()}`)}function _a(t){if(t&&typeof t=="string")return t;let e=B();return e.dashboard?.draftAgent||e.node?.defaultAgent||Object.keys(e.agents).find(a=>a.includes("devops"))||Object.keys(e.agents)[0]}async function Ea(t,e,a,n){let r=B(),o=(r.dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),s={"Content-Type":"application/json"},i=t.headers.authorization;i?s.Authorization=String(i):r.dashboard.token&&(s.Authorization=`Bearer ${r.dashboard.token}`);let l=await fetch(`${o}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"admin",sender:"admin-ui",chatId:n}})}),d=await l.text(),c;try{c=JSON.parse(d)}catch{c={content:d}}if(!l.ok)throw new Error(c?.error||`daemon /task HTTP ${l.status}`);return{worker:e,taskId:c?.taskId,content:c?.content,duration:c?.duration,error:c?.error}}function io(t){let e=ka(),a=[],n=e?.channels?.telegram?.accounts||{};for(let[o,s]of Object.entries(n))s?.agentBinding===t&&a.push({channel:"telegram",account:o,detail:s?.botUsername||o});e?.channels?.slack?.agentBinding===t&&a.push({channel:"slack",detail:"bound"}),e?.channels?.discord?.agentBinding===t&&a.push({channel:"discord",detail:"bound"});let r=e?.channels?.gitlab?.agentMappings||[];for(let o of r)o?.agentId===t&&a.push({channel:"gitlab",detail:(o?.gitlabUsernames||[]).join(", ")||"mapped"});return{bindings:a}}async function lo(t,e){try{let n=(B().dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),r=await fetch(`${n}/agents`);if(!r.ok)throw new Error(`daemon HTTP ${r.status}`);let s=(await r.json()).find(i=>i.id===t);return{activeTasks:s?.activeTasks??0,totalTasks:s?.totalTasks??0,errors:s?.errors??0,lastActive:s?.lastActive??null,runningTasks:s?.runningTasks??[],lastSummary:s?.lastSummary??null}}catch(a){return{error:a?.message,activeTasks:0,totalTasks:0,errors:0,runningTasks:[]}}}function Qe(){return new lt}function co(t){let e=Qe(),{incoming:a,outgoing:n}=e.listByAgent(t);return{incoming:a,outgoing:n}}function po(t,e){let a=String(e?.channel||"").trim(),n=String(e?.chatId||"").trim(),r=String(e?.toAgent||"").trim();if(!a||!n||!r)throw new Error("channel, chatId, toAgent required");let o=String(e?.fromAgent||t||"").trim()||t,s=e?.accountId?String(e.accountId):void 0,i=e?.summary?String(e.summary):void 0,l=e?.expiresAt?String(e.expiresAt):void 0,d=Qe().set({channel:a,chatId:n,accountId:s,fromAgent:o,toAgent:r,summary:i,expiresAt:l,createdBy:"admin-ui"});return{summary:`Handed off ${a}:${n} from ${o} to ${r}`,record:d}}function uo(t){let e=String(t?.channel||"").trim(),a=String(t?.chatId||"").trim();if(!e||!a)throw new Error("channel and chatId required");let n=t?.accountId?String(t.accountId):void 0;return{summary:Qe().remove(e,a,n)?"Released":"No active handover for that chat"}}function Ce(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function mo(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}var W={brand:"AgentX",subtitle:"Team AI ops",nodes:"machines",agentsCount:"agents",activeNow:"handling now",errorsCount:"failed",stats:{active:"Handling",total:"Today",errors:"Failed"},idle:"idle",runningNoPreview:"working \xB7 preparing reply",recentActivities:"Recent activities \u2192",noAgentsOnNode:"No agents set up on this machine.",unreachable:"This machine is unreachable.",neverRan:"not used yet",tierLabels:{"claude-code":"Claude Code",sdk:"SDK",orchestrator:"Orchestrator"},taskModalTitle:"Task activity",taskModalConnecting:"connecting\u2026",taskModalLive:"live",taskModalFinished:"finished",taskModalArchived:"archived",taskModalLoadFailed:"couldn't load",taskModalFinalResponse:"Final reply",historyPanelTitle:"Recent activities",historyEmpty:"No activity yet.",historyLoading:"loading\u2026"};var Sa=[{term:"Agent",definition:'An AI worker with its own role, instructions, and channels it responds on. Think of each agent as a job title \u2014 "support", "devops", "sales".'},{term:"Trigger word",alias:"mention",definition:"A word that activates an agent. When the trigger appears in a message (e.g. @support), AgentX routes the message to that agent."},{term:"Channel",definition:"Where messages come from \u2014 Telegram, WhatsApp, Discord, GitLab comments, a scheduled cron, or an HTTP webhook."},{term:"AI engine",alias:"tier",definition:"Which backend answers: Claude Code (reasoning + tools + files), an SDK provider (OpenAI, Anthropic API, Ollama), or an Orchestrator that coordinates sub-agents."},{term:"Agent folder",alias:"workspace",definition:"The directory on disk where the agent lives. It holds the agent's personality (CLAUDE.md), its knowledge (wiki), and the tools it can use."},{term:"Team network",alias:"mesh",definition:'When you run AgentX on more than one machine, the machines find each other and share work. Each machine is a "node"; together they are your team network.'},{term:"Status check-in",alias:"heartbeat",definition:"A lightweight ping between machines so each one knows the others are alive and responsive."},{term:"Board",definition:"A Kanban view of tasks (issues, tickets) pulled from GitLab. Drag cards between columns to move work forward \u2014 the labels update upstream automatically."},{term:"Task",definition:"A single conversation or job an agent handles, from trigger message to final reply. Every task is logged and replayable."},{term:"Schedule",alias:"cron",definition:'A recurring job \u2014 e.g. "every Monday at 9am" \u2014 that nudges an agent without a human trigger.'},{term:"Status label",alias:"scopedLabel",definition:"A GitLab label that moves an issue between Kanban columns (e.g. Status::Doing). Labels are mutually exclusive by prefix."}];function Ze(t={}){let e=`<script>window.UI_LABELS = ${JSON.stringify(W)};</script>`,a=`<span id="ts" class="ax-mono" title="Last update">\u2014</span>
6579
+ `;function wa(t,e,a,n=[],r){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(xa({agentId:a,peers:n,localToken:r}))}async function ka(t,e,a){try{let n=t.method==="GET"?void 0:await vo(t),r=new URL(t.url||"/","http://localhost"),o=Object.fromEntries(r.searchParams),s=a.match(/^\/api\/admin\/agent\/([a-z0-9][a-z0-9_-]*)(?:\/(.+))?$/);if(!s){Ce(e,404,{error:`unknown agent endpoint: ${a}`});return}let i=s[1],l=s[2]||"",d=`${t.method} ${l}`,u={"GET ":()=>me(i),"PATCH ":()=>Xr(i,n),"PATCH capability":()=>Qr(i,n),"POST mcp":()=>Vr(i,n),"DELETE mcp":()=>Yr(i,n),"GET identity":()=>Zr(i),"GET identity/file":()=>eo(i,String(o.path||"")),"PUT identity/file":()=>to(i,n),"GET skills":()=>ao(i),"POST skills":()=>no(i,n),"DELETE skills":()=>ro(i,n),"GET skills/tree":()=>oo(i,String(o.slug||"")),"GET skills/file":()=>so(i,String(o.slug||""),String(o.path||"")),"PUT skills/file":()=>io(i,n),"GET skills/deps":()=>lo(i,String(o.slug||"")),"POST skills/install":()=>co(i,n,t),"POST skills/deps":()=>po(i,n,t),"GET channels":()=>uo(i),"GET activity":()=>mo(i,t),"GET handovers":()=>go(i),"POST handovers":()=>ho(i,n),"DELETE handovers":()=>fo(n)}[d];if(!u){Ce(e,404,{error:`unknown agent sub-endpoint: ${d}`});return}let h=await u();Ce(e,200,h)}catch(n){Ce(e,400,{error:n?.message||"agent op failed"})}}function _a(){let t=ya(process.cwd(),"agentx.json");return Kr(t)?JSON.parse(Jr(t,"utf-8")):null}function D(t){let e=_a();if(!e)throw new Error("agentx.json not found");let a=e.agents?.[t];if(!a)throw new Error(`Agent "${t}" not found`);return{def:a,cfg:e}}function me(t){let{def:e,cfg:a}=D(t),n=e.workspace?re(e.workspace):null;return{id:t,name:e.name||t,tier:e.tier,model:e.model,workspace:e.workspace,systemPrompt:e.systemPrompt||"",mentions:e.mentions||[],access:e.access||"private",maxConcurrent:e.maxConcurrent??1,maxExecutionMinutes:e.maxExecutionMinutes??20,permissionMode:e.permissionMode||"default",intents:Array.isArray(e.intents)?e.intents:[],maxDelegationDepth:e.maxDelegationDepth??5,contextReferences:!!e.contextReferences,contextStrategy:e.contextStrategy||"",mcp:e.mcp&&typeof e.mcp=="object"?e.mcp:{},overview:n,defaultWorker:a.node?.defaultAgent,draftAgent:a.dashboard?.draftAgent}}function Xr(t,e){let a={};for(let r of["name","tier","model","systemPrompt","mentions","access","maxConcurrent","maxExecutionMinutes","permissionMode"])e?.[r]!==void 0&&(a[r]=e[r]);let{summary:n}=T(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);return r.agents[t]={...r.agents[t],...a},`agent "${t}" updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:me(t)}}function Vr(t,e){let a=String(e?.name||"").trim(),n=String(e?.command||"").trim();if(!a)throw new Error("name required");if(!/^[a-zA-Z0-9_-]+$/.test(a))throw new Error("name must be identifier-safe (alnum, _, -)");if(!n)throw new Error("command required");let r=Array.isArray(e?.args)?e.args.map(i=>String(i)):[],o;if(e?.env&&typeof e.env=="object"){o={};for(let[i,l]of Object.entries(e.env))typeof l=="string"&&(o[i]=l);Object.keys(o).length===0&&(o=void 0)}let{summary:s}=T(i=>{if(!i.agents?.[t])throw new Error(`Agent "${t}" not found`);return i.agents[t].mcp=i.agents[t].mcp||{},i.agents[t].mcp[a]={command:n,args:r,...o?{env:o}:{}},`agent "${t}" mcp.${a} upserted`});return{summary:s,agent:me(t)}}function Yr(t,e){let a=String(e?.name||"").trim();if(!a)throw new Error("name required");let{summary:n}=T(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);if(!r.agents[t].mcp||!(a in r.agents[t].mcp))throw new Error(`no mcp.${a} on "${t}"`);return delete r.agents[t].mcp[a],Object.keys(r.agents[t].mcp).length===0&&delete r.agents[t].mcp,`agent "${t}" mcp.${a} removed`});return{summary:n,agent:me(t)}}function Qr(t,e){let a={};if(Array.isArray(e?.intents)&&(a.intents=e.intents.map(r=>String(r)).filter(Boolean)),e?.maxDelegationDepth!==void 0){let r=Number(e.maxDelegationDepth);if(!Number.isFinite(r)||r<0||r>50)throw new Error("maxDelegationDepth must be 0..50");a.maxDelegationDepth=r}if(e?.contextReferences!==void 0&&(a.contextReferences=!!e.contextReferences),e?.contextStrategy!==void 0){if(e.contextStrategy&&!["layered","planner"].includes(e.contextStrategy))throw new Error("contextStrategy must be layered|planner|empty");e.contextStrategy?a.contextStrategy=e.contextStrategy:a.contextStrategy=void 0}if(e?.maxExecutionMinutes!==void 0){let r=Number(e.maxExecutionMinutes);if(!Number.isFinite(r)||r<1||r>240)throw new Error("maxExecutionMinutes must be 1..240");a.maxExecutionMinutes=r}if(Object.keys(a).length===0)throw new Error("nothing to update");let{summary:n}=T(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);let o={...r.agents[t]};for(let[s,i]of Object.entries(a))i===void 0?delete o[s]:o[s]=i;return r.agents[t]=o,`agent "${t}" capability updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:me(t)}}function Zr(t){let{def:e}=D(t);return re(e.workspace)}function eo(t,e){if(!e)throw new Error("path query param required");let{def:a}=D(t);return xe(a.workspace,e)}function to(t,e){let a=String(e?.path||"");if(!a)throw new Error("path required");let{def:n}=D(t);return ye(n.workspace,a,String(e?.content??""))}function ao(t){let{def:e}=D(t),a=re(e.workspace);return{skills:a.skills,workspace:a.workspace}}function no(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=D(t);return we(n.workspace,a,{title:e?.title,content:e?.content})}function ro(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=D(t);return ke(n.workspace,a)}function oo(t,e){if(!e)throw new Error("slug query param required");let{def:a}=D(t),n=Dt(a.workspace,e),r=_e(a.workspace,e);return{slug:e,tree:n,deps:r}}function so(t,e,a){if(!e||!a)throw new Error("slug and path query params required");let{def:n}=D(t);return Pt(n.workspace,e,a)}function io(t,e){let a=String(e?.slug||""),n=String(e?.path||"");if(!a||!n)throw new Error("slug and path required");let{def:r}=D(t);return Rt(r.workspace,a,n,String(e?.content??""))}function lo(t,e){if(!e)throw new Error("slug query param required");let{def:a}=D(t);return _e(a.workspace,e)}async function co(t,e,a){let n=String(e?.package||"").trim();if(!n||!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)?$/.test(n))throw new Error("package must be in 'owner/repo' or 'owner/repo/skill' form");let r=Ea(e?.worker),{def:o}=D(t),s=[`Install the skills.sh package "${n}" into agent "${t}".`,`Workspace: ${o.workspace}`,`Run: cd ${o.workspace} && npx -y skills add ${n}`,`If that fails, fall back to: agentx skill install ${n}`,`Skills should land under ${o.workspace}/.claude/skills/. Report what was installed and any errors.`].join(`
6580
+ `);return Sa(a,r,s,`install-${n}:${Date.now()}`)}async function po(t,e,a){let n=String(e?.slug||"").trim();if(!n)throw new Error("slug required");let r=Ea(e?.worker),{def:o}=D(t),s=_e(o.workspace,n);if(!s.manager)throw new Error(`No dependency manifest detected in .claude/skills/${n}. Expected one of: package.json, requirements.txt, Gemfile.`);let i=ya(o.workspace,".claude","skills",n),l=[`Install dependencies for skill "${n}" in agent "${t}".`,`cd to: ${i}`,`Detected manifest: ${s.file}`,`Run: ${s.command}`,"Stream the install output. On success, summarise the packages installed.","On failure, report the exit code and the last 20 lines of output."].join(`
6581
+ `);return Sa(a,r,l,`deps-${t}-${n}:${Date.now()}`)}function Ea(t){if(t&&typeof t=="string")return t;let e=z();return e.dashboard?.draftAgent||e.node?.defaultAgent||Object.keys(e.agents).find(a=>a.includes("devops"))||Object.keys(e.agents)[0]}async function Sa(t,e,a,n){let r=z(),o=(r.dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),s={"Content-Type":"application/json"},i=t.headers.authorization;i?s.Authorization=String(i):r.dashboard.token&&(s.Authorization=`Bearer ${r.dashboard.token}`);let l=await fetch(`${o}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"admin",sender:"admin-ui",chatId:n}})}),d=await l.text(),c;try{c=JSON.parse(d)}catch{c={content:d}}if(!l.ok)throw new Error(c?.error||`daemon /task HTTP ${l.status}`);return{worker:e,taskId:c?.taskId,content:c?.content,duration:c?.duration,error:c?.error}}function uo(t){let e=_a(),a=[],n=e?.channels?.telegram?.accounts||{};for(let[o,s]of Object.entries(n))s?.agentBinding===t&&a.push({channel:"telegram",account:o,detail:s?.botUsername||o});e?.channels?.slack?.agentBinding===t&&a.push({channel:"slack",detail:"bound"}),e?.channels?.discord?.agentBinding===t&&a.push({channel:"discord",detail:"bound"});let r=e?.channels?.gitlab?.agentMappings||[];for(let o of r)o?.agentId===t&&a.push({channel:"gitlab",detail:(o?.gitlabUsernames||[]).join(", ")||"mapped"});return{bindings:a}}async function mo(t,e){try{let n=(z().dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),r=await fetch(`${n}/agents`);if(!r.ok)throw new Error(`daemon HTTP ${r.status}`);let s=(await r.json()).find(i=>i.id===t);return{activeTasks:s?.activeTasks??0,totalTasks:s?.totalTasks??0,errors:s?.errors??0,lastActive:s?.lastActive??null,runningTasks:s?.runningTasks??[],lastSummary:s?.lastSummary??null}}catch(a){return{error:a?.message,activeTasks:0,totalTasks:0,errors:0,runningTasks:[]}}}function Ze(){return new dt}function go(t){let e=Ze(),{incoming:a,outgoing:n}=e.listByAgent(t);return{incoming:a,outgoing:n}}function ho(t,e){let a=String(e?.channel||"").trim(),n=String(e?.chatId||"").trim(),r=String(e?.toAgent||"").trim();if(!a||!n||!r)throw new Error("channel, chatId, toAgent required");let o=String(e?.fromAgent||t||"").trim()||t,s=e?.accountId?String(e.accountId):void 0,i=e?.summary?String(e.summary):void 0,l=e?.expiresAt?String(e.expiresAt):void 0,d=Ze().set({channel:a,chatId:n,accountId:s,fromAgent:o,toAgent:r,summary:i,expiresAt:l,createdBy:"admin-ui"});return{summary:`Handed off ${a}:${n} from ${o} to ${r}`,record:d}}function fo(t){let e=String(t?.channel||"").trim(),a=String(t?.chatId||"").trim();if(!e||!a)throw new Error("channel and chatId required");let n=t?.accountId?String(t.accountId):void 0;return{summary:Ze().remove(e,a,n)?"Released":"No active handover for that chat"}}function Ce(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function vo(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}var G={brand:"AgentX",subtitle:"Team AI ops",nodes:"machines",agentsCount:"agents",activeNow:"handling now",errorsCount:"failed",stats:{active:"Handling",total:"Today",errors:"Failed"},idle:"idle",runningNoPreview:"working \xB7 preparing reply",recentActivities:"Recent activities \u2192",noAgentsOnNode:"No agents set up on this machine.",unreachable:"This machine is unreachable.",neverRan:"not used yet",tierLabels:{"claude-code":"Claude Code",sdk:"SDK",orchestrator:"Orchestrator"},taskModalTitle:"Task activity",taskModalConnecting:"connecting\u2026",taskModalLive:"live",taskModalFinished:"finished",taskModalArchived:"archived",taskModalLoadFailed:"couldn't load",taskModalFinalResponse:"Final reply",historyPanelTitle:"Recent activities",historyEmpty:"No activity yet.",historyLoading:"loading\u2026"};var Ta=[{term:"Agent",definition:'An AI worker with its own role, instructions, and channels it responds on. Think of each agent as a job title \u2014 "support", "devops", "sales".'},{term:"Trigger word",alias:"mention",definition:"A word that activates an agent. When the trigger appears in a message (e.g. @support), AgentX routes the message to that agent."},{term:"Channel",definition:"Where messages come from \u2014 Telegram, WhatsApp, Discord, GitLab comments, a scheduled cron, or an HTTP webhook."},{term:"AI engine",alias:"tier",definition:"Which backend answers: Claude Code (reasoning + tools + files), an SDK provider (OpenAI, Anthropic API, Ollama), or an Orchestrator that coordinates sub-agents."},{term:"Agent folder",alias:"workspace",definition:"The directory on disk where the agent lives. It holds the agent's personality (CLAUDE.md), its knowledge (wiki), and the tools it can use."},{term:"Team network",alias:"mesh",definition:'When you run AgentX on more than one machine, the machines find each other and share work. Each machine is a "node"; together they are your team network.'},{term:"Status check-in",alias:"heartbeat",definition:"A lightweight ping between machines so each one knows the others are alive and responsive."},{term:"Board",definition:"A Kanban view of tasks (issues, tickets) pulled from GitLab. Drag cards between columns to move work forward \u2014 the labels update upstream automatically."},{term:"Task",definition:"A single conversation or job an agent handles, from trigger message to final reply. Every task is logged and replayable."},{term:"Schedule",alias:"cron",definition:'A recurring job \u2014 e.g. "every Monday at 9am" \u2014 that nudges an agent without a human trigger.'},{term:"Status label",alias:"scopedLabel",definition:"A GitLab label that moves an issue between Kanban columns (e.g. Status::Doing). Labels are mutually exclusive by prefix."}];function et(t={}){let e=`<script>window.UI_LABELS = ${JSON.stringify(G)};</script>`,a=`<span id="ts" class="ax-mono" title="Last update">\u2014</span>
6340
6582
  <span id="conn-dot" class="ax-dot ax-dot--ok ax-dot--pulse" title="connected"></span>
6341
6583
  <span id="conn-label">live</span>`,n=`<div class="ax-app-live">
6342
6584
  <section id="statstrip" class="ax-statstrip"></section>
@@ -6344,7 +6586,7 @@ loadAgent();
6344
6586
  </div>
6345
6587
  <aside id="history-panel" class="history-panel hidden" aria-hidden="true">
6346
6588
  <header>
6347
- <h2 id="history-panel-title">${R(W.historyPanelTitle)}</h2>
6589
+ <h2 id="history-panel-title">${R(G.historyPanelTitle)}</h2>
6348
6590
  <span class="history-panel-source" id="history-panel-source"></span>
6349
6591
  <button class="history-panel-close" id="history-panel-close" aria-label="Close">\xD7</button>
6350
6592
  </header>
@@ -6355,13 +6597,13 @@ loadAgent();
6355
6597
  <div class="task-modal-card" role="dialog" aria-modal="true">
6356
6598
  <header>
6357
6599
  <span class="task-modal-channel" id="task-modal-channel"></span>
6358
- <h2 id="task-modal-title">${R(W.taskModalTitle)}</h2>
6359
- <span class="task-modal-status" id="task-modal-status">${R(W.taskModalConnecting)}</span>
6600
+ <h2 id="task-modal-title">${R(G.taskModalTitle)}</h2>
6601
+ <span class="task-modal-status" id="task-modal-status">${R(G.taskModalConnecting)}</span>
6360
6602
  <button class="task-modal-close" id="task-modal-close" aria-label="Close">\xD7</button>
6361
6603
  </header>
6362
6604
  <div id="task-modal-output" class="task-modal-output"></div>
6363
6605
  </div>
6364
- </div>`;return A({title:`${W.brand} \xB7 ${W.subtitle}`,activeTab:"live",subtitle:W.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:go,scripts:e+`<script>${ho}</script>`,headExtras:`<script>
6606
+ </div>`;return A({title:`${G.brand} \xB7 ${G.subtitle}`,activeTab:"live",subtitle:G.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:bo,scripts:e+`<script>${xo}</script>`,headExtras:`<script>
6365
6607
  // rightExtras for the topbar are injected at runtime \u2014 they reference
6366
6608
  // IDs (#ts, #conn-dot) that the script below addresses directly.
6367
6609
  document.addEventListener('DOMContentLoaded', () => {
@@ -6372,7 +6614,7 @@ loadAgent();
6372
6614
  extras.innerHTML = ${JSON.stringify(a)};
6373
6615
  right.insertBefore(extras, right.firstChild);
6374
6616
  });
6375
- </script>`})}var go=`
6617
+ </script>`})}var bo=`
6376
6618
  /* --- Page frame --- */
6377
6619
  .ax-app-live { min-height: 100vh; display: flex; flex-direction: column; }
6378
6620
 
@@ -6641,7 +6883,7 @@ loadAgent();
6641
6883
  border-top-color: var(--ax-accent); border-radius: 50%;
6642
6884
  animation: ax-spin 800ms linear infinite; display: inline-block;
6643
6885
  }
6644
- @keyframes ax-spin { to { transform: rotate(360deg); } }`,ho=`
6886
+ @keyframes ax-spin { to { transform: rotate(360deg); } }`,xo=`
6645
6887
  'use strict';
6646
6888
 
6647
6889
  const ui = { nodes: new Map(), summary: { nodes: 0, agents: 0, busy: 0, errors: 0 } };
@@ -7317,7 +7559,7 @@ document.getElementById('grid').addEventListener('click', (e) => {
7317
7559
  }
7318
7560
  });
7319
7561
 
7320
- `;function Ta(t={}){let e=`
7562
+ `;function Ca(t={}){let e=`
7321
7563
  <select id="boardPicker" title="Switch board"></select>
7322
7564
  <div class="search">
7323
7565
  <span class="icon">\u2315</span>
@@ -7418,7 +7660,7 @@ document.getElementById('grid').addEventListener('click', (e) => {
7418
7660
  </footer>
7419
7661
  </div>
7420
7662
  </div>
7421
- <script src="/sortable.min.js"></script>`;return A({title:"AgentX \xB7 Boards",activeTab:"boards",subtitle:"Boards",subheader:e,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a,css:fo,scripts:`<script>${vo}</script>`,headExtras:`<script>
7663
+ <script src="/sortable.min.js"></script>`;return A({title:"AgentX \xB7 Boards",activeTab:"boards",subtitle:"Boards",subheader:e,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a,css:yo,scripts:`<script>${wo}</script>`,headExtras:`<script>
7422
7664
  // The boards page has its own connection dot + wants body height:100%
7423
7665
  // for the full-viewport kanban layout. Inject the dot into the topbar
7424
7666
  // and override body height at runtime so the shared shell doesn't
@@ -7434,7 +7676,7 @@ document.getElementById('grid').addEventListener('click', (e) => {
7434
7676
  right.insertBefore(dot, right.firstChild);
7435
7677
  }
7436
7678
  });
7437
- </script>`})}var fo=`
7679
+ </script>`})}var yo=`
7438
7680
  /* Kanban subheader \u2014 replaces the legacy toolbar that used to live in <header>. */
7439
7681
  .ax-subheader select, .ax-subheader input, .ax-subheader button {
7440
7682
  background: var(--col); color: var(--text); border: 1px solid var(--border);
@@ -7687,7 +7929,7 @@ header a.link:hover { color: var(--accent); border-color: var(--accent); }
7687
7929
  .draft-box .draft-row .hint { color: var(--muted); font-size: 12px; flex: 1; }
7688
7930
  .draft-box .draft-row .hint.err { color: var(--red); }
7689
7931
  .draft-box .draft-row .hint.ok { color: var(--green); }
7690
- `,vo=`
7932
+ `,wo=`
7691
7933
  'use strict';
7692
7934
  const state = {
7693
7935
  boards: [], current: null, items: {},
@@ -8746,9 +8988,9 @@ function appendEvents(events) {
8746
8988
  }
8747
8989
 
8748
8990
  loadBoards().catch(e => toast('Init failed: ' + e.message));
8749
- `;function Ca(t={}){let a=`<h1>Plain-English glossary</h1>
8991
+ `;function Aa(t={}){let a=`<h1>Plain-English glossary</h1>
8750
8992
  <p class="lead">What the terms on the dashboard mean. Schema keys (shown in the pill on the right of each term) are what you'd write in <code>agentx.json</code> \u2014 the dashboard just relabels them for readability.</p>
8751
- ${Sa.map(n=>{let r=n.alias?`<span class="alias" title="Schema key">${R(n.alias)}</span>`:"";return`<article class="term"><h3>${R(n.term)}${r}</h3><p>${R(n.definition)}</p></article>`}).join("")}`;return A({title:`${W.brand} \xB7 Glossary`,activeTab:"glossary",subtitle:"Glossary",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:bo})}var bo=`
8993
+ ${Ta.map(n=>{let r=n.alias?`<span class="alias" title="Schema key">${R(n.alias)}</span>`:"";return`<article class="term"><h3>${R(n.term)}${r}</h3><p>${R(n.definition)}</p></article>`}).join("")}`;return A({title:`${G.brand} \xB7 Glossary`,activeTab:"glossary",subtitle:"Glossary",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:ko})}var ko=`
8752
8994
  main { max-width: 760px; margin: 0 auto; padding: 32px 24px 80px; }
8753
8995
  h1 { font-size: 22px; margin: 0 0 6px; font-weight: 600; letter-spacing: -0.01em; }
8754
8996
  .lead {
@@ -8778,7 +9020,7 @@ article.term .alias {
8778
9020
  }
8779
9021
  article.term p {
8780
9022
  margin: 0; color: var(--ax-text-2); font-size: 13px; line-height: 1.6;
8781
- }`;function Aa(t={}){let e=`<div class="ax-wf__root">
9023
+ }`;function $a(t={}){let e=`<div class="ax-wf__root">
8782
9024
  <aside class="ax-wf__list">
8783
9025
  <header>
8784
9026
  <h2>Workflows</h2>
@@ -8825,7 +9067,7 @@ article.term p {
8825
9067
  </aside>
8826
9068
  </div>
8827
9069
 
8828
- <div id="wf-toast" class="ax-wf__toast" hidden></div>`;return A({title:"AgentX \xB7 Workflows",activeTab:"workflows",subtitle:"Workflows",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:xo,scripts:`<script>${yo}</script>`})}var xo=`
9070
+ <div id="wf-toast" class="ax-wf__toast" hidden></div>`;return A({title:"AgentX \xB7 Workflows",activeTab:"workflows",subtitle:"Workflows",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:_o,scripts:`<script>${Eo}</script>`})}var _o=`
8829
9071
  .ax-wf__root {
8830
9072
  display: grid;
8831
9073
  grid-template-columns: 340px 1fr;
@@ -9046,7 +9288,7 @@ article.term p {
9046
9288
  font-size: 12px; z-index: 50;
9047
9289
  }
9048
9290
  .hint { color: var(--ax-muted); font-size: 11px; }
9049
- `,yo=`
9291
+ `,Eo=`
9050
9292
  (() => {
9051
9293
  const $ = (sel) => document.querySelector(sel)
9052
9294
  const $$ = (sel) => Array.from(document.querySelectorAll(sel))
@@ -9364,7 +9606,7 @@ article.term p {
9364
9606
  setInterval(refresh, 15000)
9365
9607
  })
9366
9608
  })();
9367
- `;function $a(t={}){let e='<div id="wfe-root" style="height:100%"></div>';return A({title:"AgentX \xB7 Workflow editor",activeTab:"workflows",subtitle:"Workflow editor",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:wo,scripts:'<script src="/assets/workflow-editor.global.js" defer></script>',noMain:!0})}var wo=`
9609
+ `;function Ma(t={}){let e='<div id="wfe-root" style="height:100%"></div>';return A({title:"AgentX \xB7 Workflow editor",activeTab:"workflows",subtitle:"Workflow editor",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:So,scripts:'<script src="/assets/workflow-editor.global.js" defer></script>',noMain:!0})}var So=`
9368
9610
  /* Preload the fonts the redesign's CSS references. Placed in the shell so
9369
9611
  * they start fetching while the React bundle is still parsing. */
9370
9612
  @import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Instrument+Serif&display=swap");
@@ -9385,25 +9627,25 @@ body { margin: 0; overflow: hidden; }
9385
9627
  font: 13px/1 -apple-system, BlinkMacSystemFont, sans-serif;
9386
9628
  text-align: center;
9387
9629
  }
9388
- `;function Ia(t,e,a){let n=t.url||"";if(!n.startsWith("/api/workflows"))return!1;let r=t.method||"GET";if(n==="/api/workflows"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?E(e,200,{workflows:a.store.list()}):!0;if(r==="POST")return a.requireScope(t,e,["dashboard:write"])?te(t,e,s=>Ma(e,a,s,{mode:"create"})):!0}if(n.startsWith("/api/workflows/runs"))return r==="GET"&&!a.requireScope(t,e,["dashboard:read"])?!0:_o(t,e,a,n);if(n.startsWith("/api/workflows/tasks")){if(!a.tasks||!a.dispatcher)return E(e,501,{error:"task engine not enabled"});let s=n.replace(/^\/api\/workflows\/tasks/,"");if(s==="/history"||s.startsWith("/history?")){if(r!=="GET")return E(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:read"]))return!0;let l=new URL(n,"http://_").searchParams,d=parseInt(l.get("limit")||"50",10),c=Number.isFinite(d)?Math.max(1,Math.min(500,d)):50,h=a.tasks.listArchived().filter(x=>!!x.submittedAt).sort((x,p)=>x.submittedAt<p.submittedAt?1:-1).slice(0,c).map(x=>{let p=Date.parse(x.createdAt),m=Date.parse(x.submittedAt),f=x.dueAt?Date.parse(x.dueAt):null,w=f!==null&&m>f;return{id:x.id,runId:x.runId,workflowId:x.workflowId,title:x.title,assignee:x.assignee,submittedBy:x.submittedBy,submittedAt:x.submittedAt,submittedAction:x.submittedAction,createdAt:x.createdAt,dueAt:x.dueAt??null,durationMs:Number.isFinite(m-p)?m-p:null,breachedSla:w,status:x.status}});return E(e,200,{rows:h})}if(s===""||s.startsWith("?")){if(r!=="GET")return E(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:read"]))return!0;let d=new URL(n,"http://_").searchParams.get("actor")||void 0,c=d?a.tasks.listForActor(d):a.tasks.listOpen();return E(e,200,{tasks:c})}let i=s.match(/^\/([^\/?]+)(\/submit)?$/);if(i){let l=decodeURIComponent(i[1]);if(i[2])return r!=="POST"?E(e,405,{error:"method not allowed"}):a.requireScope(t,e,["dashboard:write"])?te(t,e,async d=>{let c=gt.safeParse(d&&typeof d=="object"&&"submission"in d?d.submission:d);if(!c.success)return E(e,400,{error:"invalid submission",issues:c.error.issues.map(x=>({path:x.path.join("."),message:x.message}))});let u=typeof d?.submittedBy=="string"?d.submittedBy:"anonymous",h=await a.dispatcher.submitTask(l,c.data,u);return h.ok?E(e,200,{ok:!0,runId:h.runId}):E(e,400,{error:h.error,fieldErrors:h.fieldErrors})}):!0;if(r==="GET"){if(!a.requireScope(t,e,["dashboard:read"]))return!0;let d=a.tasks.get(l);return d?E(e,200,{task:d}):E(e,404,{error:"task not found"})}}}if(n.startsWith("/api/workflows/signal/")){if(r!=="POST")return E(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;if(!a.dispatcher)return E(e,501,{error:"dispatcher not enabled"});let s=decodeURIComponent(n.replace(/^\/api\/workflows\/signal\//,"").split("?")[0]);return s?te(t,e,i=>{let l=i,d=a.dispatcher.emitSignal({name:s,scope:l?.scope,workflowId:l?.workflowId,payload:l?.payload});return E(e,200,{ok:!0,emission:d})}):E(e,400,{error:"signal name required"})}let o=n.match(/^\/api\/workflows\/([^\/?]+)(\/layout|\/validate)?(\?.*)?$/);if(o){let s=decodeURIComponent(o[1]),i=o[2];if(i==="/layout"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?E(e,200,{layout:a.layouts.get(s)}):!0;if(r==="PUT")return a.requireScope(t,e,["dashboard:write"])?te(t,e,l=>{try{let d=a.layouts.save(s,l);return E(e,200,{layout:d})}catch(d){return E(e,400,{error:"invalid layout",message:d.message})}}):!0}if(i==="/validate"&&r==="POST")return a.requireScope(t,e,["dashboard:read"])?te(t,e,l=>{let d=Ie.safeParse(l);if(!d.success)return E(e,200,{ok:!1,issues:d.error.issues.map(u=>({path:u.path.join("."),message:u.message}))});let c=Le(d.data).map(u=>({path:"",message:u}));return E(e,200,{ok:c.length===0,issues:c,workflow:d.data})}):!0;if(!i){if(r==="GET"){if(!a.requireScope(t,e,["dashboard:read"]))return!0;let l=a.store.get(s);return l?E(e,200,{workflow:l}):E(e,404,{error:"workflow not found"})}if(r==="PUT")return a.requireScope(t,e,["dashboard:write"])?te(t,e,l=>Ma(e,a,l,{mode:"update",id:s})):!0;if(r==="DELETE"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=a.store.delete(s);return a.layouts.delete(s),E(e,l?200:404,l?{ok:!0}:{error:"workflow not found"})}}}return E(e,404,{error:"unknown workflows endpoint",path:n})}var ko=["mesh"];function Ma(t,e,a,n){let r=Ie.safeParse(a);if(!r.success)return E(t,400,{error:"invalid workflow",issues:r.error.issues.map(l=>({path:l.path.join("."),message:l.message}))});let o=r.data,s=Le(o);if(s.length>0)return E(t,400,{error:"lint errors",issues:s.map(l=>({path:"",message:l}))});if(n.mode==="update"&&o.id!==n.id)return E(t,400,{error:"workflow id does not match path"});if(n.mode==="create"&&e.store.get(o.id))return E(t,409,{error:`workflow "${o.id}" already exists`});if(n.mode==="update"&&a&&typeof a=="object"){let l=a,d=e.store.get(n.id);if(d)for(let c of ko)!(c in l)&&c in d&&(o[c]=d[c])}let i=e.store.save(o);return e.layouts.sync(i.id,i.nodes.map(l=>l.id)),E(t,200,{workflow:i})}function _o(t,e,a,n){let r=new URL(n,"http://_").searchParams,o=n.replace(/^\/api\/workflows\/runs/,"");if(o===""||o.startsWith("?")){let l=Math.max(1,Math.min(500,Number(r.get("limit")||50))),d=r.get("workflowId")||void 0;return E(e,200,{runs:a.runs.list({workflowId:d,limit:l})})}let s=o.match(/^\/([^\/?]+)\/status$/);if(s){if((t.method||"GET").toUpperCase()!=="POST")return E(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=decodeURIComponent(s[1]);return te(t,e,d=>{let c=d?.status;return c!=="paused"&&c!=="running"&&c!=="canceled"?E(e,400,{error:"status must be paused|running|canceled"}):a.runs.setStatus(l,c)?E(e,200,{ok:!0,runId:l,status:c}):E(e,404,{error:"run not found"})})}let i=o.match(/^\/([^\/?]+)(\/stream)?$/);if(i){let l=decodeURIComponent(i[1]);if(i[2])return Eo(t,e,a,l);let d=a.runs.get(l);return d?E(e,200,{run:d}):E(e,404,{error:"run not found"})}return E(e,404,{error:"unknown runs endpoint"})}function Eo(t,e,a,n){let r=a.runs.get(n);if(!r)return E(e,404,{error:"run not found"}),!0;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`data: ${JSON.stringify(r)}
9630
+ `;function La(t,e,a){let n=t.url||"";if(!n.startsWith("/api/workflows"))return!1;let r=t.method||"GET";if(n==="/api/workflows"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?S(e,200,{workflows:a.store.list()}):!0;if(r==="POST")return a.requireScope(t,e,["dashboard:write"])?te(t,e,s=>Ia(e,a,s,{mode:"create"})):!0}if(n.startsWith("/api/workflows/runs"))return r==="GET"&&!a.requireScope(t,e,["dashboard:read"])?!0:Co(t,e,a,n);if(n.startsWith("/api/workflows/tasks")){if(!a.tasks||!a.dispatcher)return S(e,501,{error:"task engine not enabled"});let s=n.replace(/^\/api\/workflows\/tasks/,"");if(s==="/history"||s.startsWith("/history?")){if(r!=="GET")return S(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:read"]))return!0;let l=new URL(n,"http://_").searchParams,d=parseInt(l.get("limit")||"50",10),c=Number.isFinite(d)?Math.max(1,Math.min(500,d)):50,h=a.tasks.listArchived().filter(y=>!!y.submittedAt).sort((y,p)=>y.submittedAt<p.submittedAt?1:-1).slice(0,c).map(y=>{let p=Date.parse(y.createdAt),m=Date.parse(y.submittedAt),f=y.dueAt?Date.parse(y.dueAt):null,k=f!==null&&m>f;return{id:y.id,runId:y.runId,workflowId:y.workflowId,title:y.title,assignee:y.assignee,submittedBy:y.submittedBy,submittedAt:y.submittedAt,submittedAction:y.submittedAction,createdAt:y.createdAt,dueAt:y.dueAt??null,durationMs:Number.isFinite(m-p)?m-p:null,breachedSla:k,status:y.status}});return S(e,200,{rows:h})}if(s===""||s.startsWith("?")){if(r!=="GET")return S(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:read"]))return!0;let d=new URL(n,"http://_").searchParams.get("actor")||void 0,c=d?a.tasks.listForActor(d):a.tasks.listOpen();return S(e,200,{tasks:c})}let i=s.match(/^\/([^\/?]+)(\/submit)?$/);if(i){let l=decodeURIComponent(i[1]);if(i[2])return r!=="POST"?S(e,405,{error:"method not allowed"}):a.requireScope(t,e,["dashboard:write"])?te(t,e,async d=>{let c=ht.safeParse(d&&typeof d=="object"&&"submission"in d?d.submission:d);if(!c.success)return S(e,400,{error:"invalid submission",issues:c.error.issues.map(y=>({path:y.path.join("."),message:y.message}))});let u=typeof d?.submittedBy=="string"?d.submittedBy:"anonymous",h=await a.dispatcher.submitTask(l,c.data,u);return h.ok?S(e,200,{ok:!0,runId:h.runId}):S(e,400,{error:h.error,fieldErrors:h.fieldErrors})}):!0;if(r==="GET"){if(!a.requireScope(t,e,["dashboard:read"]))return!0;let d=a.tasks.get(l);return d?S(e,200,{task:d}):S(e,404,{error:"task not found"})}}}if(n.startsWith("/api/workflows/signal/")){if(r!=="POST")return S(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;if(!a.dispatcher)return S(e,501,{error:"dispatcher not enabled"});let s=decodeURIComponent(n.replace(/^\/api\/workflows\/signal\//,"").split("?")[0]);return s?te(t,e,i=>{let l=i,d=a.dispatcher.emitSignal({name:s,scope:l?.scope,workflowId:l?.workflowId,payload:l?.payload});return S(e,200,{ok:!0,emission:d})}):S(e,400,{error:"signal name required"})}let o=n.match(/^\/api\/workflows\/([^\/?]+)(\/layout|\/validate)?(\?.*)?$/);if(o){let s=decodeURIComponent(o[1]),i=o[2];if(i==="/layout"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?S(e,200,{layout:a.layouts.get(s)}):!0;if(r==="PUT")return a.requireScope(t,e,["dashboard:write"])?te(t,e,l=>{try{let d=a.layouts.save(s,l);return S(e,200,{layout:d})}catch(d){return S(e,400,{error:"invalid layout",message:d.message})}}):!0}if(i==="/validate"&&r==="POST")return a.requireScope(t,e,["dashboard:read"])?te(t,e,l=>{let d=Ie.safeParse(l);if(!d.success)return S(e,200,{ok:!1,issues:d.error.issues.map(u=>({path:u.path.join("."),message:u.message}))});let c=Le(d.data).map(u=>({path:"",message:u}));return S(e,200,{ok:c.length===0,issues:c,workflow:d.data})}):!0;if(!i){if(r==="GET"){if(!a.requireScope(t,e,["dashboard:read"]))return!0;let l=a.store.get(s);return l?S(e,200,{workflow:l}):S(e,404,{error:"workflow not found"})}if(r==="PUT")return a.requireScope(t,e,["dashboard:write"])?te(t,e,l=>Ia(e,a,l,{mode:"update",id:s})):!0;if(r==="DELETE"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=a.store.delete(s);return a.layouts.delete(s),S(e,l?200:404,l?{ok:!0}:{error:"workflow not found"})}}}return S(e,404,{error:"unknown workflows endpoint",path:n})}var To=["mesh"];function Ia(t,e,a,n){let r=Ie.safeParse(a);if(!r.success)return S(t,400,{error:"invalid workflow",issues:r.error.issues.map(l=>({path:l.path.join("."),message:l.message}))});let o=r.data,s=Le(o);if(s.length>0)return S(t,400,{error:"lint errors",issues:s.map(l=>({path:"",message:l}))});if(n.mode==="update"&&o.id!==n.id)return S(t,400,{error:"workflow id does not match path"});if(n.mode==="create"&&e.store.get(o.id))return S(t,409,{error:`workflow "${o.id}" already exists`});if(n.mode==="update"&&a&&typeof a=="object"){let l=a,d=e.store.get(n.id);if(d)for(let c of To)!(c in l)&&c in d&&(o[c]=d[c])}let i=e.store.save(o);return e.layouts.sync(i.id,i.nodes.map(l=>l.id)),S(t,200,{workflow:i})}function Co(t,e,a,n){let r=new URL(n,"http://_").searchParams,o=n.replace(/^\/api\/workflows\/runs/,"");if(o===""||o.startsWith("?")){let l=Math.max(1,Math.min(500,Number(r.get("limit")||50))),d=r.get("workflowId")||void 0;return S(e,200,{runs:a.runs.list({workflowId:d,limit:l})})}let s=o.match(/^\/([^\/?]+)\/status$/);if(s){if((t.method||"GET").toUpperCase()!=="POST")return S(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=decodeURIComponent(s[1]);return te(t,e,d=>{let c=d?.status;return c!=="paused"&&c!=="running"&&c!=="canceled"?S(e,400,{error:"status must be paused|running|canceled"}):a.runs.setStatus(l,c)?S(e,200,{ok:!0,runId:l,status:c}):S(e,404,{error:"run not found"})})}let i=o.match(/^\/([^\/?]+)(\/stream)?$/);if(i){let l=decodeURIComponent(i[1]);if(i[2])return Ao(t,e,a,l);let d=a.runs.get(l);return d?S(e,200,{run:d}):S(e,404,{error:"run not found"})}return S(e,404,{error:"unknown runs endpoint"})}function Ao(t,e,a,n){let r=a.runs.get(n);if(!r)return S(e,404,{error:"run not found"}),!0;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`data: ${JSON.stringify(r)}
9389
9631
 
9390
9632
  `);let o=!1,s=()=>{o=!0,l?.(),clearInterval(c);try{e.end()}catch{}};t.on("close",s);let i=u=>{if(!o)try{e.write(`data: ${JSON.stringify(u)}
9391
9633
 
9392
- `)}catch{s()}},l=a.runEvents?.subscribe(n,i),d=r.updatedAt,c=setInterval(()=>{if(o)return;let u=a.runs.get(n);u&&u.updatedAt!==d&&(d=u.updatedAt,i(u))},2e3);return!0}function te(t,e,a){let n="";return t.setEncoding("utf8"),t.on("data",r=>{n+=r}),t.on("end",()=>{let r;try{r=n?JSON.parse(n):{}}catch(o){E(e,400,{error:"invalid JSON body",message:o.message});return}Promise.resolve(a(r)).catch(o=>{try{E(e,500,{error:"handler threw",message:o?.message??String(o)})}catch{}})}),t.on("error",r=>E(e,400,{error:"body read failed",message:r.message})),!0}function E(t,e,a){return t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a)),!0}function qi(t){let e=t.dashboard,a=t.boards,n=e.port,r=e.bind,o=e.token,s=new Map;for(let x of a)try{s.set(x.id,Po(x,t))}catch(p){console.error(` Board "${x.id}" failed to initialize: ${p.message}`)}let i=t.node?.id||"local",l=t.workflows?.dir?ge(process.cwd(),t.workflows.dir):void 0,d=new pt(l?{baseDir:l}:void 0),c=new ut(l?{baseDir:l,nodeId:i}:{nodeId:i}),u=new mt(l?{baseDir:l}:void 0);ma(t),So(async(x,p)=>{try{await Io(x,p,{boards:a,sources:s,token:o,config:t,workflowStore:d,workflowRuns:c,workflowLayouts:u})}catch(m){k(p,500,{error:m.message||"internal error"})}}).listen(n,r,()=>{let x=r==="0.0.0.0"?"localhost":r;a.length===0?(console.log(`
9393
- Live dashboard: http://${x}:${n}
9634
+ `)}catch{s()}},l=a.runEvents?.subscribe(n,i),d=r.updatedAt,c=setInterval(()=>{if(o)return;let u=a.runs.get(n);u&&u.updatedAt!==d&&(d=u.updatedAt,i(u))},2e3);return!0}function te(t,e,a){let n="";return t.setEncoding("utf8"),t.on("data",r=>{n+=r}),t.on("end",()=>{let r;try{r=n?JSON.parse(n):{}}catch(o){S(e,400,{error:"invalid JSON body",message:o.message});return}Promise.resolve(a(r)).catch(o=>{try{S(e,500,{error:"handler threw",message:o?.message??String(o)})}catch{}})}),t.on("error",r=>S(e,400,{error:"body read failed",message:r.message})),!0}function S(t,e,a){return t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a)),!0}function Ui(t){let e=t.dashboard,a=t.boards,n=e.port,r=e.bind,o=e.token,s=new Map;for(let y of a)try{s.set(y.id,No(y,t))}catch(p){console.error(` Board "${y.id}" failed to initialize: ${p.message}`)}let i=t.node?.id||"local",l=t.workflows?.dir?ge(process.cwd(),t.workflows.dir):void 0,d=new ut(l?{baseDir:l}:void 0),c=new mt(l?{baseDir:l,nodeId:i}:{nodeId:i}),u=new gt(l?{baseDir:l}:void 0);ga(t),$o(async(y,p)=>{try{await Ro(y,p,{boards:a,sources:s,token:o,config:t,workflowStore:d,workflowRuns:c,workflowLayouts:u})}catch(m){_(p,500,{error:m.message||"internal error"})}}).listen(n,r,()=>{let y=r==="0.0.0.0"?"localhost":r;a.length===0?(console.log(`
9635
+ Live dashboard: http://${y}:${n}
9394
9636
  `),console.log(" (no boards configured \u2014 '/' serves the live view; add a board with 'agentx board add')")):(console.log(`
9395
- Kanban dashboard: http://${x}:${n}
9396
- `),console.log(` Boards: ${a.map(p=>p.id).join(", ")}`)),r==="127.0.0.1"&&!o?console.log(" (bound to localhost; no auth token \u2014 safe default)"):r!=="127.0.0.1"&&!o&&console.log(" \u26A0 bound to a non-loopback address without a token \u2014 writes are UNAUTHENTICATED")})}async function Io(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if(e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Allow-Methods","GET, POST, PATCH, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization, X-Requested-With"),o==="OPTIONS"){e.writeHead(204),e.end();return}if(o==="GET"&&r==="/"){let p=_t();if(!p.configExists||p.agentCount===0){e.writeHead(302,{Location:"/setup"}),e.end();return}let m=H(a.config),f=a.boards.length===0?Ze({peers:m}):Ta({peers:m});e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(f);return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ze({peers:H(a.config)}));return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ca({peers:H(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Aa({peers:H(a.config)}));return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end($a({peers:H(a.config)}));return}if(o==="GET"&&r==="/inbox"){let p=n.searchParams.get("actor")||void 0;e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(wt({actor:p}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(kt({}));return}if(o==="GET"&&r==="/graph"){e.writeHead(302,{Location:"/admin/graph"}),e.end();return}if(o==="GET"&&r==="/setup"){Et(t,e);return}if(o==="POST"&&r==="/api/setup"){await St(t,e);return}if(o==="GET"&&r==="/admin"){Nt(t,e,H(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){Wt(t,e,H(a.config),a.token);return}if(o==="GET"&&(r==="/admin/health"||r==="/admin/observability")){if(r==="/admin/observability"){e.writeHead(302,{Location:"/admin/health"}),e.end();return}Yt(t,e,H(a.config));return}if(r.startsWith("/api/admin/")){let p=String(t.headers["x-agentx-peer"]||"").trim()||n.searchParams.get("peer")||"";if(p==="fleet"){if(r==="/api/admin/activity-graph"){await Jo(t,e,a);return}let m=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(m){let f=decodeURIComponent(m[1]),w=f.indexOf("::");if(w>0){let b=f.slice(0,w),g=f.slice(w+2),v=a.config.node?.id||a.config.node?.name||"local";if(b===v)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(g)}`;else{let C=(a.config.dashboard?.daemons||[]).find(y=>(y.name||y.url)===b);if(C){let y=nt(C.url.replace(/\/+$/,""),a.config);if(y){await La(t,e,y,`/api/admin/activity-graph/dispatch/${encodeURIComponent(g)}`);return}}k(e,404,{error:`unknown node "${b}" in fleet dispatch id`});return}}}}else if(p&&p!=="primary"){let m=nt(p,a.config);if(!m){k(e,404,{error:`unknown peer: ${p}`});return}let f=(n.search||"").replace(/[?&]peer=[^&]*/g,b=>b.startsWith("?")?"?":"");await La(t,e,m,r+(f==="?"?"":f));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await Qt(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await Xo(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:p}=await import("./doctor-SEOUFHSL.js"),f=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",w=await p({running:f});k(e,200,w)}catch(p){k(e,500,{error:p?.message||String(p)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ta({peers:H(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await ea(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(aa({peers:H(a.config)}));return}if(o==="GET"&&(r==="/admin/wiki"||r.startsWith("/admin/wiki/"))){if(r==="/admin/wiki"){e.writeHead(302,{Location:"/admin/wiki/"}),e.end();return}await Oo(a)(t,e);return}if(o==="GET"&&r==="/admin/activity-graph"){sa(t,e,H(a.config));return}if(o==="GET"&&r==="/api/admin/activity-graph"&&await ga(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await ha(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await va(t,e,r))return;let s=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(s){ya(t,e,s[1],H(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let p=t.headers.authorization||"",m=p.startsWith("Bearer ")?p.slice(7):"";if(m!==a.token){let f=new U,w=m?f.verify(m):null;if(!w||!ce(w,"dashboard:write")){k(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await Bt(t,e);return}if(r.startsWith("/api/admin/graph/")){await Ut(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await wa(t,e,r);return}if(r.startsWith("/api/admin/")){await jt(t,e,r);return}if(o==="GET"&&r==="/sortable.min.js"){e.writeHead(200,{"Content-Type":"application/javascript; charset=utf-8","Cache-Control":"public, max-age=86400"}),e.end(Ct);return}if(o==="GET"&&r.startsWith("/assets/")){let p=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(p)){k(e,400,{error:"invalid asset name"});return}let m=Uo("web/"+p);try{let f=await Ko(m),w=p.endsWith(".map")?"application/json; charset=utf-8":p.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8";e.writeHead(200,{"Content-Type":w,"Cache-Control":"public, max-age=60"}),e.end(f)}catch{k(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let p=await Pa(a.config);k(e,200,p)}catch(p){k(e,502,{error:p.message})}return}if(o==="GET"&&r==="/api/live/stream"){No(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let p=new URL(t.url||"/","http://localhost"),m=p.searchParams.get("node"),f=p.searchParams.get("agent"),w=p.searchParams.get("task");if(!m||!f||!w){k(e,400,{error:"node, agent, task query params required"});return}await Bo(t,e,a,m,f,w);return}if(o==="GET"&&r==="/api/task/history"){let p=new URL(t.url||"/","http://localhost"),m=p.searchParams.get("node"),f=p.searchParams.get("agent"),w=p.searchParams.get("task"),b=p.searchParams.get("limit")||"50";if(!m||!f){k(e,400,{error:"node and agent query params required"});return}await qo(e,a,m,f,w,b);return}if(o==="GET"&&r==="/api/agents"){try{let p={};a.config.dashboard.token&&(p.Authorization=`Bearer ${a.config.dashboard.token}`);let m=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:p});if(!m.ok)throw new Error(`HTTP ${m.status}`);let f=await m.json();k(e,200,f)}catch(p){k(e,502,{error:p.message||"agents fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let p=await le(t);try{let m=await Go(a.config,p);k(e,200,m)}catch(m){k(e,502,{error:m.message||"draft failed"})}return}let i=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(i&&o==="POST"){let p=i[1];if(!jo(t,e,[`agent:${p}`]))return;await zo(t,e,a.config,p);return}if(r.startsWith("/api/")&&a.token){let p=t.headers.authorization||"",m=p.startsWith("Bearer ")?p.slice(7):"";if(m!==a.token){let f=new U,w=m?f.verify(m):null;if(!w||!ce(w,"dashboard:write")){k(e,401,{error:"unauthorized"});return}}}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){k(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(o==="GET"&&r==="/events"){let m=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"});let f=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(v=>({name:v.name,url:v.url,token:v.token}))],w={flag:!1},b=[];t.on("close",()=>{w.flag=!0;for(let v of b)try{v.abort()}catch{}});let g=setInterval(()=>{if(!w.flag)try{e.write(`: ping
9637
+ Kanban dashboard: http://${y}:${n}
9638
+ `),console.log(` Boards: ${a.map(p=>p.id).join(", ")}`)),r==="127.0.0.1"&&!o?console.log(" (bound to localhost; no auth token \u2014 safe default)"):r!=="127.0.0.1"&&!o&&console.log(" \u26A0 bound to a non-loopback address without a token \u2014 writes are UNAUTHENTICATED")})}async function Ro(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if(e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Allow-Methods","GET, POST, PATCH, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization, X-Requested-With"),o==="OPTIONS"){e.writeHead(204),e.end();return}if(o==="GET"&&r==="/"){let p=Et();if(!p.configExists||p.agentCount===0){e.writeHead(302,{Location:"/setup"}),e.end();return}let m=B(a.config),f=a.boards.length===0?et({peers:m}):Ca({peers:m});e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(f);return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(et({peers:B(a.config)}));return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Aa({peers:B(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end($a({peers:B(a.config)}));return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ma({peers:B(a.config)}));return}if(o==="GET"&&r==="/inbox"){let p=n.searchParams.get("actor")||void 0;e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(kt({actor:p}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(_t({}));return}if(o==="GET"&&r==="/graph"){e.writeHead(302,{Location:"/admin/graph"}),e.end();return}if(o==="GET"&&r==="/setup"){St(t,e);return}if(o==="POST"&&r==="/api/setup"){await Tt(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await Ct(t,e);return}if(o==="GET"&&r==="/admin"){Bt(t,e,B(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){Ut(t,e,B(a.config),a.token);return}if(o==="GET"&&(r==="/admin/health"||r==="/admin/observability")){if(r==="/admin/observability"){e.writeHead(302,{Location:"/admin/health"}),e.end();return}Qt(t,e,B(a.config));return}if(r.startsWith("/api/admin/")){let p=String(t.headers["x-agentx-peer"]||"").trim()||n.searchParams.get("peer")||"";if(p==="fleet"){if(r==="/api/admin/activity-graph"){await Qo(t,e,a);return}let m=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(m){let f=decodeURIComponent(m[1]),k=f.indexOf("::");if(k>0){let b=f.slice(0,k),w=f.slice(k+2),g=a.config.node?.id||a.config.node?.name||"local";if(b===g)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(w)}`;else{let v=(a.config.dashboard?.daemons||[]).find(x=>(x.name||x.url)===b);if(v){let x=rt(v.url.replace(/\/+$/,""),a.config);if(x){await Da(t,e,x,`/api/admin/activity-graph/dispatch/${encodeURIComponent(w)}`);return}}_(e,404,{error:`unknown node "${b}" in fleet dispatch id`});return}}}}else if(p&&p!=="primary"){let m=rt(p,a.config);if(!m){_(e,404,{error:`unknown peer: ${p}`});return}let f=(n.search||"").replace(/[?&]peer=[^&]*/g,b=>b.startsWith("?")?"?":"");await Da(t,e,m,r+(f==="?"?"":f));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await Zt(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await Zo(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:p}=await import("./doctor-ZTECTUHX.js"),f=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",k=await p({running:f});_(e,200,k)}catch(p){_(e,500,{error:p?.message||String(p)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(aa({peers:B(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await ta(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(na({peers:B(a.config)}));return}if(o==="GET"&&(r==="/admin/wiki"||r.startsWith("/admin/wiki/"))){if(r==="/admin/wiki"){e.writeHead(302,{Location:"/admin/wiki/"}),e.end();return}await jo(a)(t,e);return}if(o==="GET"&&r==="/admin/activity-graph"){ia(t,e,B(a.config));return}if(o==="GET"&&r==="/api/admin/activity-graph"&&await ha(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await fa(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await ba(t,e,r))return;let s=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(s){wa(t,e,s[1],B(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let p=t.headers.authorization||"",m=p.startsWith("Bearer ")?p.slice(7):"";if(m!==a.token){let f=new U,k=m?f.verify(m):null;if(!k||!ce(k,"dashboard:write")){_(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await jt(t,e);return}if(r.startsWith("/api/admin/graph/")){await Kt(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await ka(t,e,r);return}if(r.startsWith("/api/admin/")){await zt(t,e,r);return}if(o==="GET"&&r==="/sortable.min.js"){e.writeHead(200,{"Content-Type":"application/javascript; charset=utf-8","Cache-Control":"public, max-age=86400"}),e.end($t);return}if(o==="GET"&&r.startsWith("/assets/")){let p=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(p)){_(e,400,{error:"invalid asset name"});return}let m=Vo("web/"+p);try{let f=await Yo(m),k=p.endsWith(".map")?"application/json; charset=utf-8":p.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8";e.writeHead(200,{"Content-Type":k,"Cache-Control":"public, max-age=60"}),e.end(f)}catch{_(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let p=await Ra(a.config);_(e,200,p)}catch(p){_(e,502,{error:p.message})}return}if(o==="GET"&&r==="/api/live/stream"){qo(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let p=new URL(t.url||"/","http://localhost"),m=p.searchParams.get("node"),f=p.searchParams.get("agent"),k=p.searchParams.get("task");if(!m||!f||!k){_(e,400,{error:"node, agent, task query params required"});return}await Fo(t,e,a,m,f,k);return}if(o==="GET"&&r==="/api/task/history"){let p=new URL(t.url||"/","http://localhost"),m=p.searchParams.get("node"),f=p.searchParams.get("agent"),k=p.searchParams.get("task"),b=p.searchParams.get("limit")||"50";if(!m||!f){_(e,400,{error:"node and agent query params required"});return}await Uo(e,a,m,f,k,b);return}if(o==="GET"&&r==="/api/agents"){try{let p={};a.config.dashboard.token&&(p.Authorization=`Bearer ${a.config.dashboard.token}`);let m=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:p});if(!m.ok)throw new Error(`HTTP ${m.status}`);let f=await m.json();_(e,200,f)}catch(p){_(e,502,{error:p.message||"agents fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let p=await le(t);try{let m=await Jo(a.config,p);_(e,200,m)}catch(m){_(e,502,{error:m.message||"draft failed"})}return}let i=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(i&&o==="POST"){let p=i[1];if(!Wo(t,e,[`agent:${p}`]))return;await Go(t,e,a.config,p);return}if(r.startsWith("/api/")&&a.token){let p=t.headers.authorization||"",m=p.startsWith("Bearer ")?p.slice(7):"";if(m!==a.token){let f=new U,k=m?f.verify(m):null;if(!k||!ce(k,"dashboard:write")){_(e,401,{error:"unauthorized"});return}}}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){_(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(o==="GET"&&r==="/events"){let m=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"});let f=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(g=>({name:g.name,url:g.url,token:g.token}))],k={flag:!1},b=[];t.on("close",()=>{k.flag=!0;for(let g of b)try{g.abort()}catch{}});let w=setInterval(()=>{if(!k.flag)try{e.write(`: ping
9397
9639
 
9398
- `)}catch{}},15e3);t.on("close",()=>clearInterval(g));for(let v of f)(async()=>{let C={Accept:"text/event-stream"};v.token&&(C.Authorization=`Bearer ${v.token}`);let y=new AbortController;b.push(y);try{let _=await fetch(`${v.url.replace(/\/+$/,"")}/events${m?`?${m}`:""}`,{headers:C,signal:y.signal});if(!_.ok||!_.body)return;let T=_.body.getReader(),M=new TextDecoder,I="";for(;!w.flag;){let{done:$,value:V}=await T.read();if($)break;I+=M.decode(V,{stream:!0});let ae;for(;(ae=I.indexOf(`
9640
+ `)}catch{}},15e3);t.on("close",()=>clearInterval(w));for(let g of f)(async()=>{let v={Accept:"text/event-stream"};g.token&&(v.Authorization=`Bearer ${g.token}`);let x=new AbortController;b.push(x);try{let E=await fetch(`${g.url.replace(/\/+$/,"")}/events${m?`?${m}`:""}`,{headers:v,signal:x.signal});if(!E.ok||!E.body)return;let C=E.body.getReader(),M=new TextDecoder,I="";for(;!k.flag;){let{done:$,value:V}=await C.read();if($)break;I+=M.decode(V,{stream:!0});let ae;for(;(ae=I.indexOf(`
9399
9641
 
9400
- `))>=0;){let he=I.slice(0,ae);if(I=I.slice(ae+2),w.flag)break;try{e.write(he+`
9642
+ `))>=0;){let he=I.slice(0,ae);if(I=I.slice(ae+2),k.flag)break;try{e.write(he+`
9401
9643
 
9402
- `)}catch{w.flag=!0}}}}catch{}})();return}if(o==="GET"&&r==="/api/workflows/runs"){try{let p=new URL(t.url||"/","http://localhost"),m=Math.max(1,Math.min(500,Number(p.searchParams.get("limit")||50))),f=p.searchParams.get("workflowId")||void 0,w=a.workflowRuns.list({limit:m,workflowId:f}),b=`?limit=${m}${f?`&workflowId=${encodeURIComponent(f)}`:""}`,g=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(_=>({url:_.url,token:_.token}))],v=await Promise.all(g.map(async _=>{let T={};_.token&&(T.Authorization=`Bearer ${_.token}`);try{let M=await fetch(`${_.url.replace(/\/+$/,"")}/api/workflows/runs${b}`,{headers:T});if(!M.ok)return[];let I=await M.json();return Array.isArray(I.runs)?I.runs:[]}catch{return[]}})),C=new Map;for(let _ of w)C.set(_.id,_);for(let _ of v)for(let T of _)C.set(T.id,T);let y=Array.from(C.values()).sort((_,T)=>_.updatedAt<T.updatedAt?1:-1).slice(0,m);k(e,200,{runs:y})}catch(p){k(e,502,{error:"runs fetch failed",message:p.message||String(p)})}return}let d=o==="GET"&&r.match(/^\/api\/workflows\/runs\/([^\/]+)$/);if(d){let p=decodeURIComponent(d[1]),m=a.workflowRuns.get(p);if(m){k(e,200,{run:m});return}let f=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(w=>({url:w.url,token:w.token}))];for(let w of f)try{let b={};w.token&&(b.Authorization=`Bearer ${w.token}`);let g=await fetch(`${w.url.replace(/\/+$/,"")}/api/workflows/runs/${encodeURIComponent(p)}`,{headers:b});if(g.ok){k(e,200,await g.json());return}}catch{}k(e,404,{error:"run not found on any configured peer"});return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let p=await le(t),m={"Content-Type":"application/json"};a.config.dashboard.token&&(m.Authorization=`Bearer ${a.config.dashboard.token}`);let f=a.config.dashboard.daemonUrl.replace(/\/+$/,""),w=await fetch(`${f}/api/workflows/editor/chat`,{method:"POST",headers:m,body:JSON.stringify(p??{})}),b=await w.json().catch(()=>({error:`HTTP ${w.status}`}));k(e,w.status,b)}catch(p){k(e,502,{error:"daemon unreachable",message:p.message||String(p)})}return}if(r.startsWith("/api/workflows/tasks")&&(o==="GET"||o==="POST")){try{let p=a.config.dashboard.daemonUrl.replace(/\/+$/,""),m={"Content-Type":"application/json",...a.config.dashboard.token?{Authorization:`Bearer ${a.config.dashboard.token}`}:{}},f=o==="POST"?await new Promise(g=>{let v=[];t.on("data",C=>v.push(C)),t.on("end",()=>g(Buffer.concat(v).toString("utf-8")))}):void 0,w=await fetch(`${p}${t.url}`,{method:o,headers:m,body:f}),b=await w.text();e.writeHead(w.status,{"Content-Type":w.headers.get("content-type")||"application/json"}),e.end(b)}catch(p){k(e,502,{error:"tasks proxy failed",message:p?.message||String(p)})}return}if(r.startsWith("/api/workflows")&&Ia(t,e,{store:a.workflowStore,runs:a.workflowRuns,layouts:a.workflowLayouts,requireScope:(m,f,w)=>{if(a.token)return!0;let b=De(m);if(!b)return!0;let g=new U().verify(b);if(!g)return k(f,401,{error:"invalid or revoked token"}),!1;for(let v of w)if(!ce(g,v))return k(f,403,{error:`token missing scope: ${v}`,scopes:g.scopes}),!1;return!0}}))return;if(o==="GET"&&r==="/api/boards"){k(e,200,a.boards.map(p=>({id:p.id,name:p.name,source:p.source,primaryToolLabel:p.primaryToolLabel,labels:p.labels,columns:p.columns,timeRangeDays:p.timeRangeDays})));return}let c=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/members$/);if(c&&o==="GET"){let p=a.sources.get(c[1]);if(!p){k(e,404,{error:"unknown board"});return}try{let m=typeof p.listMembers=="function"?await p.listMembers():[];k(e,200,m)}catch(m){k(e,502,{error:m.message})}return}let u=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/milestones$/);if(u&&o==="GET"){let p=a.sources.get(u[1]);if(!p){k(e,404,{error:"unknown board"});return}try{let m=typeof p.listMilestones=="function"?await p.listMilestones():[];k(e,200,m)}catch(m){k(e,502,{error:m.message})}return}let h=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items\/(.+?)\/move$/),x=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items(?:\/(.+))?$/);if(h&&o==="PATCH"){let[,p,m]=h,f=decodeURIComponent(m),w=a.boards.find(y=>y.id===p);if(!w){k(e,404,{error:`unknown board: ${p}`});return}let b=a.sources.get(p);if(!b){k(e,503,{error:`board "${p}" source unavailable`});return}let g=await le(t),v=w.columns.find(y=>y.id===g.to),C=w.columns.find(y=>y.id===g.from);if(!v){k(e,400,{error:`unknown 'to' column: ${g.to}`});return}try{await Do(b,f,C,v),et({actor:tt(t),action:"move",boardId:p,itemId:f,payload:{from:g.from,to:g.to}}),k(e,200,{ok:!0})}catch(y){k(e,502,{error:y.message||"transition failed"})}return}if(x){let[,p,m]=x,f=m?decodeURIComponent(m):void 0,w=a.boards.find(g=>g.id===p);if(!w){k(e,404,{error:`unknown board: ${p}`});return}let b=a.sources.get(p);if(!b){k(e,503,{error:`board "${p}" source unavailable`});return}if(o==="GET"&&!f){let{columns:g,totals:v}=await Lo(w,b,n.searchParams);k(e,200,{columns:g,totals:v});return}if(o==="GET"&&f){try{let g=typeof b.getItem=="function"?await b.getItem(f):null;if(!g){k(e,404,{error:"not found"});return}k(e,200,g)}catch(g){k(e,502,{error:g.message})}return}if(o==="PATCH"&&f){let g=await le(t);try{let v=typeof b.updateItem=="function"?await b.updateItem(f,g):null;if(!v){k(e,501,{error:"update unsupported"});return}et({actor:tt(t),action:"update",boardId:p,itemId:f,payload:g}),k(e,200,v)}catch(v){k(e,502,{error:v.message})}return}if(o==="POST"&&!f){let g=await le(t);if(!g.title){k(e,400,{error:"title required"});return}if(!b.capabilities.create||!b.create){k(e,400,{error:`source ${b.type} does not support create`});return}try{let v=await b.create({title:g.title,description:g.description,labels:g.labels,assigneeUsernames:g.assigneeUsernames,milestoneTitle:g.milestoneTitle,projectHint:g.projectHint});et({actor:tt(t),action:"create",boardId:p,itemId:v.id,payload:{title:g.title}}),k(e,201,v)}catch(v){k(e,502,{error:v.message})}return}}k(e,404,{error:"not found",path:r})}async function Lo(t,e,a){if(!e.capabilities.listAll||!e.listAll){let b={};for(let g of t.columns)b[g.id]=[];return{columns:b,totals:Object.fromEntries(t.columns.map(g=>[g.id,0]))}}let n=[];t.primaryToolLabel&&n.push(t.primaryToolLabel);let r=a.get("label")||void 0;r&&n.push(r);let o=a.get("q")||void 0,s=a.get("milestone")||void 0,i=a.get("assignee")||void 0,l=parseInt(a.get("days")||String(t.timeRangeDays),10),d=parseInt(a.get("closedDays")||String(t.closedWindowDays??30),10),c=t.columns.some(b=>b.kind!=="closed"),u=t.columns.some(b=>b.kind==="closed"),h=c?await e.listAll({sinceDays:l,labels:n.length?n:void 0,search:o,milestone:s,state:"opened"}):[],x=u?await e.listAll({sinceDays:d,labels:n.length?n:void 0,search:o,milestone:s,state:"closed"}):[],p={};for(let b of t.columns)p[b.id]=[];let m=t.columns.find(b=>b.kind==="closed");for(let b of x)m&&p[m.id].push({...b,stage:m.id});let f=t.columns.filter(b=>b.kind!=="closed");for(let b of h){let g=dt(b,f);if(!g)continue;let v=p[g];v&&v.push({...b,stage:g})}if(i)for(let b of Object.keys(p))p[b]=p[b].filter(g=>g.assignee===i);for(let b of Object.keys(p))p[b].sort((g,v)=>{let C=(g.priority??99)-(v.priority??99);return C!==0?C:(v.updatedAt||"").localeCompare(g.updatedAt||"")});let w=Object.fromEntries(Object.entries(p).map(([b,g])=>[b,g.length]));return{columns:p,totals:w}}async function Do(t,e,a,n){let r=ct(a,n),o=t;r.closeIssue&&typeof o.setState=="function"?await o.setState(e,"close"):r.reopen&&typeof o.setState=="function"&&await o.setState(e,"reopen"),(r.addLabels?.length||r.removeLabels?.length)&&typeof o.transitionMany=="function"?await o.transitionMany(e,r.addLabels||[],r.removeLabels||[]):r.addLabels?.length&&t.transition&&await t.transition(e,r.addLabels[0],r.removeLabels?.[0])}function Po(t,e){if(t.source.type==="gitlab"){let a=e.channels.gitlab;if(!a?.token)throw new Error("channels.gitlab.token is required for gitlab boards");let n={};for(let r of a.agentMappings)r.gitlabUsernames.length&&(n[r.agentId]=r.gitlabUsernames);return new ht(a.host,a.token,t.source.projects,n,(...r)=>console.log("[board]",...r))}throw new Error(`unsupported board source: ${t.source.type}`)}function et(t){try{let e=ge(process.cwd(),".agentx");Da(e)||Co(e,{recursive:!0});let a=JSON.stringify({ts:new Date().toISOString(),...t})+`
9403
- `;To(ge(e,"board-audit.jsonl"),a)}catch{}}function tt(t){let e=t.headers["x-forwarded-for"];return(Array.isArray(e)?e[0]:e?.split(",")[0])||t.socket.remoteAddress||"unknown"}async function Ro(t,e,a){let n={};e&&(n.Authorization=`Bearer ${e}`);let r={id:t,name:t,url:t,reachable:!1,agents:[]};try{let[o,s,i]=await Promise.all([fetch(t+"/health",{headers:n,signal:a}).catch(()=>null),fetch(t+"/agents",{headers:n,signal:a}).catch(()=>null),fetch(t+"/mesh",{headers:n,signal:a}).catch(()=>null)]);if(!s||!s.ok)return r.error=s?`HTTP ${s.status}`:"unreachable",r;let l=await s.json();if(r.agents=l.map(d=>({id:d.id,name:d.name,tier:d.tier,model:d.model,active:d.active||0,total:d.total||0,errors:d.errors||0,lastActive:d.lastActive,lastSummary:d.lastSummary,hourlyTasks:Array.isArray(d.hourlyTasks)?d.hourlyTasks:void 0,runningTasks:Array.isArray(d.runningTasks)?d.runningTasks:[]})),o&&o.ok){let d=await o.json();r.uptimeSec=d.uptime,r.name=d.node?.name||d.node?.id||t,r.id=d.node?.id||t,d.usage&&(r.usage=d.usage)}r.reachable=!0,r._peers=Array.isArray(i&&await Ho(i))?r._peers:void 0}catch(o){r.error=o.message||String(o)}return r}var Ae=null;function Oo(t){if(Ae)return Ae;let e=ge(process.cwd(),".agentx/wiki");return Ae=Tt({wikiDir:e,pathPrefix:"/admin/wiki",mode:"graph"}),Ae}var at=new WeakMap;async function Ho(t){if(at.has(t))return at.get(t);try{let e=t.ok?await t.json():null;return at.set(t,e),e}catch{return null}}async function rt(t,e,a){try{let n={};e&&(n.Authorization=`Bearer ${e}`);let r=await fetch(t+"/mesh",{headers:n,signal:a});return r.ok?(await r.json()).filter(s=>s&&s.peerUrl).map(s=>({url:String(s.peerUrl).replace(/\/+$/,""),name:s.peer||s.peerUrl})):[]}catch{return[]}}async function Pa(t){let e=t.dashboard,a=e.daemonUrl.replace(/\/+$/,""),n=e.token,r=new Map;r.set(a,{name:"primary",url:a,token:n});for(let i of e.daemons){let l=i.url.replace(/\/+$/,"");r.has(l)||r.set(l,{name:i.name,url:l,token:i.token})}let o=new AbortController,s=setTimeout(()=>o.abort(),3e3);try{let i=await rt(a,n,o.signal);for(let d of i)r.has(d.url)||r.set(d.url,d);let l=await Promise.all([...r.values()].map(d=>Ro(d.url,d.token,o.signal)));return{ts:new Date().toISOString(),nodes:l}}finally{clearTimeout(s)}}function No(t,e,a){e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let n=!1,r=(i,l)=>{n||e.write(`event: ${i}
9644
+ `)}catch{k.flag=!0}}}}catch{}})();return}if(o==="GET"&&r==="/api/workflows/runs"){try{let p=new URL(t.url||"/","http://localhost"),m=Math.max(1,Math.min(500,Number(p.searchParams.get("limit")||50))),f=p.searchParams.get("workflowId")||void 0,k=a.workflowRuns.list({limit:m,workflowId:f}),b=`?limit=${m}${f?`&workflowId=${encodeURIComponent(f)}`:""}`,w=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(E=>({url:E.url,token:E.token}))],g=await Promise.all(w.map(async E=>{let C={};E.token&&(C.Authorization=`Bearer ${E.token}`);try{let M=await fetch(`${E.url.replace(/\/+$/,"")}/api/workflows/runs${b}`,{headers:C});if(!M.ok)return[];let I=await M.json();return Array.isArray(I.runs)?I.runs:[]}catch{return[]}})),v=new Map;for(let E of k)v.set(E.id,E);for(let E of g)for(let C of E)v.set(C.id,C);let x=Array.from(v.values()).sort((E,C)=>E.updatedAt<C.updatedAt?1:-1).slice(0,m);_(e,200,{runs:x})}catch(p){_(e,502,{error:"runs fetch failed",message:p.message||String(p)})}return}let d=o==="GET"&&r.match(/^\/api\/workflows\/runs\/([^\/]+)$/);if(d){let p=decodeURIComponent(d[1]),m=a.workflowRuns.get(p);if(m){_(e,200,{run:m});return}let f=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(k=>({url:k.url,token:k.token}))];for(let k of f)try{let b={};k.token&&(b.Authorization=`Bearer ${k.token}`);let w=await fetch(`${k.url.replace(/\/+$/,"")}/api/workflows/runs/${encodeURIComponent(p)}`,{headers:b});if(w.ok){_(e,200,await w.json());return}}catch{}_(e,404,{error:"run not found on any configured peer"});return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let p=await le(t),m={"Content-Type":"application/json"};a.config.dashboard.token&&(m.Authorization=`Bearer ${a.config.dashboard.token}`);let f=a.config.dashboard.daemonUrl.replace(/\/+$/,""),k=await fetch(`${f}/api/workflows/editor/chat`,{method:"POST",headers:m,body:JSON.stringify(p??{})}),b=await k.json().catch(()=>({error:`HTTP ${k.status}`}));_(e,k.status,b)}catch(p){_(e,502,{error:"daemon unreachable",message:p.message||String(p)})}return}if(r.startsWith("/api/workflows/tasks")&&(o==="GET"||o==="POST")){try{let p=a.config.dashboard.daemonUrl.replace(/\/+$/,""),m={"Content-Type":"application/json",...a.config.dashboard.token?{Authorization:`Bearer ${a.config.dashboard.token}`}:{}},f=o==="POST"?await new Promise(w=>{let g=[];t.on("data",v=>g.push(v)),t.on("end",()=>w(Buffer.concat(g).toString("utf-8")))}):void 0,k=await fetch(`${p}${t.url}`,{method:o,headers:m,body:f}),b=await k.text();e.writeHead(k.status,{"Content-Type":k.headers.get("content-type")||"application/json"}),e.end(b)}catch(p){_(e,502,{error:"tasks proxy failed",message:p?.message||String(p)})}return}if(r.startsWith("/api/workflows")&&La(t,e,{store:a.workflowStore,runs:a.workflowRuns,layouts:a.workflowLayouts,requireScope:(m,f,k)=>{if(a.token)return!0;let b=De(m);if(!b)return!0;let w=new U().verify(b);if(!w)return _(f,401,{error:"invalid or revoked token"}),!1;for(let g of k)if(!ce(w,g))return _(f,403,{error:`token missing scope: ${g}`,scopes:w.scopes}),!1;return!0}}))return;if(o==="GET"&&r==="/api/boards"){_(e,200,a.boards.map(p=>({id:p.id,name:p.name,source:p.source,primaryToolLabel:p.primaryToolLabel,labels:p.labels,columns:p.columns,timeRangeDays:p.timeRangeDays})));return}let c=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/members$/);if(c&&o==="GET"){let p=a.sources.get(c[1]);if(!p){_(e,404,{error:"unknown board"});return}try{let m=typeof p.listMembers=="function"?await p.listMembers():[];_(e,200,m)}catch(m){_(e,502,{error:m.message})}return}let u=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/milestones$/);if(u&&o==="GET"){let p=a.sources.get(u[1]);if(!p){_(e,404,{error:"unknown board"});return}try{let m=typeof p.listMilestones=="function"?await p.listMilestones():[];_(e,200,m)}catch(m){_(e,502,{error:m.message})}return}let h=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items\/(.+?)\/move$/),y=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items(?:\/(.+))?$/);if(h&&o==="PATCH"){let[,p,m]=h,f=decodeURIComponent(m),k=a.boards.find(x=>x.id===p);if(!k){_(e,404,{error:`unknown board: ${p}`});return}let b=a.sources.get(p);if(!b){_(e,503,{error:`board "${p}" source unavailable`});return}let w=await le(t),g=k.columns.find(x=>x.id===w.to),v=k.columns.find(x=>x.id===w.from);if(!g){_(e,400,{error:`unknown 'to' column: ${w.to}`});return}try{await Oo(b,f,v,g),tt({actor:at(t),action:"move",boardId:p,itemId:f,payload:{from:w.from,to:w.to}}),_(e,200,{ok:!0})}catch(x){_(e,502,{error:x.message||"transition failed"})}return}if(y){let[,p,m]=y,f=m?decodeURIComponent(m):void 0,k=a.boards.find(w=>w.id===p);if(!k){_(e,404,{error:`unknown board: ${p}`});return}let b=a.sources.get(p);if(!b){_(e,503,{error:`board "${p}" source unavailable`});return}if(o==="GET"&&!f){let{columns:w,totals:g}=await Ho(k,b,n.searchParams);_(e,200,{columns:w,totals:g});return}if(o==="GET"&&f){try{let w=typeof b.getItem=="function"?await b.getItem(f):null;if(!w){_(e,404,{error:"not found"});return}_(e,200,w)}catch(w){_(e,502,{error:w.message})}return}if(o==="PATCH"&&f){let w=await le(t);try{let g=typeof b.updateItem=="function"?await b.updateItem(f,w):null;if(!g){_(e,501,{error:"update unsupported"});return}tt({actor:at(t),action:"update",boardId:p,itemId:f,payload:w}),_(e,200,g)}catch(g){_(e,502,{error:g.message})}return}if(o==="POST"&&!f){let w=await le(t);if(!w.title){_(e,400,{error:"title required"});return}if(!b.capabilities.create||!b.create){_(e,400,{error:`source ${b.type} does not support create`});return}try{let g=await b.create({title:w.title,description:w.description,labels:w.labels,assigneeUsernames:w.assigneeUsernames,milestoneTitle:w.milestoneTitle,projectHint:w.projectHint});tt({actor:at(t),action:"create",boardId:p,itemId:g.id,payload:{title:w.title}}),_(e,201,g)}catch(g){_(e,502,{error:g.message})}return}}_(e,404,{error:"not found",path:r})}async function Ho(t,e,a){if(!e.capabilities.listAll||!e.listAll){let b={};for(let w of t.columns)b[w.id]=[];return{columns:b,totals:Object.fromEntries(t.columns.map(w=>[w.id,0]))}}let n=[];t.primaryToolLabel&&n.push(t.primaryToolLabel);let r=a.get("label")||void 0;r&&n.push(r);let o=a.get("q")||void 0,s=a.get("milestone")||void 0,i=a.get("assignee")||void 0,l=parseInt(a.get("days")||String(t.timeRangeDays),10),d=parseInt(a.get("closedDays")||String(t.closedWindowDays??30),10),c=t.columns.some(b=>b.kind!=="closed"),u=t.columns.some(b=>b.kind==="closed"),h=c?await e.listAll({sinceDays:l,labels:n.length?n:void 0,search:o,milestone:s,state:"opened"}):[],y=u?await e.listAll({sinceDays:d,labels:n.length?n:void 0,search:o,milestone:s,state:"closed"}):[],p={};for(let b of t.columns)p[b.id]=[];let m=t.columns.find(b=>b.kind==="closed");for(let b of y)m&&p[m.id].push({...b,stage:m.id});let f=t.columns.filter(b=>b.kind!=="closed");for(let b of h){let w=ct(b,f);if(!w)continue;let g=p[w];g&&g.push({...b,stage:w})}if(i)for(let b of Object.keys(p))p[b]=p[b].filter(w=>w.assignee===i);for(let b of Object.keys(p))p[b].sort((w,g)=>{let v=(w.priority??99)-(g.priority??99);return v!==0?v:(g.updatedAt||"").localeCompare(w.updatedAt||"")});let k=Object.fromEntries(Object.entries(p).map(([b,w])=>[b,w.length]));return{columns:p,totals:k}}async function Oo(t,e,a,n){let r=pt(a,n),o=t;r.closeIssue&&typeof o.setState=="function"?await o.setState(e,"close"):r.reopen&&typeof o.setState=="function"&&await o.setState(e,"reopen"),(r.addLabels?.length||r.removeLabels?.length)&&typeof o.transitionMany=="function"?await o.transitionMany(e,r.addLabels||[],r.removeLabels||[]):r.addLabels?.length&&t.transition&&await t.transition(e,r.addLabels[0],r.removeLabels?.[0])}function No(t,e){if(t.source.type==="gitlab"){let a=e.channels.gitlab;if(!a?.token)throw new Error("channels.gitlab.token is required for gitlab boards");let n={};for(let r of a.agentMappings)r.gitlabUsernames.length&&(n[r.agentId]=r.gitlabUsernames);return new ft(a.host,a.token,t.source.projects,n,(...r)=>console.log("[board]",...r))}throw new Error(`unsupported board source: ${t.source.type}`)}function tt(t){try{let e=ge(process.cwd(),".agentx");Pa(e)||Io(e,{recursive:!0});let a=JSON.stringify({ts:new Date().toISOString(),...t})+`
9645
+ `;Mo(ge(e,"board-audit.jsonl"),a)}catch{}}function at(t){let e=t.headers["x-forwarded-for"];return(Array.isArray(e)?e[0]:e?.split(",")[0])||t.socket.remoteAddress||"unknown"}async function Bo(t,e,a){let n={};e&&(n.Authorization=`Bearer ${e}`);let r={id:t,name:t,url:t,reachable:!1,agents:[]};try{let[o,s,i]=await Promise.all([fetch(t+"/health",{headers:n,signal:a}).catch(()=>null),fetch(t+"/agents",{headers:n,signal:a}).catch(()=>null),fetch(t+"/mesh",{headers:n,signal:a}).catch(()=>null)]);if(!s||!s.ok)return r.error=s?`HTTP ${s.status}`:"unreachable",r;let l=await s.json();if(r.agents=l.map(d=>({id:d.id,name:d.name,tier:d.tier,model:d.model,active:d.active||0,total:d.total||0,errors:d.errors||0,lastActive:d.lastActive,lastSummary:d.lastSummary,hourlyTasks:Array.isArray(d.hourlyTasks)?d.hourlyTasks:void 0,runningTasks:Array.isArray(d.runningTasks)?d.runningTasks:[]})),o&&o.ok){let d=await o.json();r.uptimeSec=d.uptime,r.name=d.node?.name||d.node?.id||t,r.id=d.node?.id||t,d.usage&&(r.usage=d.usage)}r.reachable=!0,r._peers=Array.isArray(i&&await zo(i))?r._peers:void 0}catch(o){r.error=o.message||String(o)}return r}var Ae=null;function jo(t){if(Ae)return Ae;let e=ge(process.cwd(),".agentx/wiki");return Ae=At({wikiDir:e,pathPrefix:"/admin/wiki",mode:"graph"}),Ae}var nt=new WeakMap;async function zo(t){if(nt.has(t))return nt.get(t);try{let e=t.ok?await t.json():null;return nt.set(t,e),e}catch{return null}}async function ot(t,e,a){try{let n={};e&&(n.Authorization=`Bearer ${e}`);let r=await fetch(t+"/mesh",{headers:n,signal:a});return r.ok?(await r.json()).filter(s=>s&&s.peerUrl).map(s=>({url:String(s.peerUrl).replace(/\/+$/,""),name:s.peer||s.peerUrl})):[]}catch{return[]}}async function Ra(t){let e=t.dashboard,a=e.daemonUrl.replace(/\/+$/,""),n=e.token,r=new Map;r.set(a,{name:"primary",url:a,token:n});for(let i of e.daemons){let l=i.url.replace(/\/+$/,"");r.has(l)||r.set(l,{name:i.name,url:l,token:i.token})}let o=new AbortController,s=setTimeout(()=>o.abort(),3e3);try{let i=await ot(a,n,o.signal);for(let d of i)r.has(d.url)||r.set(d.url,d);let l=await Promise.all([...r.values()].map(d=>Bo(d.url,d.token,o.signal)));return{ts:new Date().toISOString(),nodes:l}}finally{clearTimeout(s)}}function qo(t,e,a){e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let n=!1,r=(i,l)=>{n||e.write(`event: ${i}
9404
9646
  data: ${JSON.stringify(l)}
9405
9647
 
9406
- `)},o=async()=>{try{let i=await Pa(a);r("snapshot",i)}catch(i){r("error",{message:i.message})}};o();let s=setInterval(o,2e3);t.on("close",()=>{n=!0,clearInterval(s),e.end()})}async function Bo(t,e,a,n,r,o){let s=n.replace(/\/+$/,""),i=new Set;i.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let p of a.config.dashboard.daemons)i.add(p.url.replace(/\/+$/,""));try{let p=await rt(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let m of p)i.add(m.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){k(e,403,{error:"node not in dashboard allowlist",target:s});return}let l=s===a.config.dashboard.daemonUrl.replace(/\/+$/,"")?a.config.dashboard.token:a.config.dashboard.daemons.find(p=>p.url.replace(/\/+$/,"")===s)?.token,d={Accept:"text/event-stream"};l&&(d.Authorization=`Bearer ${l}`);let c=new AbortController,u;try{u=await fetch(`${s}/agents/${encodeURIComponent(r)}/tasks/${encodeURIComponent(o)}/stream`,{headers:d,signal:c.signal})}catch(p){k(e,502,{error:p.message||"upstream connect failed"});return}if(!u.ok||!u.body){k(e,u.status||502,{error:`upstream HTTP ${u.status}`});return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*","X-Accel-Buffering":"no"});let h=u.body.getReader();(async()=>{try{for(;;){let{value:p,done:m}=await h.read();if(m)break;p&&e.write(p)}}catch{}finally{try{e.end()}catch{}}})(),t.on("close",()=>{c.abort();try{e.end()}catch{}})}function jo(t,e,a){let n=De(t);if(!n)return k(e,401,{error:"missing token",hint:"pass Authorization: Bearer <token> (agentx token create)"}),null;let r=new U().verify(n);if(!r)return k(e,401,{error:"invalid or revoked token"}),null;for(let o of a)if(!ce(r,o))return k(e,403,{error:`token missing scope: ${o}`,scopes:r.scopes}),null;return r}async function zo(t,e,a,n){let r=a.agents?.[n];if(!r){k(e,404,{error:"unknown agent"});return}if(r.access!=="public"){k(e,403,{error:"agent is private",hint:`set agents.${n}.access = "public" to expose it`});return}let o;try{o=await le(t)}catch{k(e,400,{error:"invalid JSON body"});return}let s=o?.message;if(!s||typeof s!="string"){k(e,400,{error:"required: { message: string, context?: {...} }"});return}let i=a.dashboard.daemonUrl.replace(/\/+$/,""),l={"Content-Type":"application/json"};a.dashboard.token&&(l.Authorization=`Bearer ${a.dashboard.token}`);try{let d=await fetch(`${i}/task`,{method:"POST",headers:l,body:JSON.stringify({agent:n,message:s,context:{channel:"public-api",sender:o.context?.sender||"api",...o.context||{}}})}),c=await d.text();e.writeHead(d.status,{"Content-Type":d.headers.get("content-type")||"application/json; charset=utf-8","Access-Control-Allow-Origin":"*"}),e.end(c)}catch(d){k(e,502,{error:d.message||"upstream call failed"})}}async function qo(t,e,a,n,r,o){let s=a.replace(/\/+$/,""),i=new Set;i.add(e.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let u of e.config.dashboard.daemons)i.add(u.url.replace(/\/+$/,""));try{let u=await rt(e.config.dashboard.daemonUrl.replace(/\/+$/,""),e.config.dashboard.token);for(let h of u)i.add(h.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){k(t,403,{error:"node not in dashboard allowlist",target:s});return}let l=s===e.config.dashboard.daemonUrl.replace(/\/+$/,"")?e.config.dashboard.token:e.config.dashboard.daemons.find(u=>u.url.replace(/\/+$/,"")===s)?.token,d={Accept:"application/json"};l&&(d.Authorization=`Bearer ${l}`);let c=r?`/agents/${encodeURIComponent(n)}/tasks/${encodeURIComponent(r)}`:`/agents/${encodeURIComponent(n)}/tasks?limit=${encodeURIComponent(o)}`;try{let u=await fetch(`${s}${c}`,{headers:d}),h=await u.text();t.writeHead(u.status,{"Content-Type":u.headers.get("content-type")||"application/json; charset=utf-8","Access-Control-Allow-Origin":"*"}),t.end(h)}catch(u){k(t,502,{error:u.message||"upstream fetch failed"})}}var Fo=`
9648
+ `)},o=async()=>{try{let i=await Ra(a);r("snapshot",i)}catch(i){r("error",{message:i.message})}};o();let s=setInterval(o,2e3);t.on("close",()=>{n=!0,clearInterval(s),e.end()})}async function Fo(t,e,a,n,r,o){let s=n.replace(/\/+$/,""),i=new Set;i.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let p of a.config.dashboard.daemons)i.add(p.url.replace(/\/+$/,""));try{let p=await ot(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let m of p)i.add(m.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){_(e,403,{error:"node not in dashboard allowlist",target:s});return}let l=s===a.config.dashboard.daemonUrl.replace(/\/+$/,"")?a.config.dashboard.token:a.config.dashboard.daemons.find(p=>p.url.replace(/\/+$/,"")===s)?.token,d={Accept:"text/event-stream"};l&&(d.Authorization=`Bearer ${l}`);let c=new AbortController,u;try{u=await fetch(`${s}/agents/${encodeURIComponent(r)}/tasks/${encodeURIComponent(o)}/stream`,{headers:d,signal:c.signal})}catch(p){_(e,502,{error:p.message||"upstream connect failed"});return}if(!u.ok||!u.body){_(e,u.status||502,{error:`upstream HTTP ${u.status}`});return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*","X-Accel-Buffering":"no"});let h=u.body.getReader();(async()=>{try{for(;;){let{value:p,done:m}=await h.read();if(m)break;p&&e.write(p)}}catch{}finally{try{e.end()}catch{}}})(),t.on("close",()=>{c.abort();try{e.end()}catch{}})}function Wo(t,e,a){let n=De(t);if(!n)return _(e,401,{error:"missing token",hint:"pass Authorization: Bearer <token> (agentx token create)"}),null;let r=new U().verify(n);if(!r)return _(e,401,{error:"invalid or revoked token"}),null;for(let o of a)if(!ce(r,o))return _(e,403,{error:`token missing scope: ${o}`,scopes:r.scopes}),null;return r}async function Go(t,e,a,n){let r=a.agents?.[n];if(!r){_(e,404,{error:"unknown agent"});return}if(r.access!=="public"){_(e,403,{error:"agent is private",hint:`set agents.${n}.access = "public" to expose it`});return}let o;try{o=await le(t)}catch{_(e,400,{error:"invalid JSON body"});return}let s=o?.message;if(!s||typeof s!="string"){_(e,400,{error:"required: { message: string, context?: {...} }"});return}let i=a.dashboard.daemonUrl.replace(/\/+$/,""),l={"Content-Type":"application/json"};a.dashboard.token&&(l.Authorization=`Bearer ${a.dashboard.token}`);try{let d=await fetch(`${i}/task`,{method:"POST",headers:l,body:JSON.stringify({agent:n,message:s,context:{channel:"public-api",sender:o.context?.sender||"api",...o.context||{}}})}),c=await d.text();e.writeHead(d.status,{"Content-Type":d.headers.get("content-type")||"application/json; charset=utf-8","Access-Control-Allow-Origin":"*"}),e.end(c)}catch(d){_(e,502,{error:d.message||"upstream call failed"})}}async function Uo(t,e,a,n,r,o){let s=a.replace(/\/+$/,""),i=new Set;i.add(e.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let u of e.config.dashboard.daemons)i.add(u.url.replace(/\/+$/,""));try{let u=await ot(e.config.dashboard.daemonUrl.replace(/\/+$/,""),e.config.dashboard.token);for(let h of u)i.add(h.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){_(t,403,{error:"node not in dashboard allowlist",target:s});return}let l=s===e.config.dashboard.daemonUrl.replace(/\/+$/,"")?e.config.dashboard.token:e.config.dashboard.daemons.find(u=>u.url.replace(/\/+$/,"")===s)?.token,d={Accept:"application/json"};l&&(d.Authorization=`Bearer ${l}`);let c=r?`/agents/${encodeURIComponent(n)}/tasks/${encodeURIComponent(r)}`:`/agents/${encodeURIComponent(n)}/tasks?limit=${encodeURIComponent(o)}`;try{let u=await fetch(`${s}${c}`,{headers:d}),h=await u.text();t.writeHead(u.status,{"Content-Type":u.headers.get("content-type")||"application/json; charset=utf-8","Access-Control-Allow-Origin":"*"}),t.end(h)}catch(u){_(t,502,{error:u.message||"upstream fetch failed"})}}var Ko=`
9407
9649
  You are helping draft a new GitLab issue. Follow these conventions strictly.
9408
9650
 
9409
9651
  Title pattern:
@@ -9435,16 +9677,16 @@ Return ONLY a single JSON object on one line \u2014 no prose, no code fences, no
9435
9677
  Shape:
9436
9678
  { "title": string, "description": string, "labels": string[], "assigneeUsername": string | null, "kind": string }
9437
9679
  If you don't have enough information to pick a label confidently, omit it rather than guessing.
9438
- `;async function Go(t,e){let a=(e?.rough||"").toString().trim();if(!a)throw new Error("rough description required");let n=e?.agent||t.dashboard.draftAgent;if(!n)throw new Error("no draft agent configured (set dashboard.draftAgent or pass agent in body)");let r=e?.context||{},o=["Rough description from the user:",'"""',a,'"""',"",`Board: ${r.boardName||"(unspecified)"}`,r.primaryLabel?`Primary board label (include in labels): ${r.primaryLabel}`:"",r.columnLabel?`Target column label (include in labels): ${r.columnLabel}`:"",r.project?`GitLab project: ${r.project}`:"",r.knownLabels?.length?`Known labels in this project (prefer picking from these when they fit):
9680
+ `;async function Jo(t,e){let a=(e?.rough||"").toString().trim();if(!a)throw new Error("rough description required");let n=e?.agent||t.dashboard.draftAgent;if(!n)throw new Error("no draft agent configured (set dashboard.draftAgent or pass agent in body)");let r=e?.context||{},o=["Rough description from the user:",'"""',a,'"""',"",`Board: ${r.boardName||"(unspecified)"}`,r.primaryLabel?`Primary board label (include in labels): ${r.primaryLabel}`:"",r.columnLabel?`Target column label (include in labels): ${r.columnLabel}`:"",r.project?`GitLab project: ${r.project}`:"",r.knownLabels?.length?`Known labels in this project (prefer picking from these when they fit):
9439
9681
  - ${r.knownLabels.slice(0,60).join(`
9440
9682
  - `)}`:"",r.members?.length?`Possible assignees (GitLab usernames): ${r.members.slice(0,20).join(", ")}`:"","","Produce the JSON draft now."].filter(Boolean).join(`
9441
- `),s=t.dashboard.daemonUrl.replace(/\/+$/,"")+"/task",i={"Content-Type":"application/json"};t.dashboard.token&&(i.Authorization=`Bearer ${t.dashboard.token}`);let l=await fetch(s,{method:"POST",headers:i,body:JSON.stringify({agent:n,message:o,context:{channel:"a2a",sender:"board-dashboard",systemPrompt:Fo}})});if(!l.ok)throw new Error(`daemon /task HTTP ${l.status}: ${await l.text().catch(()=>"")}`);let d=await l.json();if(d.error)throw new Error(String(d.error));let c=(d.content||"").toString(),u=Wo(c);if(!u||typeof u.title!="string")throw new Error("agent did not return a valid JSON draft. Raw: "+c.slice(0,400));let h=Array.isArray(u.labels)?u.labels.filter(x=>typeof x=="string"):[];return r.primaryLabel&&!h.includes(r.primaryLabel)&&h.unshift(r.primaryLabel),r.columnLabel&&!h.includes(r.columnLabel)&&h.unshift(r.columnLabel),{title:u.title.trim(),description:(u.description||"").toString(),labels:h,assigneeUsername:typeof u.assigneeUsername=="string"?u.assigneeUsername:void 0,kind:typeof u.kind=="string"?u.kind:void 0,raw:c}}function Wo(t){if(!t)return null;try{return JSON.parse(t)}catch{}let e=t.match(/```(?:json)?\s*([\s\S]*?)```/);if(e)try{return JSON.parse(e[1])}catch{}let a=t.indexOf("{");if(a===-1)return null;let n=0;for(let r=a;r<t.length;r++){let o=t[r];if(o==="{")n++;else if(o==="}"&&(n--,n===0))try{return JSON.parse(t.slice(a,r+1))}catch{return null}}return null}function Uo(t){let e=Mo($o(import.meta.url));return ge(e,t)}async function Ko(t){return Ao(t)}function k(t,e,a){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify(a))}async function le(t){return new Promise((e,a)=>{let n=[];t.on("data",r=>n.push(r)),t.on("end",()=>{try{let r=Buffer.concat(n).toString("utf-8");e(r?JSON.parse(r):{})}catch(r){a(r)}}),t.on("error",a)})}function Ra(t){return t.dashboardUrl?t.dashboardUrl.replace(/\/+$/,""):t.url.replace(/\/+$/,"").replace(/:(?:1[89][89]00|18810)$/,":4202")}function H(t,e){let a=e||t,n={id:"primary",name:a.node?.name||"this daemon",dashboardUrl:"",primary:!0},r=(a.dashboard?.daemons||[]).map(s=>({id:s.url.replace(/\/+$/,""),name:s.name,dashboardUrl:Ra(s),tokenScope:s.dashboardToken||s.token?"proxy-ready":void 0})),o=r.length>0?[{id:"fleet",name:"Fleet (all peers)",dashboardUrl:"",tokenScope:"merged across nodes"}]:[];return[n,...r,...o]}async function Jo(t,e,a){let n=new URL(t.url||"/","http://_"),r=parseInt(n.searchParams.get("hours")||"6",10)||6,o=a.config.node?.id||a.config.node?.name||"local",s=[],i=pa(r);i&&s.push({nodeId:o,snap:i});let l=(a.config.dashboard?.daemons||[]).filter(d=>d.url);await Promise.all(l.map(async d=>{let c=nt(d.url.replace(/\/+$/,""),a.config);if(c)try{let u=new AbortController,h=setTimeout(()=>u.abort(),8e3);try{let x=await fetch(`${c.url}/api/admin/activity-graph?hours=${r}`,{headers:{Accept:"application/json","X-Agentx-Peer":"primary",...c.token?{Authorization:`Bearer ${c.token}`}:{}},signal:u.signal});if(!x.ok)return;let p=await x.json();s.push({nodeId:d.name||d.url,snap:p})}finally{clearTimeout(h)}}catch{}})),k(e,200,ua(s))}async function Xo(t,e){let{spawn:a,execSync:n}=await import("child_process"),r,o;try{n("which journalctl",{stdio:"pipe"}),r="journalctl",o=["-u","agentx","--no-pager","-n","200","-f","-o","cat"]}catch{let u=process.env.HOME||"",h=[u&&`${u}/.agentx/logs/daemon-stdout.log`,"/tmp/agentx-daemon.log"].filter(Boolean),x=h.find(p=>Da(p));if(!x){e.writeHead(503,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"no log source \u2014 install journalctl, run the daemon under launchd, or run it foreground writing to /tmp/agentx-daemon.log",searched:h}));return}r="tail",o=["-F","-n","200",x]}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`: source=${r}
9683
+ `),s=t.dashboard.daemonUrl.replace(/\/+$/,"")+"/task",i={"Content-Type":"application/json"};t.dashboard.token&&(i.Authorization=`Bearer ${t.dashboard.token}`);let l=await fetch(s,{method:"POST",headers:i,body:JSON.stringify({agent:n,message:o,context:{channel:"a2a",sender:"board-dashboard",systemPrompt:Ko}})});if(!l.ok)throw new Error(`daemon /task HTTP ${l.status}: ${await l.text().catch(()=>"")}`);let d=await l.json();if(d.error)throw new Error(String(d.error));let c=(d.content||"").toString(),u=Xo(c);if(!u||typeof u.title!="string")throw new Error("agent did not return a valid JSON draft. Raw: "+c.slice(0,400));let h=Array.isArray(u.labels)?u.labels.filter(y=>typeof y=="string"):[];return r.primaryLabel&&!h.includes(r.primaryLabel)&&h.unshift(r.primaryLabel),r.columnLabel&&!h.includes(r.columnLabel)&&h.unshift(r.columnLabel),{title:u.title.trim(),description:(u.description||"").toString(),labels:h,assigneeUsername:typeof u.assigneeUsername=="string"?u.assigneeUsername:void 0,kind:typeof u.kind=="string"?u.kind:void 0,raw:c}}function Xo(t){if(!t)return null;try{return JSON.parse(t)}catch{}let e=t.match(/```(?:json)?\s*([\s\S]*?)```/);if(e)try{return JSON.parse(e[1])}catch{}let a=t.indexOf("{");if(a===-1)return null;let n=0;for(let r=a;r<t.length;r++){let o=t[r];if(o==="{")n++;else if(o==="}"&&(n--,n===0))try{return JSON.parse(t.slice(a,r+1))}catch{return null}}return null}function Vo(t){let e=Po(Do(import.meta.url));return ge(e,t)}async function Yo(t){return Lo(t)}function _(t,e,a){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify(a))}async function le(t){return new Promise((e,a)=>{let n=[];t.on("data",r=>n.push(r)),t.on("end",()=>{try{let r=Buffer.concat(n).toString("utf-8");e(r?JSON.parse(r):{})}catch(r){a(r)}}),t.on("error",a)})}function Ha(t){return t.dashboardUrl?t.dashboardUrl.replace(/\/+$/,""):t.url.replace(/\/+$/,"").replace(/:(?:1[89][89]00|18810)$/,":4202")}function B(t,e){let a=e||t,n={id:"primary",name:a.node?.name||"this daemon",dashboardUrl:"",primary:!0},r=(a.dashboard?.daemons||[]).map(s=>({id:s.url.replace(/\/+$/,""),name:s.name,dashboardUrl:Ha(s),tokenScope:s.dashboardToken||s.token?"proxy-ready":void 0})),o=r.length>0?[{id:"fleet",name:"Fleet (all peers)",dashboardUrl:"",tokenScope:"merged across nodes"}]:[];return[n,...r,...o]}async function Qo(t,e,a){let n=new URL(t.url||"/","http://_"),r=parseInt(n.searchParams.get("hours")||"6",10)||6,o=a.config.node?.id||a.config.node?.name||"local",s=[],i=ua(r);i&&s.push({nodeId:o,snap:i});let l=(a.config.dashboard?.daemons||[]).filter(d=>d.url);await Promise.all(l.map(async d=>{let c=rt(d.url.replace(/\/+$/,""),a.config);if(c)try{let u=new AbortController,h=setTimeout(()=>u.abort(),8e3);try{let y=await fetch(`${c.url}/api/admin/activity-graph?hours=${r}`,{headers:{Accept:"application/json","X-Agentx-Peer":"primary",...c.token?{Authorization:`Bearer ${c.token}`}:{}},signal:u.signal});if(!y.ok)return;let p=await y.json();s.push({nodeId:d.name||d.url,snap:p})}finally{clearTimeout(h)}}catch{}})),_(e,200,ma(s))}async function Zo(t,e){let{spawn:a,execSync:n}=await import("child_process"),r,o;try{n("which journalctl",{stdio:"pipe"}),r="journalctl",o=["-u","agentx","--no-pager","-n","200","-f","-o","cat"]}catch{let u=process.env.HOME||"",h=[u&&`${u}/.agentx/logs/daemon-stdout.log`,"/tmp/agentx-daemon.log"].filter(Boolean),y=h.find(p=>Pa(p));if(!y){e.writeHead(503,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"no log source \u2014 install journalctl, run the daemon under launchd, or run it foreground writing to /tmp/agentx-daemon.log",searched:h}));return}r="tail",o=["-F","-n","200",y]}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`: source=${r}
9442
9684
 
9443
9685
  `);let s=a(r,o,{stdio:["ignore","pipe","pipe"]}),i="",l=u=>{i+=u.toString("utf8");let h;for(;(h=i.indexOf(`
9444
- `))>=0;){let x=i.slice(0,h).replace(/\r$/,"");i=i.slice(h+1);try{e.write(`event: line
9445
- data: ${x.replace(/\n/g," ")}
9686
+ `))>=0;){let y=i.slice(0,h).replace(/\r$/,"");i=i.slice(h+1);try{e.write(`event: line
9687
+ data: ${y.replace(/\n/g," ")}
9446
9688
 
9447
9689
  `)}catch{}}};s.stdout?.on("data",l),s.stderr?.on("data",l);let d=setInterval(()=>{try{e.write(`: hb
9448
9690
 
9449
- `)}catch{}},15e3),c=()=>{clearInterval(d);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",c),s.on("exit",c),s.on("error",c)}async function La(t,e,a,n){let r=a.url+n,o=(t.method||"GET").toUpperCase(),i=o!=="GET"&&o!=="HEAD"?await new Promise((u,h)=>{let x=[];t.on("data",p=>x.push(p)),t.on("end",()=>u(Buffer.concat(x))),t.on("error",h)}):void 0,l={},d=t.headers["content-type"];d&&(l["Content-Type"]=Array.isArray(d)?d[0]:d);let c=t.headers["x-requested-with"];c&&(l["X-Requested-With"]=Array.isArray(c)?c[0]:c),a.token&&(l.Authorization=`Bearer ${a.token}`),l["X-Agentx-Peer"]="primary";try{let u=await fetch(r,{method:o,headers:l,body:i&&i.length>0?i:void 0}),h=Buffer.from(await u.arrayBuffer());e.writeHead(u.status,{"Content-Type":u.headers.get("content-type")||"application/json","Cache-Control":"no-store","Access-Control-Allow-Origin":"*"}),e.end(h)}catch(u){k(e,502,{error:`proxy to peer failed: ${u?.message||u}`,target:r})}}function nt(t,e){let a=t.replace(/\/+$/,""),n=(e.dashboard?.daemons||[]).find(r=>r.url.replace(/\/+$/,"")===a);return n?{url:Ra(n),token:n.dashboardToken||n.token}:null}export{qi as startBoardDashboard};
9450
- //# sourceMappingURL=board-dashboard-HXDOYGIG.js.map
9691
+ `)}catch{}},15e3),c=()=>{clearInterval(d);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",c),s.on("exit",c),s.on("error",c)}async function Da(t,e,a,n){let r=a.url+n,o=(t.method||"GET").toUpperCase(),i=o!=="GET"&&o!=="HEAD"?await new Promise((u,h)=>{let y=[];t.on("data",p=>y.push(p)),t.on("end",()=>u(Buffer.concat(y))),t.on("error",h)}):void 0,l={},d=t.headers["content-type"];d&&(l["Content-Type"]=Array.isArray(d)?d[0]:d);let c=t.headers["x-requested-with"];c&&(l["X-Requested-With"]=Array.isArray(c)?c[0]:c),a.token&&(l.Authorization=`Bearer ${a.token}`),l["X-Agentx-Peer"]="primary";try{let u=await fetch(r,{method:o,headers:l,body:i&&i.length>0?i:void 0}),h=Buffer.from(await u.arrayBuffer());e.writeHead(u.status,{"Content-Type":u.headers.get("content-type")||"application/json","Cache-Control":"no-store","Access-Control-Allow-Origin":"*"}),e.end(h)}catch(u){_(e,502,{error:`proxy to peer failed: ${u?.message||u}`,target:r})}}function rt(t,e){let a=t.replace(/\/+$/,""),n=(e.dashboard?.daemons||[]).find(r=>r.url.replace(/\/+$/,"")===a);return n?{url:Ha(n),token:n.dashboardToken||n.token}:null}export{Ui as startBoardDashboard};
9692
+ //# sourceMappingURL=board-dashboard-2CPBWFOB.js.map