@frumu/tandem-panel 0.3.27

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.
@@ -0,0 +1,916 @@
1
+ (function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const o of i.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(s){if(s.ep)return;s.ep=!0;const i=n(s);fetch(s.href,i)}})();function g(e,t,n){function r(c,d){if(c._zod||Object.defineProperty(c,"_zod",{value:{def:d,constr:o,traits:new Set},enumerable:!1}),c._zod.traits.has(e))return;c._zod.traits.add(e),t(c,d);const l=o.prototype,p=Object.keys(l);for(let v=0;v<p.length;v++){const $=p[v];$ in c||(c[$]=l[$].bind(c))}}const s=n?.Parent??Object;class i extends s{}Object.defineProperty(i,"name",{value:e});function o(c){var d;const l=n?.Parent?new i:this;r(l,c),(d=l._zod).deferred??(d.deferred=[]);for(const p of l._zod.deferred)p();return l}return Object.defineProperty(o,"init",{value:r}),Object.defineProperty(o,Symbol.hasInstance,{value:c=>n?.Parent&&c instanceof n.Parent?!0:c?._zod?.traits?.has(e)}),Object.defineProperty(o,"name",{value:e}),o}class $t extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class br extends Error{constructor(t){super(`Encountered unidirectional transform during encode: ${t}`),this.name="ZodEncodeError"}}const wr={};function Ve(e){return wr}function $r(e){const t=Object.values(e).filter(r=>typeof r=="number");return Object.entries(e).filter(([r,s])=>t.indexOf(+r)===-1).map(([r,s])=>s)}function Sn(e,t){return typeof t=="bigint"?t.toString():t}function zn(e){return{get value(){{const t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function An(e){return e==null}function Rn(e){const t=e.startsWith("^")?1:0,n=e.endsWith("$")?e.length-1:e.length;return e.slice(t,n)}function ys(e,t){const n=(e.toString().split(".")[1]||"").length,r=t.toString();let s=(r.split(".")[1]||"").length;if(s===0&&/\d?e-\d?/.test(r)){const d=r.match(/\d?e-(\d?)/);d?.[1]&&(s=Number.parseInt(d[1]))}const i=n>s?n:s,o=Number.parseInt(e.toFixed(i).replace(".","")),c=Number.parseInt(t.toFixed(i).replace(".",""));return o%c/10**i}const Zn=Symbol("evaluating");function G(e,t,n){let r;Object.defineProperty(e,t,{get(){if(r!==Zn)return r===void 0&&(r=Zn,r=n()),r},set(s){Object.defineProperty(e,t,{value:s})},configurable:!0})}function at(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function Ke(...e){const t={};for(const n of e){const r=Object.getOwnPropertyDescriptors(n);Object.assign(t,r)}return Object.defineProperties({},t)}function qn(e){return JSON.stringify(e)}function bs(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}const Sr="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function Qt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}const ws=zn(()=>{if(typeof navigator<"u"&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{const e=Function;return new e(""),!0}catch{return!1}});function St(e){if(Qt(e)===!1)return!1;const t=e.constructor;if(t===void 0||typeof t!="function")return!0;const n=t.prototype;return!(Qt(n)===!1||Object.prototype.hasOwnProperty.call(n,"isPrototypeOf")===!1)}function _r(e){return St(e)?{...e}:Array.isArray(e)?[...e]:e}const $s=new Set(["string","number","symbol"]);function on(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ge(e,t,n){const r=new e._zod.constr(t??e._zod.def);return(!t||n?.parent)&&(r._zod.parent=e),r}function O(e){const t=e;if(!t)return{};if(typeof t=="string")return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw new Error("Cannot specify both `message` and `error` params");t.error=t.message}return delete t.message,typeof t.error=="string"?{...t,error:()=>t.error}:t}function Ss(e){return Object.keys(e).filter(t=>e[t]._zod.optin==="optional"&&e[t]._zod.optout==="optional")}const _s={safeint:[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-34028234663852886e22,34028234663852886e22],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]};function ks(e,t){const n=e._zod.def,r=n.checks;if(r&&r.length>0)throw new Error(".pick() cannot be used on object schemas containing refinements");const i=Ke(e._zod.def,{get shape(){const o={};for(const c in t){if(!(c in n.shape))throw new Error(`Unrecognized key: "${c}"`);t[c]&&(o[c]=n.shape[c])}return at(this,"shape",o),o},checks:[]});return Ge(e,i)}function xs(e,t){const n=e._zod.def,r=n.checks;if(r&&r.length>0)throw new Error(".omit() cannot be used on object schemas containing refinements");const i=Ke(e._zod.def,{get shape(){const o={...e._zod.def.shape};for(const c in t){if(!(c in n.shape))throw new Error(`Unrecognized key: "${c}"`);t[c]&&delete o[c]}return at(this,"shape",o),o},checks:[]});return Ge(e,i)}function Is(e,t){if(!St(t))throw new Error("Invalid input to extend: expected a plain object");const n=e._zod.def.checks;if(n&&n.length>0){const i=e._zod.def.shape;for(const o in t)if(Object.getOwnPropertyDescriptor(i,o)!==void 0)throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}const s=Ke(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t};return at(this,"shape",i),i}});return Ge(e,s)}function Es(e,t){if(!St(t))throw new Error("Invalid input to safeExtend: expected a plain object");const n=Ke(e._zod.def,{get shape(){const r={...e._zod.def.shape,...t};return at(this,"shape",r),r}});return Ge(e,n)}function Ts(e,t){const n=Ke(e._zod.def,{get shape(){const r={...e._zod.def.shape,...t._zod.def.shape};return at(this,"shape",r),r},get catchall(){return t._zod.def.catchall},checks:[]});return Ge(e,n)}function zs(e,t,n){const s=t._zod.def.checks;if(s&&s.length>0)throw new Error(".partial() cannot be used on object schemas containing refinements");const o=Ke(t._zod.def,{get shape(){const c=t._zod.def.shape,d={...c};if(n)for(const l in n){if(!(l in c))throw new Error(`Unrecognized key: "${l}"`);n[l]&&(d[l]=e?new e({type:"optional",innerType:c[l]}):c[l])}else for(const l in c)d[l]=e?new e({type:"optional",innerType:c[l]}):c[l];return at(this,"shape",d),d},checks:[]});return Ge(t,o)}function As(e,t,n){const r=Ke(t._zod.def,{get shape(){const s=t._zod.def.shape,i={...s};if(n)for(const o in n){if(!(o in i))throw new Error(`Unrecognized key: "${o}"`);n[o]&&(i[o]=new e({type:"nonoptional",innerType:s[o]}))}else for(const o in s)i[o]=new e({type:"nonoptional",innerType:s[o]});return at(this,"shape",i),i}});return Ge(t,r)}function bt(e,t=0){if(e.aborted===!0)return!0;for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue!==!0)return!0;return!1}function wt(e,t){return t.map(n=>{var r;return(r=n).path??(r.path=[]),n.path.unshift(e),n})}function Vt(e){return typeof e=="string"?e:e?.message}function Be(e,t,n){const r={...e,path:e.path??[]};if(!e.message){const s=Vt(e.inst?._zod.def?.error?.(e))??Vt(t?.error?.(e))??Vt(n.customError?.(e))??Vt(n.localeError?.(e))??"Invalid input";r.message=s}return delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}function Cn(e){return Array.isArray(e)?"array":typeof e=="string"?"string":"unknown"}function At(...e){const[t,n,r]=e;return typeof t=="string"?{message:t,code:"custom",input:n,inst:r}:{...t}}const kr=(e,t)=>{e.name="$ZodError",Object.defineProperty(e,"_zod",{value:e._zod,enumerable:!1}),Object.defineProperty(e,"issues",{value:t,enumerable:!1}),e.message=JSON.stringify(t,Sn,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},xr=g("$ZodError",kr),Ir=g("$ZodError",kr,{Parent:Error});function Rs(e,t=n=>n.message){const n={},r=[];for(const s of e.issues)s.path.length>0?(n[s.path[0]]=n[s.path[0]]||[],n[s.path[0]].push(t(s))):r.push(t(s));return{formErrors:r,fieldErrors:n}}function Cs(e,t=n=>n.message){const n={_errors:[]},r=s=>{for(const i of s.issues)if(i.code==="invalid_union"&&i.errors.length)i.errors.map(o=>r({issues:o}));else if(i.code==="invalid_key")r({issues:i.issues});else if(i.code==="invalid_element")r({issues:i.issues});else if(i.path.length===0)n._errors.push(t(i));else{let o=n,c=0;for(;c<i.path.length;){const d=i.path[c];c===i.path.length-1?(o[d]=o[d]||{_errors:[]},o[d]._errors.push(t(i))):o[d]=o[d]||{_errors:[]},o=o[d],c++}}};return r(e),n}const On=e=>(t,n,r,s)=>{const i=r?Object.assign(r,{async:!1}):{async:!1},o=t._zod.run({value:n,issues:[]},i);if(o instanceof Promise)throw new $t;if(o.issues.length){const c=new(s?.Err??e)(o.issues.map(d=>Be(d,i,Ve())));throw Sr(c,s?.callee),c}return o.value},Pn=e=>async(t,n,r,s)=>{const i=r?Object.assign(r,{async:!0}):{async:!0};let o=t._zod.run({value:n,issues:[]},i);if(o instanceof Promise&&(o=await o),o.issues.length){const c=new(s?.Err??e)(o.issues.map(d=>Be(d,i,Ve())));throw Sr(c,s?.callee),c}return o.value},an=e=>(t,n,r)=>{const s=r?{...r,async:!1}:{async:!1},i=t._zod.run({value:n,issues:[]},s);if(i instanceof Promise)throw new $t;return i.issues.length?{success:!1,error:new(e??xr)(i.issues.map(o=>Be(o,s,Ve())))}:{success:!0,data:i.value}},Os=an(Ir),cn=e=>async(t,n,r)=>{const s=r?Object.assign(r,{async:!0}):{async:!0};let i=t._zod.run({value:n,issues:[]},s);return i instanceof Promise&&(i=await i),i.issues.length?{success:!1,error:new e(i.issues.map(o=>Be(o,s,Ve())))}:{success:!0,data:i.value}},Ps=cn(Ir),Ms=e=>(t,n,r)=>{const s=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return On(e)(t,n,s)},Ns=e=>(t,n,r)=>On(e)(t,n,r),Ls=e=>async(t,n,r)=>{const s=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return Pn(e)(t,n,s)},Ds=e=>async(t,n,r)=>Pn(e)(t,n,r),js=e=>(t,n,r)=>{const s=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return an(e)(t,n,s)},Zs=e=>(t,n,r)=>an(e)(t,n,r),qs=e=>async(t,n,r)=>{const s=r?Object.assign(r,{direction:"backward"}):{direction:"backward"};return cn(e)(t,n,s)},Us=e=>async(t,n,r)=>cn(e)(t,n,r),Fs=/^[cC][^\s-]{8,}$/,Js=/^[0-9a-z]+$/,Hs=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,Vs=/^[0-9a-vA-V]{20}$/,Bs=/^[A-Za-z0-9]{27}$/,Ws=/^[a-zA-Z0-9_-]{21}$/,Ks=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,Gs=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,Un=e=>e?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,Xs=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/,Ys="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";function Qs(){return new RegExp(Ys,"u")}const eo=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,to=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,no=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,ro=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,so=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,Er=/^[A-Za-z0-9_-]*$/,oo=/^\+[1-9]\d{6,14}$/,Tr="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))",io=new RegExp(`^${Tr}$`);function zr(e){const t="(?:[01]\\d|2[0-3]):[0-5]\\d";return typeof e.precision=="number"?e.precision===-1?`${t}`:e.precision===0?`${t}:[0-5]\\d`:`${t}:[0-5]\\d\\.\\d{${e.precision}}`:`${t}(?::[0-5]\\d(?:\\.\\d+)?)?`}function ao(e){return new RegExp(`^${zr(e)}$`)}function co(e){const t=zr({precision:e.precision}),n=["Z"];e.local&&n.push(""),e.offset&&n.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");const r=`${t}(?:${n.join("|")})`;return new RegExp(`^${Tr}T(?:${r})$`)}const lo=e=>{const t=e?`[\\s\\S]{${e?.minimum??0},${e?.maximum??""}}`:"[\\s\\S]*";return new RegExp(`^${t}$`)},uo=/^-?\d+$/,Ar=/^-?\d+(?:\.\d+)?$/,po=/^(?:true|false)$/i,mo=/^[^A-Z]*$/,fo=/^[^a-z]*$/,ge=g("$ZodCheck",(e,t)=>{var n;e._zod??(e._zod={}),e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),Rr={number:"number",bigint:"bigint",object:"date"},Cr=g("$ZodCheckLessThan",(e,t)=>{ge.init(e,t);const n=Rr[typeof t.value];e._zod.onattach.push(r=>{const s=r._zod.bag,i=(t.inclusive?s.maximum:s.exclusiveMaximum)??Number.POSITIVE_INFINITY;t.value<i&&(t.inclusive?s.maximum=t.value:s.exclusiveMaximum=t.value)}),e._zod.check=r=>{(t.inclusive?r.value<=t.value:r.value<t.value)||r.issues.push({origin:n,code:"too_big",maximum:typeof t.value=="object"?t.value.getTime():t.value,input:r.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),Or=g("$ZodCheckGreaterThan",(e,t)=>{ge.init(e,t);const n=Rr[typeof t.value];e._zod.onattach.push(r=>{const s=r._zod.bag,i=(t.inclusive?s.minimum:s.exclusiveMinimum)??Number.NEGATIVE_INFINITY;t.value>i&&(t.inclusive?s.minimum=t.value:s.exclusiveMinimum=t.value)}),e._zod.check=r=>{(t.inclusive?r.value>=t.value:r.value>t.value)||r.issues.push({origin:n,code:"too_small",minimum:typeof t.value=="object"?t.value.getTime():t.value,input:r.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),ho=g("$ZodCheckMultipleOf",(e,t)=>{ge.init(e,t),e._zod.onattach.push(n=>{var r;(r=n._zod.bag).multipleOf??(r.multipleOf=t.value)}),e._zod.check=n=>{if(typeof n.value!=typeof t.value)throw new Error("Cannot mix number and bigint in multiple_of check.");(typeof n.value=="bigint"?n.value%t.value===BigInt(0):ys(n.value,t.value)===0)||n.issues.push({origin:typeof n.value,code:"not_multiple_of",divisor:t.value,input:n.value,inst:e,continue:!t.abort})}}),go=g("$ZodCheckNumberFormat",(e,t)=>{ge.init(e,t),t.format=t.format||"float64";const n=t.format?.includes("int"),r=n?"int":"number",[s,i]=_s[t.format];e._zod.onattach.push(o=>{const c=o._zod.bag;c.format=t.format,c.minimum=s,c.maximum=i,n&&(c.pattern=uo)}),e._zod.check=o=>{const c=o.value;if(n){if(!Number.isInteger(c)){o.issues.push({expected:r,format:t.format,code:"invalid_type",continue:!1,input:c,inst:e});return}if(!Number.isSafeInteger(c)){c>0?o.issues.push({input:c,code:"too_big",maximum:Number.MAX_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:r,inclusive:!0,continue:!t.abort}):o.issues.push({input:c,code:"too_small",minimum:Number.MIN_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:r,inclusive:!0,continue:!t.abort});return}}c<s&&o.issues.push({origin:"number",input:c,code:"too_small",minimum:s,inclusive:!0,inst:e,continue:!t.abort}),c>i&&o.issues.push({origin:"number",input:c,code:"too_big",maximum:i,inclusive:!0,inst:e,continue:!t.abort})}}),vo=g("$ZodCheckMaxLength",(e,t)=>{var n;ge.init(e,t),(n=e._zod.def).when??(n.when=r=>{const s=r.value;return!An(s)&&s.length!==void 0}),e._zod.onattach.push(r=>{const s=r._zod.bag.maximum??Number.POSITIVE_INFINITY;t.maximum<s&&(r._zod.bag.maximum=t.maximum)}),e._zod.check=r=>{const s=r.value;if(s.length<=t.maximum)return;const o=Cn(s);r.issues.push({origin:o,code:"too_big",maximum:t.maximum,inclusive:!0,input:s,inst:e,continue:!t.abort})}}),yo=g("$ZodCheckMinLength",(e,t)=>{var n;ge.init(e,t),(n=e._zod.def).when??(n.when=r=>{const s=r.value;return!An(s)&&s.length!==void 0}),e._zod.onattach.push(r=>{const s=r._zod.bag.minimum??Number.NEGATIVE_INFINITY;t.minimum>s&&(r._zod.bag.minimum=t.minimum)}),e._zod.check=r=>{const s=r.value;if(s.length>=t.minimum)return;const o=Cn(s);r.issues.push({origin:o,code:"too_small",minimum:t.minimum,inclusive:!0,input:s,inst:e,continue:!t.abort})}}),bo=g("$ZodCheckLengthEquals",(e,t)=>{var n;ge.init(e,t),(n=e._zod.def).when??(n.when=r=>{const s=r.value;return!An(s)&&s.length!==void 0}),e._zod.onattach.push(r=>{const s=r._zod.bag;s.minimum=t.length,s.maximum=t.length,s.length=t.length}),e._zod.check=r=>{const s=r.value,i=s.length;if(i===t.length)return;const o=Cn(s),c=i>t.length;r.issues.push({origin:o,...c?{code:"too_big",maximum:t.length}:{code:"too_small",minimum:t.length},inclusive:!0,exact:!0,input:r.value,inst:e,continue:!t.abort})}}),ln=g("$ZodCheckStringFormat",(e,t)=>{var n,r;ge.init(e,t),e._zod.onattach.push(s=>{const i=s._zod.bag;i.format=t.format,t.pattern&&(i.patterns??(i.patterns=new Set),i.patterns.add(t.pattern))}),t.pattern?(n=e._zod).check??(n.check=s=>{t.pattern.lastIndex=0,!t.pattern.test(s.value)&&s.issues.push({origin:"string",code:"invalid_format",format:t.format,input:s.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(r=e._zod).check??(r.check=()=>{})}),wo=g("$ZodCheckRegex",(e,t)=>{ln.init(e,t),e._zod.check=n=>{t.pattern.lastIndex=0,!t.pattern.test(n.value)&&n.issues.push({origin:"string",code:"invalid_format",format:"regex",input:n.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),$o=g("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=mo),ln.init(e,t)}),So=g("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=fo),ln.init(e,t)}),_o=g("$ZodCheckIncludes",(e,t)=>{ge.init(e,t);const n=on(t.includes),r=new RegExp(typeof t.position=="number"?`^.{${t.position}}${n}`:n);t.pattern=r,e._zod.onattach.push(s=>{const i=s._zod.bag;i.patterns??(i.patterns=new Set),i.patterns.add(r)}),e._zod.check=s=>{s.value.includes(t.includes,t.position)||s.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:t.includes,input:s.value,inst:e,continue:!t.abort})}}),ko=g("$ZodCheckStartsWith",(e,t)=>{ge.init(e,t);const n=new RegExp(`^${on(t.prefix)}.*`);t.pattern??(t.pattern=n),e._zod.onattach.push(r=>{const s=r._zod.bag;s.patterns??(s.patterns=new Set),s.patterns.add(n)}),e._zod.check=r=>{r.value.startsWith(t.prefix)||r.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:t.prefix,input:r.value,inst:e,continue:!t.abort})}}),xo=g("$ZodCheckEndsWith",(e,t)=>{ge.init(e,t);const n=new RegExp(`.*${on(t.suffix)}$`);t.pattern??(t.pattern=n),e._zod.onattach.push(r=>{const s=r._zod.bag;s.patterns??(s.patterns=new Set),s.patterns.add(n)}),e._zod.check=r=>{r.value.endsWith(t.suffix)||r.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:t.suffix,input:r.value,inst:e,continue:!t.abort})}}),Io=g("$ZodCheckOverwrite",(e,t)=>{ge.init(e,t),e._zod.check=n=>{n.value=t.tx(n.value)}});class Eo{constructor(t=[]){this.content=[],this.indent=0,this&&(this.args=t)}indented(t){this.indent+=1,t(this),this.indent-=1}write(t){if(typeof t=="function"){t(this,{execution:"sync"}),t(this,{execution:"async"});return}const r=t.split(`
2
+ `).filter(o=>o),s=Math.min(...r.map(o=>o.length-o.trimStart().length)),i=r.map(o=>o.slice(s)).map(o=>" ".repeat(this.indent*2)+o);for(const o of i)this.content.push(o)}compile(){const t=Function,n=this?.args,s=[...(this?.content??[""]).map(i=>` ${i}`)];return new t(...n,s.join(`
3
+ `))}}const To={major:4,minor:3,patch:6},ee=g("$ZodType",(e,t)=>{var n;e??(e={}),e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=To;const r=[...e._zod.def.checks??[]];e._zod.traits.has("$ZodCheck")&&r.unshift(e);for(const s of r)for(const i of s._zod.onattach)i(e);if(r.length===0)(n=e._zod).deferred??(n.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{const s=(o,c,d)=>{let l=bt(o),p;for(const v of c){if(v._zod.def.when){if(!v._zod.def.when(o))continue}else if(l)continue;const $=o.issues.length,w=v._zod.check(o);if(w instanceof Promise&&d?.async===!1)throw new $t;if(p||w instanceof Promise)p=(p??Promise.resolve()).then(async()=>{await w,o.issues.length!==$&&(l||(l=bt(o,$)))});else{if(o.issues.length===$)continue;l||(l=bt(o,$))}}return p?p.then(()=>o):o},i=(o,c,d)=>{if(bt(o))return o.aborted=!0,o;const l=s(c,r,d);if(l instanceof Promise){if(d.async===!1)throw new $t;return l.then(p=>e._zod.parse(p,d))}return e._zod.parse(l,d)};e._zod.run=(o,c)=>{if(c.skipChecks)return e._zod.parse(o,c);if(c.direction==="backward"){const l=e._zod.parse({value:o.value,issues:[]},{...c,skipChecks:!0});return l instanceof Promise?l.then(p=>i(p,o,c)):i(l,o,c)}const d=e._zod.parse(o,c);if(d instanceof Promise){if(c.async===!1)throw new $t;return d.then(l=>s(l,r,c))}return s(d,r,c)}}G(e,"~standard",()=>({validate:s=>{try{const i=Os(e,s);return i.success?{value:i.data}:{issues:i.error?.issues}}catch{return Ps(e,s).then(o=>o.success?{value:o.data}:{issues:o.error?.issues})}},vendor:"zod",version:1}))}),Mn=g("$ZodString",(e,t)=>{ee.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??lo(e._zod.bag),e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=String(n.value)}catch{}return typeof n.value=="string"||n.issues.push({expected:"string",code:"invalid_type",input:n.value,inst:e}),n}}),Q=g("$ZodStringFormat",(e,t)=>{ln.init(e,t),Mn.init(e,t)}),zo=g("$ZodGUID",(e,t)=>{t.pattern??(t.pattern=Gs),Q.init(e,t)}),Ao=g("$ZodUUID",(e,t)=>{if(t.version){const r={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[t.version];if(r===void 0)throw new Error(`Invalid UUID version: "${t.version}"`);t.pattern??(t.pattern=Un(r))}else t.pattern??(t.pattern=Un());Q.init(e,t)}),Ro=g("$ZodEmail",(e,t)=>{t.pattern??(t.pattern=Xs),Q.init(e,t)}),Co=g("$ZodURL",(e,t)=>{Q.init(e,t),e._zod.check=n=>{try{const r=n.value.trim(),s=new URL(r);t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(s.hostname)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:t.hostname.source,input:n.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(s.protocol.endsWith(":")?s.protocol.slice(0,-1):s.protocol)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid protocol",pattern:t.protocol.source,input:n.value,inst:e,continue:!t.abort})),t.normalize?n.value=s.href:n.value=r;return}catch{n.issues.push({code:"invalid_format",format:"url",input:n.value,inst:e,continue:!t.abort})}}}),Oo=g("$ZodEmoji",(e,t)=>{t.pattern??(t.pattern=Qs()),Q.init(e,t)}),Po=g("$ZodNanoID",(e,t)=>{t.pattern??(t.pattern=Ws),Q.init(e,t)}),Mo=g("$ZodCUID",(e,t)=>{t.pattern??(t.pattern=Fs),Q.init(e,t)}),No=g("$ZodCUID2",(e,t)=>{t.pattern??(t.pattern=Js),Q.init(e,t)}),Lo=g("$ZodULID",(e,t)=>{t.pattern??(t.pattern=Hs),Q.init(e,t)}),Do=g("$ZodXID",(e,t)=>{t.pattern??(t.pattern=Vs),Q.init(e,t)}),jo=g("$ZodKSUID",(e,t)=>{t.pattern??(t.pattern=Bs),Q.init(e,t)}),Zo=g("$ZodISODateTime",(e,t)=>{t.pattern??(t.pattern=co(t)),Q.init(e,t)}),qo=g("$ZodISODate",(e,t)=>{t.pattern??(t.pattern=io),Q.init(e,t)}),Uo=g("$ZodISOTime",(e,t)=>{t.pattern??(t.pattern=ao(t)),Q.init(e,t)}),Fo=g("$ZodISODuration",(e,t)=>{t.pattern??(t.pattern=Ks),Q.init(e,t)}),Jo=g("$ZodIPv4",(e,t)=>{t.pattern??(t.pattern=eo),Q.init(e,t),e._zod.bag.format="ipv4"}),Ho=g("$ZodIPv6",(e,t)=>{t.pattern??(t.pattern=to),Q.init(e,t),e._zod.bag.format="ipv6",e._zod.check=n=>{try{new URL(`http://[${n.value}]`)}catch{n.issues.push({code:"invalid_format",format:"ipv6",input:n.value,inst:e,continue:!t.abort})}}}),Vo=g("$ZodCIDRv4",(e,t)=>{t.pattern??(t.pattern=no),Q.init(e,t)}),Bo=g("$ZodCIDRv6",(e,t)=>{t.pattern??(t.pattern=ro),Q.init(e,t),e._zod.check=n=>{const r=n.value.split("/");try{if(r.length!==2)throw new Error;const[s,i]=r;if(!i)throw new Error;const o=Number(i);if(`${o}`!==i)throw new Error;if(o<0||o>128)throw new Error;new URL(`http://[${s}]`)}catch{n.issues.push({code:"invalid_format",format:"cidrv6",input:n.value,inst:e,continue:!t.abort})}}});function Pr(e){if(e==="")return!0;if(e.length%4!==0)return!1;try{return atob(e),!0}catch{return!1}}const Wo=g("$ZodBase64",(e,t)=>{t.pattern??(t.pattern=so),Q.init(e,t),e._zod.bag.contentEncoding="base64",e._zod.check=n=>{Pr(n.value)||n.issues.push({code:"invalid_format",format:"base64",input:n.value,inst:e,continue:!t.abort})}});function Ko(e){if(!Er.test(e))return!1;const t=e.replace(/[-_]/g,r=>r==="-"?"+":"/"),n=t.padEnd(Math.ceil(t.length/4)*4,"=");return Pr(n)}const Go=g("$ZodBase64URL",(e,t)=>{t.pattern??(t.pattern=Er),Q.init(e,t),e._zod.bag.contentEncoding="base64url",e._zod.check=n=>{Ko(n.value)||n.issues.push({code:"invalid_format",format:"base64url",input:n.value,inst:e,continue:!t.abort})}}),Xo=g("$ZodE164",(e,t)=>{t.pattern??(t.pattern=oo),Q.init(e,t)});function Yo(e,t=null){try{const n=e.split(".");if(n.length!==3)return!1;const[r]=n;if(!r)return!1;const s=JSON.parse(atob(r));return!("typ"in s&&s?.typ!=="JWT"||!s.alg||t&&(!("alg"in s)||s.alg!==t))}catch{return!1}}const Qo=g("$ZodJWT",(e,t)=>{Q.init(e,t),e._zod.check=n=>{Yo(n.value,t.alg)||n.issues.push({code:"invalid_format",format:"jwt",input:n.value,inst:e,continue:!t.abort})}}),Mr=g("$ZodNumber",(e,t)=>{ee.init(e,t),e._zod.pattern=e._zod.bag.pattern??Ar,e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=Number(n.value)}catch{}const s=n.value;if(typeof s=="number"&&!Number.isNaN(s)&&Number.isFinite(s))return n;const i=typeof s=="number"?Number.isNaN(s)?"NaN":Number.isFinite(s)?void 0:"Infinity":void 0;return n.issues.push({expected:"number",code:"invalid_type",input:s,inst:e,...i?{received:i}:{}}),n}}),ei=g("$ZodNumberFormat",(e,t)=>{go.init(e,t),Mr.init(e,t)}),ti=g("$ZodBoolean",(e,t)=>{ee.init(e,t),e._zod.pattern=po,e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=!!n.value}catch{}const s=n.value;return typeof s=="boolean"||n.issues.push({expected:"boolean",code:"invalid_type",input:s,inst:e}),n}}),ni=g("$ZodAny",(e,t)=>{ee.init(e,t),e._zod.parse=n=>n}),ri=g("$ZodUnknown",(e,t)=>{ee.init(e,t),e._zod.parse=n=>n}),si=g("$ZodNever",(e,t)=>{ee.init(e,t),e._zod.parse=(n,r)=>(n.issues.push({expected:"never",code:"invalid_type",input:n.value,inst:e}),n)});function Fn(e,t,n){e.issues.length&&t.issues.push(...wt(n,e.issues)),t.value[n]=e.value}const oi=g("$ZodArray",(e,t)=>{ee.init(e,t),e._zod.parse=(n,r)=>{const s=n.value;if(!Array.isArray(s))return n.issues.push({expected:"array",code:"invalid_type",input:s,inst:e}),n;n.value=Array(s.length);const i=[];for(let o=0;o<s.length;o++){const c=s[o],d=t.element._zod.run({value:c,issues:[]},r);d instanceof Promise?i.push(d.then(l=>Fn(l,n,o))):Fn(d,n,o)}return i.length?Promise.all(i).then(()=>n):n}});function en(e,t,n,r,s){if(e.issues.length){if(s&&!(n in r))return;t.issues.push(...wt(n,e.issues))}e.value===void 0?n in r&&(t.value[n]=void 0):t.value[n]=e.value}function Nr(e){const t=Object.keys(e.shape);for(const r of t)if(!e.shape?.[r]?._zod?.traits?.has("$ZodType"))throw new Error(`Invalid element at key "${r}": expected a Zod schema`);const n=Ss(e.shape);return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(n)}}function Lr(e,t,n,r,s,i){const o=[],c=s.keySet,d=s.catchall._zod,l=d.def.type,p=d.optout==="optional";for(const v in t){if(c.has(v))continue;if(l==="never"){o.push(v);continue}const $=d.run({value:t[v],issues:[]},r);$ instanceof Promise?e.push($.then(w=>en(w,n,v,t,p))):en($,n,v,t,p)}return o.length&&n.issues.push({code:"unrecognized_keys",keys:o,input:t,inst:i}),e.length?Promise.all(e).then(()=>n):n}const ii=g("$ZodObject",(e,t)=>{if(ee.init(e,t),!Object.getOwnPropertyDescriptor(t,"shape")?.get){const c=t.shape;Object.defineProperty(t,"shape",{get:()=>{const d={...c};return Object.defineProperty(t,"shape",{value:d}),d}})}const r=zn(()=>Nr(t));G(e._zod,"propValues",()=>{const c=t.shape,d={};for(const l in c){const p=c[l]._zod;if(p.values){d[l]??(d[l]=new Set);for(const v of p.values)d[l].add(v)}}return d});const s=Qt,i=t.catchall;let o;e._zod.parse=(c,d)=>{o??(o=r.value);const l=c.value;if(!s(l))return c.issues.push({expected:"object",code:"invalid_type",input:l,inst:e}),c;c.value={};const p=[],v=o.shape;for(const $ of o.keys){const w=v[$],f=w._zod.optout==="optional",h=w._zod.run({value:l[$],issues:[]},d);h instanceof Promise?p.push(h.then(_=>en(_,c,$,l,f))):en(h,c,$,l,f)}return i?Lr(p,l,c,d,r.value,e):p.length?Promise.all(p).then(()=>c):c}}),ai=g("$ZodObjectJIT",(e,t)=>{ii.init(e,t);const n=e._zod.parse,r=zn(()=>Nr(t)),s=$=>{const w=new Eo(["shape","payload","ctx"]),f=r.value,h=q=>{const H=qn(q);return`shape[${H}]._zod.run({ value: input[${H}], issues: [] }, ctx)`};w.write("const input = payload.value;");const _=Object.create(null);let Z=0;for(const q of f.keys)_[q]=`key_${Z++}`;w.write("const newResult = {};");for(const q of f.keys){const H=_[q],x=qn(q),A=$[q]?._zod?.optout==="optional";w.write(`const ${H} = ${h(q)};`),A?w.write(`
4
+ if (${H}.issues.length) {
5
+ if (${x} in input) {
6
+ payload.issues = payload.issues.concat(${H}.issues.map(iss => ({
7
+ ...iss,
8
+ path: iss.path ? [${x}, ...iss.path] : [${x}]
9
+ })));
10
+ }
11
+ }
12
+
13
+ if (${H}.value === undefined) {
14
+ if (${x} in input) {
15
+ newResult[${x}] = undefined;
16
+ }
17
+ } else {
18
+ newResult[${x}] = ${H}.value;
19
+ }
20
+
21
+ `):w.write(`
22
+ if (${H}.issues.length) {
23
+ payload.issues = payload.issues.concat(${H}.issues.map(iss => ({
24
+ ...iss,
25
+ path: iss.path ? [${x}, ...iss.path] : [${x}]
26
+ })));
27
+ }
28
+
29
+ if (${H}.value === undefined) {
30
+ if (${x} in input) {
31
+ newResult[${x}] = undefined;
32
+ }
33
+ } else {
34
+ newResult[${x}] = ${H}.value;
35
+ }
36
+
37
+ `)}w.write("payload.value = newResult;"),w.write("return payload;");const N=w.compile();return(q,H)=>N($,q,H)};let i;const o=Qt,c=!wr.jitless,l=c&&ws.value,p=t.catchall;let v;e._zod.parse=($,w)=>{v??(v=r.value);const f=$.value;return o(f)?c&&l&&w?.async===!1&&w.jitless!==!0?(i||(i=s(t.shape)),$=i($,w),p?Lr([],f,$,w,v,e):$):n($,w):($.issues.push({expected:"object",code:"invalid_type",input:f,inst:e}),$)}});function Jn(e,t,n,r){for(const i of e)if(i.issues.length===0)return t.value=i.value,t;const s=e.filter(i=>!bt(i));return s.length===1?(t.value=s[0].value,s[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:n,errors:e.map(i=>i.issues.map(o=>Be(o,r,Ve())))}),t)}const ci=g("$ZodUnion",(e,t)=>{ee.init(e,t),G(e._zod,"optin",()=>t.options.some(s=>s._zod.optin==="optional")?"optional":void 0),G(e._zod,"optout",()=>t.options.some(s=>s._zod.optout==="optional")?"optional":void 0),G(e._zod,"values",()=>{if(t.options.every(s=>s._zod.values))return new Set(t.options.flatMap(s=>Array.from(s._zod.values)))}),G(e._zod,"pattern",()=>{if(t.options.every(s=>s._zod.pattern)){const s=t.options.map(i=>i._zod.pattern);return new RegExp(`^(${s.map(i=>Rn(i.source)).join("|")})$`)}});const n=t.options.length===1,r=t.options[0]._zod.run;e._zod.parse=(s,i)=>{if(n)return r(s,i);let o=!1;const c=[];for(const d of t.options){const l=d._zod.run({value:s.value,issues:[]},i);if(l instanceof Promise)c.push(l),o=!0;else{if(l.issues.length===0)return l;c.push(l)}}return o?Promise.all(c).then(d=>Jn(d,s,e,i)):Jn(c,s,e,i)}}),li=g("$ZodIntersection",(e,t)=>{ee.init(e,t),e._zod.parse=(n,r)=>{const s=n.value,i=t.left._zod.run({value:s,issues:[]},r),o=t.right._zod.run({value:s,issues:[]},r);return i instanceof Promise||o instanceof Promise?Promise.all([i,o]).then(([d,l])=>Hn(n,d,l)):Hn(n,i,o)}});function _n(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e==+t)return{valid:!0,data:e};if(St(e)&&St(t)){const n=Object.keys(t),r=Object.keys(e).filter(i=>n.indexOf(i)!==-1),s={...e,...t};for(const i of r){const o=_n(e[i],t[i]);if(!o.valid)return{valid:!1,mergeErrorPath:[i,...o.mergeErrorPath]};s[i]=o.data}return{valid:!0,data:s}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};const n=[];for(let r=0;r<e.length;r++){const s=e[r],i=t[r],o=_n(s,i);if(!o.valid)return{valid:!1,mergeErrorPath:[r,...o.mergeErrorPath]};n.push(o.data)}return{valid:!0,data:n}}return{valid:!1,mergeErrorPath:[]}}function Hn(e,t,n){const r=new Map;let s;for(const c of t.issues)if(c.code==="unrecognized_keys"){s??(s=c);for(const d of c.keys)r.has(d)||r.set(d,{}),r.get(d).l=!0}else e.issues.push(c);for(const c of n.issues)if(c.code==="unrecognized_keys")for(const d of c.keys)r.has(d)||r.set(d,{}),r.get(d).r=!0;else e.issues.push(c);const i=[...r].filter(([,c])=>c.l&&c.r).map(([c])=>c);if(i.length&&s&&e.issues.push({...s,keys:i}),bt(e))return e;const o=_n(t.value,n.value);if(!o.valid)throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(o.mergeErrorPath)}`);return e.value=o.data,e}const di=g("$ZodRecord",(e,t)=>{ee.init(e,t),e._zod.parse=(n,r)=>{const s=n.value;if(!St(s))return n.issues.push({expected:"record",code:"invalid_type",input:s,inst:e}),n;const i=[],o=t.keyType._zod.values;if(o){n.value={};const c=new Set;for(const l of o)if(typeof l=="string"||typeof l=="number"||typeof l=="symbol"){c.add(typeof l=="number"?l.toString():l);const p=t.valueType._zod.run({value:s[l],issues:[]},r);p instanceof Promise?i.push(p.then(v=>{v.issues.length&&n.issues.push(...wt(l,v.issues)),n.value[l]=v.value})):(p.issues.length&&n.issues.push(...wt(l,p.issues)),n.value[l]=p.value)}let d;for(const l in s)c.has(l)||(d=d??[],d.push(l));d&&d.length>0&&n.issues.push({code:"unrecognized_keys",input:s,inst:e,keys:d})}else{n.value={};for(const c of Reflect.ownKeys(s)){if(c==="__proto__")continue;let d=t.keyType._zod.run({value:c,issues:[]},r);if(d instanceof Promise)throw new Error("Async schemas not supported in object keys currently");if(typeof c=="string"&&Ar.test(c)&&d.issues.length){const v=t.keyType._zod.run({value:Number(c),issues:[]},r);if(v instanceof Promise)throw new Error("Async schemas not supported in object keys currently");v.issues.length===0&&(d=v)}if(d.issues.length){t.mode==="loose"?n.value[c]=s[c]:n.issues.push({code:"invalid_key",origin:"record",issues:d.issues.map(v=>Be(v,r,Ve())),input:c,path:[c],inst:e});continue}const p=t.valueType._zod.run({value:s[c],issues:[]},r);p instanceof Promise?i.push(p.then(v=>{v.issues.length&&n.issues.push(...wt(c,v.issues)),n.value[d.value]=v.value})):(p.issues.length&&n.issues.push(...wt(c,p.issues)),n.value[d.value]=p.value)}}return i.length?Promise.all(i).then(()=>n):n}}),ui=g("$ZodEnum",(e,t)=>{ee.init(e,t);const n=$r(t.entries),r=new Set(n);e._zod.values=r,e._zod.pattern=new RegExp(`^(${n.filter(s=>$s.has(typeof s)).map(s=>typeof s=="string"?on(s):s.toString()).join("|")})$`),e._zod.parse=(s,i)=>{const o=s.value;return r.has(o)||s.issues.push({code:"invalid_value",values:n,input:o,inst:e}),s}}),pi=g("$ZodTransform",(e,t)=>{ee.init(e,t),e._zod.parse=(n,r)=>{if(r.direction==="backward")throw new br(e.constructor.name);const s=t.transform(n.value,n);if(r.async)return(s instanceof Promise?s:Promise.resolve(s)).then(o=>(n.value=o,n));if(s instanceof Promise)throw new $t;return n.value=s,n}});function Vn(e,t){return e.issues.length&&t===void 0?{issues:[],value:void 0}:e}const Dr=g("$ZodOptional",(e,t)=>{ee.init(e,t),e._zod.optin="optional",e._zod.optout="optional",G(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),G(e._zod,"pattern",()=>{const n=t.innerType._zod.pattern;return n?new RegExp(`^(${Rn(n.source)})?$`):void 0}),e._zod.parse=(n,r)=>{if(t.innerType._zod.optin==="optional"){const s=t.innerType._zod.run(n,r);return s instanceof Promise?s.then(i=>Vn(i,n.value)):Vn(s,n.value)}return n.value===void 0?n:t.innerType._zod.run(n,r)}}),mi=g("$ZodExactOptional",(e,t)=>{Dr.init(e,t),G(e._zod,"values",()=>t.innerType._zod.values),G(e._zod,"pattern",()=>t.innerType._zod.pattern),e._zod.parse=(n,r)=>t.innerType._zod.run(n,r)}),fi=g("$ZodNullable",(e,t)=>{ee.init(e,t),G(e._zod,"optin",()=>t.innerType._zod.optin),G(e._zod,"optout",()=>t.innerType._zod.optout),G(e._zod,"pattern",()=>{const n=t.innerType._zod.pattern;return n?new RegExp(`^(${Rn(n.source)}|null)$`):void 0}),G(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(n,r)=>n.value===null?n:t.innerType._zod.run(n,r)}),hi=g("$ZodDefault",(e,t)=>{ee.init(e,t),e._zod.optin="optional",G(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(n,r)=>{if(r.direction==="backward")return t.innerType._zod.run(n,r);if(n.value===void 0)return n.value=t.defaultValue,n;const s=t.innerType._zod.run(n,r);return s instanceof Promise?s.then(i=>Bn(i,t)):Bn(s,t)}});function Bn(e,t){return e.value===void 0&&(e.value=t.defaultValue),e}const gi=g("$ZodPrefault",(e,t)=>{ee.init(e,t),e._zod.optin="optional",G(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(n,r)=>(r.direction==="backward"||n.value===void 0&&(n.value=t.defaultValue),t.innerType._zod.run(n,r))}),vi=g("$ZodNonOptional",(e,t)=>{ee.init(e,t),G(e._zod,"values",()=>{const n=t.innerType._zod.values;return n?new Set([...n].filter(r=>r!==void 0)):void 0}),e._zod.parse=(n,r)=>{const s=t.innerType._zod.run(n,r);return s instanceof Promise?s.then(i=>Wn(i,e)):Wn(s,e)}});function Wn(e,t){return!e.issues.length&&e.value===void 0&&e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}const yi=g("$ZodCatch",(e,t)=>{ee.init(e,t),G(e._zod,"optin",()=>t.innerType._zod.optin),G(e._zod,"optout",()=>t.innerType._zod.optout),G(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(n,r)=>{if(r.direction==="backward")return t.innerType._zod.run(n,r);const s=t.innerType._zod.run(n,r);return s instanceof Promise?s.then(i=>(n.value=i.value,i.issues.length&&(n.value=t.catchValue({...n,error:{issues:i.issues.map(o=>Be(o,r,Ve()))},input:n.value}),n.issues=[]),n)):(n.value=s.value,s.issues.length&&(n.value=t.catchValue({...n,error:{issues:s.issues.map(i=>Be(i,r,Ve()))},input:n.value}),n.issues=[]),n)}}),bi=g("$ZodPipe",(e,t)=>{ee.init(e,t),G(e._zod,"values",()=>t.in._zod.values),G(e._zod,"optin",()=>t.in._zod.optin),G(e._zod,"optout",()=>t.out._zod.optout),G(e._zod,"propValues",()=>t.in._zod.propValues),e._zod.parse=(n,r)=>{if(r.direction==="backward"){const i=t.out._zod.run(n,r);return i instanceof Promise?i.then(o=>Bt(o,t.in,r)):Bt(i,t.in,r)}const s=t.in._zod.run(n,r);return s instanceof Promise?s.then(i=>Bt(i,t.out,r)):Bt(s,t.out,r)}});function Bt(e,t,n){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},n)}const wi=g("$ZodReadonly",(e,t)=>{ee.init(e,t),G(e._zod,"propValues",()=>t.innerType._zod.propValues),G(e._zod,"values",()=>t.innerType._zod.values),G(e._zod,"optin",()=>t.innerType?._zod?.optin),G(e._zod,"optout",()=>t.innerType?._zod?.optout),e._zod.parse=(n,r)=>{if(r.direction==="backward")return t.innerType._zod.run(n,r);const s=t.innerType._zod.run(n,r);return s instanceof Promise?s.then(Kn):Kn(s)}});function Kn(e){return e.value=Object.freeze(e.value),e}const $i=g("$ZodCustom",(e,t)=>{ge.init(e,t),ee.init(e,t),e._zod.parse=(n,r)=>n,e._zod.check=n=>{const r=n.value,s=t.fn(r);if(s instanceof Promise)return s.then(i=>Gn(i,n,r,e));Gn(s,n,r,e)}});function Gn(e,t,n,r){if(!e){const s={code:"custom",input:n,inst:r,path:[...r._zod.def.path??[]],continue:!r._zod.def.abort};r._zod.def.params&&(s.params=r._zod.def.params),t.issues.push(At(s))}}var Xn;class Si{constructor(){this._map=new WeakMap,this._idmap=new Map}add(t,...n){const r=n[0];return this._map.set(t,r),r&&typeof r=="object"&&"id"in r&&this._idmap.set(r.id,t),this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(t){const n=this._map.get(t);return n&&typeof n=="object"&&"id"in n&&this._idmap.delete(n.id),this._map.delete(t),this}get(t){const n=t._zod.parent;if(n){const r={...this.get(n)??{}};delete r.id;const s={...r,...this._map.get(t)};return Object.keys(s).length?s:void 0}return this._map.get(t)}has(t){return this._map.has(t)}}function _i(){return new Si}(Xn=globalThis).__zod_globalRegistry??(Xn.__zod_globalRegistry=_i());const Tt=globalThis.__zod_globalRegistry;function ki(e,t){return new e({type:"string",...O(t)})}function xi(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...O(t)})}function Yn(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...O(t)})}function Ii(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...O(t)})}function Ei(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...O(t)})}function Ti(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...O(t)})}function zi(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...O(t)})}function Ai(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...O(t)})}function Ri(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...O(t)})}function Ci(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...O(t)})}function Oi(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...O(t)})}function Pi(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...O(t)})}function Mi(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...O(t)})}function Ni(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...O(t)})}function Li(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...O(t)})}function Di(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...O(t)})}function ji(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...O(t)})}function Zi(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...O(t)})}function qi(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...O(t)})}function Ui(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...O(t)})}function Fi(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...O(t)})}function Ji(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...O(t)})}function Hi(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...O(t)})}function Vi(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...O(t)})}function Bi(e,t){return new e({type:"string",format:"date",check:"string_format",...O(t)})}function Wi(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...O(t)})}function Ki(e,t){return new e({type:"string",format:"duration",check:"string_format",...O(t)})}function Gi(e,t){return new e({type:"number",checks:[],...O(t)})}function Xi(e,t){return new e({type:"number",check:"number_format",abort:!1,format:"safeint",...O(t)})}function Yi(e,t){return new e({type:"boolean",...O(t)})}function Qi(e){return new e({type:"any"})}function ea(e){return new e({type:"unknown"})}function ta(e,t){return new e({type:"never",...O(t)})}function Qn(e,t){return new Cr({check:"less_than",...O(t),value:e,inclusive:!1})}function vn(e,t){return new Cr({check:"less_than",...O(t),value:e,inclusive:!0})}function er(e,t){return new Or({check:"greater_than",...O(t),value:e,inclusive:!1})}function yn(e,t){return new Or({check:"greater_than",...O(t),value:e,inclusive:!0})}function tr(e,t){return new ho({check:"multiple_of",...O(t),value:e})}function jr(e,t){return new vo({check:"max_length",...O(t),maximum:e})}function tn(e,t){return new yo({check:"min_length",...O(t),minimum:e})}function Zr(e,t){return new bo({check:"length_equals",...O(t),length:e})}function na(e,t){return new wo({check:"string_format",format:"regex",...O(t),pattern:e})}function ra(e){return new $o({check:"string_format",format:"lowercase",...O(e)})}function sa(e){return new So({check:"string_format",format:"uppercase",...O(e)})}function oa(e,t){return new _o({check:"string_format",format:"includes",...O(t),includes:e})}function ia(e,t){return new ko({check:"string_format",format:"starts_with",...O(t),prefix:e})}function aa(e,t){return new xo({check:"string_format",format:"ends_with",...O(t),suffix:e})}function _t(e){return new Io({check:"overwrite",tx:e})}function ca(e){return _t(t=>t.normalize(e))}function la(){return _t(e=>e.trim())}function da(){return _t(e=>e.toLowerCase())}function ua(){return _t(e=>e.toUpperCase())}function pa(){return _t(e=>bs(e))}function ma(e,t,n){return new e({type:"array",element:t,...O(n)})}function fa(e,t,n){return new e({type:"custom",check:"custom",fn:t,...O(n)})}function ha(e){const t=ga(n=>(n.addIssue=r=>{if(typeof r=="string")n.issues.push(At(r,n.value,t._zod.def));else{const s=r;s.fatal&&(s.continue=!1),s.code??(s.code="custom"),s.input??(s.input=n.value),s.inst??(s.inst=t),s.continue??(s.continue=!t._zod.def.abort),n.issues.push(At(s))}},e(n.value,n)));return t}function ga(e,t){const n=new ge({check:"custom",...O(t)});return n._zod.check=e,n}function qr(e){let t=e?.target??"draft-2020-12";return t==="draft-4"&&(t="draft-04"),t==="draft-7"&&(t="draft-07"),{processors:e.processors??{},metadataRegistry:e?.metadata??Tt,target:t,unrepresentable:e?.unrepresentable??"throw",override:e?.override??(()=>{}),io:e?.io??"output",counter:0,seen:new Map,cycles:e?.cycles??"ref",reused:e?.reused??"inline",external:e?.external??void 0}}function ie(e,t,n={path:[],schemaPath:[]}){var r;const s=e._zod.def,i=t.seen.get(e);if(i)return i.count++,n.schemaPath.includes(e)&&(i.cycle=n.path),i.schema;const o={schema:{},count:1,cycle:void 0,path:n.path};t.seen.set(e,o);const c=e._zod.toJSONSchema?.();if(c)o.schema=c;else{const p={...n,schemaPath:[...n.schemaPath,e],path:n.path};if(e._zod.processJSONSchema)e._zod.processJSONSchema(t,o.schema,p);else{const $=o.schema,w=t.processors[s.type];if(!w)throw new Error(`[toJSONSchema]: Non-representable type encountered: ${s.type}`);w(e,t,$,p)}const v=e._zod.parent;v&&(o.ref||(o.ref=v),ie(v,t,p),t.seen.get(v).isParent=!0)}const d=t.metadataRegistry.get(e);return d&&Object.assign(o.schema,d),t.io==="input"&&ue(e)&&(delete o.schema.examples,delete o.schema.default),t.io==="input"&&o.schema._prefault&&((r=o.schema).default??(r.default=o.schema._prefault)),delete o.schema._prefault,t.seen.get(e).schema}function Ur(e,t){const n=e.seen.get(t);if(!n)throw new Error("Unprocessed schema. This is a bug in Zod.");const r=new Map;for(const o of e.seen.entries()){const c=e.metadataRegistry.get(o[0])?.id;if(c){const d=r.get(c);if(d&&d!==o[0])throw new Error(`Duplicate schema id "${c}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);r.set(c,o[0])}}const s=o=>{const c=e.target==="draft-2020-12"?"$defs":"definitions";if(e.external){const v=e.external.registry.get(o[0])?.id,$=e.external.uri??(f=>f);if(v)return{ref:$(v)};const w=o[1].defId??o[1].schema.id??`schema${e.counter++}`;return o[1].defId=w,{defId:w,ref:`${$("__shared")}#/${c}/${w}`}}if(o[1]===n)return{ref:"#"};const l=`#/${c}/`,p=o[1].schema.id??`__schema${e.counter++}`;return{defId:p,ref:l+p}},i=o=>{if(o[1].schema.$ref)return;const c=o[1],{ref:d,defId:l}=s(o);c.def={...c.schema},l&&(c.defId=l);const p=c.schema;for(const v in p)delete p[v];p.$ref=d};if(e.cycles==="throw")for(const o of e.seen.entries()){const c=o[1];if(c.cycle)throw new Error(`Cycle detected: #/${c.cycle?.join("/")}/<root>
38
+
39
+ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`)}for(const o of e.seen.entries()){const c=o[1];if(t===o[0]){i(o);continue}if(e.external){const l=e.external.registry.get(o[0])?.id;if(t!==o[0]&&l){i(o);continue}}if(e.metadataRegistry.get(o[0])?.id){i(o);continue}if(c.cycle){i(o);continue}if(c.count>1&&e.reused==="ref"){i(o);continue}}}function Fr(e,t){const n=e.seen.get(t);if(!n)throw new Error("Unprocessed schema. This is a bug in Zod.");const r=o=>{const c=e.seen.get(o);if(c.ref===null)return;const d=c.def??c.schema,l={...d},p=c.ref;if(c.ref=null,p){r(p);const $=e.seen.get(p),w=$.schema;if(w.$ref&&(e.target==="draft-07"||e.target==="draft-04"||e.target==="openapi-3.0")?(d.allOf=d.allOf??[],d.allOf.push(w)):Object.assign(d,w),Object.assign(d,l),o._zod.parent===p)for(const h in d)h==="$ref"||h==="allOf"||h in l||delete d[h];if(w.$ref&&$.def)for(const h in d)h==="$ref"||h==="allOf"||h in $.def&&JSON.stringify(d[h])===JSON.stringify($.def[h])&&delete d[h]}const v=o._zod.parent;if(v&&v!==p){r(v);const $=e.seen.get(v);if($?.schema.$ref&&(d.$ref=$.schema.$ref,$.def))for(const w in d)w==="$ref"||w==="allOf"||w in $.def&&JSON.stringify(d[w])===JSON.stringify($.def[w])&&delete d[w]}e.override({zodSchema:o,jsonSchema:d,path:c.path??[]})};for(const o of[...e.seen.entries()].reverse())r(o[0]);const s={};if(e.target==="draft-2020-12"?s.$schema="https://json-schema.org/draft/2020-12/schema":e.target==="draft-07"?s.$schema="http://json-schema.org/draft-07/schema#":e.target==="draft-04"?s.$schema="http://json-schema.org/draft-04/schema#":e.target,e.external?.uri){const o=e.external.registry.get(t)?.id;if(!o)throw new Error("Schema is missing an `id` property");s.$id=e.external.uri(o)}Object.assign(s,n.def??n.schema);const i=e.external?.defs??{};for(const o of e.seen.entries()){const c=o[1];c.def&&c.defId&&(i[c.defId]=c.def)}e.external||Object.keys(i).length>0&&(e.target==="draft-2020-12"?s.$defs=i:s.definitions=i);try{const o=JSON.parse(JSON.stringify(s));return Object.defineProperty(o,"~standard",{value:{...t["~standard"],jsonSchema:{input:nn(t,"input",e.processors),output:nn(t,"output",e.processors)}},enumerable:!1,writable:!1}),o}catch{throw new Error("Error converting schema to JSON.")}}function ue(e,t){const n=t??{seen:new Set};if(n.seen.has(e))return!1;n.seen.add(e);const r=e._zod.def;if(r.type==="transform")return!0;if(r.type==="array")return ue(r.element,n);if(r.type==="set")return ue(r.valueType,n);if(r.type==="lazy")return ue(r.getter(),n);if(r.type==="promise"||r.type==="optional"||r.type==="nonoptional"||r.type==="nullable"||r.type==="readonly"||r.type==="default"||r.type==="prefault")return ue(r.innerType,n);if(r.type==="intersection")return ue(r.left,n)||ue(r.right,n);if(r.type==="record"||r.type==="map")return ue(r.keyType,n)||ue(r.valueType,n);if(r.type==="pipe")return ue(r.in,n)||ue(r.out,n);if(r.type==="object"){for(const s in r.shape)if(ue(r.shape[s],n))return!0;return!1}if(r.type==="union"){for(const s of r.options)if(ue(s,n))return!0;return!1}if(r.type==="tuple"){for(const s of r.items)if(ue(s,n))return!0;return!!(r.rest&&ue(r.rest,n))}return!1}const va=(e,t={})=>n=>{const r=qr({...n,processors:t});return ie(e,r),Ur(r,e),Fr(r,e)},nn=(e,t,n={})=>r=>{const{libraryOptions:s,target:i}=r??{},o=qr({...s??{},target:i,io:t,processors:n});return ie(e,o),Ur(o,e),Fr(o,e)},ya={guid:"uuid",url:"uri",datetime:"date-time",json_string:"json-string",regex:""},ba=(e,t,n,r)=>{const s=n;s.type="string";const{minimum:i,maximum:o,format:c,patterns:d,contentEncoding:l}=e._zod.bag;if(typeof i=="number"&&(s.minLength=i),typeof o=="number"&&(s.maxLength=o),c&&(s.format=ya[c]??c,s.format===""&&delete s.format,c==="time"&&delete s.format),l&&(s.contentEncoding=l),d&&d.size>0){const p=[...d];p.length===1?s.pattern=p[0].source:p.length>1&&(s.allOf=[...p.map(v=>({...t.target==="draft-07"||t.target==="draft-04"||t.target==="openapi-3.0"?{type:"string"}:{},pattern:v.source}))])}},wa=(e,t,n,r)=>{const s=n,{minimum:i,maximum:o,format:c,multipleOf:d,exclusiveMaximum:l,exclusiveMinimum:p}=e._zod.bag;typeof c=="string"&&c.includes("int")?s.type="integer":s.type="number",typeof p=="number"&&(t.target==="draft-04"||t.target==="openapi-3.0"?(s.minimum=p,s.exclusiveMinimum=!0):s.exclusiveMinimum=p),typeof i=="number"&&(s.minimum=i,typeof p=="number"&&t.target!=="draft-04"&&(p>=i?delete s.minimum:delete s.exclusiveMinimum)),typeof l=="number"&&(t.target==="draft-04"||t.target==="openapi-3.0"?(s.maximum=l,s.exclusiveMaximum=!0):s.exclusiveMaximum=l),typeof o=="number"&&(s.maximum=o,typeof l=="number"&&t.target!=="draft-04"&&(l<=o?delete s.maximum:delete s.exclusiveMaximum)),typeof d=="number"&&(s.multipleOf=d)},$a=(e,t,n,r)=>{n.type="boolean"},Sa=(e,t,n,r)=>{n.not={}},_a=(e,t,n,r)=>{},ka=(e,t,n,r)=>{},xa=(e,t,n,r)=>{const s=e._zod.def,i=$r(s.entries);i.every(o=>typeof o=="number")&&(n.type="number"),i.every(o=>typeof o=="string")&&(n.type="string"),n.enum=i},Ia=(e,t,n,r)=>{if(t.unrepresentable==="throw")throw new Error("Custom types cannot be represented in JSON Schema")},Ea=(e,t,n,r)=>{if(t.unrepresentable==="throw")throw new Error("Transforms cannot be represented in JSON Schema")},Ta=(e,t,n,r)=>{const s=n,i=e._zod.def,{minimum:o,maximum:c}=e._zod.bag;typeof o=="number"&&(s.minItems=o),typeof c=="number"&&(s.maxItems=c),s.type="array",s.items=ie(i.element,t,{...r,path:[...r.path,"items"]})},za=(e,t,n,r)=>{const s=n,i=e._zod.def;s.type="object",s.properties={};const o=i.shape;for(const l in o)s.properties[l]=ie(o[l],t,{...r,path:[...r.path,"properties",l]});const c=new Set(Object.keys(o)),d=new Set([...c].filter(l=>{const p=i.shape[l]._zod;return t.io==="input"?p.optin===void 0:p.optout===void 0}));d.size>0&&(s.required=Array.from(d)),i.catchall?._zod.def.type==="never"?s.additionalProperties=!1:i.catchall?i.catchall&&(s.additionalProperties=ie(i.catchall,t,{...r,path:[...r.path,"additionalProperties"]})):t.io==="output"&&(s.additionalProperties=!1)},Aa=(e,t,n,r)=>{const s=e._zod.def,i=s.inclusive===!1,o=s.options.map((c,d)=>ie(c,t,{...r,path:[...r.path,i?"oneOf":"anyOf",d]}));i?n.oneOf=o:n.anyOf=o},Ra=(e,t,n,r)=>{const s=e._zod.def,i=ie(s.left,t,{...r,path:[...r.path,"allOf",0]}),o=ie(s.right,t,{...r,path:[...r.path,"allOf",1]}),c=l=>"allOf"in l&&Object.keys(l).length===1,d=[...c(i)?i.allOf:[i],...c(o)?o.allOf:[o]];n.allOf=d},Ca=(e,t,n,r)=>{const s=n,i=e._zod.def;s.type="object";const o=i.keyType,d=o._zod.bag?.patterns;if(i.mode==="loose"&&d&&d.size>0){const p=ie(i.valueType,t,{...r,path:[...r.path,"patternProperties","*"]});s.patternProperties={};for(const v of d)s.patternProperties[v.source]=p}else(t.target==="draft-07"||t.target==="draft-2020-12")&&(s.propertyNames=ie(i.keyType,t,{...r,path:[...r.path,"propertyNames"]})),s.additionalProperties=ie(i.valueType,t,{...r,path:[...r.path,"additionalProperties"]});const l=o._zod.values;if(l){const p=[...l].filter(v=>typeof v=="string"||typeof v=="number");p.length>0&&(s.required=p)}},Oa=(e,t,n,r)=>{const s=e._zod.def,i=ie(s.innerType,t,r),o=t.seen.get(e);t.target==="openapi-3.0"?(o.ref=s.innerType,n.nullable=!0):n.anyOf=[i,{type:"null"}]},Pa=(e,t,n,r)=>{const s=e._zod.def;ie(s.innerType,t,r);const i=t.seen.get(e);i.ref=s.innerType},Ma=(e,t,n,r)=>{const s=e._zod.def;ie(s.innerType,t,r);const i=t.seen.get(e);i.ref=s.innerType,n.default=JSON.parse(JSON.stringify(s.defaultValue))},Na=(e,t,n,r)=>{const s=e._zod.def;ie(s.innerType,t,r);const i=t.seen.get(e);i.ref=s.innerType,t.io==="input"&&(n._prefault=JSON.parse(JSON.stringify(s.defaultValue)))},La=(e,t,n,r)=>{const s=e._zod.def;ie(s.innerType,t,r);const i=t.seen.get(e);i.ref=s.innerType;let o;try{o=s.catchValue(void 0)}catch{throw new Error("Dynamic catch values are not supported in JSON Schema")}n.default=o},Da=(e,t,n,r)=>{const s=e._zod.def,i=t.io==="input"?s.in._zod.def.type==="transform"?s.out:s.in:s.out;ie(i,t,r);const o=t.seen.get(e);o.ref=i},ja=(e,t,n,r)=>{const s=e._zod.def;ie(s.innerType,t,r);const i=t.seen.get(e);i.ref=s.innerType,n.readOnly=!0},Jr=(e,t,n,r)=>{const s=e._zod.def;ie(s.innerType,t,r);const i=t.seen.get(e);i.ref=s.innerType},Za=g("ZodISODateTime",(e,t)=>{Zo.init(e,t),ne.init(e,t)});function qa(e){return Vi(Za,e)}const Ua=g("ZodISODate",(e,t)=>{qo.init(e,t),ne.init(e,t)});function Fa(e){return Bi(Ua,e)}const Ja=g("ZodISOTime",(e,t)=>{Uo.init(e,t),ne.init(e,t)});function Ha(e){return Wi(Ja,e)}const Va=g("ZodISODuration",(e,t)=>{Fo.init(e,t),ne.init(e,t)});function Ba(e){return Ki(Va,e)}const Wa=(e,t)=>{xr.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:n=>Cs(e,n)},flatten:{value:n=>Rs(e,n)},addIssue:{value:n=>{e.issues.push(n),e.message=JSON.stringify(e.issues,Sn,2)}},addIssues:{value:n=>{e.issues.push(...n),e.message=JSON.stringify(e.issues,Sn,2)}},isEmpty:{get(){return e.issues.length===0}}})},$e=g("ZodError",Wa,{Parent:Error}),Ka=On($e),Ga=Pn($e),Xa=an($e),Ya=cn($e),Qa=Ms($e),ec=Ns($e),tc=Ls($e),nc=Ds($e),rc=js($e),sc=Zs($e),oc=qs($e),ic=Us($e),te=g("ZodType",(e,t)=>(ee.init(e,t),Object.assign(e["~standard"],{jsonSchema:{input:nn(e,"input"),output:nn(e,"output")}}),e.toJSONSchema=va(e,{}),e.def=t,e.type=t.type,Object.defineProperty(e,"_def",{value:t}),e.check=(...n)=>e.clone(Ke(t,{checks:[...t.checks??[],...n.map(r=>typeof r=="function"?{_zod:{check:r,def:{check:"custom"},onattach:[]}}:r)]}),{parent:!0}),e.with=e.check,e.clone=(n,r)=>Ge(e,n,r),e.brand=()=>e,e.register=((n,r)=>(n.add(e,r),e)),e.parse=(n,r)=>Ka(e,n,r,{callee:e.parse}),e.safeParse=(n,r)=>Xa(e,n,r),e.parseAsync=async(n,r)=>Ga(e,n,r,{callee:e.parseAsync}),e.safeParseAsync=async(n,r)=>Ya(e,n,r),e.spa=e.safeParseAsync,e.encode=(n,r)=>Qa(e,n,r),e.decode=(n,r)=>ec(e,n,r),e.encodeAsync=async(n,r)=>tc(e,n,r),e.decodeAsync=async(n,r)=>nc(e,n,r),e.safeEncode=(n,r)=>rc(e,n,r),e.safeDecode=(n,r)=>sc(e,n,r),e.safeEncodeAsync=async(n,r)=>oc(e,n,r),e.safeDecodeAsync=async(n,r)=>ic(e,n,r),e.refine=(n,r)=>e.check(tl(n,r)),e.superRefine=n=>e.check(nl(n)),e.overwrite=n=>e.check(_t(n)),e.optional=()=>or(e),e.exactOptional=()=>Uc(e),e.nullable=()=>ir(e),e.nullish=()=>or(ir(e)),e.nonoptional=n=>Wc(e,n),e.array=()=>ct(e),e.or=n=>Pc([e,n]),e.and=n=>Nc(e,n),e.transform=n=>ar(e,Zc(n)),e.default=n=>Hc(e,n),e.prefault=n=>Bc(e,n),e.catch=n=>Gc(e,n),e.pipe=n=>ar(e,n),e.readonly=()=>Qc(e),e.describe=n=>{const r=e.clone();return Tt.add(r,{description:n}),r},Object.defineProperty(e,"description",{get(){return Tt.get(e)?.description},configurable:!0}),e.meta=(...n)=>{if(n.length===0)return Tt.get(e);const r=e.clone();return Tt.add(r,n[0]),r},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e.apply=n=>n(e),e)),Hr=g("_ZodString",(e,t)=>{Mn.init(e,t),te.init(e,t),e._zod.processJSONSchema=(r,s,i)=>ba(e,r,s);const n=e._zod.bag;e.format=n.format??null,e.minLength=n.minimum??null,e.maxLength=n.maximum??null,e.regex=(...r)=>e.check(na(...r)),e.includes=(...r)=>e.check(oa(...r)),e.startsWith=(...r)=>e.check(ia(...r)),e.endsWith=(...r)=>e.check(aa(...r)),e.min=(...r)=>e.check(tn(...r)),e.max=(...r)=>e.check(jr(...r)),e.length=(...r)=>e.check(Zr(...r)),e.nonempty=(...r)=>e.check(tn(1,...r)),e.lowercase=r=>e.check(ra(r)),e.uppercase=r=>e.check(sa(r)),e.trim=()=>e.check(la()),e.normalize=(...r)=>e.check(ca(...r)),e.toLowerCase=()=>e.check(da()),e.toUpperCase=()=>e.check(ua()),e.slugify=()=>e.check(pa())}),ac=g("ZodString",(e,t)=>{Mn.init(e,t),Hr.init(e,t),e.email=n=>e.check(xi(cc,n)),e.url=n=>e.check(Ai(lc,n)),e.jwt=n=>e.check(Hi(kc,n)),e.emoji=n=>e.check(Ri(dc,n)),e.guid=n=>e.check(Yn(nr,n)),e.uuid=n=>e.check(Ii(Wt,n)),e.uuidv4=n=>e.check(Ei(Wt,n)),e.uuidv6=n=>e.check(Ti(Wt,n)),e.uuidv7=n=>e.check(zi(Wt,n)),e.nanoid=n=>e.check(Ci(uc,n)),e.guid=n=>e.check(Yn(nr,n)),e.cuid=n=>e.check(Oi(pc,n)),e.cuid2=n=>e.check(Pi(mc,n)),e.ulid=n=>e.check(Mi(fc,n)),e.base64=n=>e.check(Ui($c,n)),e.base64url=n=>e.check(Fi(Sc,n)),e.xid=n=>e.check(Ni(hc,n)),e.ksuid=n=>e.check(Li(gc,n)),e.ipv4=n=>e.check(Di(vc,n)),e.ipv6=n=>e.check(ji(yc,n)),e.cidrv4=n=>e.check(Zi(bc,n)),e.cidrv6=n=>e.check(qi(wc,n)),e.e164=n=>e.check(Ji(_c,n)),e.datetime=n=>e.check(qa(n)),e.date=n=>e.check(Fa(n)),e.time=n=>e.check(Ha(n)),e.duration=n=>e.check(Ba(n))});function E(e){return ki(ac,e)}const ne=g("ZodStringFormat",(e,t)=>{Q.init(e,t),Hr.init(e,t)}),cc=g("ZodEmail",(e,t)=>{Ro.init(e,t),ne.init(e,t)}),nr=g("ZodGUID",(e,t)=>{zo.init(e,t),ne.init(e,t)}),Wt=g("ZodUUID",(e,t)=>{Ao.init(e,t),ne.init(e,t)}),lc=g("ZodURL",(e,t)=>{Co.init(e,t),ne.init(e,t)}),dc=g("ZodEmoji",(e,t)=>{Oo.init(e,t),ne.init(e,t)}),uc=g("ZodNanoID",(e,t)=>{Po.init(e,t),ne.init(e,t)}),pc=g("ZodCUID",(e,t)=>{Mo.init(e,t),ne.init(e,t)}),mc=g("ZodCUID2",(e,t)=>{No.init(e,t),ne.init(e,t)}),fc=g("ZodULID",(e,t)=>{Lo.init(e,t),ne.init(e,t)}),hc=g("ZodXID",(e,t)=>{Do.init(e,t),ne.init(e,t)}),gc=g("ZodKSUID",(e,t)=>{jo.init(e,t),ne.init(e,t)}),vc=g("ZodIPv4",(e,t)=>{Jo.init(e,t),ne.init(e,t)}),yc=g("ZodIPv6",(e,t)=>{Ho.init(e,t),ne.init(e,t)}),bc=g("ZodCIDRv4",(e,t)=>{Vo.init(e,t),ne.init(e,t)}),wc=g("ZodCIDRv6",(e,t)=>{Bo.init(e,t),ne.init(e,t)}),$c=g("ZodBase64",(e,t)=>{Wo.init(e,t),ne.init(e,t)}),Sc=g("ZodBase64URL",(e,t)=>{Go.init(e,t),ne.init(e,t)}),_c=g("ZodE164",(e,t)=>{Xo.init(e,t),ne.init(e,t)}),kc=g("ZodJWT",(e,t)=>{Qo.init(e,t),ne.init(e,t)}),Vr=g("ZodNumber",(e,t)=>{Mr.init(e,t),te.init(e,t),e._zod.processJSONSchema=(r,s,i)=>wa(e,r,s),e.gt=(r,s)=>e.check(er(r,s)),e.gte=(r,s)=>e.check(yn(r,s)),e.min=(r,s)=>e.check(yn(r,s)),e.lt=(r,s)=>e.check(Qn(r,s)),e.lte=(r,s)=>e.check(vn(r,s)),e.max=(r,s)=>e.check(vn(r,s)),e.int=r=>e.check(rr(r)),e.safe=r=>e.check(rr(r)),e.positive=r=>e.check(er(0,r)),e.nonnegative=r=>e.check(yn(0,r)),e.negative=r=>e.check(Qn(0,r)),e.nonpositive=r=>e.check(vn(0,r)),e.multipleOf=(r,s)=>e.check(tr(r,s)),e.step=(r,s)=>e.check(tr(r,s)),e.finite=()=>e;const n=e._zod.bag;e.minValue=Math.max(n.minimum??Number.NEGATIVE_INFINITY,n.exclusiveMinimum??Number.NEGATIVE_INFINITY)??null,e.maxValue=Math.min(n.maximum??Number.POSITIVE_INFINITY,n.exclusiveMaximum??Number.POSITIVE_INFINITY)??null,e.isInt=(n.format??"").includes("int")||Number.isSafeInteger(n.multipleOf??.5),e.isFinite=!0,e.format=n.format??null});function we(e){return Gi(Vr,e)}const xc=g("ZodNumberFormat",(e,t)=>{ei.init(e,t),Vr.init(e,t)});function rr(e){return Xi(xc,e)}const Ic=g("ZodBoolean",(e,t)=>{ti.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>$a(e,n,r)});function dn(e){return Yi(Ic,e)}const Ec=g("ZodAny",(e,t)=>{ni.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>_a()});function un(){return Qi(Ec)}const Tc=g("ZodUnknown",(e,t)=>{ri.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>ka()});function sr(){return ea(Tc)}const zc=g("ZodNever",(e,t)=>{si.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Sa(e,n,r)});function Ac(e){return ta(zc,e)}const Rc=g("ZodArray",(e,t)=>{oi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Ta(e,n,r,s),e.element=t.element,e.min=(n,r)=>e.check(tn(n,r)),e.nonempty=n=>e.check(tn(1,n)),e.max=(n,r)=>e.check(jr(n,r)),e.length=(n,r)=>e.check(Zr(n,r)),e.unwrap=()=>e.element});function ct(e,t){return ma(Rc,e,t)}const Cc=g("ZodObject",(e,t)=>{ai.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>za(e,n,r,s),G(e,"shape",()=>t.shape),e.keyof=()=>Dc(Object.keys(e._zod.def.shape)),e.catchall=n=>e.clone({...e._zod.def,catchall:n}),e.passthrough=()=>e.clone({...e._zod.def,catchall:sr()}),e.loose=()=>e.clone({...e._zod.def,catchall:sr()}),e.strict=()=>e.clone({...e._zod.def,catchall:Ac()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=n=>Is(e,n),e.safeExtend=n=>Es(e,n),e.merge=n=>Ts(e,n),e.pick=n=>ks(e,n),e.omit=n=>xs(e,n),e.partial=(...n)=>zs(Wr,e,n[0]),e.required=(...n)=>As(Kr,e,n[0])});function de(e,t){const n={type:"object",shape:e??{},...O(t)};return new Cc(n)}const Oc=g("ZodUnion",(e,t)=>{ci.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Aa(e,n,r,s),e.options=t.options});function Pc(e,t){return new Oc({type:"union",options:e,...O(t)})}const Mc=g("ZodIntersection",(e,t)=>{li.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Ra(e,n,r,s)});function Nc(e,t){return new Mc({type:"intersection",left:e,right:t})}const Lc=g("ZodRecord",(e,t)=>{di.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Ca(e,n,r,s),e.keyType=t.keyType,e.valueType=t.valueType});function Br(e,t,n){return new Lc({type:"record",keyType:e,valueType:t,...O(n)})}const kn=g("ZodEnum",(e,t)=>{ui.init(e,t),te.init(e,t),e._zod.processJSONSchema=(r,s,i)=>xa(e,r,s),e.enum=t.entries,e.options=Object.values(t.entries);const n=new Set(Object.keys(t.entries));e.extract=(r,s)=>{const i={};for(const o of r)if(n.has(o))i[o]=t.entries[o];else throw new Error(`Key ${o} not found in enum`);return new kn({...t,checks:[],...O(s),entries:i})},e.exclude=(r,s)=>{const i={...t.entries};for(const o of r)if(n.has(o))delete i[o];else throw new Error(`Key ${o} not found in enum`);return new kn({...t,checks:[],...O(s),entries:i})}});function Dc(e,t){const n=Array.isArray(e)?Object.fromEntries(e.map(r=>[r,r])):e;return new kn({type:"enum",entries:n,...O(t)})}const jc=g("ZodTransform",(e,t)=>{pi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Ea(e,n),e._zod.parse=(n,r)=>{if(r.direction==="backward")throw new br(e.constructor.name);n.addIssue=i=>{if(typeof i=="string")n.issues.push(At(i,n.value,t));else{const o=i;o.fatal&&(o.continue=!1),o.code??(o.code="custom"),o.input??(o.input=n.value),o.inst??(o.inst=e),n.issues.push(At(o))}};const s=t.transform(n.value,n);return s instanceof Promise?s.then(i=>(n.value=i,n)):(n.value=s,n)}});function Zc(e){return new jc({type:"transform",transform:e})}const Wr=g("ZodOptional",(e,t)=>{Dr.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Jr(e,n,r,s),e.unwrap=()=>e._zod.def.innerType});function or(e){return new Wr({type:"optional",innerType:e})}const qc=g("ZodExactOptional",(e,t)=>{mi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Jr(e,n,r,s),e.unwrap=()=>e._zod.def.innerType});function Uc(e){return new qc({type:"optional",innerType:e})}const Fc=g("ZodNullable",(e,t)=>{fi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Oa(e,n,r,s),e.unwrap=()=>e._zod.def.innerType});function ir(e){return new Fc({type:"nullable",innerType:e})}const Jc=g("ZodDefault",(e,t)=>{hi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Ma(e,n,r,s),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});function Hc(e,t){return new Jc({type:"default",innerType:e,get defaultValue(){return typeof t=="function"?t():_r(t)}})}const Vc=g("ZodPrefault",(e,t)=>{gi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Na(e,n,r,s),e.unwrap=()=>e._zod.def.innerType});function Bc(e,t){return new Vc({type:"prefault",innerType:e,get defaultValue(){return typeof t=="function"?t():_r(t)}})}const Kr=g("ZodNonOptional",(e,t)=>{vi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Pa(e,n,r,s),e.unwrap=()=>e._zod.def.innerType});function Wc(e,t){return new Kr({type:"nonoptional",innerType:e,...O(t)})}const Kc=g("ZodCatch",(e,t)=>{yi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>La(e,n,r,s),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});function Gc(e,t){return new Kc({type:"catch",innerType:e,catchValue:typeof t=="function"?t:()=>t})}const Xc=g("ZodPipe",(e,t)=>{bi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Da(e,n,r,s),e.in=t.in,e.out=t.out});function ar(e,t){return new Xc({type:"pipe",in:e,out:t})}const Yc=g("ZodReadonly",(e,t)=>{wi.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>ja(e,n,r,s),e.unwrap=()=>e._zod.def.innerType});function Qc(e){return new Yc({type:"readonly",innerType:e})}const el=g("ZodCustom",(e,t)=>{$i.init(e,t),te.init(e,t),e._zod.processJSONSchema=(n,r,s)=>Ia(e,n)});function tl(e,t={}){return fa(el,e,t)}function nl(e){return ha(e)}var rl=class extends Error{constructor(e,t,n,r){super(`Tandem API Validation Error [${t}] at ${e}: ${n.length} issues found.`),this.endpoint=e,this.status=t,this.issues=n,this.rawSnippet=r,this.name="TandemValidationError"}},cr=E().or(de({id:E().optional(),runID:E().optional(),runId:E().optional(),run_id:E().optional(),sessionID:E().optional(),sessionId:E().optional(),session_id:E().optional(),missionID:E().optional(),missionId:E().optional(),mission_id:E().optional(),instanceID:E().optional(),instanceId:E().optional(),instance_id:E().optional()})).transform(e=>typeof e=="string"?e:e.id||e.runID||e.runId||e.run_id||e.sessionID||e.sessionId||e.session_id||e.missionID||e.missionId||e.mission_id||e.instanceID||e.instanceId||e.instance_id);un().transform(e=>e);Br(E(),un()).transform(e=>e);var sl=de({ready:dn().optional(),phase:E().optional()}).passthrough(),Gt=de({id:E(),title:E(),created_at_ms:we().optional(),createdAtMs:we().optional(),directory:E().optional(),workspace_root:E().optional(),workspaceRoot:E().optional(),archived:dn().optional()}).passthrough().transform(e=>({...e,createdAtMs:e.created_at_ms??e.createdAtMs??0,workspaceRoot:e.workspace_root??e.workspaceRoot})),lr=de({sessions:ct(Gt).optional().default([]),count:we().optional().default(0)}).passthrough(),ol=de({active:de({runID:E().optional(),runId:E().optional(),run_id:E().optional(),attachEventStream:E().optional()}).passthrough().nullable().optional()}).passthrough().transform(e=>e.active?{active:{...e.active,runId:e.active.runId||e.active.runID||e.active.run_id}}:{active:null}),Gr=de({ok:dn().optional(),runID:E().optional(),runId:E().optional(),run_id:E().optional(),status:E().optional()}).passthrough().transform(e=>({...e,runId:e.runId||e.runID||e.run_id})),Xr=de({id:E().optional(),runID:E().optional(),runId:E().optional(),run_id:E().optional(),routine_id:E().optional(),automation_id:E().optional(),status:E().optional(),started_at_ms:we().optional(),finished_at_ms:we().optional()}).passthrough().transform(e=>({...e,runId:e.runId||e.runID||e.run_id,routineId:e.routine_id,automationId:e.automation_id,startedAtMs:e.started_at_ms,finishedAtMs:e.finished_at_ms}));de({ok:dn().default(!0),rev:we().optional()}).passthrough();var il=de({key:E(),value:un(),rev:we().optional(),updated_at_ms:we().optional(),updated_by:E().optional()}).passthrough().transform(e=>({...e,updatedAtMs:e.updated_at_ms,updatedBy:e.updated_by})),al=de({items:ct(il).optional().default([]),count:we().optional().default(0)}).passthrough(),cl=de({id:E().optional(),text:E().optional(),content:E().optional(),user_id:E().optional(),userID:E().optional(),source_type:E().optional(),sourceType:E().optional(),tags:ct(E()).optional(),source:E().optional(),session_id:E().optional(),sessionID:E().optional(),run_id:E().optional(),runID:E().optional()}).passthrough().transform(e=>({...e,text:e.text||e.content,content:e.content||e.text,userId:e.userID||e.user_id,sourceType:e.sourceType||e.source_type,sessionId:e.session_id||e.sessionID,runId:e.run_id||e.runID})),ll=de({items:ct(cl).optional().default([]),count:we().optional().default(0)}).passthrough(),dl=de({id:E(),text:E().optional(),content:E().optional(),score:we().optional(),source_type:E().optional(),sourceType:E().optional(),run_id:E().optional(),runID:E().optional(),tags:ct(E()).optional()}).passthrough().transform(e=>({...e,text:e.text||e.content,content:e.content||e.text,sourceType:e.sourceType||e.source_type,runId:e.runID||e.run_id})),ul=de({results:ct(dl).optional().default([]),count:we().optional().default(0)}).passthrough(),pl=de({type:E(),properties:Br(E(),un()).optional().default({}),sessionID:E().optional(),session_id:E().optional(),sessionId:E().optional(),runID:E().optional(),run_id:E().optional(),runId:E().optional(),timestamp:E().optional()}).passthrough().transform(e=>({...e,properties:e.properties,sessionId:e.sessionId||e.sessionID||e.session_id,runId:e.runId||e.runID||e.run_id}));function he(e,t,n,r){const s=e.safeParse(t);if(!s.success){const i=JSON.stringify(t).substring(0,200);throw new rl(n,r,s.error.issues,i)}return s.data}function ml(e){const t=e.trim();if(!t||t===": keep-alive"||t.startsWith(":"))return null;try{const n=JSON.parse(t),r=pl.safeParse(n);return r.success?r.data:null}catch{return null}}async function*dr(e,t,n){const r=n?.connectTimeoutMs??3e4,s=new AbortController,i=setTimeout(()=>s.abort(),r),o=n?.signal?fl([s.signal,n.signal]):s.signal;let c;try{c=await fetch(e,{headers:{Accept:"text/event-stream",Authorization:`Bearer ${t}`,"Cache-Control":"no-cache"},signal:o})}finally{clearTimeout(i)}if(!c.ok){const v=await c.text().catch(()=>"");throw new Error(`SSE connect failed (${c.status} ${c.statusText}): ${v}`)}if(!c.body)throw new Error("SSE response has no body");const d=new TextDecoder,l=c.body.getReader();let p="";try{for(;;){const{done:v,value:$}=await l.read();if(v)break;p+=d.decode($,{stream:!0});const w=p.split(`
40
+ `);p=w.pop()??"";let f="";for(const h of w)if(h.startsWith("data:"))f+=h.slice(5).trimStart();else if(h===""&&f){const _=ml(f);_&&(yield _),f=""}}}finally{l.releaseLock()}}function fl(e){const t=new AbortController;for(const n of e){if(n.aborted){t.abort(n.reason);break}n.addEventListener("abort",()=>t.abort(n.reason),{once:!0})}return t.signal}var yt=e=>typeof e=="string"&&e.trim().length>0?e:null,hl=e=>{try{const t=cr.parse(e);if(t)return t}catch{const t=e.run||null;if(t)try{const n=cr.parse(t);if(n)return n}catch{}}throw new Error("Run ID missing in engine response")},gl=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/+$/,""),this.token=e.token,this.timeoutMs=e.timeoutMs??2e4;const t=this._request.bind(this);this.sessions=new vl(this.baseUrl,this.token,this.timeoutMs,t),this.permissions=new yl(t),this.questions=new bl(t),this.providers=new wl(t),this.channels=new $l(t),this.mcp=new Sl(t),this.routines=new Il(t),this.automations=new El(t),this.memory=new _l(t),this.skills=new kl(t),this.resources=new xl(t),this.agentTeams=new Tl(t),this.missions=new zl(t)}setToken(e){this.token=e,this.sessions.setToken(e)}async health(){const e=await this._request("/global/health");return he(sl,e,"/global/health",200)}async listToolIds(){return this._request("/tool/ids")}async listTools(){const e=await this._request("/tool");return Array.isArray(e)?e:[]}async executeTool(e,t){return this._request("/tool/execute",{method:"POST",body:JSON.stringify({tool:e,args:t??{}})})}stream(e,t,n){const r=new URLSearchParams({sessionID:e});t&&r.set("runID",t);const s=`${this.baseUrl}/event?${r.toString()}`;return dr(s,this.token,n)}globalStream(e){const t=`${this.baseUrl}/global/event`;return dr(t,this.token,e)}async runEvents(e,t){const n=new URLSearchParams;t?.sinceSeq!==void 0&&n.set("since_seq",String(t.sinceSeq)),t?.tail!==void 0&&n.set("tail",String(t.tail));const r=n.toString()?`?${n.toString()}`:"",s=await this._request(`/run/${encodeURIComponent(e)}/events${r}`);return Array.isArray(s)?s:[]}async _request(e,t={}){const n=new AbortController,r=setTimeout(()=>n.abort(),this.timeoutMs);let s;try{s=await fetch(`${this.baseUrl}${e}`,{...t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`,...t.headers??{}},signal:n.signal})}catch(i){throw i instanceof Error&&i.name==="AbortError"?new Error(`Request timed out after ${this.timeoutMs}ms: ${e}`):i}finally{clearTimeout(r)}if(s.status!==204){if(!s.ok){const i=await s.text().catch(()=>"");throw new Error(`Request failed (${s.status} ${s.statusText}): ${i}`)}return s.json()}}},vl=class{constructor(e,t,n,r){this.baseUrl=e,this.token=t,this.timeoutMs=n,this.req=r}setToken(e){this.token=e}async create(e={}){const t={title:e.title??"Tandem SDK Session",directory:e.directory??"."};return e.permissions&&(t.permission=e.permissions),e.model&&e.provider&&(t.model={providerID:e.provider,modelID:e.model},t.provider=e.provider),(await this.req("/session",{method:"POST",body:JSON.stringify(t)})).id}async list(e={}){const t=new URLSearchParams;e.q&&t.set("q",e.q),e.page!==void 0&&t.set("page",String(e.page)),e.pageSize!==void 0&&t.set("page_size",String(e.pageSize)),e.archived!==void 0&&t.set("archived",String(e.archived)),e.scope&&t.set("scope",e.scope),e.workspace&&t.set("workspace",e.workspace);const n=t.toString()?`?${t.toString()}`:"",r=await this.req(`/session${n}`);return he(lr,r,"/session",200)}async get(e){const t=await this.req(`/session/${encodeURIComponent(e)}`);return he(Gt,t,`/session/${e}`,200)}async update(e,t){const n=await this.req(`/session/${encodeURIComponent(e)}`,{method:"PATCH",body:JSON.stringify(t)});return he(Gt,n,`/session/${e}`,200)}async archive(e){return this.update(e,{archived:!0})}async delete(e){await this.req(`/session/${encodeURIComponent(e)}`,{method:"DELETE"})}async messages(e){return this.req(`/session/${encodeURIComponent(e)}/message`)}async todos(e){const t=await this.req(`/session/${encodeURIComponent(e)}/todo`);return Array.isArray(t)?t:t.todos??[]}async activeRun(e){const t=await this.req(`/session/${encodeURIComponent(e)}/run`);return he(ol,t,`/session/${e}/run`,200)}async promptAsync(e,t,n){const r={parts:[{type:"text",text:t}]};n?.provider&&n?.model&&(r.model={providerID:n.provider,modelID:n.model});const s=`/session/${encodeURIComponent(e)}/prompt_async?return=run`,i=new AbortController,o=setTimeout(()=>i.abort(),this.timeoutMs);let c;try{c=await fetch(`${this.baseUrl}${s}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`},body:JSON.stringify(r),signal:i.signal})}finally{clearTimeout(o)}if(c.status===409){const p=(await c.json().catch(()=>({}))).activeRun,v=yt(p?.runID)||yt(p?.runId)||yt(p?.run_id);if(v)return{runId:v}}if(!c.ok){const l=await c.text().catch(()=>"");throw new Error(`promptAsync failed (${c.status}): ${l}`)}const d=await c.json();return{runId:hl(d)}}async promptSync(e,t){const n={parts:[{type:"text",text:t}]},r=await this.req(`/session/${encodeURIComponent(e)}/prompt_sync`,{method:"POST",body:JSON.stringify(n)});return yt(r.reply)||yt(r.text)||yt(r.output)||""}async abort(e){return this.req(`/session/${encodeURIComponent(e)}/abort`,{method:"POST",body:JSON.stringify({})})}async cancel(e){return this.req(`/session/${encodeURIComponent(e)}/cancel`,{method:"POST",body:JSON.stringify({})})}async cancelRun(e,t){return this.req(`/session/${encodeURIComponent(e)}/run/${encodeURIComponent(t)}/cancel`,{method:"POST",body:JSON.stringify({})})}async fork(e){const t=await this.req(`/session/${encodeURIComponent(e)}/fork`,{method:"POST",body:JSON.stringify({})});return he(Gt,t,`/session/${e}/fork`,200)}async diff(e){return this.req(`/session/${encodeURIComponent(e)}/diff`)}async revert(e){return this.req(`/session/${encodeURIComponent(e)}/revert`,{method:"POST",body:JSON.stringify({})})}async unrevert(e){return this.req(`/session/${encodeURIComponent(e)}/unrevert`,{method:"POST",body:JSON.stringify({})})}async children(e){const t=await this.req(`/session/${encodeURIComponent(e)}/children`);return he(lr,t,`/session/${e}/children`,200).sessions}async summarize(e){return this.req(`/session/${encodeURIComponent(e)}/summarize`,{method:"POST",body:JSON.stringify({})})}async attach(e,t){return this.req(`/session/${encodeURIComponent(e)}/attach`,{method:"POST",body:JSON.stringify({target_workspace:t})})}},yl=class{constructor(e){this.req=e}async list(){return this.req("/permission")}async reply(e,t){const n=await this.req(`/permission/${encodeURIComponent(e)}/reply`,{method:"POST",body:JSON.stringify({reply:t})});if(!n.ok)throw new Error(`Permission reply rejected: ${n.error??e}`);return{ok:!0}}},bl=class{constructor(e){this.req=e}async list(){const e=await this.req("/question");return Array.isArray(e)?{questions:e}:e}async reply(e,t){return this.req(`/question/${encodeURIComponent(e)}/reply`,{method:"POST",body:JSON.stringify({answer:t})})}async reject(e){return this.req(`/question/${encodeURIComponent(e)}/reject`,{method:"POST",body:JSON.stringify({})})}},wl=class{constructor(e){this.req=e}async catalog(){return this.req("/provider")}async config(){return this.req("/config/providers")}async setDefaults(e,t){await this.req("/config",{method:"PATCH",body:JSON.stringify({default_provider:e,providers:{[e]:{default_model:t}}})})}async setApiKey(e,t){await this.req(`/auth/${encodeURIComponent(e)}`,{method:"PUT",body:JSON.stringify({apiKey:t})})}async authStatus(){return this.req("/provider/auth")}},$l=class{constructor(e){this.req=e}async config(){return this.req("/channels/config")}async status(){return this.req("/channels/status")}async put(e,t){return this.req(`/channels/${e}`,{method:"PUT",body:JSON.stringify(t)})}async delete(e){return this.req(`/channels/${e}`,{method:"DELETE"})}},Sl=class{constructor(e){this.req=e}async list(){return this.req("/mcp")}async listTools(){return this.req("/mcp/tools")}async listResources(){const e=await this.req("/mcp/resources");return Array.isArray(e)?e:[]}async add(e){return this.req("/mcp",{method:"POST",body:JSON.stringify(e)})}async connect(e){return this.req(`/mcp/${encodeURIComponent(e)}/connect`,{method:"POST"})}async disconnect(e){return this.req(`/mcp/${encodeURIComponent(e)}/disconnect`,{method:"POST"})}async refresh(e){return this.req(`/mcp/${encodeURIComponent(e)}/refresh`,{method:"POST"})}async setEnabled(e,t){return this.req(`/mcp/${encodeURIComponent(e)}`,{method:"PATCH",body:JSON.stringify({enabled:t})})}},_l=class{constructor(e){this.req=e}async put(e){return this.req("/memory/put",{method:"POST",body:JSON.stringify(e)})}async search(e){const t=await this.req("/memory/search",{method:"POST",body:JSON.stringify(e)});return he(ul,t,"/memory/search",200)}async list(e){const t=new URLSearchParams;e?.q&&t.set("q",e.q),e?.limit!==void 0&&t.set("limit",String(e.limit)),e?.offset!==void 0&&t.set("offset",String(e.offset)),e?.userId&&t.set("user_id",e.userId);const n=t.toString()?`?${t.toString()}`:"",r=await this.req(`/memory${n}`);return he(ll,r,"/memory",200)}async delete(e){return this.req(`/memory/${encodeURIComponent(e)}`,{method:"DELETE"})}async promote(e){return this.req("/memory/promote",{method:"POST",body:JSON.stringify(e)})}async demote(e){const t={id:e.id,run_id:e.runId};return this.req("/memory/demote",{method:"POST",body:JSON.stringify(t)})}async audit(e){const t=new URLSearchParams;e?.run_id&&t.set("run_id",e.run_id),e?.limit!==void 0&&t.set("limit",String(e.limit));const n=t.toString()?`?${t.toString()}`:"",r=await this.req(`/memory/audit${n}`);return Array.isArray(r)?{entries:r,count:r.length}:r}},kl=class{constructor(e){this.req=e}async list(e){const t=e?`?location=${encodeURIComponent(e)}`:"",n=await this.req(`/skills${t}`);return Array.isArray(n)?{skills:n,count:n.length}:n}async get(e){return this.req(`/skills/${encodeURIComponent(e)}`)}async import(e){return this.req("/skills/import",{method:"POST",body:JSON.stringify(e)})}async preview(e){return this.req("/skills/import/preview",{method:"POST",body:JSON.stringify(e)})}async templates(){const e=await this.req("/skills/templates");return Array.isArray(e)?{templates:e,count:e.length}:e}},xl=class{constructor(e){this.req=e}async list(e){const t=new URLSearchParams;e?.prefix&&t.set("prefix",e.prefix),e?.limit!==void 0&&t.set("limit",String(e.limit));const n=t.toString()?`?${t.toString()}`:"",r=await this.req(`/resource${n}`);return he(al,r,"/resource",200)}async write(e){return this.req("/resource",{method:"PUT",body:JSON.stringify(e)})}async delete(e,t){return this.req("/resource",{method:"DELETE",body:JSON.stringify({key:e,...t})})}},Il=class{constructor(e){this.req=e}async list(){return this.req("/routines")}async create(e){const t={...e};return"prompt"in t&&!("entrypoint"in t)&&(t.entrypoint=t.prompt),this.req("/routines",{method:"POST",body:JSON.stringify(t)})}async update(e,t){return this.req(`/routines/${encodeURIComponent(e)}`,{method:"PATCH",body:JSON.stringify(t)})}async delete(e){await this.req(`/routines/${encodeURIComponent(e)}`,{method:"DELETE"})}async runNow(e){const t=await this.req(`/routines/${encodeURIComponent(e)}/run_now`,{method:"POST",body:JSON.stringify({})});return he(Gr,t,`/routines/${e}/run_now`,200)}async listRuns(e){const t=new URLSearchParams;e?.routine_id&&t.set("routine_id",e.routine_id),e?.limit!==void 0&&t.set("limit",String(e.limit));const n=t.toString()?`?${t.toString()}`:"";return this.req(`/routines/runs${n}`)}async getRunsForRoutine(e,t=25){return this.req(`/routines/${encodeURIComponent(e)}/runs?limit=${t}`)}async getRun(e){const t=await this.req(`/routines/runs/${encodeURIComponent(e)}`);return he(Xr,t,`/routines/runs/${e}`,200)}async listArtifacts(e){return this.req(`/routines/runs/${encodeURIComponent(e)}/artifacts`)}async approveRun(e,t){return this.req(`/routines/runs/${encodeURIComponent(e)}/approve`,{method:"POST",body:JSON.stringify({reason:t??""})})}async denyRun(e,t){return this.req(`/routines/runs/${encodeURIComponent(e)}/deny`,{method:"POST",body:JSON.stringify({reason:t??""})})}async pauseRun(e,t){return this.req(`/routines/runs/${encodeURIComponent(e)}/pause`,{method:"POST",body:JSON.stringify({reason:t??""})})}async resumeRun(e,t){return this.req(`/routines/runs/${encodeURIComponent(e)}/resume`,{method:"POST",body:JSON.stringify({reason:t??""})})}async history(e,t){const n=t!==void 0?`?limit=${t}`:"",r=await this.req(`/routines/${encodeURIComponent(e)}/history${n}`);return Array.isArray(r)?{history:r,count:r.length}:r}},El=class{constructor(e){this.req=e}async list(){return this.req("/automations")}async create(e){return this.req("/automations",{method:"POST",body:JSON.stringify(e)})}async update(e,t){return this.req(`/automations/${encodeURIComponent(e)}`,{method:"PATCH",body:JSON.stringify(t)})}async delete(e){await this.req(`/automations/${encodeURIComponent(e)}`,{method:"DELETE"})}async runNow(e){const t=await this.req(`/automations/${encodeURIComponent(e)}/run_now`,{method:"POST",body:JSON.stringify({})});return he(Gr,t,`/automations/${e}/run_now`,200)}async listRuns(e){const t=new URLSearchParams;e?.automation_id&&t.set("automation_id",e.automation_id),e?.limit!==void 0&&t.set("limit",String(e.limit));const n=t.toString()?`?${t.toString()}`:"";return this.req(`/automations/runs${n}`)}async getRunsForAutomation(e,t=25){return this.req(`/automations/${encodeURIComponent(e)}/runs?limit=${t}`)}async getRun(e){const t=await this.req(`/automations/runs/${encodeURIComponent(e)}`);return he(Xr,t,`/automations/runs/${e}`,200)}async listArtifacts(e){return this.req(`/automations/runs/${encodeURIComponent(e)}/artifacts`)}async approveRun(e,t){return this.req(`/automations/runs/${encodeURIComponent(e)}/approve`,{method:"POST",body:JSON.stringify({reason:t??""})})}async denyRun(e,t){return this.req(`/automations/runs/${encodeURIComponent(e)}/deny`,{method:"POST",body:JSON.stringify({reason:t??""})})}async pauseRun(e,t){return this.req(`/automations/runs/${encodeURIComponent(e)}/pause`,{method:"POST",body:JSON.stringify({reason:t??""})})}async resumeRun(e,t){return this.req(`/automations/runs/${encodeURIComponent(e)}/resume`,{method:"POST",body:JSON.stringify({reason:t??""})})}async history(e,t){const n=t!==void 0?`?limit=${t}`:"",r=await this.req(`/automations/${encodeURIComponent(e)}/history${n}`);return Array.isArray(r)?{history:r,count:r.length}:r}},Tl=class{constructor(e){this.req=e}async listTemplates(){return this.req("/agent-team/templates")}async listInstances(e){const t=new URLSearchParams;e?.missionID&&t.set("missionID",e.missionID),e?.parentInstanceID&&t.set("parentInstanceID",e.parentInstanceID),e?.status&&t.set("status",e.status);const n=t.toString()?`?${t.toString()}`:"";return this.req(`/agent-team/instances${n}`)}async listMissions(){return this.req("/agent-team/missions")}async listApprovals(){return this.req("/agent-team/approvals")}async spawn(e){return this.req("/agent-team/spawn",{method:"POST",body:JSON.stringify(e)})}async approveSpawn(e,t){return this.req(`/agent-team/approvals/spawn/${encodeURIComponent(e)}/approve`,{method:"POST",body:JSON.stringify({reason:t??""})})}async denySpawn(e,t){return this.req(`/agent-team/approvals/spawn/${encodeURIComponent(e)}/deny`,{method:"POST",body:JSON.stringify({reason:t??""})})}},zl=class{constructor(e){this.req=e}async list(){return this.req("/mission")}async create(e){return this.req("/mission",{method:"POST",body:JSON.stringify(e)})}async get(e){return this.req(`/mission/${encodeURIComponent(e)}`)}async applyEvent(e,t){return this.req(`/mission/${encodeURIComponent(e)}/event`,{method:"POST",body:JSON.stringify({event:t})})}};async function We(e,t={}){const n=await fetch(e,{...t,credentials:"include",headers:{"content-type":"application/json",...t.headers||{}}});if(!n.ok){const s=await n.text().catch(()=>"");let i=s||`${e} failed (${n.status})`;try{const o=s?JSON.parse(s):null;o?.error&&(i=o.error)}catch{}throw new Error(i)}const r=await n.text();return r?JSON.parse(r):{}}function ye(e){return document.getElementById(e)}function ae(e){return String(e||"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Yr(e="dashboard"){return(window.location.hash||`#/${e}`).replace(/^#\//,"")}function Nn(e,t,n="dashboard"){return t.find(r=>r[0]===e)?e:n}function Al(e){window.location.hash=`#/${e}`}function Rl(e){function t(){let s=ye("toasts");return s||(s=document.createElement("div"),s.id="toasts",s.className="toasts",document.body.appendChild(s)),s}function n(){const s=t();s.innerHTML=e.toasts.map(i=>`<div class="toast toast-${i.kind}">${ae(i.text)}</div>`).join("")}function r(s,i){const o=Math.random().toString(36).slice(2);e.toasts.push({id:o,kind:s,text:i}),e.toasts=e.toasts.slice(-4),n(),setTimeout(()=>{e.toasts=e.toasts.filter(c=>c.id!==o),n()},3500)}return{toast:r,renderToasts:n}}const Rt=[["dashboard","Dashboard","home"],["chat","Chat","message-square"],["agents","Agents","clock"],["channels","Channels","message-circle"],["mcp","MCP","link"],["swarm","Swarm","share-2"],["files","Files","folder-open"],["memory","Memory","database"],["teams","Teams","users"],["feed","Live Feed","radio"],["settings","Settings","settings"]],Cl={openai:{label:"OpenAI",keyUrl:"https://platform.openai.com/api-keys",placeholder:"sk-proj-..."},anthropic:{label:"Anthropic",keyUrl:"https://console.anthropic.com/settings/keys",placeholder:"sk-ant-..."},google:{label:"Google",keyUrl:"https://aistudio.google.com/app/apikey",placeholder:"AIza..."},groq:{label:"Groq",keyUrl:"https://console.groq.com/keys",placeholder:"gsk_..."},mistral:{label:"Mistral",keyUrl:"https://console.mistral.ai/api-keys/",placeholder:"..."},openrouter:{label:"OpenRouter",keyUrl:"https://openrouter.ai/settings/keys",placeholder:"sk-or-v1-..."},ollama:{label:"Ollama",keyUrl:"",placeholder:"No key required"}};function Ol(){return{authed:!1,route:"dashboard",me:null,client:null,needsProviderOnboarding:!1,providerReady:!1,providerDefault:"",providerDefaultModel:"",providerConnected:[],providerError:"",botName:"Tandem",botAvatarUrl:"",controlPanelName:"Tandem Control Panel",currentSessionId:"",chatUploadedFiles:[],filesDir:"uploads",cleanup:[],toasts:[]}}async function Pl(e){const{api:t,state:n,byId:r,escapeHtml:s,setRoute:i}=e,o=await t("/api/system/health").catch(()=>({})),c=await n.client.providers.config().catch(()=>({default:null,providers:{}})),d=await n.client.channels.status().catch(()=>({})),l=await n.client.routines.list().catch(()=>({routines:[]})),p=await n.client.automations.list().catch(()=>({automations:[]}));r("view").innerHTML=`
41
+ <div class="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
42
+ <div class="tcp-card">
43
+ <div class="mb-2 flex items-center justify-between"><span class="tcp-subtle">Engine</span><i data-lucide="cpu"></i></div>
44
+ <div class="text-2xl font-semibold">${s(o.engine?.version||"unknown")}</div>
45
+ <p class="mt-1 text-sm ${o.engine?.ready||o.engine?.healthy?"text-lime-300":"text-rose-300"}">${o.engine?.ready||o.engine?.healthy?"Healthy":"Unhealthy"}</p>
46
+ </div>
47
+ <div class="tcp-card">
48
+ <div class="mb-2 flex items-center justify-between"><span class="tcp-subtle">Provider</span><i data-lucide="bot"></i></div>
49
+ <div class="text-2xl font-semibold">${s(c.default||"none")}</div>
50
+ <p class="mt-1 text-sm text-slate-400">Default model configured</p>
51
+ </div>
52
+ <div class="tcp-card">
53
+ <div class="mb-2 flex items-center justify-between"><span class="tcp-subtle">Channels</span><i data-lucide="messages-square"></i></div>
54
+ <div class="text-2xl font-semibold">${Object.values(d||{}).filter(v=>v?.connected).length}</div>
55
+ <p class="mt-1 text-sm text-slate-400">Connected integrations</p>
56
+ </div>
57
+ <div class="tcp-card">
58
+ <div class="mb-2 flex items-center justify-between"><span class="tcp-subtle">Scheduled</span><i data-lucide="clock-3"></i></div>
59
+ <div class="text-2xl font-semibold">${(l.routines||[]).length+(p.automations||[]).length}</div>
60
+ <p class="mt-1 text-sm text-slate-400">Routines + automations</p>
61
+ </div>
62
+ </div>
63
+ <div class="tcp-card">
64
+ <h3 class="tcp-title mb-3">Quick Actions</h3>
65
+ <div class="grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
66
+ <button class="tcp-btn w-full justify-start" data-goto="chat"><i data-lucide="message-square"></i> Open Chat</button>
67
+ <button class="tcp-btn w-full justify-start" data-goto="agents"><i data-lucide="clipboard-list"></i> Manage Routines</button>
68
+ <button class="tcp-btn w-full justify-start" data-goto="swarm"><i data-lucide="workflow"></i> Launch Swarm</button>
69
+ <button class="tcp-btn w-full justify-start" data-goto="mcp"><i data-lucide="plug-zap"></i> Connect MCP</button>
70
+ </div>
71
+ </div>
72
+ `,r("view").querySelectorAll("[data-goto]").forEach(v=>{v.addEventListener("click",()=>i(v.dataset.goto))})}function ur(e){const t=String(e||"").trim();return t&&(/^https?:\/\//i.test(t)||/^mailto:/i.test(t))?t:""}function Et(e){let t=ae(e||"");const n=[];return t=t.replace(/`([^`]+)`/g,(r,s)=>{const i=`@@CODE${n.length}@@`;return n.push(`<code>${ae(s)}</code>`),i}),t=t.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g,(r,s,i)=>{const o=ur(i);return o?`<a href="${ae(o)}" target="_blank" rel="noreferrer">${ae(s)}</a>`:`${ae(s)} (${ae(i)})`}),t=t.replace(/(https?:\/\/[^\s<]+)/g,r=>{const s=ur(r);return s?`<a href="${ae(s)}" target="_blank" rel="noreferrer">${ae(r)}</a>`:ae(r)}),t=t.replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>"),t=t.replace(/__([^_]+)__/g,"<strong>$1</strong>"),t=t.replace(/\*([^*]+)\*/g,"<em>$1</em>"),t=t.replace(/_([^_]+)_/g,"<em>$1</em>"),t=t.replace(/~~([^~]+)~~/g,"<s>$1</s>"),t=t.replace(/@@CODE(\d+)@@/g,(r,s)=>n[Number(s)]||""),t}function Ml(e){const t=String(e||"").replace(/\r/g,"").split(`
73
+ `),n=[];let r=0;for(;r<t.length;){const s=t[r];if(/^\s*```/.test(s)){const c=[];for(r+=1;r<t.length&&!/^\s*```/.test(t[r]);)c.push(t[r]),r+=1;r<t.length&&(r+=1),n.push(`<pre><code>${ae(c.join(`
74
+ `))}</code></pre>`);continue}const i=s.match(/^(#{1,6})\s+(.+)$/);if(i){const c=i[1].length;n.push(`<h${c}>${Et(i[2])}</h${c}>`),r+=1;continue}if(/^[-*+]\s+/.test(s)){const c=[];for(;r<t.length&&/^[-*+]\s+/.test(t[r]);)c.push(t[r].replace(/^[-*+]\s+/,"")),r+=1;n.push(`<ul>${c.map(d=>`<li>${Et(d)}</li>`).join("")}</ul>`);continue}if(/^\d+\.\s+/.test(s)){const c=[];for(;r<t.length&&/^\d+\.\s+/.test(t[r]);)c.push(t[r].replace(/^\d+\.\s+/,"")),r+=1;n.push(`<ol>${c.map(d=>`<li>${Et(d)}</li>`).join("")}</ol>`);continue}if(/^>\s?/.test(s)){const c=[];for(;r<t.length&&/^>\s?/.test(t[r]);)c.push(t[r].replace(/^>\s?/,"")),r+=1;n.push(`<blockquote>${c.map(d=>Et(d)).join("<br/>")}</blockquote>`);continue}if(!s.trim()){r+=1;continue}const o=[s];for(r+=1;r<t.length&&t[r].trim()&&!/^(#{1,6})\s+/.test(t[r])&&!/^[-*+]\s+/.test(t[r])&&!/^\d+\.\s+/.test(t[r])&&!/^>\s?/.test(t[r])&&!/^\s*```/.test(t[r]);)o.push(t[r]),r+=1;n.push(`<p>${o.map(c=>Et(c)).join("<br/>")}</p>`)}return n.join("")}const Nl="control-panel",Ll={md:"text/markdown",txt:"text/plain",csv:"text/csv",json:"application/json",pdf:"application/pdf",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp"};function pr(e=""){const t=String(e).toLowerCase().split(".").pop()||"";return Ll[t]||"application/octet-stream"}function Dl(e,t){if(!e||!t)return t||"";const n=String(e).replace(/[\\/]+$/,""),r=String(t).replace(/^[\\/]+/,"");return`${n}/${r}`}async function jl(e){const{state:t,byId:n,toast:r,escapeHtml:s,api:i,renderIcons:o}=e,c=await _e();t.currentSessionId||(t.currentSessionId=c[0]?.id||"");let d=!1;n("view").innerHTML=`
75
+ <div id="chat-layout" class="chat-layout min-w-0 h-[calc(100vh-2rem)]">
76
+ <aside id="chat-sessions-panel" class="chat-sessions-panel">
77
+ <div class="chat-sessions-header">
78
+ <h3 class="chat-sessions-title"><i data-lucide="clock-3"></i> Sessions</h3>
79
+ <button id="new-session" class="tcp-btn h-8 px-2.5 text-xs"><i data-lucide="plus"></i> New</button>
80
+ </div>
81
+ <div id="session-list" class="chat-session-list"></div>
82
+ </aside>
83
+ <button id="chat-scrim" class="chat-scrim" aria-label="Close sessions"></button>
84
+ <div class="chat-workspace min-h-0 min-w-0">
85
+ <div class="chat-main-shell flex min-h-0 min-w-0 flex-col overflow-hidden">
86
+ <div class="chat-main-header shrink-0">
87
+ <button id="chat-toggle-sessions" type="button" class="chat-icon-btn h-8 w-8" title="Sessions"><i data-lucide="clock-3"></i></button>
88
+ <div class="chat-main-dot"></div>
89
+ <h3 id="chat-title" class="tcp-title chat-main-title">Chat</h3>
90
+ <span id="chat-tool-count" class="chat-main-tools hidden"></span>
91
+ </div>
92
+ <div id="messages" class="chat-messages mb-2 min-h-0 min-w-0 flex-1 space-y-2 overflow-auto p-3"></div>
93
+ <div class="chat-composer shrink-0">
94
+ <div id="chat-attach-row" class="chat-attach-row mb-2 hidden">
95
+ <input id="chat-file-input" type="file" class="hidden" multiple />
96
+ <span id="chat-attach-summary" class="tcp-subtle">0 files attached</span>
97
+ <div id="chat-files" class="chat-files-line"></div>
98
+ </div>
99
+ <div id="chat-upload-progress" class="mb-2 grid gap-1.5"></div>
100
+ <div class="chat-input-wrap">
101
+ <button id="chat-file-pick-inner" type="button" class="chat-icon-btn chat-icon-btn-inner" title="Attach files"><i data-lucide="paperclip"></i></button>
102
+ <textarea id="chat-input" rows="1" class="tcp-input chat-input-with-clip chat-input-modern resize-none border-slate-600/80 bg-slate-800/60" placeholder="Ask anything... (Enter to send, Shift+Enter newline)"></textarea>
103
+ <button id="send-chat" class="chat-send-btn" title="Send"><i data-lucide="send"></i></button>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ <aside class="chat-right-rail hidden min-h-0 flex-col gap-3 overflow-hidden xl:flex">
108
+ <section class="min-h-0">
109
+ <div class="mb-2 flex items-center justify-between">
110
+ <p class="chat-rail-label">Tools</p>
111
+ <span id="chat-rail-tools-count" class="chat-rail-count">0</span>
112
+ </div>
113
+ <div id="chat-tools-list" class="chat-tools-list"></div>
114
+ </section>
115
+ <section class="min-h-0 flex-1">
116
+ <div class="mb-2 flex items-center justify-between">
117
+ <p class="chat-rail-label">Tool Activity</p>
118
+ <button id="chat-tools-clear" class="tcp-btn h-7 px-2 text-[11px]">Clear</button>
119
+ </div>
120
+ <div id="chat-tools-activity" class="chat-tools-activity"></div>
121
+ </section>
122
+ </aside>
123
+ </div>
124
+ </div>
125
+ `;const l=n("chat-layout"),p=n("chat-sessions-panel"),v=n("chat-scrim"),$=n("session-list"),w=n("messages"),f=n("chat-input"),h=n("send-chat"),_=n("chat-file-input"),Z=n("chat-file-pick-inner"),N=n("chat-attach-row"),q=n("chat-files"),H=n("chat-upload-progress"),x=n("chat-attach-summary"),j=n("chat-title"),A=n("chat-tool-count"),M=n("chat-rail-tools-count"),J=n("chat-tools-list"),T=n("chat-tools-activity"),F=Array.isArray(t.chatUploadedFiles)?t.chatUploadedFiles:[];t.chatUploadedFiles=F;const B=new Map,W=[],Se=new Set;let Me=[],Xe=!1;function xe(y){d=!!y,l.classList.toggle("sessions-open",d),p.classList.toggle("open",d),v.classList.toggle("open",d)}function Ne(){f.style.height="0px",f.style.height=`${Math.min(f.scrollHeight,180)}px`}async function _e(){try{const y=await t.client.sessions.list({pageSize:50});if(Array.isArray(y))return y;if(Array.isArray(y?.sessions))return y.sessions}catch{}try{const y=await i("/api/engine/session?page_size=50");return Array.isArray(y)?y:Array.isArray(y?.sessions)?y.sessions:[]}catch{return[]}}function Ye(){const y=String(t.providerDefault||"").trim(),z=String(t.providerDefaultModel||"").trim();return!y||!z?null:{providerID:y,modelID:z}}async function lt(){const y=Ye();if(y)return y;try{const z=await t.client.providers.config(),C=String(z?.default||"").trim(),P=String(z?.providers?.[C]?.default_model||"").trim();if(C&&(t.providerDefault=C),P&&(t.providerDefaultModel=P),C&&P)return{providerID:C,modelID:P}}catch{}return Ye()}async function Ae(){const y=await lt(),z={title:`Chat ${new Date().toLocaleTimeString()}`};y&&(z.provider=y.providerID,z.model=y.modelID);const C=await t.client.sessions.create(z),P=await t.client.sessions.get(C).catch(()=>({id:C,title:C}));return c.unshift(P),t.currentSessionId=C,pt(),De(),await ce(),C}function dt(y){const z=Number(y||0);return z<1024?`${z} B`:z<1024*1024?`${(z/1024).toFixed(1)} KB`:`${(z/(1024*1024)).toFixed(1)} MB`}function Ot(){const y=c.find(C=>C.id===t.currentSessionId),z=String(y?.title||"").trim();return z||(t.currentSessionId?`Session ${t.currentSessionId.slice(0,8)}`:"Chat")}function Pt(){j.textContent=Ot();const y=Me.length;if(y>0){const z=`${y} tool${y===1?"":"s"}`;A.textContent=z,A.classList.remove("hidden"),M.textContent=String(y)}else A.classList.add("hidden"),M.textContent="0"}function Mt(y){return y==="completed"?"chat-tool-chip-ok":y==="failed"?"chat-tool-chip-failed":"chat-tool-chip-running"}function ut(){J.innerHTML=Me.slice(0,32).map(y=>`<button type="button" class="chat-tool-pill" data-tool-insert="${s(y)}" title="Insert ${s(y)}">${s(y)}</button>`).join("")||'<p class="chat-rail-empty">No tools loaded.</p>',J.querySelectorAll("[data-tool-insert]").forEach(y=>{y.addEventListener("click",()=>{const z=String(y.dataset.toolInsert||"").trim();z&&(f.value=f.value.trim()?`${f.value} ${z}`:z,f.focus())})}),T.innerHTML=W.slice(0,24).map(y=>{const z=new Date(y.at).toLocaleTimeString();return`<div class="chat-tool-chip ${Mt(y.status)}" title="${s(z)}">${s(y.tool)}: ${s(y.status)}</div>`}).join("")||'<p class="chat-rail-empty">No tool events yet.</p>',Pt()}function pt(){W.splice(0,W.length),Se.clear(),ut()}function mt(y,z,C=""){const P=String(y||"").trim();if(P){if(C){if(Se.has(C))return;Se.add(C),Se.size>1e3&&Se.clear()}W.unshift({id:`${P}:${z}:${Date.now()}:${Math.random().toString(36).slice(2,8)}`,tool:P,status:z,at:Date.now()}),W.length>80&&(W.length=80),ut()}}function Nt(y){return(Array.isArray(y)?y:Array.isArray(y?.tools)?y.tools:[]).map(C=>{if(typeof C=="string")return C;const P=C||{};return String(P.name||P.id||P.tool||"").trim()}).filter(Boolean)}async function ft(){try{const y=await t.client.listTools().catch(()=>null);let z=Nt(y||[]);if(!z.length){const C=await i("/api/engine/tool").catch(()=>[]);z=Nt(C||[])}Me=[...new Set(z)].sort((C,P)=>C.localeCompare(P))}catch{Me=[]}ut()}function Ie(){const y=[...B.entries()];if(!y.length){H.innerHTML="";return}H.innerHTML=y.map(([z,C])=>{const P=Math.max(0,Math.min(100,Number(C.progress||0)));return`
126
+ <div class="rounded-lg border border-slate-700/70 bg-slate-900/40 px-2 py-1.5">
127
+ <div class="mb-1 flex items-center justify-between gap-2 text-xs">
128
+ <span class="truncate text-slate-200">${s(C.name)}</span>
129
+ <span class="${C.error?"text-rose-300":"text-slate-400"}">${C.error?s(C.error):`${P}%`}</span>
130
+ </div>
131
+ <div class="h-1.5 overflow-hidden rounded-full bg-slate-800">
132
+ <div class="h-full rounded-full bg-slate-400/80 transition-all duration-150" style="width:${P}%"></div>
133
+ </div>
134
+ </div>
135
+ `}).join("")}function Le(){if(!F.length){q.innerHTML="",x.textContent="",N.classList.add("hidden");return}const y=F.length;x.textContent=`${y} attached`,N.classList.remove("hidden"),q.innerHTML=F.map((z,C)=>`
136
+ <div class="chat-file-pill min-w-0">
137
+ <span class="chat-file-pill-name" title="${s(z.path)}">${s(z.path)}</span>
138
+ <span class="chat-file-pill-size">${s(dt(z.size))}</span>
139
+ <button class="chat-file-pill-btn chat-file-pill-btn-danger" type="button" data-file-remove="${C}" title="Remove from list"><i data-lucide="x"></i></button>
140
+ </div>
141
+ `).join(""),q.querySelectorAll("[data-file-remove]").forEach(z=>{z.addEventListener("click",()=>{const C=Number(z.dataset.fileRemove);Number.isFinite(C)&&(F.splice(C,1),Le())})}),o(q)}function Lt(y){return new Promise((z,C)=>{const P=`${Date.now()}-${Math.random().toString(16).slice(2)}`;B.set(P,{name:y.name,progress:0,error:""}),Ie();const L=new XMLHttpRequest;L.open("POST",`/api/files/upload?dir=${encodeURIComponent(Nl)}`),L.withCredentials=!0,L.responseType="json",L.setRequestHeader("x-file-name",encodeURIComponent(y.name)),L.upload.onprogress=oe=>{if(!oe.lengthComputable)return;const be=B.get(P);be&&(be.progress=oe.loaded/oe.total*100,Ie())},L.onerror=()=>{const oe=B.get(P);oe&&(oe.error="Network error"),Ie(),setTimeout(()=>{B.delete(P),Ie()},1200),C(new Error(`Upload failed: ${y.name}`))},L.onload=()=>{const oe=L.response||{};if(L.status<200||L.status>=300||oe?.ok===!1){const be=oe?.error||`Upload failed (${L.status})`,Re=B.get(P);Re&&(Re.error=String(be)),Ie(),setTimeout(()=>{B.delete(P),Ie()},1800),C(new Error(String(be)));return}B.delete(P),Ie(),z(oe)},L.send(y)})}async function fn(y){const z=[...y||[]];if(!z.length)return;let C=0;for(const P of z)try{const L=await Lt(P);F.unshift({name:L.name||P.name,path:L.path||P.name,size:Number(L.size||P.size||0),mime:P.type||pr(L.name||P.name),url:L.absPath||Dl(L.root,L.path)||L.path||P.name}),C+=1,Le()}catch(L){r("err",L instanceof Error?L.message:String(L))}C>0&&r("ok",`Uploaded ${C} file${C===1?"":"s"}.`)}async function Dt(y){await t.client.sessions.delete(y);const z=c.findIndex(C=>C.id===y);z>=0&&c.splice(z,1),t.currentSessionId===y&&(t.currentSessionId=c[0]?.id||"",t.currentSessionId||await Ae()),pt(),De(),await ce()}function De(){$.innerHTML=c.map(y=>`
142
+ <div class="chat-session-row">
143
+ <button class="chat-session-btn ${y.id===t.currentSessionId?"active":""}" data-sid="${y.id}" title="${s(y.id)}">
144
+ <span class="block truncate">${s(y.title||y.id.slice(0,8))}</span>
145
+ </button>
146
+ <button class="chat-session-del" data-del-sid="${y.id}" title="Delete session">
147
+ <i data-lucide="trash-2"></i>
148
+ </button>
149
+ </div>
150
+ `).join(""),$.querySelectorAll("[data-sid]").forEach(y=>{y.addEventListener("click",async()=>{t.currentSessionId=y.dataset.sid,pt(),De(),await ce(),xe(!1)})}),$.querySelectorAll("[data-del-sid]").forEach(y=>{y.addEventListener("click",async z=>{z.stopPropagation();const C=y.dataset.delSid;if(C&&window.confirm("Delete this session?"))try{await Dt(C),r("ok","Session deleted.")}catch(P){r("err",P instanceof Error?P.message:String(P))}})}),o($)}async function ce(){if(Pt(),!t.currentSessionId){w.innerHTML='<p class="tcp-subtle">Create a session to begin.</p>';return}const y=await t.client.sessions.messages(t.currentSessionId).catch(()=>[]),z=String(t.botName||"Assistant").trim()||"Assistant",C=String(t.botAvatarUrl||"").trim();w.innerHTML=y.map(P=>{const L=String(P?.info?.role||"unknown"),be=s(L==="assistant"?z:L==="user"?"User":L==="system"?"System":L),Re=L==="assistant"?`<span class="inline-flex items-center gap-2">${C?`<img src="${s(C)}" alt="${s(z)}" class="h-5 w-5 rounded-full object-cover ring-1 ring-slate-600" />`:""}<span>${be}</span></span>`:be,le=(P.parts||[]).map(Qe=>Qe.text||"").join(`
151
+ `),X=L==="assistant"||L==="system",je=X?`<div class="tcp-markdown tcp-markdown-ai">${Ml(le)}</div>`:`<pre class="max-w-full whitespace-pre-wrap break-all font-mono text-xs text-slate-200">${s(le)}</pre>`;return`<div class="chat-msg ${X?"assistant":"user"}"><div class="chat-msg-role">${Re}</div>${je}</div>`}).join(""),w.scrollTop=w.scrollHeight}n("new-session").addEventListener("click",async()=>{try{await Ae()}catch(y){r("err",y instanceof Error?y.message:String(y))}});async function kt(){if(Xe)return;const y=f.value.trim(),z=F.slice(),C=y||(z.length?"Please analyze the attached file(s).":"");if(!(!C&&z.length===0)){f.value="",Ne(),Xe=!0,h.disabled=!0;try{t.currentSessionId||await Ae();const P=await lt();if(!P)throw new Error("No default provider/model configured. Set it in Settings before sending chat.");z.length>0&&r("info",`Sending with ${z.length} attached file${z.length===1?"":"s"}.`);const L=z.map(I=>({type:"file",mime:I.mime||pr(I.name||I.path),filename:I.name||I.path||"attachment",url:I.url||I.path}));L.push({type:"text",text:C});const oe=async()=>{const I=await fetch(`/api/engine/session/${encodeURIComponent(t.currentSessionId)}/run`,{method:"GET",credentials:"include"});if(!I.ok)return"";const U=await I.json().catch(()=>({}));return U?.active?.runID||U?.active?.runId||U?.active?.run_id||""},be=async()=>{const I=await oe().catch(()=>"");I&&await fetch(`/api/engine/session/${encodeURIComponent(t.currentSessionId)}/run/${encodeURIComponent(I)}/cancel`,{method:"POST",credentials:"include",headers:{"content-type":"application/json"},body:JSON.stringify({})}).catch(()=>{}),await fetch(`/api/engine/session/${encodeURIComponent(t.currentSessionId)}/cancel`,{method:"POST",credentials:"include",headers:{"content-type":"application/json"},body:JSON.stringify({})}).catch(()=>{});for(let U=0;U<50;U+=1){if(!await oe().catch(()=>""))return!0;await new Promise(Y=>setTimeout(Y,200))}return!1},Re=async()=>fetch(`/api/engine/session/${encodeURIComponent(t.currentSessionId)}/prompt_async?return=run`,{method:"POST",credentials:"include",headers:{"content-type":"application/json"},body:JSON.stringify({parts:L,model:{providerID:P.providerID,modelID:P.modelID}})});let le=await Re(),X="";if(le.status===409){if(!await be())throw new Error("Session has a stuck active run. Cancel it from engine/session and retry.");if(le=await Re(),le.ok){const U=await le.json().catch(()=>({}));X=U?.runID||U?.runId||U?.run_id||""}else{if(le.status===409)throw new Error("Session is still busy with another run. Please retry in a moment.");{const U=await le.text().catch(()=>"");throw new Error(`prompt_async retry failed (${le.status}): ${U}`)}}}else if(le.ok){const I=await le.json().catch(()=>({}));X=I?.runID||I?.runId||I?.run_id||""}else{const I=await le.text().catch(()=>"");throw new Error(`prompt_async failed (${le.status}): ${I}`)}if(!X)throw new Error("No run ID returned from engine.");z.length>0&&(F.splice(0,F.length),Le());let je="",ht=!1;const Qe=s(String(t.botName||"Assistant").trim()||"Assistant"),pe=String(t.botAvatarUrl||"").trim(),et=document.createElement("div");et.className="chat-msg assistant",et.innerHTML=`
152
+ <div class="chat-msg-role"><span class="inline-flex items-center gap-2">${pe?`<img src="${s(pe)}" alt="${Qe}" class="h-5 w-5 rounded-full object-cover ring-1 ring-slate-600" />`:""}<span>${Qe}</span></span></div>
153
+ <div class="tcp-thinking" aria-live="polite">
154
+ <span>Thinking</span>
155
+ <i></i><i></i><i></i>
156
+ </div>
157
+ <pre class="streaming-msg hidden whitespace-pre-wrap break-all font-mono text-xs text-slate-200"></pre>
158
+ `,w.appendChild(et),w.scrollTop=w.scrollHeight;const gt=et.querySelector(".tcp-thinking"),jt=et.querySelector(".streaming-msg"),hn=new Set(["run.complete","run.completed","session.run.finished","session.run.completed"]),tt=new Set(["run.failed","session.run.failed","run.cancelled","run.canceled","session.run.cancelled","session.run.canceled"]);let Ee=!1;const Ze=new AbortController;let Te=null,qe=null,Ce="";const Zt=3e4,nt=18e4,vt=async(I,U)=>{const K=Date.now();for(;Date.now()-K<U;){const Y=await oe().catch(()=>I);if(await ce(),!Y||Y!==I)return!0;await new Promise(re=>setTimeout(re,350))}return!1},rt=I=>{const U=String(I||"").trim();return U!=="server.connected"&&U!=="engine.lifecycle.ready"},Ue=()=>{Te&&clearTimeout(Te),Te=setTimeout(()=>{Ee=!0,Ce="no-events-timeout",Ze.abort("no-events-timeout")},Zt)};Ue(),qe=setTimeout(()=>{Ee=!0,Ce="max-stream-window",Ze.abort("max-stream-window")},nt);try{for await(const I of t.client.stream(t.currentSessionId,X,{signal:Ze.signal})){rt(I.type)&&Ue();const U=String(I.runId||I.runID||I.run_id||I.properties?.runID||"").trim();if(!(U&&U!==X)){if(I.type==="session.response"){const K=String(I.properties?.delta||"");if(!K)continue;ht=!0,gt&&gt.classList.add("hidden"),jt.classList.remove("hidden"),je+=K,jt.textContent=je,w.scrollTop=w.scrollHeight}if(I.type==="tool.called"||I.type==="tool_call.started"){const K=String(I.properties?.tool||"tool");mt(K,"started",`${I.type}:${U||X}:${K}:start`)}if(I.type==="tool.result"||I.type==="tool_call.completed"||I.type==="tool_call.failed"){const K=String(I.properties?.tool||"tool"),Y=I.type==="tool_call.failed";mt(K,Y?"failed":"completed",`${I.type}:${U||X}:${K}:${Y?"failed":"completed"}`)}if(I.type==="message.part.updated"){const K=I.properties?.part||{},Y=String(K.type||"").trim(),re=String(K.tool||K.toolName||"").trim();if(re&&Y==="tool_invocation"){const st=String(K.id||"").trim();mt(re,"started",`${I.type}:${st||U||X}:${re}:start`)}if(re&&Y==="tool_result"){const st=String(K.id||"").trim(),me=String(K.state||"").toLowerCase(),fe=me==="failed"||me==="error";mt(re,fe?"failed":"completed",`${I.type}:${st||U||X}:${re}:${fe?"failed":"completed"}`)}}if(tt.has(I.type))throw new Error(String(I.properties?.error||"Run failed."));if((I.type==="session.updated"||I.type==="session.status")&&String(I.properties?.status||"").toLowerCase()==="idle"||hn.has(I.type))break}}}catch(I){const U=String(I?.message||I||"").toLowerCase();if(!(Ee||U.includes("abort")||U.includes("terminated")||U.includes("networkerror")))throw I}if(Te&&clearTimeout(Te),qe&&clearTimeout(qe),Ee){const I=await vt(X,45e3);if(await ce(),!I)throw new Error("Run stream timed out and the run is still active. Check engine/provider logs and retry.")}if(!ht&&gt&&(gt.innerHTML="<span>Finalizing response...</span>"),await ce(),await new Promise(I=>setTimeout(I,180)),await ce(),await new Promise(I=>setTimeout(I,220)),await ce(),!ht&&await oe().catch(()=>"")===X){if(await vt(X,3e4)){await ce();return}const K=Ce||"stream-ended-without-final-delta";throw new Error(`Run ${X} is still active without a final response (${K}).`)}}catch(P){const L=P instanceof Error?P.message:String(P),oe=L.includes("no-events-timeout")||L.includes("max-stream-window")||L.includes("AbortError")||L.toLowerCase().includes("terminated")?"Run stream timed out before events were received. Check engine/provider logs and retry.":L;r("err",oe),await ce()}finally{Xe=!1,h.disabled=!1}}}h.addEventListener("click",()=>{kt()}),n("chat-toggle-sessions")?.addEventListener("click",()=>{xe(!d)}),v?.addEventListener("click",()=>{xe(!1)}),n("chat-tools-clear")?.addEventListener("click",()=>{pt()}),Z.addEventListener("click",()=>{_.click()}),_.addEventListener("change",async()=>{await fn(_.files),_.value=""}),f.addEventListener("keydown",y=>{y.key==="Enter"&&!y.shiftKey&&(y.preventDefault(),kt())}),f.addEventListener("input",()=>{Ne()}),De(),Le(),ut(),ft(),!t.currentSessionId&&c.length===0&&await Ae().catch(()=>{}),xe(!1),Ne(),await ce()}async function Pe(e){const{state:t,byId:n,toast:r,escapeHtml:s,api:i,renderIcons:o}=e,[c,d,l,p,v,$,w]=await Promise.all([t.client.routines.list().catch(()=>({routines:[]})),t.client.automations.list().catch(()=>({automations:[]})),t.client.routines.listRuns({limit:100}).catch(()=>({runs:[]})),t.client.automations.listRuns({limit:100}).catch(()=>({runs:[]})),t.client.providers.catalog().catch(()=>({all:[],connected:[],default:null})),t.client.providers.config().catch(()=>({default:null,providers:{}})),t.client.listToolIds().catch(()=>[])]),f=c.routines||[],h=d.automations||[],_=Array.isArray(l?.runs)?l.runs:[],Z=Array.isArray(p?.runs)?p.runs:[],N=Array.isArray(v?.all)?v.all:[],q=$?.providers||{},H=Array.isArray(w)?w.map(a=>String(a||"").trim()).filter(Boolean).sort():[],x=(a="")=>String(a).toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)||"routine",j=a=>{if(!a)return"manual";if(typeof a=="string")return a;const u=Number(a?.interval_seconds?.seconds??a?.intervalSeconds?.seconds??a?.intervalSeconds??0);if(u>0)return u%3600===0?`every ${u/3600}h`:u%60===0?`every ${u/60}m`:`every ${u}s`;const m=String(a?.cron?.expression??a?.cron?.cron??a?.expression??a?.cron??"").trim();if(m){const b=m,S=b.match(/^(\d{1,2})\s+(\d{1,2})\s+\*\s+\*\s+\*$/);if(S){const D=String(S[1]).padStart(2,"0");return`daily ${String(S[2]).padStart(2,"0")}:${D}`}const R=b.match(/^(\d{1,2})\s+(\d{1,2})\s+\*\s+\*\s+([0-6])$/);if(R){const D=String(R[1]).padStart(2,"0"),V=String(R[2]).padStart(2,"0");return`weekly ${["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][Number.parseInt(R[3],10)]||R[3]} ${V}:${D}`}return`cron ${b}`.trim()}return a.type==="manual"?"manual":JSON.stringify(a)},A=a=>{const u=String(a?.args?.promptFilePath||"").trim();return u||String(a?.entrypoint||a?.prompt||"").match(/(control-panel\/routines\/[A-Za-z0-9._\-\/]+\.md)/)?.[1]||""},M=a=>{const u=a?.args?.model_policy?.default_model,m=String(u?.provider_id||"").trim(),b=String(u?.model_id||"").trim();return!m||!b?"":`${m}/${b}`},J=(a,u,m)=>{const b=a?.[u]??a?.[m]??[];if(!Array.isArray(b))return[];const S=new Set,R=[];for(const D of b){const V=String(D||"").trim();V&&(S.has(V)||(S.add(V),R.push(V)))}return R},T=(a,u,m,b)=>{const S=a?.[u];if(typeof S=="boolean")return S;const R=a?.[m];return typeof R=="boolean"?R:b},F=a=>{const u=new Set,m=[];return String(a||"").split(",").map(b=>b.trim()).filter(Boolean).forEach(b=>{u.has(b)||(u.add(b),m.push(b))}),m},B=a=>String(a?.id||a?.routine_id||a?.routineID||a?.routineId||"").trim(),W=a=>String(a?.id||a?.automation_id||a?.automationID||a?.automationId||"").trim(),Se=a=>String(a?.runId||a?.runID||a?.run_id||a?.id||"").trim(),Me=a=>String(a?.routineId||a?.routine_id||a?.routineID||a?.routineId||"").trim(),Xe=a=>String(a?.automationId||a?.automation_id||a?.automationID||a?.automationId||"").trim(),xe=a=>String(a?.status||"unknown").toLowerCase(),Ne=a=>String(a?.detail||a?.reason||"").trim(),_e=a=>{const u=[a?.updatedAtMs,a?.updated_at_ms,a?.finishedAtMs,a?.finished_at_ms,a?.startedAtMs,a?.started_at_ms,a?.createdAtMs,a?.created_at_ms,a?.firedAtMs,a?.fired_at_ms];for(const m of u){const b=Number(m);if(Number.isFinite(b)&&b>0)return b}return 0},Ye=a=>{const u=Number(a);return!Number.isFinite(u)||u<=0?"time n/a":new Date(u).toLocaleString()},lt=(a,u=120)=>{const m=String(a||"").trim();return m?m.length>u?`${m.slice(0,u-1)}...`:m:""},Ae=a=>{const u=String(a||"").toLowerCase();return u.includes("complete")||u.includes("succeed")?"tcp-badge-info":u.includes("fail")||u.includes("cancel")||u.includes("deny")?"tcp-badge-err":u.includes("block")||u.includes("approval")||u.includes("pause")?"tcp-badge-warn":"tcp-badge-info"},dt=a=>{const u=String(a||"").toLowerCase();return u==="pending_approval"||u.includes("awaiting_approval")},Ot=(a,u)=>{const m=new Map,b=[...a].sort((S,R)=>_e(R)-_e(S));for(const S of b){const R=u(S);!R||m.has(R)||m.set(R,S)}return m},Pt=new Map(f.map(a=>[B(a),String(a.name||B(a)||"Routine").trim()]).filter(([a])=>!!a)),Mt=new Map(f.map(a=>[B(a),a]).filter(([a])=>!!a)),ut=new Map(h.map(a=>[W(a),String(a.name||W(a)||"Automation").trim()]).filter(([a])=>!!a)),pt=Ot(_,Me),mt=Ot(Z,Xe),Nt=[..._.map(a=>({family:"routine",run:a})),...Z.map(a=>({family:"automation",run:a}))].sort((a,u)=>_e(u.run)-_e(a.run)),ft=[],Ie=new Set;for(const a of Nt){const u=Se(a.run),m=a.family==="routine"?Me(a.run):Xe(a.run),b=u||`${a.family}:${m}:${_e(a.run)}:${xe(a.run)}`;if(!Ie.has(b)&&(Ie.add(b),ft.push(a),ft.length>=30))break}const Le=new Set(h.map(a=>W(a)).filter(Boolean)),Lt=new Set(f.map(a=>B(a)).filter(Boolean)),fn=Le.size>0&&Le.size===Lt.size&&[...Le].every(a=>Lt.has(a)),Dt=Object.fromEntries(Object.entries(q).map(([a,u])=>[a,String(u?.default_model||u?.defaultModel||"").trim()])),De=N.map(a=>a.id).filter(Boolean),ce=a=>{const u=N.find(m=>m.id===a);return Object.keys(u?.models||{})},kt=String($?.default||v?.default||t.providerDefault||"").trim(),y=De.includes(kt)?kt:De[0]||"",z=String(Dt[y]||t.providerDefaultModel||"").trim(),C=ce(y),P=C.includes(z)?z:C[0]||"",L=N.map(a=>{const u=String(a.name||a.id||"").trim()||a.id;return`<option value="${s(a.id)}" ${a.id===y?"selected":""}>${s(u)}</option>`}).join("")||'<option value="">No providers found</option>',oe=C.map(a=>`<option value="${s(a)}" ${a===P?"selected":""}>${s(a)}</option>`).join("")||'<option value="">No models found</option>',be=H.map(a=>`<option value="${s(a)}"></option>`).join(""),Re=h.map(a=>{const u=W(a),m=mt.get(u),b=xe(m),S=Se(m),R=lt(Ne(m)),D=dt(b)&&!!S;return`<div class="tcp-list-item">
159
+ <div class="flex items-center justify-between gap-2">
160
+ <span>${s(String(a.name||u||"Automation"))}</span>
161
+ <div class="flex items-center gap-2">
162
+ <span class="tcp-subtle">${s(String(a.status||""))}</span>
163
+ ${u?`<button data-run-automation="${s(u)}" class="tcp-btn h-7 px-2 text-xs"><i data-lucide="play"></i> Run</button>`:""}
164
+ </div>
165
+ </div>
166
+ ${m?`<div class="mt-1 flex flex-wrap items-center gap-2 text-xs">
167
+ <span class="${Ae(b)}">${s(b)}</span>
168
+ <span class="tcp-subtle">${s(Ye(_e(m)))}</span>
169
+ <span class="tcp-subtle font-mono">${s(S||"run n/a")}</span>
170
+ </div>
171
+ ${D?`<div class="mt-1 flex flex-wrap items-center gap-2 text-xs">
172
+ <button data-run-review="approve" data-run-id="${s(S)}" data-run-family="automation" class="tcp-btn h-7 px-2 text-xs">Approve</button>
173
+ <button data-run-review="deny" data-run-id="${s(S)}" data-run-family="automation" class="tcp-btn-danger h-7 px-2 text-xs">Deny</button>
174
+ </div>`:""}
175
+ ${R?`<div class="mt-1 text-xs text-slate-400">${s(R)}</div>`:""}`:'<div class="mt-1 text-xs text-slate-500">No automation runs yet.</div>'}
176
+ </div>`}).join("")||'<p class="tcp-subtle">No automations.</p>',le=ft.map(({family:a,run:u})=>{const m=a==="routine",b=m?Me(u):Xe(u),S=Se(u),R=m?Pt.get(b)||b||"Routine":ut.get(b)||b||"Automation",D=xe(u),V=dt(D)&&!!S,se=lt(Ne(u),180);return`<div class="tcp-list-item">
177
+ <div class="flex items-center justify-between gap-2">
178
+ <span class="font-medium">${s(R)}</span>
179
+ <div class="flex items-center gap-2">
180
+ ${S?`<button data-inspect-run="${s(S)}" data-run-family="${s(a)}" class="tcp-btn h-7 px-2 text-xs">Details</button>`:""}
181
+ ${V?`<button data-run-review="approve" data-run-id="${s(S)}" data-run-family="${s(a)}" class="tcp-btn h-7 px-2 text-xs">Approve</button>
182
+ <button data-run-review="deny" data-run-id="${s(S)}" data-run-family="${s(a)}" class="tcp-btn-danger h-7 px-2 text-xs">Deny</button>`:""}
183
+ <span class="${Ae(D)}">${s(D)}</span>
184
+ </div>
185
+ </div>
186
+ <div class="mt-1 flex flex-wrap items-center gap-2 text-xs">
187
+ <span class="tcp-subtle">${m?"Routine":"Automation"}</span>
188
+ <span class="tcp-subtle">${s(Ye(_e(u)))}</span>
189
+ <span class="tcp-subtle font-mono">${s(S||"run n/a")}</span>
190
+ </div>
191
+ ${se?`<div class="mt-1 text-xs text-slate-400">${s(se)}</div>`:""}
192
+ </div>`}).join("")||'<p class="tcp-subtle">No runs yet.</p>';n("view").innerHTML=`
193
+ <div class="tcp-card">
194
+ <h3 class="tcp-title mb-3">Create Routine</h3>
195
+ <p id="routine-form-mode" class="mb-2 text-xs text-slate-400">Creating new routine</p>
196
+ <div class="grid gap-3 md:grid-cols-2">
197
+ <input id="routine-name" class="tcp-input" placeholder="Routine name" />
198
+ <select id="routine-schedule-mode" class="tcp-select">
199
+ <option value="interval">Every X minutes/hours</option>
200
+ <option value="daily">Daily at specific time</option>
201
+ <option value="weekly">Weekly on a specific day/time</option>
202
+ <option value="customCron">Custom cron</option>
203
+ <option value="manual">Manual only</option>
204
+ </select>
205
+ </div>
206
+ <div id="routine-interval-controls" class="mt-3 grid gap-3 md:grid-cols-2">
207
+ <input id="routine-interval-value" class="tcp-input" type="number" min="1" max="10000" step="1" value="30" />
208
+ <select id="routine-interval-unit" class="tcp-select">
209
+ <option value="minutes">Minutes</option>
210
+ <option value="hours">Hours</option>
211
+ </select>
212
+ </div>
213
+ <div id="routine-daily-controls" class="mt-3 grid hidden gap-3 md:grid-cols-2">
214
+ <input id="routine-time" class="tcp-input" type="time" value="09:00" />
215
+ <div class="tcp-subtle self-center text-xs">Runs once per day at selected time</div>
216
+ </div>
217
+ <div id="routine-weekly-controls" class="mt-3 grid hidden gap-3 md:grid-cols-2">
218
+ <select id="routine-weekday" class="tcp-select">
219
+ <option value="1">Monday</option>
220
+ <option value="2">Tuesday</option>
221
+ <option value="3">Wednesday</option>
222
+ <option value="4">Thursday</option>
223
+ <option value="5">Friday</option>
224
+ <option value="6">Saturday</option>
225
+ <option value="0">Sunday</option>
226
+ </select>
227
+ <input id="routine-weekly-time" class="tcp-input" type="time" value="09:00" />
228
+ </div>
229
+ <div id="routine-cron-controls" class="mt-3 grid hidden gap-3 md:grid-cols-1">
230
+ <input id="routine-cron" class="tcp-input hidden" placeholder="Cron e.g. 0 * * * *" />
231
+ </div>
232
+ <div class="mt-2 text-xs text-slate-400">
233
+ <span id="routine-schedule-preview" class="font-mono">Schedule: every 30m</span>
234
+ </div>
235
+ <div class="mt-3 grid gap-3 md:grid-cols-2">
236
+ <div>
237
+ <label class="mb-1 block text-sm text-slate-300">Routine Provider</label>
238
+ <select id="routine-model-provider" class="tcp-select" ${N.length?"":"disabled"}>
239
+ ${L}
240
+ </select>
241
+ </div>
242
+ <div>
243
+ <label class="mb-1 block text-sm text-slate-300">Routine Model</label>
244
+ <select id="routine-model-id" class="tcp-select" ${C.length?"":"disabled"}>
245
+ ${oe}
246
+ </select>
247
+ </div>
248
+ </div>
249
+ <div class="mt-1 text-xs text-slate-400">
250
+ Model route for this routine: <span id="routine-model-preview" class="font-mono">${s(y&&P?`${y}/${P}`:"default engine route")}</span>
251
+ </div>
252
+ <div class="mt-3 rounded-xl border border-slate-700/70 bg-slate-900/35 p-3">
253
+ <label class="mb-2 inline-flex items-center gap-2 text-xs text-slate-200">
254
+ <input id="routine-allow-everything" type="checkbox" class="h-4 w-4 accent-slate-400" />
255
+ Allow everything (no approval, all tools, external integrations)
256
+ </label>
257
+ <label class="mb-1 block text-sm text-slate-300">Tool Allowlist (optional)</label>
258
+ <input
259
+ id="routine-allowed-tools"
260
+ list="routine-tool-options"
261
+ class="tcp-input font-mono text-xs"
262
+ placeholder="Comma-separated tool IDs (leave empty to allow all tools by policy)"
263
+ />
264
+ <datalist id="routine-tool-options">${be}</datalist>
265
+ <div id="routine-tool-scope-preview" class="mt-1 text-xs text-slate-400">Tool scope: all tools allowed by policy</div>
266
+ <div class="mt-2 grid gap-2 md:grid-cols-2">
267
+ <label class="inline-flex items-center gap-2 text-xs text-slate-300">
268
+ <input id="routine-requires-approval" type="checkbox" class="h-4 w-4 accent-slate-400" checked />
269
+ Require approval for external side effects
270
+ </label>
271
+ <label class="inline-flex items-center gap-2 text-xs text-slate-300">
272
+ <input id="routine-external-integrations" type="checkbox" class="h-4 w-4 accent-slate-400" />
273
+ Allow external integrations (MCP/connectors)
274
+ </label>
275
+ </div>
276
+ </div>
277
+ <div class="mt-4 rounded-xl border border-slate-700/70 bg-slate-900/35 p-3">
278
+ <div class="mb-2 flex items-center justify-between gap-2">
279
+ <label class="inline-flex items-center gap-2 text-sm text-slate-200">
280
+ <input id="routine-use-file" type="checkbox" class="h-4 w-4 accent-slate-400" checked />
281
+ Save prompt as Markdown file (recommended)
282
+ </label>
283
+ <button id="save-routine-file" class="tcp-btn"><i data-lucide="save"></i> Save Prompt File</button>
284
+ </div>
285
+ <input id="routine-file-path" class="tcp-input mb-3 font-mono text-xs" value="control-panel/routines/new-routine.md" />
286
+ <textarea id="routine-prompt" class="tcp-input" rows="6" placeholder="Write your routine instructions in Markdown..."></textarea>
287
+ <div class="mt-2 text-xs text-slate-400">
288
+ Tip: keep goals, constraints, and output format in this file so you can improve it anytime without rewriting the routine.
289
+ </div>
290
+ </div>
291
+ <div class="mt-3 grid gap-2 md:grid-cols-[1fr_auto]">
292
+ <div class="text-xs text-slate-400">Create will use the selected schedule and entry prompt.</div>
293
+ <div class="flex items-center justify-end gap-2">
294
+ <button id="cancel-edit-routine" class="tcp-btn hidden">Cancel Edit</button>
295
+ <button id="create-routine" class="tcp-btn-primary"><i data-lucide="plus"></i> Create</button>
296
+ </div>
297
+ </div>
298
+ </div>
299
+ <div class="tcp-card">
300
+ <h3 class="tcp-title mb-3">Routines (${f.length})</h3>
301
+ <div id="routine-list" class="tcp-list"></div>
302
+ </div>
303
+ <div class="tcp-card">
304
+ <h3 class="tcp-title mb-3">Automations (${h.length})</h3>
305
+ ${fn?'<p class="tcp-subtle mb-2">Automation endpoints currently mirror routine records in this workspace.</p>':""}
306
+ <div class="tcp-list">${Re}</div>
307
+ </div>
308
+ <div class="tcp-card">
309
+ <div class="mb-3 flex items-center justify-between gap-2">
310
+ <h3 class="tcp-title">Recent Runs (${ft.length})</h3>
311
+ <button id="refresh-runs" class="tcp-btn"><i data-lucide="refresh-cw"></i> Refresh</button>
312
+ </div>
313
+ <div class="tcp-list">${le}</div>
314
+ </div>
315
+ <div class="tcp-card">
316
+ <h3 class="tcp-title mb-2">Run Inspector</h3>
317
+ <div id="run-inspector" class="tcp-list">
318
+ <p class="tcp-subtle">Pick any recent run and click Details to inspect status, full detail, and artifacts.</p>
319
+ </div>
320
+ </div>
321
+ `;const X=n("routine-list");X.innerHTML=f.map(a=>{const u=B(a),m=pt.get(u),b=xe(m),S=Se(m),R=lt(Ne(m)),D=M(a),V=String(a.status||"active").toLowerCase(),se=J(a,"allowed_tools","allowedTools"),ze=T(a,"requires_approval","requiresApproval",!0),Fe=T(a,"external_integrations_allowed","externalIntegrationsAllowed",!1),ke=V==="paused",ot=dt(b)&&!!S;return`
322
+ <div class="tcp-list-item flex items-center justify-between gap-3">
323
+ <div>
324
+ <div class="font-medium">${s(a.name||u||"Unnamed routine")}</div>
325
+ <div class="mt-1 flex items-center gap-2">
326
+ <span class="${ke?"tcp-badge-warn":"tcp-badge-info"}">${s(V)}</span>
327
+ <span class="tcp-subtle font-mono">${s(j(a.schedule))}</span>
328
+ </div>
329
+ <div class="mt-1 text-xs text-slate-400 font-mono">${s(D||"default engine route")}</div>
330
+ <div class="mt-1 text-xs text-slate-400">
331
+ tools: ${s(se.length?se.join(", "):"all (no explicit allowlist)")}
332
+ </div>
333
+ <div class="mt-1 flex flex-wrap items-center gap-2 text-xs">
334
+ <span class="${ze?"tcp-badge-warn":"tcp-badge-info"}">${ze?"approval required":"no approval gate"}</span>
335
+ <span class="${Fe?"tcp-badge-info":"tcp-badge-warn"}">${Fe?"external integrations allowed":"external integrations blocked"}</span>
336
+ </div>
337
+ ${m?`<div class="mt-1 flex flex-wrap items-center gap-2 text-xs">
338
+ <span class="${Ae(b)}">${s(b)}</span>
339
+ <span class="tcp-subtle">${s(Ye(_e(m)))}</span>
340
+ <span class="tcp-subtle font-mono">${s(S||"run n/a")}</span>
341
+ </div>
342
+ ${R?`<div class="mt-1 text-xs text-slate-400">${s(R)}</div>`:""}`:'<div class="mt-1 text-xs text-slate-500">No runs yet.</div>'}
343
+ ${A(a)?`<div class="mt-1 text-xs text-slate-400 font-mono">${s(A(a))}</div>`:""}
344
+ </div>
345
+ <div class="flex gap-2">
346
+ <button data-run="${s(u)}" class="tcp-btn"><i data-lucide="play"></i> Run</button>
347
+ ${ot?`<button data-run-review="approve" data-run-id="${s(S)}" data-run-family="routine" class="tcp-btn">Approve</button>
348
+ <button data-run-review="deny" data-run-id="${s(S)}" data-run-family="routine" class="tcp-btn-danger">Deny</button>`:""}
349
+ <button data-toggle-status="${s(u)}" data-next-status="${ke?"active":"paused"}" class="tcp-btn">
350
+ <i data-lucide="${ke?"play-circle":"pause-circle"}"></i> ${ke?"Resume":"Pause"}
351
+ </button>
352
+ <button data-edit-routine="${s(u)}" class="tcp-btn"><i data-lucide="pencil"></i> Edit</button>
353
+ ${A(a)?`<button data-edit-file="${s(A(a))}" class="tcp-btn"><i data-lucide="folder-open"></i> Prompt File</button>`:""}
354
+ <button data-del="${s(u)}" class="tcp-btn-danger"><i data-lucide="trash-2"></i></button>
355
+ </div>
356
+ </div>`}).join("")||'<p class="tcp-subtle">No routines.</p>',o(X),n("refresh-runs").addEventListener("click",()=>{Pe(e)});const je=n("run-inspector"),ht=async(a,u,m)=>{const b=String(u||"").toLowerCase()==="automation",S=String(m||"").toLowerCase()==="deny"?"deny":"approve";if(!a)throw new Error("Run ID is missing.");if(S==="approve"){b?await t.client.automations.approveRun(a,"approved from control panel"):await t.client.routines.approveRun(a,"approved from control panel");return}b?await t.client.automations.denyRun(a,"denied from control panel"):await t.client.routines.denyRun(a,"denied from control panel")},Qe=a=>{a.querySelectorAll("[data-run-review]").forEach(u=>{u.dataset.wired!=="1"&&(u.dataset.wired="1",u.addEventListener("click",async()=>{const m=String(u.dataset.runId||"").trim(),b=String(u.dataset.runFamily||"routine").trim().toLowerCase(),S=String(u.dataset.runReview||"approve").trim().toLowerCase();if(!m){r("err","Run ID is missing.");return}const R=[...n("view").querySelectorAll("[data-run-review]")].filter(V=>String(V.dataset.runId||"").trim()===m&&String(V.dataset.runFamily||"routine").trim().toLowerCase()===b),D=new Map;for(const V of R)D.set(V,V.innerHTML),V.disabled=!0,V.innerHTML='<i data-lucide="refresh-cw" class="animate-spin"></i>',o(V);try{await ht(m,b,S),r("ok",`${S==="deny"?"Denied":"Approved"} ${b} run ${m}.`),setTimeout(()=>{Pe(e)},250)}catch(V){r("err",V instanceof Error?V.message:String(V));for(const se of R)se.isConnected&&(se.disabled=!1,se.innerHTML=D.get(se)||se.innerHTML,o(se))}}))})};Qe(n("view")),n("view").querySelectorAll("[data-inspect-run]").forEach(a=>a.addEventListener("click",async()=>{const u=String(a.dataset.inspectRun||"").trim(),m=String(a.dataset.runFamily||"routine").trim();if(!u){r("err","Run ID is missing.");return}const b=a.innerHTML;a.disabled=!0,a.innerHTML='<i data-lucide="refresh-cw" class="animate-spin"></i> Loading',o(a);try{let S=await t.client.routines.getRun(u).catch(()=>null),R=await t.client.routines.listArtifacts(u).catch(()=>null);if(!S&&m==="automation"&&(S=await t.client.automations.getRun(u).catch(()=>null),R=await t.client.automations.listArtifacts(u).catch(()=>null)),!S)throw new Error("Run details not found.");const D=Array.isArray(R?.artifacts)?R.artifacts:[],V=J(S,"allowed_tools","allowedTools"),se=xe(S),ze=T(S,"requires_approval","requiresApproval",!0),Fe=T(S,"external_integrations_allowed","externalIntegrationsAllowed",!1);je.innerHTML=`
357
+ <div class="tcp-list-item">
358
+ <div class="mb-2 flex flex-wrap items-center gap-2">
359
+ <span class="${Ae(se)}">${s(se)}</span>
360
+ <span class="tcp-subtle font-mono">${s(u)}</span>
361
+ <span class="tcp-subtle">${s(Ye(_e(S)))}</span>
362
+ </div>
363
+ <div class="mb-2 text-xs text-slate-300">
364
+ ${s(V.length?`Allowlist (${V.length}): ${V.join(", ")}`:"No explicit allowlist: all tools are available subject to policy.")}
365
+ </div>
366
+ <div class="mb-2 flex flex-wrap items-center gap-2 text-xs">
367
+ <span class="${ze?"tcp-badge-warn":"tcp-badge-info"}">${ze?"approval required":"no approval gate"}</span>
368
+ <span class="${Fe?"tcp-badge-info":"tcp-badge-warn"}">${Fe?"external integrations allowed":"external integrations blocked"}</span>
369
+ </div>
370
+ ${dt(se)?`<div class="mb-2 flex flex-wrap items-center gap-2 text-xs">
371
+ <button data-run-review="approve" data-run-id="${s(u)}" data-run-family="${s(m)}" class="tcp-btn h-7 px-2 text-xs">Approve</button>
372
+ <button data-run-review="deny" data-run-id="${s(u)}" data-run-family="${s(m)}" class="tcp-btn-danger h-7 px-2 text-xs">Deny</button>
373
+ </div>`:""}
374
+ <div class="mb-2 text-xs text-slate-300">${s(Ne(S)||"No detail text available.")}</div>
375
+ <div class="mb-2 text-xs text-slate-400">Artifacts: ${D.length}</div>
376
+ ${D.length?`<div class="mb-2 grid gap-1">${D.map(ke=>{const ot=String(ke?.uri||"").trim(),Je=String(ke?.kind||"artifact"),He=String(ke?.label||Je).trim();return`<div class="text-xs text-slate-300"><span class="tcp-subtle">${s(Je)}</span> <span class="font-mono">${s(He)}</span> ${ot?`<span class="tcp-subtle">${s(ot)}</span>`:""}</div>`}).join("")}</div>`:""}
377
+ <details class="mt-2">
378
+ <summary class="cursor-pointer text-xs text-slate-400">Raw run payload</summary>
379
+ <pre class="tcp-code mt-2">${s(JSON.stringify(S,null,2))}</pre>
380
+ </details>
381
+ </div>
382
+ `,Qe(je),o(je)}catch(S){r("err",S instanceof Error?S.message:String(S))}finally{a.isConnected&&(a.disabled=!1,a.innerHTML=b,o(a))}})),n("view").querySelectorAll("[data-run-automation]").forEach(a=>a.addEventListener("click",async()=>{const u=String(a.dataset.runAutomation||"").trim();if(!u){r("err","Automation ID is missing. Refresh and try again.");return}const m=a.innerHTML;a.disabled=!0,a.innerHTML='<i data-lucide="refresh-cw" class="animate-spin"></i> Running...',o(a);try{const b=await t.client.automations.runNow(u),S=String(b?.runId||"").trim(),R=String(b?.status||"").trim(),D=[];S&&D.push(`run ${S}`),R&&D.push(`status ${R}`),r("ok",D.length?`Automation triggered (${D.join(", ")}). It should move from queued to running within ~1 second.`:"Automation triggered."),setTimeout(()=>{Pe(e)},500)}catch(b){r("err",b instanceof Error?b.message:String(b))}finally{a.isConnected&&(a.disabled=!1,a.innerHTML=m,o(a))}})),X.querySelectorAll("[data-toggle-status]").forEach(a=>a.addEventListener("click",async()=>{const u=String(a.dataset.toggleStatus||"").trim(),m=String(a.dataset.nextStatus||"").trim();if(!u||!m){r("err","Routine status action is missing details. Refresh and try again.");return}const b=a.innerHTML;a.disabled=!0,a.innerHTML='<i data-lucide="refresh-cw" class="animate-spin"></i> Saving...',o(a);try{await t.client.routines.update(u,{status:m}),r("ok",`Routine ${m==="paused"?"paused":"resumed"}.`),Pe(e)}catch(S){r("err",S instanceof Error?S.message:String(S)),a.isConnected&&(a.disabled=!1,a.innerHTML=b,o(a))}})),X.querySelectorAll("[data-run]").forEach(a=>a.addEventListener("click",async()=>{const u=String(a.dataset.run||"").trim();if(!u){r("err","Routine ID is missing. Refresh and try again.");return}const m=a.innerHTML;a.disabled=!0,a.innerHTML='<i data-lucide="refresh-cw" class="animate-spin"></i> Running...',o(a);try{const b=await t.client.routines.runNow(u),S=String(b?.runId||"").trim(),R=String(b?.status||"").trim(),D=[];S&&D.push(`run ${S}`),R&&D.push(`status ${R}`),r("ok",D.length?`Routine triggered (${D.join(", ")}). It should move from queued to running within ~1 second.`:"Routine triggered."),setTimeout(()=>{Pe(e)},500)}catch(b){r("err",b instanceof Error?b.message:String(b))}finally{a.isConnected&&(a.disabled=!1,a.innerHTML=m,o(a))}})),X.querySelectorAll("[data-del]").forEach(a=>a.addEventListener("click",async()=>{const u=String(a.dataset.del||"").trim();if(!u){r("err","Routine ID is missing. Refresh and try again.");return}try{await t.client.routines.delete(u),r("ok","Routine deleted."),Pe(e)}catch(m){r("err",m instanceof Error?m.message:String(m))}})),X.querySelectorAll("[data-edit-file]").forEach(a=>a.addEventListener("click",async()=>{const u=String(a.dataset.editFile||"").trim();if(u)try{const m=await i(`/api/files/read?path=${encodeURIComponent(u)}`);n("routine-use-file").checked=!0,n("routine-file-path").value=u,n("routine-prompt").value=String(m?.text||""),r("ok",`Loaded prompt file: ${u}`)}catch(m){r("err",m instanceof Error?m.message:String(m))}})),X.querySelectorAll("[data-edit-routine]").forEach(a=>a.addEventListener("click",async()=>{const u=String(a.dataset.editRoutine||"").trim();if(!u){r("err","Routine ID is missing.");return}const m=Mt.get(u);if(!m){r("err","Routine details not found. Refresh and try again.");return}nt.value=String(m.name||"").trim(),ms(m.schedule);const b=A(m);if(b){vt.checked=!0,Ue.value=b;try{const R=await i(`/api/files/read?path=${encodeURIComponent(b)}`);rt.value=String(R?.text||"")}catch{rt.value=String(m.entrypoint||""),r("err",`Could not read ${b}; loaded entrypoint text instead.`)}}else vt.checked=!1,rt.value=String(m.entrypoint||m.prompt||""),Ft();re.value=J(m,"allowed_tools","allowedTools").join(", "),me.checked=T(m,"requires_approval","requiresApproval",!0),fe.checked=T(m,"external_integrations_allowed","externalIntegrationsAllowed",!1);const S=ps(F(re.value||""),!!me.checked,!!fe.checked);gn(S,{restore:!1}),Ht(),fs(m),hs(u,String(m.name||"")),nt.focus()})),o(n("view"));const pe=n("routine-schedule-mode"),et=n("routine-interval-controls"),gt=n("routine-daily-controls"),jt=n("routine-weekly-controls"),hn=n("routine-cron-controls"),tt=n("routine-interval-value"),Ee=n("routine-interval-unit"),Ze=n("routine-time"),Te=n("routine-weekday"),qe=n("routine-weekly-time"),Ce=n("routine-cron"),Zt=n("routine-schedule-preview"),nt=n("routine-name"),vt=n("routine-use-file"),rt=n("routine-prompt"),Ue=n("routine-file-path"),I=n("routine-model-provider"),U=n("routine-model-id"),K=n("routine-model-preview"),Y=n("routine-allow-everything"),re=n("routine-allowed-tools"),st=n("routine-tool-scope-preview"),me=n("routine-requires-approval"),fe=n("routine-external-integrations"),qt=n("routine-form-mode"),xt=n("cancel-edit-routine"),Ut=n("create-routine");let It="";const Ft=()=>{const a=`control-panel/routines/${x(nt.value||"new-routine")}.md`,m=String(Ue.value||"").trim().replace(/\\/g,"/").replace(/^\/+/,"")||a,b=m==="control-panel"||m.startsWith("control-panel/")?m:`control-panel/${m}`;Ue.value=b.endsWith(".md")?b:`${b}.md`},us=a=>{const u=ce(a);if(!u.length)return"";const m=String(Dt[a]||"").trim();return m&&u.includes(m)?m:u[0]},Jt=()=>{const a=String(I?.value||"").trim(),u=ce(a);if(!U)return;if(U.innerHTML=u.map(S=>`<option value="${s(S)}">${s(S)}</option>`).join("")||'<option value="">No models found</option>',!u.length){U.disabled=!0,K&&(K.textContent="default engine route");return}U.disabled=!1;const m=us(a);m&&(U.value=m);const b=String(U.value||"").trim();K&&(K.textContent=a&&b?`${a}/${b}`:"default engine route")},Ht=()=>{const a=F(re?.value||"");if(st){if(Y?.checked){st.textContent="Tool scope: unrestricted (all tools + external integrations, no approval gate)";return}st.textContent=a.length?`Tool scope: allowlist (${a.length})`:"Tool scope: all tools allowed by policy"}},ps=(a,u,m)=>!u&&m&&a.length===0,gn=(a,{restore:u=!0}={})=>{Y&&(Y.checked=!!a,a?(Y.dataset.prevTools=String(re?.value||""),Y.dataset.prevRequiresApproval=me?.checked?"1":"0",Y.dataset.prevExternalIntegrations=fe?.checked?"1":"0",re&&(re.value="",re.disabled=!0),me&&(me.checked=!1,me.disabled=!0),fe&&(fe.checked=!0,fe.disabled=!0)):(re&&(re.disabled=!1),me&&(me.disabled=!1),fe&&(fe.disabled=!1),u&&(re&&(re.value=String(Y.dataset.prevTools||"")),me&&(me.checked=String(Y.dataset.prevRequiresApproval||"1")==="1"),fe&&(fe.checked=String(Y.dataset.prevExternalIntegrations||"0")==="1"))),Ht())},ms=a=>{const u=Number(a?.interval_seconds?.seconds??a?.intervalSeconds?.seconds??a?.intervalSeconds??0),m=String(a?.cron?.expression??a?.cron?.cron??a?.expression??a?.cron??"").trim();if(u>0){u%3600===0?(pe.value="interval",Ee.value="hours",tt.value=String(Math.max(1,Math.floor(u/3600)))):(pe.value="interval",Ee.value="minutes",tt.value=String(Math.max(1,Math.floor(u/60)))),ve();return}if(!m){pe.value="manual",ve();return}const b=m.match(/^(\d{1,2})\s+(\d{1,2})\s+\*\s+\*\s+\*$/);if(b){pe.value="daily";const R=String(Number.parseInt(b[1],10)).padStart(2,"0"),D=String(Number.parseInt(b[2],10)).padStart(2,"0");Ze.value=`${D}:${R}`,ve();return}const S=m.match(/^(\d{1,2})\s+(\d{1,2})\s+\*\s+\*\s+([0-6])$/);if(S){pe.value="weekly";const R=String(Number.parseInt(S[1],10)).padStart(2,"0"),D=String(Number.parseInt(S[2],10)).padStart(2,"0");Te.value=String(Number.parseInt(S[3],10)),qe.value=`${D}:${R}`,ve();return}pe.value="customCron",Ce.value=m,ve()},fs=a=>{const u=String(a?.args?.model_policy?.default_model?.provider_id||"").trim(),m=String(a?.args?.model_policy?.default_model?.model_id||"").trim();if(!u||!De.includes(u)){Jt();return}I.value=u,Jt();const b=ce(u);m&&b.includes(m)&&(U.value=m,K&&(K.textContent=`${u}/${m}`))},hs=(a,u="")=>{It=a,qt&&(qt.textContent=`Editing routine ${u||a}`),Ut&&(Ut.innerHTML='<i data-lucide="save"></i> Save Changes'),xt&&xt.classList.remove("hidden"),o(n("view"))},gs=()=>{It="",qt&&(qt.textContent="Creating new routine"),Ut&&(Ut.innerHTML='<i data-lucide="plus"></i> Create'),xt&&xt.classList.add("hidden"),o(n("view"))},Dn=()=>{const a=String(pe.value||"interval");if(a==="interval"){const m=Number.parseInt(String(tt.value||"30"),10),b=Number.isFinite(m)?m:30;if(b<=0)throw new Error("Interval must be at least 1.");const R=String(Ee.value||"minutes")==="hours"?3600:60;return{interval_seconds:{seconds:b*R}}}if(a==="manual")return{interval_seconds:{seconds:24*3600}};if(a==="daily"){const[m,b]=String(Ze.value||"09:00").split(":").map(D=>Number.parseInt(D,10)),S=Number.isFinite(m)?Math.min(23,Math.max(0,m)):9;return{cron:{expression:`${Number.isFinite(b)?Math.min(59,Math.max(0,b)):0} ${S} * * *`}}}if(a==="weekly"){const[m,b]=String(qe.value||"09:00").split(":").map(se=>Number.parseInt(se,10)),S=Number.isFinite(m)?Math.min(23,Math.max(0,m)):9,R=Number.isFinite(b)?Math.min(59,Math.max(0,b)):0,D=Number.parseInt(String(Te.value||"1"),10),V=Number.isFinite(D)?Math.min(6,Math.max(0,D)):1;return{cron:{expression:`${R} ${S} * * ${V}`}}}const u=String(Ce.value||"").trim();if(!u)throw new Error("Custom cron is required.");return{cron:{expression:u}}},vs=()=>{const a=String(pe.value||"interval");if(a==="interval"){const m=Number.parseInt(String(tt.value||"30"),10),b=String(Ee.value||"minutes");return`every ${Number.isFinite(m)&&m>0?m:30}${b==="hours"?"h":"m"}`}if(a==="daily")return`daily at ${String(Ze.value||"09:00")}`;if(a==="weekly"){const m={0:"Sunday",1:"Monday",2:"Tuesday",3:"Wednesday",4:"Thursday",5:"Friday",6:"Saturday"},b=Number.parseInt(String(Te.value||"1"),10);return`weekly on ${m[b]||"Monday"} at ${String(qe.value||"09:00")}`}if(a==="manual")return"manual";const u=String(Ce.value||"").trim();return u?`cron ${u}`:"custom cron (required)"},ve=()=>{const a=String(pe.value||"interval"),u=a==="interval",m=a==="daily",b=a==="weekly",S=a==="customCron";et.classList.toggle("hidden",!u),gt.classList.toggle("hidden",!m),jt.classList.toggle("hidden",!b),hn.classList.toggle("hidden",!S),Ce.classList.toggle("hidden",!S);try{const R=Dn();Zt.textContent=`Schedule: ${vs()} (${j(R)})`}catch(R){Zt.textContent=`Schedule: ${R instanceof Error?R.message:String(R)}`}},jn=async()=>{Ft();const a=String(Ue.value||"").trim(),u=String(rt.value||"");if(!a||!u.trim())throw new Error("Prompt file path and content are required.");return await i("/api/files/write",{method:"POST",body:JSON.stringify({path:a,text:u,overwrite:!0})}),a};n("save-routine-file").addEventListener("click",async()=>{try{const a=await jn();r("ok",`Saved ${a}`)}catch(a){r("err",a instanceof Error?a.message:String(a))}}),nt.addEventListener("input",()=>{const a=String(Ue.value||"").trim();(!a||/new-routine\.md$/i.test(a))&&Ft()}),pe.addEventListener("change",ve),tt.addEventListener("input",ve),Ee.addEventListener("change",ve),Ze.addEventListener("input",ve),Te.addEventListener("change",ve),qe.addEventListener("input",ve),Ce.addEventListener("input",ve),I?.addEventListener("change",()=>{Jt()}),U?.addEventListener("change",()=>{const a=String(I?.value||"").trim(),u=String(U?.value||"").trim();K&&(K.textContent=a&&u?`${a}/${u}`:"default engine route")}),Y?.addEventListener("change",()=>{gn(!!Y.checked,{restore:!0})}),re?.addEventListener("input",Ht),xt?.addEventListener("click",()=>{Pe(e)}),ve(),Ft(),Jt(),gn(!!Y?.checked,{restore:!1}),Ht(),gs(),n("create-routine").addEventListener("click",async()=>{try{const a=String(nt.value||"").trim(),u=String(rt.value||"").trim();if(!a||!u)throw new Error("Name and prompt are required.");const m=Dn(),b=String(pe.value||"")==="manual";let S=u,R="";vt.checked&&(R=await jn(),S=[`Use the routine prompt markdown at: ${R}`,"Read the file first, then execute its instructions exactly."].join(`
383
+ `));const D={};R&&(D.promptFilePath=R);const V=String(I?.value||"").trim(),se=String(U?.value||"").trim();V&&se&&(D.model_policy={default_model:{provider_id:V,model_id:se}});const ze=!!Y?.checked,Fe=ze?[]:F(re?.value||""),ke=ze?!1:!!me?.checked,ot=ze?!0:!!fe?.checked;if(It){const Je=Mt.get(It),He={name:a,entrypoint:S,schedule:m,args:D,allowed_tools:Fe,requires_approval:ke,external_integrations_allowed:ot};b?He.status="paused":Je?.status&&(He.status=String(Je.status).toLowerCase()),await t.client.routines.update(It,He),r("ok","Routine updated.")}else{const Je=await t.client.routines.create({name:a,entrypoint:S,schedule:m,args:D,allowed_tools:Fe,requires_approval:ke,external_integrations_allowed:ot});if(b){const He=B(Je?.routine||Je||{});He&&await t.client.routines.update(He,{status:"paused"})}r("ok","Routine created.")}Pe(e)}catch(a){r("err",a instanceof Error?a.message:String(a))}})}async function xn(e){const{state:t,byId:n,toast:r,escapeHtml:s,api:i}=e,[o,c]=await Promise.all([t.client.channels.status().catch(()=>({})),t.client.channels.config().catch(()=>({}))]),d=["telegram","discord","slack"],l=(f,h,_,Z=void 0)=>!f||typeof f!="object"?Z:f[h]!==void 0?f[h]:f[_]!==void 0?f[_]:Z,p=f=>Array.isArray(f)&&f.length?f.join(", "):"*",v=!!l(c.discord||{},"has_token","hasToken",!1);n("view").innerHTML=`
384
+ <div class="tcp-card">
385
+ <div class="mb-3 flex items-center justify-between">
386
+ <h3 class="tcp-title">Channels</h3>
387
+ <i data-lucide="messages-square"></i>
388
+ </div>
389
+ ${v?"":`<div class="mb-3 rounded-lg border border-amber-500/30 bg-amber-500/10 p-3 text-sm text-amber-100">
390
+ <div class="font-semibold">Discord Quick Setup</div>
391
+ <div class="mt-1">1) Create bot and copy token. 2) Enable Message Content Intent. 3) Invite bot with channel send/read permissions. 4) Save then click Verify Discord.</div>
392
+ </div>`}
393
+ <div id="channels-list" class="tcp-list"></div>
394
+ </div>
395
+ `;const $=n("channels-list");$.innerHTML=d.map(f=>{const h=o[f]||{},_=l(h,"last_error","lastError","");return`
396
+ <div class="tcp-list-item">
397
+ <div class="mb-3 flex items-center justify-between">
398
+ <strong class="capitalize">${f}</strong>
399
+ <span class="${h.connected?"tcp-badge-ok":"tcp-badge-warn"}">${h.connected?"connected":"not connected"}</span>
400
+ </div>
401
+ <div class="grid gap-3 lg:grid-cols-4">
402
+ <input id="${f}-token" class="tcp-input" placeholder="bot token" />
403
+ <input id="${f}-users" class="tcp-input" placeholder="allowed users (comma, * for all)" />
404
+ ${f==="discord"?`<input id="${f}-guild" class="tcp-input" placeholder="guild id (optional)" />`:f==="slack"?`<input id="${f}-channel" class="tcp-input" placeholder="channel id (required for slack)" />`:`<select id="${f}-style" class="tcp-select">
405
+ <option value="default">style: default</option>
406
+ <option value="compact">style: compact</option>
407
+ <option value="friendly">style: friendly</option>
408
+ <option value="ops">style: ops</option>
409
+ </select>`}
410
+ <div class="flex gap-2">
411
+ <button class="tcp-btn-primary" data-save="${f}"><i data-lucide="save"></i> Save</button>
412
+ ${f==="discord"?`<button class="tcp-btn" data-verify="${f}">Verify Discord</button>`:""}
413
+ <button class="tcp-btn-danger" data-del="${f}"><i data-lucide="trash-2"></i></button>
414
+ </div>
415
+ </div>
416
+ <div class="mt-2 flex flex-wrap items-center gap-3 text-xs text-slate-400">
417
+ ${f==="telegram"||f==="discord"?`<label class="inline-flex items-center gap-2"><input id="${f}-mention" type="checkbox" /> mention only</label>`:""}
418
+ ${f==="discord"?"<span>Tip: use <code>@bot /help</code> style commands (Discord app slash commands are not registered).</span>":""}
419
+ </div>
420
+ ${f==="discord"?`<div id="${f}-verify-result" class="mt-2 text-xs text-slate-300"></div>`:""}
421
+ ${_?`<div class="mt-2 text-xs text-rose-300">last error: ${s(String(_))}</div>`:""}
422
+ </div>
423
+ `}).join(""),d.forEach(f=>{const h=c[f]||{},_=l(h,"allowed_users","allowedUsers",["*"]),Z=!!l(h,"mention_only","mentionOnly",f==="discord"),N=l(h,"guild_id","guildId",""),q=l(h,"channel_id","channelId",""),H=String(l(h,"style_profile","styleProfile","default")||"default"),x=!!l(h,"has_token","hasToken",!1),j=n(`${f}-token`);j&&x&&(j.placeholder="token configured (leave blank to keep)");const A=n(`${f}-users`);A&&(A.value=p(_));const M=n(`${f}-mention`);M&&(M.checked=Z);const J=n(`${f}-guild`);J&&(J.value=N||"");const T=n(`${f}-channel`);T&&(T.value=q||"");const F=n(`${f}-style`);F&&(F.value=H)});const w=f=>{const h=n(`${f}-token`).value.trim(),_=n(`${f}-users`).value.trim(),Z={bot_token:h,allowed_users:_?_.split(",").map(N=>N.trim()).filter(Boolean):["*"]};return(f==="telegram"||f==="discord")&&(Z.mention_only=!!n(`${f}-mention`)?.checked),f==="telegram"&&(Z.style_profile=String(n(`${f}-style`)?.value||"default")),f==="discord"&&(Z.guild_id=n(`${f}-guild`)?.value?.trim()||null),f==="slack"&&(Z.channel_id=n(`${f}-channel`)?.value?.trim()||null),Z};$.querySelectorAll("[data-save]").forEach(f=>f.addEventListener("click",async()=>{const h=f.dataset.save,_=w(h);try{await t.client.channels.put(h,_),r("ok",`${h} saved.`),xn(e)}catch(Z){r("err",Z instanceof Error?Z.message:String(Z))}})),$.querySelectorAll("[data-verify]").forEach(f=>f.addEventListener("click",async()=>{const h=f.dataset.verify,_=n(`${h}-verify-result`);_&&(_.className="mt-2 text-xs text-slate-300",_.textContent="Verifying Discord configuration...");try{const Z=await i(`/api/engine/channels/${encodeURIComponent(h)}/verify`,{method:"POST",body:JSON.stringify(w(h))}),N=l(Z,"checks","checks",{}),q=l(Z,"hints","hints",[]),H=!!l(Z,"ok","ok",!1),x=!!l(N,"token_auth_ok","tokenAuthOk",!1),j=!!l(N,"gateway_ok","gatewayOk",!1),A=!!l(N,"message_content_intent_ok","messageContentIntentOk",!1),M=Array.isArray(q)&&q.length>0?String(q[0]):"",J=H?"Verification passed: token/auth, gateway, and Message Content intent are OK.":`Verification failed: token=${x?"ok":"fail"}, gateway=${j?"ok":"fail"}, message_intent=${A?"ok":"fail"}. ${M}`;_&&(_.className=`mt-2 text-xs ${H?"text-emerald-300":"text-amber-200"}`,_.innerHTML=s(J)),r(H?"ok":"warn",H?"Discord verify passed.":"Discord verify failed.")}catch(Z){const N=Z instanceof Error?Z.message:String(Z);_&&(_.className="mt-2 text-xs text-rose-300",_.textContent=`Verify request failed: ${N}`),r("err",N)}})),$.querySelectorAll("[data-del]").forEach(f=>f.addEventListener("click",async()=>{const h=f.dataset.del;try{await t.client.channels.delete(h),r("ok",`${h} deleted.`),xn(e)}catch(_){r("err",_ instanceof Error?_.message:String(_))}}))}async function In(e){const{state:t,byId:n,toast:r,escapeHtml:s}=e,[i,o]=await Promise.all([t.client.mcp.list().catch(()=>({})),t.client.mcp.listTools().catch(()=>[])]);n("view").innerHTML=`
424
+ <div class="grid gap-4 xl:grid-cols-[420px_1fr]">
425
+ <div class="tcp-card">
426
+ <h3 class="tcp-title mb-3">Add MCP Server</h3>
427
+ <div class="grid gap-3">
428
+ <input id="mcp-name" class="tcp-input" placeholder="name" value="arcade" />
429
+ <input id="mcp-transport" class="tcp-input" placeholder="https://.../mcp or stdio:..." />
430
+ <button id="mcp-add" class="tcp-btn-primary"><i data-lucide="link"></i> Add + Connect</button>
431
+ </div>
432
+ </div>
433
+ <div class="grid gap-4">
434
+ <div class="tcp-card">
435
+ <h3 class="tcp-title mb-3">Servers</h3>
436
+ <div id="mcp-servers" class="tcp-list"></div>
437
+ </div>
438
+ <div class="tcp-card">
439
+ <h3 class="tcp-title mb-3">MCP Tools (${o.length})</h3>
440
+ <pre class="tcp-code max-h-[280px] overflow-auto">${s(o.slice(0,200).map(l=>l.id||JSON.stringify(l)).join(`
441
+ `))}</pre>
442
+ </div>
443
+ </div>
444
+ </div>
445
+ `,n("mcp-add").addEventListener("click",async()=>{const l=n("mcp-name").value.trim(),p=n("mcp-transport").value.trim();if(!l||!p)return r("err","name and transport are required");try{await t.client.mcp.add({name:l,transport:p,enabled:!0}),await t.client.mcp.connect(l),r("ok","MCP connected."),In(e)}catch(v){r("err",v instanceof Error?v.message:String(v))}});const c=n("mcp-servers"),d=Object.entries(i||{});c.innerHTML=d.map(([l,p])=>`
446
+ <div class="tcp-list-item flex items-center justify-between gap-3">
447
+ <div><strong>${s(l)}</strong><div class="tcp-subtle">${s(p.transport||"")}</div></div>
448
+ <div class="flex gap-2">
449
+ <button data-c="${l}" class="tcp-btn">Connect</button>
450
+ <button data-r="${l}" class="tcp-btn">Refresh</button>
451
+ <button data-d="${l}" class="tcp-btn-danger">Delete</button>
452
+ </div>
453
+ </div>
454
+ `).join("")||'<p class="tcp-subtle">No MCP servers configured.</p>',c.querySelectorAll("[data-c]").forEach(l=>l.addEventListener("click",async()=>{try{await t.client.mcp.connect(l.dataset.c),r("ok","Connected.")}catch(p){r("err",p instanceof Error?p.message:String(p))}})),c.querySelectorAll("[data-r]").forEach(l=>l.addEventListener("click",async()=>{try{await t.client.mcp.refresh(l.dataset.r),r("ok","Refreshed.")}catch(p){r("err",p instanceof Error?p.message:String(p))}})),c.querySelectorAll("[data-d]").forEach(l=>l.addEventListener("click",async()=>{try{await t.client.mcp.delete(l.dataset.d),r("ok","Deleted."),In(e)}catch(p){r("err",p instanceof Error?p.message:String(p))}}))}function bn(e){const t=String(e||"").toLowerCase();return t.includes("fail")||t.includes("error")?"tcp-badge-err":t.includes("wait")||t.includes("queue")||t.includes("new")?"tcp-badge-warn":"tcp-badge-ok"}function Zl(e){const t=new Map;for(const n of e){const r=n.ownerRole||"unknown",s=t.get(r)||{total:0,running:0,done:0,failed:0};s.total+=1;const i=String(n.status||"").toLowerCase();i.includes("fail")||i.includes("error")?s.failed+=1:i.includes("done")||i.includes("complete")?s.done+=1:s.running+=1,t.set(r,s)}return[...t.entries()]}function ql(e){return e?e.kind==="task_transition"?`${e.taskId}: ${e.from} -> ${e.to} (${e.reason||"status changed"})`:e.kind==="task_reason"?`${e.taskId}: ${e.reason||"updated"}`:e.reason||JSON.stringify(e):""}async function zt(e){const{api:t,byId:n,escapeHtml:r,toast:s,state:i,addCleanup:o}=e,c=await t("/api/swarm/status").catch(()=>({status:"error"})),d=await t("/api/swarm/snapshot").catch(()=>({registry:{value:{tasks:{}}},logs:[],reasons:[]})),l=Object.values(d.registry?.value?.tasks||{}),p=(d.reasons||[]).slice().reverse(),v=Zl(l);n("view").innerHTML=`
455
+ <div class="tcp-card">
456
+ <div class="mb-3 flex items-center justify-between gap-3">
457
+ <h3 class="tcp-title flex items-center gap-2"><i data-lucide="cpu"></i> Node Swarm Orchestrator</h3>
458
+ <span class="${bn(c.status)}">${r(c.status||"idle")}</span>
459
+ </div>
460
+ <div class="grid gap-3 md:grid-cols-[1fr_1fr_120px_auto]">
461
+ <input id="swarm-root" class="tcp-input" value="${r(c.workspaceRoot||"")}" placeholder="workspace root" />
462
+ <input id="swarm-objective" class="tcp-input" value="${r(c.objective||"Ship a small feature end-to-end")}" placeholder="objective" />
463
+ <input id="swarm-max" class="tcp-input" type="number" min="1" value="${r(String(c.maxTasks||3))}" />
464
+ <div class="flex gap-2">
465
+ <button id="swarm-start" class="tcp-btn-primary" ${c.localEngine?"":"disabled"}><i data-lucide="play"></i> Start</button>
466
+ <button id="swarm-stop" class="tcp-btn-danger"><i data-lucide="square"></i> Stop</button>
467
+ </div>
468
+ </div>
469
+ ${c.localEngine?"":'<p class="mt-3 rounded-xl border border-amber-700/60 bg-amber-950/20 px-3 py-2 text-sm text-amber-300">Swarm orchestration is disabled on remote engine URLs. Monitoring remains available.</p>'}
470
+ </div>
471
+
472
+ <div class="tcp-card">
473
+ <h3 class="tcp-title mb-3">Live Agent Flow</h3>
474
+ <div class="overflow-hidden rounded-xl border border-slate-700 bg-black/20 p-2">
475
+ <svg viewBox="0 0 680 240" class="h-[280px] w-full">
476
+ <defs>
477
+ <linearGradient id="wire-grad" x1="0" y1="0" x2="1" y2="0">
478
+ <stop offset="0%" stop-color="#64748b" stop-opacity="0.12"></stop>
479
+ <stop offset="50%" stop-color="#94a3b8" stop-opacity="0.95"></stop>
480
+ <stop offset="100%" stop-color="#64748b" stop-opacity="0.12"></stop>
481
+ </linearGradient>
482
+ </defs>
483
+ <line x1="140" y1="120" x2="320" y2="60" stroke="url(#wire-grad)" stroke-width="2" class="wire-line-active"></line>
484
+ <line x1="140" y1="120" x2="320" y2="120" stroke="url(#wire-grad)" stroke-width="2" class="wire-line-active"></line>
485
+ <line x1="140" y1="120" x2="320" y2="180" stroke="url(#wire-grad)" stroke-width="2" class="wire-line-active"></line>
486
+ <line x1="360" y1="60" x2="540" y2="50" stroke="url(#wire-grad)" stroke-width="2" class="wire-line-active"></line>
487
+ <line x1="360" y1="120" x2="540" y2="120" stroke="url(#wire-grad)" stroke-width="2" class="wire-line-active"></line>
488
+ <line x1="360" y1="180" x2="540" y2="190" stroke="url(#wire-grad)" stroke-width="2" class="wire-line-active"></line>
489
+
490
+ <circle cx="120" cy="120" r="20" fill="rgba(30,41,59,0.95)" stroke="rgba(148,163,184,0.8)" stroke-width="1.5" class="node-active"></circle>
491
+ <text x="120" y="152" text-anchor="middle" fill="#cbd5e1" font-size="11">Manager</text>
492
+ <circle cx="340" cy="60" r="18" fill="rgba(30,41,59,0.95)" stroke="rgba(148,163,184,0.7)" stroke-width="1.5" class="node-active"></circle>
493
+ <text x="340" y="92" text-anchor="middle" fill="#cbd5e1" font-size="11">Worker</text>
494
+ <circle cx="340" cy="120" r="18" fill="rgba(30,41,59,0.95)" stroke="rgba(148,163,184,0.7)" stroke-width="1.5" class="node-active"></circle>
495
+ <text x="340" y="152" text-anchor="middle" fill="#cbd5e1" font-size="11">Tester</text>
496
+ <circle cx="340" cy="180" r="18" fill="rgba(30,41,59,0.95)" stroke="rgba(148,163,184,0.7)" stroke-width="1.5" class="node-active"></circle>
497
+ <text x="340" y="212" text-anchor="middle" fill="#cbd5e1" font-size="11">Reviewer</text>
498
+ </svg>
499
+ </div>
500
+ <div class="mt-3 grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
501
+ ${v.map(([h,_])=>`<div class="tcp-list-item"><div class="font-medium">${r(h)}</div><div class="tcp-subtle mt-1">${_.total} tasks</div><div class="text-xs text-slate-400">${_.running} active / ${_.done} done / ${_.failed} failed</div></div>`).join("")||'<p class="tcp-subtle">No active roles yet.</p>'}
502
+ </div>
503
+ </div>
504
+
505
+ <div class="tcp-card">
506
+ <div class="mb-3 flex items-center justify-between gap-2">
507
+ <h3 class="tcp-title">Swarm Why Timeline</h3>
508
+ <div class="flex gap-2">
509
+ <select id="swarm-reason-kind" class="tcp-select !w-auto !py-1.5 text-xs">
510
+ <option value="">All kinds</option>
511
+ <option value="task_transition">task_transition</option>
512
+ <option value="task_reason">task_reason</option>
513
+ </select>
514
+ <input id="swarm-reason-task" class="tcp-input !w-44 !py-1.5 text-xs" placeholder="Filter by task id" />
515
+ </div>
516
+ </div>
517
+ <div id="swarm-reasons" class="grid max-h-[420px] gap-2 overflow-auto"></div>
518
+ </div>
519
+
520
+ <div class="grid gap-4 lg:grid-cols-2">
521
+ <div class="tcp-card">
522
+ <h3 class="tcp-title mb-3">Tasks (${l.length})</h3>
523
+ <div id="swarm-tasks" class="grid max-h-[420px] gap-2 overflow-auto"></div>
524
+ </div>
525
+ <div class="tcp-card">
526
+ <h3 class="tcp-title mb-3">Swarm Logs</h3>
527
+ <pre id="swarm-logs" class="tcp-code max-h-[420px] overflow-auto"></pre>
528
+ </div>
529
+ </div>
530
+ `;const $=n("swarm-tasks");$.innerHTML=l.sort((h,_)=>(_.lastUpdateMs||0)-(h.lastUpdateMs||0)).map(h=>`<div class="tcp-list-item"><div class="flex items-center justify-between gap-2"><strong>${r(h.taskId)}</strong><span class="${bn(h.status)}">${r(h.status||"unknown")}</span></div><div class="mt-1 text-xs uppercase tracking-wide text-slate-400">${r(h.ownerRole||"")}</div><div class="tcp-subtle mt-1">${r(h.statusReason||"")}</div></div>`).join("")||'<p class="tcp-subtle">No swarm tasks yet.</p>';function w(){const h=n("swarm-reason-kind").value.trim(),_=n("swarm-reason-task").value.trim().toLowerCase(),Z=p.filter(N=>!(h&&N.kind!==h||_&&!String(N.taskId||"").toLowerCase().includes(_)));n("swarm-reasons").innerHTML=Z.map(N=>`
531
+ <div class="tcp-list-item">
532
+ <div class="flex items-center justify-between gap-2"><span class="text-xs text-slate-400">${new Date(N.at).toLocaleTimeString()}</span><span class="${bn(N.to||N.from)}">${r(N.kind||"reason")}</span></div>
533
+ <div class="mt-1"><strong>${r(N.taskId||"swarm")}</strong> <span class="tcp-subtle">${r(N.role||"")}</span></div>
534
+ <div class="mt-1 text-sm text-slate-300">${r(ql(N))}</div>
535
+ </div>
536
+ `).join("")||'<p class="tcp-subtle">No timeline reasons yet.</p>'}n("swarm-reason-kind").addEventListener("change",w),n("swarm-reason-task").addEventListener("input",w),w(),n("swarm-logs").textContent=(d.logs||[]).slice(-200).map(h=>`[${new Date(h.at).toLocaleTimeString()}] ${h.stream}: ${h.line}`).join(`
537
+ `),n("swarm-start").addEventListener("click",async()=>{try{await t("/api/swarm/start",{method:"POST",body:JSON.stringify({workspaceRoot:n("swarm-root").value.trim(),objective:n("swarm-objective").value.trim(),maxTasks:Number.parseInt(n("swarm-max").value,10)||3})}),s("ok","Swarm started."),zt(e)}catch(h){s("err",h instanceof Error?h.message:String(h))}}),n("swarm-stop").addEventListener("click",async()=>{try{await t("/api/swarm/stop",{method:"POST"}),s("ok","Swarm stop requested."),zt(e)}catch(h){s("err",h instanceof Error?h.message:String(h))}});const f=setInterval(()=>{i.route==="swarm"&&zt(e)},4e3);o(()=>clearInterval(f));try{const h=new EventSource("/api/swarm/events",{withCredentials:!0});h.onmessage=()=>{i.route==="swarm"&&zt(e)},h.onerror=()=>h.close(),o(()=>h.close())}catch{}}function Ul(e){const t=Number(e||0);return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}function Fl(e){const t=Number(e||0);return t?new Date(t).toLocaleString():"n/a"}const Jl={md:"text/markdown",txt:"text/plain",csv:"text/csv",json:"application/json",pdf:"application/pdf",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp"};function Qr(e=""){const t=String(e).toLowerCase().split(".").pop()||"";return Jl[t]||"application/octet-stream"}function Hl(e,t){if(!e||!t)return t||"";const n=String(e).replace(/[\\/]+$/,""),r=String(t).replace(/^[\\/]+/,"");return`${n}/${r}`}function mr(e){const t=String(e?.root||"").trim();return(Array.isArray(e)?e:Array.isArray(e?.files)?e.files:Array.isArray(e?.entries)?e.entries:Array.isArray(e?.items)?e.items:[]).map(r=>{if(typeof r=="string"){const o=r.replace(/^\/+/,"");return{name:o.split("/").pop()||o,path:o,size:0,updatedAt:0}}const s=String(r.relative_to_base||r.path||r.key||r.name||"").replace(/^\/+/,"");if(!s)return null;const i=String(r.name||s.split("/").pop()||s);return{name:i,path:s,size:Number(r.size||r.size_bytes||r.bytes||0),updatedAt:Number(r.updatedAt||r.modified_at_ms||r.modifiedAt||r.mtimeMs||0),mime:Qr(i),url:String(r.absPath||r.absolute_path||Hl(t,s)||s)}}).filter(Boolean)}function es(e){return String(e||"").trim().replace(/\\/g,"/").replace(/^\/+/,"").replace(/\/+$/,"")}const Xt="control-panel",fr="channel_uploads";function Vl(e){const t=es(e);return t===Xt||t.startsWith(`${Xt}/`)?t:Xt}async function Bl(e){const{state:t,byId:n,api:r,escapeHtml:s,toast:i,renderIcons:o,setRoute:c}=e,d=new Map,l=[],p=Vl(t.filesDir||Xt);t.filesDir=p,n("view").innerHTML=`
538
+ <div class="tcp-card grid gap-3">
539
+ <div class="flex flex-wrap items-center justify-between gap-2">
540
+ <h3 class="tcp-title">Storage Browser</h3>
541
+ <div class="flex flex-wrap items-center gap-2">
542
+ <label for="files-upload-input" class="tcp-btn cursor-pointer"><i data-lucide="file-up"></i> Upload Files</label>
543
+ <input id="files-upload-input" type="file" class="hidden" multiple />
544
+ <button id="files-refresh" class="tcp-btn"><i data-lucide="refresh-cw"></i> Refresh</button>
545
+ </div>
546
+ </div>
547
+ <div id="files-upload-progress" class="grid gap-1.5"></div>
548
+ <div class="overflow-auto rounded-xl border border-slate-700 bg-black/20">
549
+ <table class="w-full min-w-[760px] text-sm">
550
+ <thead class="border-b border-slate-700 bg-slate-900/40 text-left text-slate-400">
551
+ <tr>
552
+ <th class="px-3 py-2">Name</th>
553
+ <th class="px-3 py-2">Path</th>
554
+ <th class="px-3 py-2">Size</th>
555
+ <th class="px-3 py-2">Updated</th>
556
+ <th class="px-3 py-2 text-right">Actions</th>
557
+ </tr>
558
+ </thead>
559
+ <tbody id="files-table"></tbody>
560
+ </table>
561
+ </div>
562
+ </div>
563
+ `;const v=n("files-table"),$=n("files-upload-progress"),w=n("files-upload-input");function f(){const x=[...d.entries()];$.innerHTML=x.map(([j,A])=>{const M=Math.max(0,Math.min(100,Number(A.progress||0)));return`
564
+ <div class="rounded-lg border border-slate-700/70 bg-slate-900/40 px-2 py-1.5">
565
+ <div class="mb-1 flex items-center justify-between gap-2 text-xs">
566
+ <span class="truncate text-slate-200">${s(A.name)}</span>
567
+ <span class="${A.error?"text-rose-300":"text-slate-400"}">${A.error?s(A.error):`${M}%`}</span>
568
+ </div>
569
+ <div class="h-1.5 overflow-hidden rounded-full bg-slate-800">
570
+ <div class="h-full rounded-full bg-slate-400/80 transition-all duration-150" style="width:${M}%"></div>
571
+ </div>
572
+ </div>
573
+ `}).join("")}function h(){if(!l.length){v.innerHTML='<tr><td colspan="5" class="px-3 py-5 text-center text-slate-400">No files in this directory.</td></tr>';return}v.innerHTML=l.map((x,j)=>`
574
+ <tr class="border-b border-slate-800/70">
575
+ <td class="px-3 py-2 font-medium text-slate-200">
576
+ ${s(x.name)}
577
+ </td>
578
+ <td class="px-3 py-2 font-mono text-xs text-slate-400">${s(x.path)}</td>
579
+ <td class="px-3 py-2 text-slate-300">${s(Ul(x.size))}</td>
580
+ <td class="px-3 py-2 text-slate-400">${s(Fl(x.updatedAt))}</td>
581
+ <td class="px-3 py-2">
582
+ <div class="flex justify-end gap-1.5">
583
+ <button type="button" class="tcp-btn px-2.5" data-use-chat="${j}" title="Use in chat">Use in Chat</button>
584
+ <a class="tcp-btn px-2.5" href="/api/files/download?path=${encodeURIComponent(x.path)}" title="Download"><i data-lucide="download"></i></a>
585
+ <button type="button" class="tcp-btn-danger px-2.5" data-del-file="${j}" title="Delete"><i data-lucide="trash-2"></i></button>
586
+ </div>
587
+ </td>
588
+ </tr>
589
+ `).join(""),v.querySelectorAll("[data-use-chat]").forEach(x=>{x.addEventListener("click",()=>{const j=Number(x.dataset.useChat);if(!Number.isFinite(j)||!l[j])return;const A=l[j];(t.chatUploadedFiles||[]).some(J=>J.path===A.path)||(t.chatUploadedFiles=[{name:A.name,path:A.path,size:A.size,mime:A.mime||Qr(A.name),url:A.url||A.path,attach:!0},...t.chatUploadedFiles||[]]),i("ok",`${A.name} added to chat attachments.`),c("chat")})}),v.querySelectorAll("[data-del-file]").forEach(x=>{x.addEventListener("click",async()=>{const j=Number(x.dataset.delFile);if(!Number.isFinite(j)||!l[j])return;const A=l[j];if(window.confirm(`Delete ${A.path}?`))try{await r("/api/files/delete",{method:"POST",body:JSON.stringify({path:A.path})}),i("ok",`${A.name} deleted.`),await N()}catch(M){i("err",M instanceof Error?M.message:String(M))}})}),o(v)}async function _(x){const j=x?`${fr}/${x}`:fr,A=`?path=${encodeURIComponent(j)}`,M=await r(`/api/engine/global/storage/files${A}`);return mr(M)}async function Z(x){const j=x?`?dir=${encodeURIComponent(x)}`:"",A=await r(`/api/files/list${j}`);return mr(A)}async function N(){try{let x=[];try{x=await _(p)}catch{x=await Z(p)}const j=x.map(A=>{const M=es(A.path||"");if(!M)return null;const J=M.split("/").pop()||M;return{...A,kind:"file",name:J,path:M}}).filter(Boolean).sort((A,M)=>A.path.localeCompare(M.path));l.splice(0,l.length,...j),h()}catch(x){i("err",x instanceof Error?x.message:String(x))}}function q(x){return new Promise((j,A)=>{const M=`${Date.now()}-${Math.random().toString(16).slice(2)}`;d.set(M,{name:x.name,progress:0,error:""}),f();const J=new XMLHttpRequest,T=p?`?dir=${encodeURIComponent(p)}`:"";J.open("POST",`/api/files/upload${T}`),J.withCredentials=!0,J.responseType="json",J.setRequestHeader("x-file-name",encodeURIComponent(x.name)),J.upload.onprogress=F=>{if(!F.lengthComputable)return;const B=d.get(M);B&&(B.progress=F.loaded/F.total*100,f())},J.onerror=()=>{const F=d.get(M);F&&(F.error="Network error"),f(),setTimeout(()=>{d.delete(M),f()},1200),A(new Error(`Upload failed: ${x.name}`))},J.onload=()=>{const F=J.response||{};if(J.status<200||J.status>=300||F?.ok===!1){const B=F?.error||`Upload failed (${J.status})`,W=d.get(M);W&&(W.error=String(B)),f(),setTimeout(()=>{d.delete(M),f()},1800),A(new Error(String(B)));return}d.delete(M),f(),j(F)},J.send(x)})}async function H(x){const j=[...x||[]];if(!j.length)return;let A=0;for(const M of j)try{await q(M),A+=1}catch(J){i("err",J instanceof Error?J.message:String(J))}A>0&&(i("ok",`Uploaded ${A} file${A===1?"":"s"} to tandem/${p||"."}.`),await N())}n("files-refresh").addEventListener("click",()=>{N()}),w.addEventListener("change",async()=>{await H(w.files),w.value=""}),o(n("view")),await N()}async function En(e){const{state:t,byId:n,toast:r,escapeHtml:s}=e,o=(await t.client.memory.list({limit:100}).catch(()=>({items:[]}))).items||[];n("view").innerHTML=`
590
+ <div class="tcp-card">
591
+ <div class="mb-3 flex items-center justify-between">
592
+ <h3 class="tcp-title">Memory</h3>
593
+ <span class="tcp-badge-info">${o.length} records</span>
594
+ </div>
595
+ <div class="grid gap-3 md:grid-cols-[1fr_auto_auto]">
596
+ <input id="mem-query" class="tcp-input" placeholder="Search query" />
597
+ <button id="mem-search" class="tcp-btn-primary"><i data-lucide="search"></i> Search</button>
598
+ <button id="mem-refresh" class="tcp-btn"><i data-lucide="refresh-cw"></i></button>
599
+ </div>
600
+ <div id="mem-results" class="tcp-list mt-3"></div>
601
+ </div>
602
+ `;const c=d=>{n("mem-results").innerHTML=d.map(l=>`
603
+ <div class="tcp-list-item flex items-center justify-between gap-3">
604
+ <div>
605
+ <strong class="font-mono text-xs text-slate-300">${s(l.id||"(no id)")}</strong>
606
+ <div class="tcp-subtle mt-1">${s((l.text||l.content||"").slice(0,140))}</div>
607
+ </div>
608
+ <button data-del="${s(l.id||"")}" class="tcp-btn-danger"><i data-lucide="trash-2"></i></button>
609
+ </div>
610
+ `).join("")||'<p class="tcp-subtle">No memory records.</p>',n("mem-results").querySelectorAll("[data-del]").forEach(l=>l.addEventListener("click",async()=>{const p=l.dataset.del;if(p)try{await t.client.memory.delete(p),r("ok","Memory deleted."),En(e)}catch(v){r("err",v instanceof Error?v.message:String(v))}}))};c(o),n("mem-refresh").addEventListener("click",()=>En(e)),n("mem-search").addEventListener("click",async()=>{const d=n("mem-query").value.trim();if(!d)return c(o);try{const l=await t.client.memory.search({query:d,limit:50});c(l.results||[])}catch(l){r("err",l instanceof Error?l.message:String(l))}})}function Kt(e){return Array.isArray(e)?e:[]}function Wl(e){return e?.id||e?.instanceID||e?.missionID||e?.templateID||"(unknown)"}function Kl(e){return e?.status||e?.state||e?.phase||"unknown"}function wn(e,t){return t?JSON.stringify(e||{}).toLowerCase().includes(t):!0}function $n(e,t,n,r="id"){return e.length?e.map(s=>{const i=n(s?.[r]||Wl(s)),o=n(Kl(s));return`
611
+ <article class="tcp-list-item">
612
+ <div class="flex items-center justify-between gap-2">
613
+ <strong>${i}</strong>
614
+ <span class="tcp-badge-info">${o}</span>
615
+ </div>
616
+ <div class="tcp-subtle mt-1">role: ${n(s?.role||s?.ownerRole||"n/a")}</div>
617
+ <div class="tcp-subtle">mission: ${n(s?.missionID||s?.missionId||s?.mission||"n/a")}</div>
618
+ <details class="mt-2">
619
+ <summary class="cursor-pointer text-xs text-slate-400">Details</summary>
620
+ <pre class="tcp-code mt-2">${n(JSON.stringify(s,null,2))}</pre>
621
+ </details>
622
+ </article>
623
+ `}).join(""):`<p class="tcp-subtle">${t}</p>`}async function Yt(e){const{state:t,byId:n,toast:r,escapeHtml:s}=e,[i,o,c,d]=await Promise.all([t.client.agentTeams.listTemplates().catch(()=>({templates:[]})),t.client.agentTeams.listInstances().catch(()=>({instances:[]})),t.client.agentTeams.listMissions().catch(()=>({missions:[]})),t.client.agentTeams.listApprovals().catch(()=>({spawnApprovals:[]}))]),l=Kt(i.templates),p=Kt(o.instances),v=Kt(c.missions),$=Kt(d.spawnApprovals);n("view").innerHTML=`
624
+ <div class="tcp-card">
625
+ <h3 class="tcp-title mb-3">Spawn Agent Team Instance</h3>
626
+ <div class="grid gap-3 md:grid-cols-4">
627
+ <input id="team-mission" class="tcp-input" placeholder="missionID" />
628
+ <input id="team-role" class="tcp-input" placeholder="role" value="worker" />
629
+ <input id="team-template" class="tcp-input" placeholder="templateID" value="worker-default" />
630
+ <button id="team-spawn" class="tcp-btn-primary">Spawn</button>
631
+ </div>
632
+ </div>
633
+
634
+ <div class="tcp-card">
635
+ <div class="mb-3 flex items-center justify-between gap-3">
636
+ <h3 class="tcp-title">Teams & Missions</h3>
637
+ <input id="teams-filter" class="tcp-input max-w-sm" placeholder="Filter instances/missions/templates" />
638
+ </div>
639
+
640
+ <div class="grid gap-4 lg:grid-cols-2">
641
+ <section>
642
+ <h4 class="mb-2 font-medium">Approvals (${$.length})</h4>
643
+ <div id="team-approvals" class="tcp-list"></div>
644
+ </section>
645
+ <section>
646
+ <h4 class="mb-2 font-medium">Instances (${p.length})</h4>
647
+ <div id="team-instances" class="tcp-list"></div>
648
+ </section>
649
+ </div>
650
+
651
+ <div class="mt-4 grid gap-4 lg:grid-cols-2">
652
+ <section>
653
+ <h4 class="mb-2 font-medium">Missions (${v.length})</h4>
654
+ <div id="team-missions" class="tcp-list"></div>
655
+ </section>
656
+ <section>
657
+ <h4 class="mb-2 font-medium">Templates (${l.length})</h4>
658
+ <div id="team-templates" class="tcp-list"></div>
659
+ </section>
660
+ </div>
661
+ </div>
662
+ `,n("team-spawn").addEventListener("click",async()=>{try{await t.client.agentTeams.spawn({missionID:n("team-mission").value.trim(),role:n("team-role").value.trim()||"worker",templateID:n("team-template").value.trim()||"worker-default",source:"ui_action",justification:"spawn from control panel"}),r("ok","Spawn requested."),Yt(e)}catch(h){r("err",h instanceof Error?h.message:String(h))}});function w(){const h=n("teams-filter").value.trim().toLowerCase(),_=p.filter(q=>wn(q,h)),Z=v.filter(q=>wn(q,h)),N=l.filter(q=>wn(q,h));n("team-instances").innerHTML=$n(_,"No instances.",s,"instanceID"),n("team-missions").innerHTML=$n(Z,"No missions.",s,"missionID"),n("team-templates").innerHTML=$n(N,"No templates.",s,"templateID")}const f=n("team-approvals");f.innerHTML=$.map(h=>{const _=s(h.approvalID||h.id||"");return`
663
+ <div class="tcp-list-item flex items-center justify-between gap-3">
664
+ <div>
665
+ <div><strong>${_||"approval"}</strong></div>
666
+ <div class="tcp-subtle">mission: ${s(h.missionID||h.missionId||"n/a")}</div>
667
+ </div>
668
+ <div class="flex gap-2">
669
+ <button data-ap="${_}" class="tcp-btn-primary">Approve</button>
670
+ <button data-den="${_}" class="tcp-btn-danger">Deny</button>
671
+ </div>
672
+ </div>`}).join("")||'<p class="tcp-subtle">No pending spawn approvals.</p>',f.querySelectorAll("[data-ap]").forEach(h=>h.addEventListener("click",async()=>{try{await t.client.agentTeams.approveSpawn(h.dataset.ap,"approved in portal"),r("ok","Approved."),Yt(e)}catch(_){r("err",_ instanceof Error?_.message:String(_))}})),f.querySelectorAll("[data-den]").forEach(h=>h.addEventListener("click",async()=>{try{await t.client.agentTeams.denySpawn(h.dataset.den,"denied in portal"),r("ok","Denied."),Yt(e)}catch(_){r("err",_ instanceof Error?_.message:String(_))}})),n("teams-filter").addEventListener("input",w),w()}function hr(e){return e?.type||e?.event||"event"}function Gl(e){const t=String(e||"").toLowerCase();return t.includes("fail")||t.includes("error")?"tcp-badge-err":t.includes("warn")||t.includes("retry")?"tcp-badge-warn":"tcp-badge-info"}async function Xl(e){const{byId:t,escapeHtml:n,state:r,addCleanup:s,toast:i}=e;t("view").innerHTML=`
673
+ <div class="tcp-card">
674
+ <div class="mb-3 flex flex-wrap items-center justify-between gap-3">
675
+ <h3 class="tcp-title flex items-center gap-2"><i data-lucide="activity"></i> Global Live Feed</h3>
676
+ <div class="flex gap-2">
677
+ <input id="feed-filter" class="tcp-input min-w-[220px]" placeholder="Filter by type or payload" />
678
+ <button id="feed-clear" class="tcp-btn">Clear</button>
679
+ </div>
680
+ </div>
681
+ <div id="feed-events" class="grid max-h-[68vh] gap-2 overflow-auto rounded-xl border border-slate-700 bg-black/20 p-2"></div>
682
+ </div>
683
+ `;const o=t("feed-events"),c=[];function d(){const p=t("feed-filter").value.trim().toLowerCase(),v=c.filter($=>p?`${hr($.data)} ${JSON.stringify($.data||{})}`.toLowerCase().includes(p):!0);o.innerHTML=v.map($=>{const w=hr($.data);return`
684
+ <article class="tcp-list-item">
685
+ <div class="flex items-center justify-between gap-2">
686
+ <strong>${n(w)}</strong>
687
+ <span class="${Gl(w)}">${new Date($.at).toLocaleTimeString()}</span>
688
+ </div>
689
+ <div class="tcp-subtle mt-1">session: ${n($.data?.sessionID||$.data?.sessionId||"n/a")} run: ${n($.data?.runID||$.data?.runId||"n/a")}</div>
690
+ <details class="mt-2">
691
+ <summary class="cursor-pointer text-xs text-slate-400">Payload</summary>
692
+ <pre class="tcp-code mt-2">${n(JSON.stringify($.data,null,2))}</pre>
693
+ </details>
694
+ </article>
695
+ `}).join("")||'<p class="tcp-subtle">No events yet.</p>',o.scrollTop=o.scrollHeight}const l=new EventSource("/api/engine/global/event",{withCredentials:!0});l.onmessage=p=>{try{const v=JSON.parse(p.data);for(c.push({at:Date.now(),data:v});c.length>300;)c.shift();r.route==="feed"&&d()}catch{}},l.onerror=()=>{l.close(),i("err","Live feed disconnected.")},t("feed-filter").addEventListener("input",d),t("feed-clear").addEventListener("click",()=>{c.length=0,d()}),s(()=>l.close()),d()}const Oe="__custom_provider__";async function ts(e){const{byId:t,state:n,escapeHtml:r}=e;t("view").innerHTML=`
696
+ <div class="tcp-card">
697
+ <div class="mb-3 flex flex-wrap items-center justify-between gap-2">
698
+ <h3 class="tcp-title flex items-center gap-2"><i data-lucide="settings-2"></i> Provider Setup Wizard</h3>
699
+ <span class="${n.providerReady?"tcp-badge-ok":"tcp-badge-warn"}">${n.providerReady?"Ready":"Not Configured"}</span>
700
+ </div>
701
+ <p class="tcp-subtle">Step 1: Select provider. Step 2: Configure model. Step 3: Add key (if required). Step 4: Run test. Step 5: Set bot identity + personality.</p>
702
+ <div class="mt-3 flex flex-wrap gap-2">
703
+ <span class="${n.providerDefault?"tcp-badge-ok":"tcp-badge-warn"}">Default: ${r(n.providerDefault||"none")}</span>
704
+ <span class="${n.providerConnected.length>0?"tcp-badge-info":"tcp-badge-warn"}">Connected: ${n.providerConnected.length}</span>
705
+ </div>
706
+ ${n.providerError?`<p class="mt-3 rounded-xl border border-amber-700/60 bg-amber-950/30 px-3 py-2 text-sm text-amber-300"><i data-lucide="triangle-alert"></i> ${r(n.providerError)}</p>`:""}
707
+ <div id="provider-settings" class="mt-4"></div>
708
+ <div id="identity-settings" class="mt-6 border-t border-slate-800 pt-5"></div>
709
+ </div>
710
+ <div class="tcp-card">
711
+ <h3 class="tcp-title mb-2 flex items-center gap-2"><i data-lucide="shield"></i> Session Authorization</h3>
712
+ <p class="tcp-subtle">Use Logout in the sidebar to clear your current portal session token binding.</p>
713
+ </div>
714
+ `,await Yl(e,t("provider-settings")),await Ql(e,t("identity-settings"))}async function Yl(e,t){const{state:n,api:r,toast:s,escapeHtml:i,providerHints:o,refreshProviderStatus:c}=e,d=await n.client.providers.catalog(),l=await n.client.providers.config(),p=d.all||[],v=new Set(p.map(x=>x.id)),$=String(d.default||l.default||p[0]?.id||"").trim();let w=v.has($)?$:Oe,f="",h=w===Oe?$:"",_=h?String(l.providers?.[h]?.url||""):"",Z=h?String(l.providers?.[h]?.defaultModel||l.providers?.[h]?.default_model||""):"";const N=()=>{if(w===Oe)return;const x=p.find(M=>M.id===w),j=Object.keys(x?.models||{}),A=l.providers?.[w]||{};f=A.defaultModel||A.default_model||j[0]||""};N();const q=[...p.map(x=>({id:x.id,label:o[x.id]?.label||x.name||x.id})),{id:Oe,label:"Custom Provider"}],H=()=>{const x=w===Oe?[]:Object.keys((p.find(T=>T.id===w)||{}).models||{});t.innerHTML=`
715
+ <div class="grid gap-3 md:grid-cols-2">
716
+ <div>
717
+ <label class="mb-1 block text-sm text-slate-300">Provider</label>
718
+ <select id="provider-select" class="tcp-select">
719
+ ${q.map(T=>`<option value="${i(T.id)}" ${T.id===w?"selected":""}>${i(T.label)}</option>`).join("")}
720
+ </select>
721
+ </div>
722
+ ${w===Oe?`<div>
723
+ <label class="mb-1 block text-sm text-slate-300">Custom Provider ID</label>
724
+ <input id="custom-provider-id" class="tcp-input" placeholder="my-provider" value="${i(h)}" />
725
+ </div>`:`<div>
726
+ <label class="mb-1 block text-sm text-slate-300">Model</label>
727
+ <select id="provider-model" class="tcp-select">${x.map(T=>`<option ${T===f?"selected":""}>${i(T)}</option>`).join("")}</select>
728
+ </div>`}
729
+ </div>
730
+
731
+ ${w===Oe?`<div class="mt-3 grid gap-3 md:grid-cols-2">
732
+ <div>
733
+ <label class="mb-1 block text-sm text-slate-300">Base URL</label>
734
+ <input id="custom-provider-url" class="tcp-input" placeholder="https://api.example.com/v1" value="${i(_)}" />
735
+ </div>
736
+ <div>
737
+ <label class="mb-1 block text-sm text-slate-300">Default Model</label>
738
+ <input id="custom-provider-model" class="tcp-input" placeholder="gpt-4o-mini" value="${i(Z)}" />
739
+ </div>
740
+ </div>
741
+ <p class="tcp-subtle mt-2">Custom providers use OpenAI-compatible chat completions endpoints.</p>`:""}
742
+
743
+ <div class="mt-3 grid gap-3 md:grid-cols-2">
744
+ <div>
745
+ <label class="mb-1 block text-sm text-slate-300">API Key (optional)</label>
746
+ <input id="provider-key" class="tcp-input" type="password" placeholder="${i(o[w]?.placeholder||"sk-...")}" />
747
+ </div>
748
+ <div class="flex items-end justify-end gap-2">
749
+ <button id="provider-test" class="tcp-btn"><i data-lucide="flask-conical"></i> Test Model Run</button>
750
+ <button id="provider-save" class="tcp-btn-primary"><i data-lucide="save"></i> Save Provider</button>
751
+ </div>
752
+ </div>
753
+ `,t.querySelector("#provider-select").addEventListener("change",T=>{w=T.target.value,w!==Oe&&N(),H()});const j=t.querySelector("#provider-model");j&&j.addEventListener("change",T=>f=T.target.value);const A=t.querySelector("#custom-provider-id");A&&A.addEventListener("input",T=>h=T.target.value.trim());const M=t.querySelector("#custom-provider-url");M&&M.addEventListener("input",T=>_=T.target.value.trim());const J=t.querySelector("#custom-provider-model");J&&J.addEventListener("input",T=>Z=T.target.value.trim()),t.querySelector("#provider-save").addEventListener("click",async()=>{const T=t.querySelector("#provider-key").value.trim();try{if(w===Oe){if(!h)throw new Error("Custom provider ID is required.");if(!_)throw new Error("Custom provider URL is required.");if(!Z)throw new Error("Custom default model is required.");await r("/api/engine/config",{method:"PATCH",body:JSON.stringify({default_provider:h,providers:{[h]:{url:_,default_model:Z}}})}),T&&await n.client.providers.setApiKey(h,T)}else T&&await n.client.providers.setApiKey(w,T),await n.client.providers.setDefaults(w,f);await c(),s("ok","Provider configuration saved."),ts(e)}catch(F){s("err",F instanceof Error?F.message:String(F))}}),t.querySelector("#provider-test").addEventListener("click",async()=>{try{const T=await n.client.sessions.create({title:`Provider test ${new Date().toISOString()}`}),{runId:F}=await n.client.sessions.promptAsync(T,"Reply with exactly: READY");let B=!1;for await(const W of n.client.stream(T,F))if(W.type==="session.response"&&String(W.properties?.delta||"").trim()&&(B=!0),W.type==="run.complete"||W.type==="run.failed"||W.type==="session.run.finished")break;if(!B)throw new Error("No model tokens received. Save provider + key first, then retry.");await c(),s("ok","Model run test succeeded.")}catch(T){s("err",T instanceof Error?T.message:String(T))}})};H()}async function Ql(e,t){const{state:n,toast:r,escapeHtml:s,refreshIdentityStatus:i,renderShell:o,renderIcons:c,api:d}=e,l=async()=>n.client?.identity?.get?n.client.identity.get():d("/api/engine/config/identity",{method:"GET"}),p=async M=>n.client?.identity?.patch?n.client.identity.patch(M):d("/api/engine/config/identity",{method:"PATCH",body:JSON.stringify(M)});let v;try{v=await l()}catch(M){t.innerHTML=`
754
+ <p class="rounded-xl border border-rose-700/60 bg-rose-950/30 px-3 py-2 text-sm text-rose-300">
755
+ Failed to load identity settings: ${s(M instanceof Error?M.message:String(M))}
756
+ </p>
757
+ `;return}const $=v?.identity||{},w=$?.bot||{},f=w?.aliases||{},_=($?.personality||{})?.default||{},Z=Array.isArray(v?.presets)&&v.presets.length>0?v.presets:[{id:"balanced",label:"Balanced"},{id:"concise",label:"Concise"},{id:"friendly",label:"Friendly"},{id:"mentor",label:"Mentor"},{id:"critical",label:"Critical"}];let N=String(w?.canonical_name||w?.canonicalName||"").trim(),q=String(w?.avatar_url||w?.avatarUrl||"").trim(),H=String(f?.control_panel||f?.controlPanel||"").trim(),x=String(_?.preset||"balanced").trim()||"balanced",j=String(_?.custom_instructions||_?.customInstructions||"").trim();const A=()=>{t.innerHTML=`
758
+ <div class="mb-3">
759
+ <h4 class="tcp-title flex items-center gap-2"><i data-lucide="bot"></i> Identity & Personality</h4>
760
+ <p class="tcp-subtle mt-1">Control assistant naming and default response style.</p>
761
+ </div>
762
+
763
+ <div class="grid gap-3 md:grid-cols-2">
764
+ <div>
765
+ <label class="mb-1 block text-sm text-slate-300">Canonical bot name</label>
766
+ <input id="identity-canonical-name" class="tcp-input" placeholder="Assistant" value="${s(N)}" />
767
+ </div>
768
+ <div>
769
+ <label class="mb-1 block text-sm text-slate-300">Control panel alias (optional)</label>
770
+ <input id="identity-control-panel-alias" class="tcp-input" placeholder="Assistant Control Panel" value="${s(H)}" />
771
+ </div>
772
+ </div>
773
+
774
+ <div class="mt-3">
775
+ <label class="mb-1 block text-sm text-slate-300">Avatar (optional)</label>
776
+ <div class="flex flex-wrap items-center gap-3">
777
+ <div class="h-10 w-10 overflow-hidden rounded-xl border border-slate-600 bg-muted">
778
+ <img src="${s(q||"/tandem-logo.png")}" alt="${s(N||"Assistant")}" class="h-full w-full object-cover" />
779
+ </div>
780
+ <input id="identity-avatar-file" type="file" accept="image/png,image/jpeg,image/webp,image/gif" class="tcp-input !h-auto !py-1.5 text-xs" />
781
+ ${q?'<button id="identity-avatar-clear" class="tcp-btn h-8 px-2 text-xs">Remove</button>':""}
782
+ </div>
783
+ </div>
784
+
785
+ <div class="mt-3 grid gap-3 md:grid-cols-2">
786
+ <div>
787
+ <label class="mb-1 block text-sm text-slate-300">Personality preset</label>
788
+ <select id="identity-preset" class="tcp-select">
789
+ ${Z.map(T=>`<option value="${s(T.id)}" ${T.id===x?"selected":""}>${s(T.label||T.id)}</option>`).join("")}
790
+ </select>
791
+ </div>
792
+ </div>
793
+
794
+ <div class="mt-3">
795
+ <label class="mb-1 block text-sm text-slate-300">Custom personality instructions (optional)</label>
796
+ <textarea id="identity-custom-instructions" class="tcp-input min-h-[96px]" rows="4" placeholder="Keep responses concise and operationally focused.">${s(j)}</textarea>
797
+ </div>
798
+
799
+ <div class="mt-3 flex items-center justify-end gap-2">
800
+ <button id="identity-save" class="tcp-btn-primary"><i data-lucide="save"></i> Save Identity</button>
801
+ </div>
802
+ `,t.querySelector("#identity-canonical-name").addEventListener("input",T=>{N=T.target.value}),t.querySelector("#identity-control-panel-alias").addEventListener("input",T=>{H=T.target.value});const M=t.querySelector("#identity-avatar-file");M&&M.addEventListener("change",async T=>{const F=T.target?.files?.[0];if(!F)return;if(F.size>10*1024*1024){r("err","Avatar image is too large (max 10 MB).");return}const B=new FileReader;B.onload=()=>{const W=typeof B.result=="string"?B.result:"";if(!W){r("err","Failed to read avatar file.");return}q=W,A()},B.onerror=()=>r("err","Failed to read avatar file."),B.readAsDataURL(F)});const J=t.querySelector("#identity-avatar-clear");J&&J.addEventListener("click",()=>{q="",A()}),t.querySelector("#identity-preset").addEventListener("change",T=>{x=T.target.value}),t.querySelector("#identity-custom-instructions").addEventListener("input",T=>{j=T.target.value}),t.querySelector("#identity-save").addEventListener("click",async()=>{try{const T=N.trim();if(!T)throw new Error("Canonical bot name is required.");const F=H.trim(),B=j.trim(),W=await p({identity:{bot:{canonical_name:T,avatar_url:q||null,aliases:{control_panel:F||void 0}},personality:{default:{preset:x||"balanced",custom_instructions:B||null}}}});await i(),o(),r("ok","Identity settings saved."),v=W,N=String(W?.identity?.bot?.canonical_name||"").trim(),q=String(W?.identity?.bot?.avatar_url||"").trim(),H=String(W?.identity?.bot?.aliases?.control_panel||"").trim(),x=String(W?.identity?.personality?.default?.preset||"balanced").trim()||"balanced",j=String(W?.identity?.personality?.default?.custom_instructions||"").trim(),A()}catch(T){r("err",T instanceof Error?T.message:String(T))}}),c()};A()}const gr={dashboard:Pl,chat:jl,agents:Pe,channels:xn,mcp:In,swarm:zt,files:Bl,memory:En,teams:Yt,feed:Xl,settings:ts};const ns={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"};const rs=([e,t,n])=>{const r=document.createElementNS("http://www.w3.org/2000/svg",e);return Object.keys(t).forEach(s=>{r.setAttribute(s,String(t[s]))}),n?.length&&n.forEach(s=>{const i=rs(s);r.appendChild(i)}),r},ed=(e,t={})=>{const r={...ns,...t};return rs(["svg",r,e])};const td=e=>{for(const t in e)if(t.startsWith("aria-")||t==="role"||t==="title")return!0;return!1};const nd=(...e)=>e.filter((t,n,r)=>!!t&&t.trim()!==""&&r.indexOf(t)===n).join(" ").trim();const rd=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(t,n,r)=>r?r.toUpperCase():n.toLowerCase());const sd=e=>{const t=rd(e);return t.charAt(0).toUpperCase()+t.slice(1)};const od=e=>Array.from(e.attributes).reduce((t,n)=>(t[n.name]=n.value,t),{}),vr=e=>typeof e=="string"?e:!e||!e.class?"":e.class&&typeof e.class=="string"?e.class.split(" "):e.class&&Array.isArray(e.class)?e.class:"",yr=(e,{nameAttr:t,icons:n,attrs:r})=>{const s=e.getAttribute(t);if(s==null)return;const i=sd(s),o=n[i];if(!o)return console.warn(`${e.outerHTML} icon name was not found in the provided icons object.`);const c=od(e),d=td(c)?{}:{"aria-hidden":"true"},l={...ns,"data-lucide":s,...d,...r,...c},p=vr(c),v=vr(r),$=nd("lucide",`lucide-${s}`,...p,...v);$&&Object.assign(l,{class:$});const w=ed(o,l);return e.parentNode?.replaceChild(w,e)};const id=[["path",{d:"M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"}]];const ad=[["path",{d:"M12 8V4H8"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2"}],["path",{d:"M2 14h2"}],["path",{d:"M20 14h2"}],["path",{d:"M15 13v2"}],["path",{d:"M9 13v2"}]];const cd=[["rect",{width:"8",height:"4",x:"8",y:"2",rx:"1",ry:"1"}],["path",{d:"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"}],["path",{d:"M12 11h4"}],["path",{d:"M12 16h4"}],["path",{d:"M8 11h.01"}],["path",{d:"M8 16h.01"}]];const ld=[["circle",{cx:"12",cy:"12",r:"10"}],["path",{d:"M12 6v6h4"}]];const dd=[["circle",{cx:"12",cy:"12",r:"10"}],["path",{d:"M12 6v6l4 2"}]];const ud=[["path",{d:"M12 20v2"}],["path",{d:"M12 2v2"}],["path",{d:"M17 20v2"}],["path",{d:"M17 2v2"}],["path",{d:"M2 12h2"}],["path",{d:"M2 17h2"}],["path",{d:"M2 7h2"}],["path",{d:"M20 12h2"}],["path",{d:"M20 17h2"}],["path",{d:"M20 7h2"}],["path",{d:"M7 20v2"}],["path",{d:"M7 2v2"}],["rect",{x:"4",y:"4",width:"16",height:"16",rx:"2"}],["rect",{x:"8",y:"8",width:"8",height:"8",rx:"1"}]];const pd=[["ellipse",{cx:"12",cy:"5",rx:"9",ry:"3"}],["path",{d:"M3 5V19A9 3 0 0 0 21 19V5"}],["path",{d:"M3 12A9 3 0 0 0 21 12"}]];const md=[["path",{d:"M12 15V3"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"}],["path",{d:"m7 10 5 5 5-5"}]];const fd=[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5"}],["path",{d:"M12 12v6"}],["path",{d:"m15 15-3-3-3 3"}]];const hd=[["path",{d:"M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2"}],["path",{d:"M6.453 15h11.094"}],["path",{d:"M8.5 2h7"}]];const gd=[["path",{d:"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2"}]];const vd=[["path",{d:"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"}],["path",{d:"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"}]];const yd=[["path",{d:"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z"}],["circle",{cx:"16.5",cy:"7.5",r:".5",fill:"currentColor"}]];const bd=[["path",{d:"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"}],["path",{d:"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"}]];const wd=[["path",{d:"m16 17 5-5-5-5"}],["path",{d:"M21 12H9"}],["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"}]];const $d=[["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"}]];const Sd=[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z"}]];const _d=[["path",{d:"M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"}],["path",{d:"M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1"}]];const kd=[["path",{d:"m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551"}]];const xd=[["path",{d:"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z"}]];const Id=[["path",{d:"M6.3 20.3a2.4 2.4 0 0 0 3.4 0L12 18l-6-6-2.3 2.3a2.4 2.4 0 0 0 0 3.4Z"}],["path",{d:"m2 22 3-3"}],["path",{d:"M7.5 13.5 10 11"}],["path",{d:"M10.5 16.5 13 14"}],["path",{d:"m18 3-4 4h6l-4 4"}]];const Ed=[["path",{d:"M5 12h14"}],["path",{d:"M12 5v14"}]];const Td=[["path",{d:"M16.247 7.761a6 6 0 0 1 0 8.478"}],["path",{d:"M19.075 4.933a10 10 0 0 1 0 14.134"}],["path",{d:"M4.925 19.067a10 10 0 0 1 0-14.134"}],["path",{d:"M7.753 16.239a6 6 0 0 1 0-8.478"}],["circle",{cx:"12",cy:"12",r:"2"}]];const zd=[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"}],["path",{d:"M21 3v5h-5"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"}],["path",{d:"M8 16H3v5"}]];const Ad=[["path",{d:"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z"}],["path",{d:"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7"}],["path",{d:"M7 3v4a1 1 0 0 0 1 1h7"}]];const Rd=[["path",{d:"m21 21-4.34-4.34"}],["circle",{cx:"11",cy:"11",r:"8"}]];const Cd=[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"}],["path",{d:"m21.854 2.147-10.94 10.939"}]];const Od=[["path",{d:"M14 17H5"}],["path",{d:"M19 7h-9"}],["circle",{cx:"17",cy:"17",r:"3"}],["circle",{cx:"7",cy:"7",r:"3"}]];const Pd=[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"}],["circle",{cx:"12",cy:"12",r:"3"}]];const Md=[["circle",{cx:"18",cy:"5",r:"3"}],["circle",{cx:"6",cy:"12",r:"3"}],["circle",{cx:"18",cy:"19",r:"3"}],["line",{x1:"8.59",x2:"15.42",y1:"13.51",y2:"17.49"}],["line",{x1:"15.41",x2:"8.59",y1:"6.51",y2:"10.49"}]];const Nd=[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"}]];const Ld=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2"}]];const Dd=[["path",{d:"M10 11v6"}],["path",{d:"M14 11v6"}],["path",{d:"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"}],["path",{d:"M3 6h18"}],["path",{d:"M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"}]];const jd=[["path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"}],["path",{d:"M12 9v4"}],["path",{d:"M12 17h.01"}]];const Zd=[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"}],["path",{d:"M16 3.128a4 4 0 0 1 0 7.744"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87"}],["circle",{cx:"9",cy:"7",r:"4"}]];const qd=[["rect",{width:"8",height:"8",x:"3",y:"3",rx:"2"}],["path",{d:"M7 11v4a2 2 0 0 0 2 2h4"}],["rect",{width:"8",height:"8",x:"13",y:"13",rx:"2"}]];const Ud=[["path",{d:"M18 6 6 18"}],["path",{d:"m6 6 12 12"}]];const ss=({icons:e={},nameAttr:t="data-lucide",attrs:n={},root:r=document,inTemplates:s}={})=>{if(!Object.values(e).length)throw new Error(`Please provide an icons object.
803
+ If you want to use all the icons you can import it like:
804
+ \`import { createIcons, icons } from 'lucide';
805
+ lucide.createIcons({icons});\``);if(typeof r>"u")throw new Error("`createIcons()` only works in a browser environment.");if(Array.from(r.querySelectorAll(`[${t}]`)).forEach(o=>yr(o,{nameAttr:t,icons:e,attrs:n})),s&&Array.from(r.querySelectorAll("template")).forEach(c=>ss({icons:e,nameAttr:t,attrs:n,root:c.content,inTemplates:s})),t==="data-lucide"){const o=r.querySelectorAll("[icon-name]");o.length>0&&(console.warn("[Lucide] Some icons were found with the now deprecated icon-name attribute. These will still be replaced for backwards compatibility, but will no longer be supported in v1.0 and you should switch to data-lucide"),Array.from(o).forEach(c=>yr(c,{nameAttr:"icon-name",icons:e,attrs:n})))}},Fd={Activity:id,Bot:ad,ClipboardList:cd,Clock:dd,Clock3:ld,Cpu:ud,Database:pd,Download:md,FileUp:fd,FlaskConical:hd,FolderOpen:gd,Home:vd,KeyRound:yd,Link:bd,LogOut:wd,MessageCircle:$d,MessageSquare:Sd,MessagesSquare:_d,Paperclip:kd,Play:xd,PlugZap:Id,Plus:Ed,Radio:Td,RefreshCw:zd,Save:Ad,Search:Rd,Send:Cd,Settings:Pd,Settings2:Od,Share2:Md,Shield:Nd,Square:Ld,Trash2:Dd,TriangleAlert:jd,X:Ud,Users:Zd,Workflow:qd};function pn(e){ss({icons:Fd,attrs:{width:"16",height:"16","stroke-width":"1.8"},...e?{root:e}:{}})}const rn=document.getElementById("app"),k=Ol(),{toast:it,renderToasts:Jd}=Rl(k),Ln="tandem_control_panel_token",Hd={app:rn,state:k,api:We,byId:ye,escapeHtml:ae,ROUTES:Rt,providerHints:Cl,toast:it,addCleanup:os,clearCleanup:is,setRoute:Ct,renderShell:mn,refreshProviderStatus:ls,refreshIdentityStatus:ds,renderIcons:pn};function os(e){k.cleanup.push(e)}function is(){for(const e of k.cleanup)try{e()}catch{}k.cleanup=[]}function as(){try{return localStorage.getItem(Ln)||""}catch{return""}}function Vd(e){try{localStorage.setItem(Ln,e)}catch{}}function cs(){try{localStorage.removeItem(Ln)}catch{}}async function Tn(){try{const e=await We("/api/auth/me",{method:"GET"});k.authed=!0,k.me=e,k.client=new gl({baseUrl:"/api/engine",token:"session"}),await Promise.all([ls(),ds()])}catch{k.authed=!1,k.me=null,k.client=null,k.needsProviderOnboarding=!1,k.providerReady=!1,k.providerDefault="",k.providerConnected=[],k.providerError="",k.botName="Tandem",k.botAvatarUrl="",k.controlPanelName="Tandem Control Panel"}}async function ls(){if(!k.client){k.needsProviderOnboarding=!1,k.providerReady=!1,k.providerDefault="",k.providerDefaultModel="",k.providerConnected=[],k.providerError="";return}try{const[e,t]=await Promise.all([k.client.providers.config(),k.client.providers.catalog()]),n=String(e?.default||"").trim(),r=String(e?.providers?.[n]?.default_model||"").trim(),s=new Set(t?.connected||[]),i=!!n&&(n==="ollama"||s.has(n));k.providerDefault=n,k.providerDefaultModel=r,k.providerConnected=[...s],k.providerReady=i,k.providerError="",k.needsProviderOnboarding=!i}catch(e){k.providerReady=!1,k.providerDefault="",k.providerDefaultModel="",k.providerConnected=[],k.providerError=e instanceof Error?e.message:String(e),k.needsProviderOnboarding=!0}}async function ds(){if(!k.client){k.botName="Tandem",k.botAvatarUrl="",k.controlPanelName="Tandem Control Panel";return}try{const t=(k.client?.identity?.get?await k.client.identity.get():await We("/api/engine/config/identity",{method:"GET"}))?.identity||{},n=String(t?.bot?.canonical_name||t?.bot?.canonicalName||"").trim(),r=t?.bot?.aliases||{},s=String(t?.bot?.avatar_url||t?.bot?.avatarUrl||"").trim(),i=String(r?.control_panel||r?.controlPanel||"").trim();k.botName=n||"Tandem",k.botAvatarUrl=s,k.controlPanelName=i||`${k.botName} Control Panel`}catch{k.botName="Tandem",k.botAvatarUrl="",k.controlPanelName="Tandem Control Panel"}}function Ct(e){k.route=Nn(e,Rt),Al(k.route),mn()}function sn(){const e=as();rn.innerHTML=`
806
+ <main class="mx-auto grid min-h-screen w-full max-w-3xl place-items-center p-5">
807
+ <section class="tcp-panel w-full max-w-xl">
808
+ <div class="mb-6 rounded-2xl border border-slate-700 bg-black/20 p-3">
809
+ <svg viewBox="0 0 520 160" class="hero-svg" aria-hidden="true">
810
+ <defs>
811
+ <linearGradient id="hero-path-grad" x1="0" y1="0" x2="1" y2="0">
812
+ <stop offset="0%" stop-color="#64748b" stop-opacity="0.35"></stop>
813
+ <stop offset="50%" stop-color="#cbd5e1" stop-opacity="0.95"></stop>
814
+ <stop offset="100%" stop-color="#64748b" stop-opacity="0.35"></stop>
815
+ </linearGradient>
816
+ <radialGradient id="hero-core-grad" cx="50%" cy="50%" r="60%">
817
+ <stop offset="0%" stop-color="#f1f5f9" stop-opacity="0.9"></stop>
818
+ <stop offset="100%" stop-color="#64748b" stop-opacity="0.15"></stop>
819
+ </radialGradient>
820
+ </defs>
821
+
822
+ <g class="hero-grid">
823
+ <line x1="24" y1="34" x2="496" y2="34"></line>
824
+ <line x1="24" y1="80" x2="496" y2="80"></line>
825
+ <line x1="24" y1="126" x2="496" y2="126"></line>
826
+ <line x1="120" y1="24" x2="120" y2="136"></line>
827
+ <line x1="260" y1="24" x2="260" y2="136"></line>
828
+ <line x1="400" y1="24" x2="400" y2="136"></line>
829
+ </g>
830
+
831
+ <path class="hero-path hero-path-left" d="M60 92 C110 92, 150 78, 194 80 S238 80, 260 80"></path>
832
+ <path class="hero-path hero-path-right" d="M460 68 C410 68, 370 82, 326 80 S282 80, 260 80"></path>
833
+ <path class="hero-path hero-path-upper" d="M88 52 C150 52, 200 58, 260 58 S370 58, 432 52"></path>
834
+
835
+ <g class="hero-node hero-node-left">
836
+ <circle cx="60" cy="92" r="8"></circle>
837
+ </g>
838
+ <g class="hero-node hero-node-right">
839
+ <circle cx="460" cy="68" r="8"></circle>
840
+ </g>
841
+ <g class="hero-node hero-node-top-left">
842
+ <circle cx="88" cy="52" r="6"></circle>
843
+ </g>
844
+ <g class="hero-node hero-node-top-right">
845
+ <circle cx="432" cy="52" r="6"></circle>
846
+ </g>
847
+
848
+ <circle class="hero-core-glow" cx="260" cy="80" r="28"></circle>
849
+ <circle class="hero-core-ring" cx="260" cy="80" r="24"></circle>
850
+ <circle class="hero-core" cx="260" cy="80" r="12"></circle>
851
+ <circle class="hero-scan" cx="260" cy="80" r="34"></circle>
852
+
853
+ <g class="hero-packet hero-packet-left">
854
+ <circle cx="0" cy="0" r="3"></circle>
855
+ </g>
856
+ <g class="hero-packet hero-packet-right">
857
+ <circle cx="0" cy="0" r="3"></circle>
858
+ </g>
859
+ <g class="hero-packet hero-packet-upper">
860
+ <circle cx="0" cy="0" r="2.5"></circle>
861
+ </g>
862
+ </svg>
863
+ </div>
864
+ <h1 class="mb-1 text-4xl font-semibold tracking-tight">${ae(k.controlPanelName)}</h1>
865
+ <p class="tcp-subtle mb-6">Use your engine API token to unlock the full web control center.</p>
866
+ <form id="login-form" class="grid gap-3">
867
+ <label class="text-sm text-slate-300">Engine Token</label>
868
+ <input id="token" class="tcp-input" type="password" placeholder="tk_..." autocomplete="off" value="${ae(e)}" />
869
+ <label class="inline-flex items-center gap-2 text-xs text-slate-400">
870
+ <input id="remember-token" type="checkbox" class="h-4 w-4 accent-slate-400" checked />
871
+ Remember token on this browser
872
+ </label>
873
+ <button id="login-btn" type="submit" class="tcp-btn-primary w-full"><i data-lucide="key-round"></i> Sign In</button>
874
+ <button id="check-engine-btn" type="button" class="tcp-btn w-full"><i data-lucide="activity"></i> Check Engine Connectivity</button>
875
+ <div id="login-err" class="min-h-[1.2rem] text-sm text-rose-300"></div>
876
+ </form>
877
+ </section>
878
+ </main>
879
+ `,pn(),ye("login-form").addEventListener("submit",async t=>{t.preventDefault();const n=ye("token").value.trim(),r=!!ye("remember-token")?.checked,s=ye("login-err");if(s.textContent="",!n){s.textContent="Token is required.",it("warn","Engine token is required.");return}try{await We("/api/auth/login",{method:"POST",body:JSON.stringify({token:n})}),r?Vd(n):cs(),await Tn(),it("ok","Signed in."),Ct("dashboard")}catch(i){const o=i instanceof Error?i.message:String(i);s.textContent=o,it("err",o)}}),ye("check-engine-btn").addEventListener("click",async()=>{const t=ye("login-err");t.textContent="";try{const n=await We("/api/system/health"),r=n.engine?.ready||n.engine?.healthy?"healthy":"unhealthy";t.textContent=`Engine check: ${r} at ${n.engineUrl}`,t.className="min-h-[1.2rem] text-sm text-lime-300",it(n.engine?.ready||n.engine?.healthy?"ok":"warn",`Engine ${r}: ${n.engineUrl}`)}catch(n){const r=n instanceof Error?n.message:String(n);t.textContent=r,t.className="min-h-[1.2rem] text-sm text-rose-300",it("err",r)}})}async function Bd(){const e=ye("view");if(!e)return;if(e.innerHTML='<div class="tcp-subtle">Loading...</div>',new Set(["chat","agents","swarm","teams"]).has(k.route)&&!k.providerReady){e.innerHTML=`
880
+ <div class="tcp-card">
881
+ <h3 class="tcp-title mb-2">Provider Setup Required</h3>
882
+ <p class="tcp-subtle">This page requires a connected default provider/model before runs can execute.</p>
883
+ <div class="mt-3 flex flex-wrap gap-2">
884
+ <span class="tcp-badge-warn">default: ${ae(k.providerDefault||"none")}</span>
885
+ <span class="tcp-badge-warn">connected: ${ae(String(k.providerConnected.length))}</span>
886
+ </div>
887
+ <div class="mt-4 flex justify-end">
888
+ <button id="goto-settings" class="tcp-btn-primary">Open Provider Setup</button>
889
+ </div>
890
+ </div>
891
+ `;const r=ye("goto-settings");r&&r.addEventListener("click",()=>Ct("settings"));return}await(gr[k.route]||gr.dashboard)(Hd),pn(ye("view"))}function mn(){if(!k.authed){sn();return}is(),rn.innerHTML=`
892
+ <div class="grid min-h-screen grid-cols-1 lg:grid-cols-[260px_1fr]">
893
+ <aside class="border-r border-slate-700 bg-panel/90 p-4">
894
+ <div class="mb-4 flex items-center gap-3 rounded-xl border border-slate-700 bg-black/20 p-3">
895
+ <div class="grid h-10 w-10 place-items-center overflow-hidden rounded-xl border border-slate-600 bg-muted text-slate-200">
896
+ ${k.botAvatarUrl?`<img src="${ae(k.botAvatarUrl)}" alt="${ae(k.botName)}" class="h-full w-full object-cover" />`:'<i data-lucide="cpu"></i>'}
897
+ </div>
898
+ <div>
899
+ <div class="text-base font-semibold">${ae(k.botName)}</div>
900
+ <div class="text-xs uppercase tracking-wider text-slate-400">Control Center</div>
901
+ </div>
902
+ </div>
903
+ <nav id="nav" class="grid gap-1"></nav>
904
+ <div class="mt-4 border-t border-slate-700 pt-4">
905
+ <button id="logout-btn" class="tcp-btn w-full"><i data-lucide="log-out"></i> Logout</button>
906
+ </div>
907
+ </aside>
908
+ <main class="min-w-0 p-3 md:p-4">
909
+ <section id="view" class="grid h-full gap-4"></section>
910
+ </main>
911
+ </div>
912
+ `;const e=ye("nav");e.innerHTML=Rt.map(([t,n,r])=>`
913
+ <button data-route="${t}" class="nav-item ${t===k.route?"active":""}">
914
+ <i data-lucide="${r}"></i><span>${n}</span>
915
+ </button>
916
+ `).join(""),e.querySelectorAll(".nav-item").forEach(t=>{t.addEventListener("click",()=>Ct(t.dataset.route))}),ye("logout-btn").addEventListener("click",async()=>{await We("/api/auth/logout",{method:"POST"}).catch(()=>{}),k.authed=!1,k.me=null,k.client=null,sn()}),pn(rn),Jd(),Bd()}async function Wd(){try{await We("/api/auth/me")}catch{k.authed=!1,sn()}}window.addEventListener("hashchange",()=>{k.route=Nn(Yr(),Rt),mn()});async function Kd(){if(k.route=Nn(Yr(),Rt),await Tn(),!k.authed){const t=as().trim();if(t)try{await We("/api/auth/login",{method:"POST",body:JSON.stringify({token:t})}),await Tn()}catch{cs()}}if(!k.authed)return sn();mn(),k.needsProviderOnboarding&&k.route==="dashboard"&&(it("info","Complete provider setup to start using chat/agents."),Ct("settings"));const e=setInterval(Wd,3e4);os(()=>clearInterval(e))}Kd();