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.
- package/dist/{agent-57MG4LBM.js → agent-Y4U4R3ZZ.js} +2 -2
- package/dist/{board-dashboard-HXDOYGIG.js → board-dashboard-2CPBWFOB.js} +339 -97
- package/dist/board-dashboard-2CPBWFOB.js.map +1 -0
- package/dist/chunk-2HXSJYAJ.js +15 -0
- package/dist/chunk-2HXSJYAJ.js.map +1 -0
- package/dist/{chunk-QW2OYR3N.js → chunk-ABVZHJUO.js} +2 -2
- package/dist/chunk-BHSPAP4U.js +44 -0
- package/dist/chunk-BHSPAP4U.js.map +1 -0
- package/dist/chunk-CO4YCIIA.js +13 -0
- package/dist/chunk-CO4YCIIA.js.map +1 -0
- package/dist/{chunk-4MREHZP5.js → chunk-GOLZ6NEL.js} +2 -2
- package/dist/chunk-GOLZ6NEL.js.map +1 -0
- package/dist/chunk-GSX4NK2N.js +2 -0
- package/dist/chunk-GSX4NK2N.js.map +1 -0
- package/dist/chunk-GV7S5BAX.js +2 -0
- package/dist/chunk-GV7S5BAX.js.map +1 -0
- package/dist/{chunk-WPPUOTY6.js → chunk-KX626FN4.js} +2 -2
- package/dist/chunk-OPKQNLGX.js +450 -0
- package/dist/chunk-OPKQNLGX.js.map +1 -0
- package/dist/chunk-OZOQKPJV.js +102 -0
- package/dist/chunk-OZOQKPJV.js.map +1 -0
- package/dist/{chunk-DLVOHCTA.js → chunk-P3TJHGO5.js} +2 -2
- package/dist/chunk-SZDACK6O.js +2 -0
- package/dist/chunk-SZDACK6O.js.map +1 -0
- package/dist/{chunk-TC3BSUP7.js → chunk-VYLZ7UYM.js} +2 -2
- package/dist/{chunk-WFHIIVLL.js → chunk-WHP4I44J.js} +75 -51
- package/dist/chunk-WHP4I44J.js.map +1 -0
- package/dist/chunk-X5D5AV5N.js +833 -0
- package/dist/chunk-X5D5AV5N.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/{config-QXWKEQON.js → config-BLOKGMER.js} +2 -2
- package/dist/config-mutator-RG7QY2EL.js +2 -0
- package/dist/doctor-ZTECTUHX.js +2 -0
- package/dist/index.d.ts +140 -3
- package/dist/index.js +1 -1
- package/dist/program-GZOJIWTB.js +2 -0
- package/dist/registry-QZIUSQ5J.js +2 -0
- package/dist/runner-BFYDWPUO.js +2 -0
- package/dist/scheduler-B2BQPV4M.js +2 -0
- package/dist/store-I3HEWVLQ.js +2 -0
- package/dist/store-I3HEWVLQ.js.map +1 -0
- package/dist/types-Y6ZCZ52Z.js +2 -0
- package/dist/types-Y6ZCZ52Z.js.map +1 -0
- package/dist/web/workflow-editor.global.js +12 -10
- package/dist/web/workflow-editor.global.js.map +1 -1
- package/dist/workspace-setup-DQCZX2NE.js +2 -0
- package/dist/workspace-setup-DQCZX2NE.js.map +1 -0
- package/package.json +1 -1
- package/dist/board-dashboard-HXDOYGIG.js.map +0 -1
- package/dist/chunk-23AUU4S2.js +0 -102
- package/dist/chunk-23AUU4S2.js.map +0 -1
- package/dist/chunk-4MREHZP5.js.map +0 -1
- package/dist/chunk-6B74TO2J.js +0 -743
- package/dist/chunk-6B74TO2J.js.map +0 -1
- package/dist/chunk-7GVXCOLO.js +0 -440
- package/dist/chunk-7GVXCOLO.js.map +0 -1
- package/dist/chunk-E4ZZILAK.js +0 -15
- package/dist/chunk-E4ZZILAK.js.map +0 -1
- package/dist/chunk-MBOLXKA2.js +0 -6
- package/dist/chunk-MBOLXKA2.js.map +0 -1
- package/dist/chunk-WFHIIVLL.js.map +0 -1
- package/dist/chunk-ZE2YFX4K.js +0 -45
- package/dist/chunk-ZE2YFX4K.js.map +0 -1
- package/dist/config-mutator-53XGR2NT.js +0 -2
- package/dist/doctor-SEOUFHSL.js +0 -2
- package/dist/program-WWCXMRU2.js +0 -2
- package/dist/registry-HM4ELSXS.js +0 -2
- package/dist/scheduler-XVFIK4XH.js +0 -2
- package/dist/workspace-setup-FPGN5VNY.js +0 -2
- /package/dist/{agent-57MG4LBM.js.map → agent-Y4U4R3ZZ.js.map} +0 -0
- /package/dist/{chunk-QW2OYR3N.js.map → chunk-ABVZHJUO.js.map} +0 -0
- /package/dist/{chunk-WPPUOTY6.js.map → chunk-KX626FN4.js.map} +0 -0
- /package/dist/{chunk-DLVOHCTA.js.map → chunk-P3TJHGO5.js.map} +0 -0
- /package/dist/{chunk-TC3BSUP7.js.map → chunk-VYLZ7UYM.js.map} +0 -0
- /package/dist/{config-QXWKEQON.js.map → config-BLOKGMER.js.map} +0 -0
- /package/dist/{config-mutator-53XGR2NT.js.map → config-mutator-RG7QY2EL.js.map} +0 -0
- /package/dist/{doctor-SEOUFHSL.js.map → doctor-ZTECTUHX.js.map} +0 -0
- /package/dist/{program-WWCXMRU2.js.map → program-GZOJIWTB.js.map} +0 -0
- /package/dist/{registry-HM4ELSXS.js.map → registry-QZIUSQ5J.js.map} +0 -0
- /package/dist/{scheduler-XVFIK4XH.js.map → runner-BFYDWPUO.js.map} +0 -0
- /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
|
|
17
|
-
${
|
|
18
|
-
${
|
|
19
|
-
${
|
|
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
|
-
})();`,
|
|
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
|
-
${
|
|
225
|
-
${
|
|
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
|
-
${
|
|
248
|
-
${
|
|
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
|
-
${
|
|
299
|
-
${
|
|
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
|
-
${
|
|
397
|
-
${
|
|
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
|
-
${
|
|
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
|
-
${
|
|
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
|
-
${
|
|
447
|
-
${
|
|
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:<id></code> or <code>role:<id></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
|
-
${
|
|
494
|
-
${
|
|
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
|
-
${
|
|
560
|
-
${
|
|
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
|
-
${
|
|
585
|
-
${
|
|
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
|
-
${
|
|
605
|
-
${
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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[].
|
|
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:
|
|
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; }`,
|
|
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
|
|
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:
|
|
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
|
-
`,
|
|
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
|
|
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:
|
|
4366
|
-
`)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function
|
|
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),
|
|
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(
|
|
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
|
|
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=
|
|
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:
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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=
|
|
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
|
|
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
|
|
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 (${
|
|
4791
|
-
`).all(
|
|
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(
|
|
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=
|
|
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=
|
|
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<
|
|
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
|
-
`,
|
|
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
|
-
`,
|
|
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
|
|
6338
|
-
`);return
|
|
6339
|
-
`);return
|
|
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(
|
|
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(
|
|
6359
|
-
<span class="task-modal-status" id="task-modal-status">${R(
|
|
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:`${
|
|
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
|
|
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); } }`,
|
|
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
|
|
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:
|
|
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
|
|
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
|
-
`,
|
|
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
|
|
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
|
-
${
|
|
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
|
|
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:
|
|
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
|
-
`,
|
|
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
|
|
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
|
|
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){
|
|
9393
|
-
Live dashboard: http://${
|
|
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://${
|
|
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
|
|
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(
|
|
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),
|
|
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{
|
|
9403
|
-
`;
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
9445
|
-
data: ${
|
|
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
|
|
9450
|
-
//# sourceMappingURL=board-dashboard-
|
|
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
|