@superglue/cli 1.1.212 → 1.1.214

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var xJ=Object.create;var Ep=Object.defineProperty;var LJ=Object.getOwnPropertyDescriptor;var PJ=Object.getOwnPropertyNames;var $J=Object.getPrototypeOf,FJ=Object.prototype.hasOwnProperty;var Xe=(t,e)=>()=>(t&&(e=t(t=0)),e);var m=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),s0=(t,e)=>{for(var r in e)Ep(t,r,{get:e[r],enumerable:!0})},a0=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of PJ(e))!FJ.call(t,i)&&i!==r&&Ep(t,i,{get:()=>e[i],enumerable:!(n=LJ(e,i))||n.enumerable});return t};var ye=(t,e,r)=>(r=t!=null?xJ($J(t)):{},a0(e||!t||!t.__esModule?Ep(r,"default",{value:t,enumerable:!0}):r,t)),WE=t=>a0(Ep({},"__esModule",{value:!0}),t);var xr=m(k=>{"use strict";Object.defineProperty(k,"__esModule",{value:!0});k.MCP_SERVER_AUTH_MODES=k.OAUTH_POPUP_CLOSED_MESSAGE=k.OAUTH_CONTINUATION_REASON_MAX_CHARS=k.TEAMS_CHANNEL_STARTER_PROMPTS=k.AGENT_REQUEST_BUSY_STATUSES=k.NEXT_STEP_LINK_ACTIONS=k.NEXT_STEP_LINK_PARAMS=k.NEXT_STEP_STATUSES=k.AGENT_SESSION_TEAMS_METADATA_KEY=k.AGENT_SESSION_TASK_PREPARATION_METADATA_KEY=k.AGENT_SESSION_USER_OPENED_METADATA_KEY=k.AGENT_SESSION_RESOURCE_KINDS=k.AGENT_MESSAGE_SCHEMA_VERSION=k.AGENT_APPROVAL_MODES=k.ConfirmationAction=k.LOADABLE_MARKDOWN_NAMES=k.SKILL_REFERENCE_NAMES=k.SKILL_BODY_NAMES=k.AGENT_CHECKLIST_MAX_LABEL_CHARS=k.AGENT_CHECKLIST_MAX_ITEMS=k.AGENT_CHECKLIST_MIN_ITEMS=k.DYNAMIC_AGENT_TOOLS=k.AGENT_TOOLS=k.AGENT_NATIVE_TOOLS=k.MEMORY_AGENT_TYPES=k.PLAYBOOK_PLAYGROUND_DRAFT_ID=k.PLAYGROUND_TOOL_DRAFT_ID=k.AgentType=k.FileStatus=k.MAX_BULK_RESOURCE_SHARE_OPERATIONS=k.MAX_BULK_MUTATION_IDS=k.SERVER_MANAGED_CONFIG_FIELDS=k.RunExecutionKind=k.RequestSource=k.RunStatus=k.CredentialMode=k.UpsertMode=k.LogLevel=k.PaginationType=k.DecompressionMethod=k.AuthType=k.FileType=k.CacheMode=k.HttpMethod=k.SupportedFileType=k.AGENT_SESSION_BACKGROUND_JOBS_METADATA_KEY=k.AGENT_BACKGROUND_JOB_STATUSES=k.RUN_COMMAND_EFFECT_KINDS=k.CONNECTION_PROTOCOLS=k.TURN_CONTEXT_BLOCK_TYPES=void 0;k.PLAYBOOK_LIMITS=void 0;k.isRequestConfig=jJ;k.isTransformConfig=zJ;k.isAgentSessionOpenedByUser=S0;k.isAgentSessionHiddenUntilOpened=HJ;k.TURN_CONTEXT_BLOCK_TYPES=["connections","playbooks","artifacts","project","background-job"];k.CONNECTION_PROTOCOLS=["http","postgres","mssql","redis","mongodb","sftp","smb","odbc","script","suitecloud"];k.RUN_COMMAND_EFFECT_KINDS=["tool","tool_state","system","connection","project","schedule","session","briefing","mcp_server","role","playbook","artifact","share","org_settings","design_system","file","memory","visual"];k.AGENT_BACKGROUND_JOB_STATUSES=["running","completed","failed","stopped","lost"];k.AGENT_SESSION_BACKGROUND_JOBS_METADATA_KEY="backgroundJobs";var c0;(function(t){t.JSON="JSON",t.CSV="CSV",t.XML="XML",t.HTML="HTML",t.YAML="YAML",t.EXCEL="EXCEL",t.PDF="PDF",t.DOCX="DOCX",t.PPTX="PPTX",t.ZIP="ZIP",t.GZIP="GZIP",t.QBM="QBM",t.BINARY="BINARY",t.RAW="RAW",t.AUTO="AUTO"})(c0||(k.SupportedFileType=c0={}));var u0;(function(t){t.GET="GET",t.POST="POST",t.PUT="PUT",t.DELETE="DELETE",t.PATCH="PATCH",t.HEAD="HEAD",t.OPTIONS="OPTIONS"})(u0||(k.HttpMethod=u0={}));var l0;(function(t){t.ENABLED="ENABLED",t.READONLY="READONLY",t.WRITEONLY="WRITEONLY",t.DISABLED="DISABLED"})(l0||(k.CacheMode=l0={}));var d0;(function(t){t.CSV="CSV",t.JSON="JSON",t.XML="XML",t.YAML="YAML",t.EXCEL="EXCEL",t.HTML="HTML",t.PDF="PDF",t.DOCX="DOCX",t.PPTX="PPTX",t.ZIP="ZIP",t.BINARY="BINARY",t.RAW="RAW",t.AUTO="AUTO"})(d0||(k.FileType=d0={}));var A0;(function(t){t.NONE="NONE",t.OAUTH2="OAUTH2",t.HEADER="HEADER",t.QUERY_PARAM="QUERY_PARAM"})(A0||(k.AuthType=A0={}));var p0;(function(t){t.GZIP="GZIP",t.DEFLATE="DEFLATE",t.NONE="NONE",t.AUTO="AUTO",t.ZIP="ZIP"})(p0||(k.DecompressionMethod=p0={}));var f0;(function(t){t.OFFSET_BASED="OFFSET_BASED",t.PAGE_BASED="PAGE_BASED",t.CURSOR_BASED="CURSOR_BASED",t.DISABLED="DISABLED"})(f0||(k.PaginationType=f0={}));var h0;(function(t){t.DEBUG="DEBUG",t.INFO="INFO",t.WARN="WARN",t.ERROR="ERROR"})(h0||(k.LogLevel=h0={}));var g0;(function(t){t.CREATE="CREATE",t.UPDATE="UPDATE",t.UPSERT="UPSERT"})(g0||(k.UpsertMode=g0={}));var m0;(function(t){t.MERGE="MERGE",t.REPLACE="REPLACE"})(m0||(k.CredentialMode=m0={}));var y0;(function(t){t.RUNNING="RUNNING",t.SUCCESS="SUCCESS",t.FAILED="FAILED",t.ABORTED="ABORTED"})(y0||(k.RunStatus=y0={}));var E0;(function(t){t.API="api",t.FRONTEND="frontend",t.AGENT="agent",t.SCHEDULER="scheduler",t.MCP="mcp",t.TOOL_CHAIN="tool-chain",t.WEBHOOK="webhook",t.CLI="cli"})(E0||(k.RequestSource=E0={}));var I0;(function(t){t.FULL="full",t.DRAFT="draft",t.SINGLE_STEP="single-step"})(I0||(k.RunExecutionKind=I0={}));k.SERVER_MANAGED_CONFIG_FIELDS=["version","createdByUserId","createdAt","updatedAt","lastUsedAt"];k.MAX_BULK_MUTATION_IDS=100;k.MAX_BULK_RESOURCE_SHARE_OPERATIONS=1e3;function jJ(t){return!t||typeof t!="object"?!1:t.type==="request"||!("type"in t)||t.type===void 0}function zJ(t){return t?.type==="transform"}var C0;(function(t){t.PENDING="PENDING",t.UPLOADING="UPLOADING",t.PROCESSING="PROCESSING",t.COMPLETED="COMPLETED",t.FAILED="FAILED"})(C0||(k.FileStatus=C0={}));var Yn;(function(t){t.MAIN="main",t.PLAYGROUND="playground",t.PLAYBOOK_PLAYGROUND="playbook_playground",t.ARTIFACT_PLAYGROUND="artifact_playground",t.ACCESS_RULES="access_rules",t.CONNECTION_PLAYGROUND="connection_playground",t.OUTLOOK="outlook"})(Yn||(k.AgentType=Yn={}));k.PLAYGROUND_TOOL_DRAFT_ID="@playground-draft";k.PLAYBOOK_PLAYGROUND_DRAFT_ID="@playground-draft";k.MEMORY_AGENT_TYPES=[Yn.MAIN,Yn.OUTLOOK];k.AGENT_NATIVE_TOOLS=["run_command","load_skill","use_checklist","create_connection","setup_gateway","request_sign_off"];k.AGENT_TOOLS={[Yn.MAIN]:[...k.AGENT_NATIVE_TOOLS],[Yn.PLAYGROUND]:[...k.AGENT_NATIVE_TOOLS],[Yn.PLAYBOOK_PLAYGROUND]:[...k.AGENT_NATIVE_TOOLS],[Yn.ARTIFACT_PLAYGROUND]:[...k.AGENT_NATIVE_TOOLS],[Yn.ACCESS_RULES]:[...k.AGENT_NATIVE_TOOLS],[Yn.CONNECTION_PLAYGROUND]:[...k.AGENT_NATIVE_TOOLS],[Yn.OUTLOOK]:k.AGENT_NATIVE_TOOLS.filter(t=>t!=="use_checklist")};k.DYNAMIC_AGENT_TOOLS=["web_search"];k.AGENT_CHECKLIST_MIN_ITEMS=4;k.AGENT_CHECKLIST_MAX_ITEMS=15;k.AGENT_CHECKLIST_MAX_LABEL_CHARS=120;k.SKILL_BODY_NAMES=["superglue-info","tools","connections","access-management","tool-deployment","notifications","artifacts","playbooks","projects","superglue-brain","email","workspace-apps","meetings","design-system","demos","chat-visuals","acumatica","netsuite","sage-intacct","microsoft-dynamics"];k.SKILL_REFERENCE_NAMES=["http","graphql","postgres","mssql","odbc","redis","mongodb","sftp-smb","suitecloud","task-preparation","acumatica-configuration","microsoft-dynamics-dependencies","power-automate","sage-intacct-configuration","quickbooks-desktop-files","tool-files","tunnel-handling","artifacts-html","artifacts-excel"];k.LOADABLE_MARKDOWN_NAMES=[...k.SKILL_BODY_NAMES,...k.SKILL_REFERENCE_NAMES];var b0;(function(t){t.CONFIRMED="confirmed",t.DECLINED="declined",t.OAUTH_SUCCESS="oauth_success",t.OAUTH_FAILURE="oauth_failure"})(b0||(k.ConfirmationAction=b0={}));k.AGENT_APPROVAL_MODES=["ask","act"];k.AGENT_MESSAGE_SCHEMA_VERSION=1;k.AGENT_SESSION_RESOURCE_KINDS=["tool","system","playbook","artifact","briefing","credential"];k.AGENT_SESSION_USER_OPENED_METADATA_KEY="userOpened";k.AGENT_SESSION_TASK_PREPARATION_METADATA_KEY="taskPreparation";k.AGENT_SESSION_TEAMS_METADATA_KEY="teams";function S0(t){return t[k.AGENT_SESSION_USER_OPENED_METADATA_KEY]===!0}function HJ(t){return(t.resourceBinding?.kind==="briefing"||t.metadata[k.AGENT_SESSION_TASK_PREPARATION_METADATA_KEY]===!0)&&!S0(t.metadata)}k.NEXT_STEP_STATUSES=["open","started","done"];k.NEXT_STEP_LINK_PARAMS={id:"nextStep",action:"nextStepAction"};k.NEXT_STEP_LINK_ACTIONS=["start","done"];k.AGENT_REQUEST_BUSY_STATUSES=["queued","claimed","running","cancelling"];k.TEAMS_CHANNEL_STARTER_PROMPTS=[{title:"What is the project status?",description:"Progress, blockers, owners and dates"},{title:"What is waiting on me?",description:"Ask superglue anything in plain words"},{title:"Recap the last meeting",description:"Recap a meeting and update the tasks"}];k.OAUTH_CONTINUATION_REASON_MAX_CHARS=500;k.OAUTH_POPUP_CLOSED_MESSAGE="OAuth authentication did not complete.";k.MCP_SERVER_AUTH_MODES=["oauth","creator_api_key"];k.PLAYBOOK_LIMITS={name:120,whenToRun:500,inputs:25e3,instructions:1e5,completionCriteria:25e3,toolRefs:25,credentialRefs:10,fileRefs:15,compiledRender:512e3}});var ga=m(Xt=>{"use strict";var w0;Object.defineProperty(Xt,"__esModule",{value:!0});Xt.globalConfig=Xt.$ZodEncodeError=Xt.$ZodAsyncError=Xt.$brand=Xt.NEVER=void 0;Xt.$constructor=qJ;Xt.config=GJ;Xt.NEVER=Object.freeze({status:"aborted"});function qJ(t,e,r){function n(a,c){if(a._zod||Object.defineProperty(a,"_zod",{value:{def:c,constr:s,traits:new Set},enumerable:!1}),a._zod.traits.has(t))return;a._zod.traits.add(t),e(a,c);let u=s.prototype,l=Object.keys(u);for(let d=0;d<l.length;d++){let A=l[d];A in a||(a[A]=u[A].bind(a))}}let i=r?.Parent??Object;class o extends i{}Object.defineProperty(o,"name",{value:t});function s(a){var c;let u=r?.Parent?new o:this;n(u,a),(c=u._zod).deferred??(c.deferred=[]);for(let l of u._zod.deferred)l();return u}return Object.defineProperty(s,"init",{value:n}),Object.defineProperty(s,Symbol.hasInstance,{value:a=>r?.Parent&&a instanceof r.Parent?!0:a?._zod?.traits?.has(t)}),Object.defineProperty(s,"name",{value:t}),s}Xt.$brand=Symbol("zod_brand");var ZE=class extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}};Xt.$ZodAsyncError=ZE;var KE=class extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name="ZodEncodeError"}};Xt.$ZodEncodeError=KE;(w0=globalThis).__zod_globalConfig??(w0.__zod_globalConfig={});Xt.globalConfig=globalThis.__zod_globalConfig;function GJ(t){return t&&Object.assign(Xt.globalConfig,t),Xt.globalConfig}});var re=m(V=>{"use strict";Object.defineProperty(V,"__esModule",{value:!0});V.Class=V.BIGINT_FORMAT_RANGES=V.NUMBER_FORMAT_RANGES=V.primitiveTypes=V.propertyKeyTypes=V.getParsedType=V.allowsEval=V.captureStackTrace=void 0;V.assertEqual=VJ;V.assertNotEqual=JJ;V.assertIs=WJ;V.assertNever=ZJ;V.assert=KJ;V.getEnumValues=XJ;V.joinValues=eW;V.jsonStringifyReplacer=tW;V.cached=_0;V.nullish=rW;V.cleanRegex=nW;V.floatSafeRemainder=iW;V.defineLazy=oW;V.objectClone=sW;V.assignProp=ms;V.mergeDefs=Uo;V.cloneDef=aW;V.getElementAtPath=cW;V.promiseAllObject=uW;V.randomString=lW;V.esc=dW;V.slugify=AW;V.isObject=XE;V.isPlainObject=Ip;V.shallowClone=pW;V.numKeys=fW;V.escapeRegex=gW;V.clone=ys;V.normalizeParams=mW;V.createTransparentProxy=yW;V.stringifyPrimitive=Q0;V.optionalKeys=EW;V.pick=IW;V.omit=CW;V.extend=bW;V.safeExtend=SW;V.merge=wW;V.partial=BW;V.required=_W;V.aborted=QW;V.explicitlyAborted=vW;V.prefixIssues=DW;V.unwrapMessage=Ul;V.finalizeIssue=TW;V.getSizableOrigin=RW;V.getLengthableOrigin=NW;V.parsedType=kW;V.issue=OW;V.cleanEnum=UW;V.base64ToUint8Array=v0;V.uint8ArrayToBase64=D0;V.base64urlToUint8Array=MW;V.uint8ArrayToBase64url=xW;V.hexToUint8Array=LW;V.uint8ArrayToHex=PW;var YJ=ga();function VJ(t){return t}function JJ(t){return t}function WJ(t){}function ZJ(t){throw new Error("Unexpected value in exhaustive check")}function KJ(t){}function XJ(t){let e=Object.values(t).filter(n=>typeof n=="number");return Object.entries(t).filter(([n,i])=>e.indexOf(+n)===-1).map(([n,i])=>i)}function eW(t,e="|"){return t.map(r=>Q0(r)).join(e)}function tW(t,e){return typeof e=="bigint"?e.toString():e}function _0(t){return{get value(){{let r=t();return Object.defineProperty(this,"value",{value:r}),r}throw new Error("cached value already set")}}}function rW(t){return t==null}function nW(t){let e=t.startsWith("^")?1:0,r=t.endsWith("$")?t.length-1:t.length;return t.slice(e,r)}function iW(t,e){let r=t/e,n=Math.round(r),i=Number.EPSILON*Math.max(Math.abs(r),1);return Math.abs(r-n)<i?0:r-n}var B0=Symbol("evaluating");function oW(t,e,r){let n;Object.defineProperty(t,e,{get(){if(n!==B0)return n===void 0&&(n=B0,n=r()),n},set(i){Object.defineProperty(t,e,{value:i})},configurable:!0})}function sW(t){return Object.create(Object.getPrototypeOf(t),Object.getOwnPropertyDescriptors(t))}function ms(t,e,r){Object.defineProperty(t,e,{value:r,writable:!0,enumerable:!0,configurable:!0})}function Uo(...t){let e={};for(let r of t){let n=Object.getOwnPropertyDescriptors(r);Object.assign(e,n)}return Object.defineProperties({},e)}function aW(t){return Uo(t._zod.def)}function cW(t,e){return e?e.reduce((r,n)=>r?.[n],t):t}function uW(t){let e=Object.keys(t),r=e.map(n=>t[n]);return Promise.all(r).then(n=>{let i={};for(let o=0;o<e.length;o++)i[e[o]]=n[o];return i})}function lW(t=10){let e="abcdefghijklmnopqrstuvwxyz",r="";for(let n=0;n<t;n++)r+=e[Math.floor(Math.random()*e.length)];return r}function dW(t){return JSON.stringify(t)}function AW(t){return t.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}V.captureStackTrace="captureStackTrace"in Error?Error.captureStackTrace:(...t)=>{};function XE(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}V.allowsEval=_0(()=>{if(YJ.globalConfig.jitless||typeof navigator<"u"&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{let t=Function;return new t(""),!0}catch{return!1}});function Ip(t){if(XE(t)===!1)return!1;let e=t.constructor;if(e===void 0||typeof e!="function")return!0;let r=e.prototype;return!(XE(r)===!1||Object.prototype.hasOwnProperty.call(r,"isPrototypeOf")===!1)}function pW(t){return Ip(t)?{...t}:Array.isArray(t)?[...t]:t instanceof Map?new Map(t):t instanceof Set?new Set(t):t}function fW(t){let e=0;for(let r in t)Object.prototype.hasOwnProperty.call(t,r)&&e++;return e}var hW=t=>{let e=typeof t;switch(e){case"undefined":return"undefined";case"string":return"string";case"number":return Number.isNaN(t)?"nan":"number";case"boolean":return"boolean";case"function":return"function";case"bigint":return"bigint";case"symbol":return"symbol";case"object":return Array.isArray(t)?"array":t===null?"null":t.then&&typeof t.then=="function"&&t.catch&&typeof t.catch=="function"?"promise":typeof Map<"u"&&t instanceof Map?"map":typeof Set<"u"&&t instanceof Set?"set":typeof Date<"u"&&t instanceof Date?"date":typeof File<"u"&&t instanceof File?"file":"object";default:throw new Error(`Unknown data type: ${e}`)}};V.getParsedType=hW;V.propertyKeyTypes=new Set(["string","number","symbol"]);V.primitiveTypes=new Set(["string","number","bigint","boolean","symbol","undefined"]);function gW(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ys(t,e,r){let n=new t._zod.constr(e??t._zod.def);return(!e||r?.parent)&&(n._zod.parent=t),n}function mW(t){let e=t;if(!e)return{};if(typeof e=="string")return{error:()=>e};if(e?.message!==void 0){if(e?.error!==void 0)throw new Error("Cannot specify both `message` and `error` params");e.error=e.message}return delete e.message,typeof e.error=="string"?{...e,error:()=>e.error}:e}function yW(t){let e;return new Proxy({},{get(r,n,i){return e??(e=t()),Reflect.get(e,n,i)},set(r,n,i,o){return e??(e=t()),Reflect.set(e,n,i,o)},has(r,n){return e??(e=t()),Reflect.has(e,n)},deleteProperty(r,n){return e??(e=t()),Reflect.deleteProperty(e,n)},ownKeys(r){return e??(e=t()),Reflect.ownKeys(e)},getOwnPropertyDescriptor(r,n){return e??(e=t()),Reflect.getOwnPropertyDescriptor(e,n)},defineProperty(r,n,i){return e??(e=t()),Reflect.defineProperty(e,n,i)}})}function Q0(t){return typeof t=="bigint"?t.toString()+"n":typeof t=="string"?`"${t}"`:`${t}`}function EW(t){return Object.keys(t).filter(e=>t[e]._zod.optin==="optional"&&t[e]._zod.optout==="optional")}V.NUMBER_FORMAT_RANGES={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]};V.BIGINT_FORMAT_RANGES={int64:[BigInt("-9223372036854775808"),BigInt("9223372036854775807")],uint64:[BigInt(0),BigInt("18446744073709551615")]};function IW(t,e){let r=t._zod.def,n=r.checks;if(n&&n.length>0)throw new Error(".pick() cannot be used on object schemas containing refinements");let o=Uo(t._zod.def,{get shape(){let s={};for(let a in e){if(!(a in r.shape))throw new Error(`Unrecognized key: "${a}"`);e[a]&&(s[a]=r.shape[a])}return ms(this,"shape",s),s},checks:[]});return ys(t,o)}function CW(t,e){let r=t._zod.def,n=r.checks;if(n&&n.length>0)throw new Error(".omit() cannot be used on object schemas containing refinements");let o=Uo(t._zod.def,{get shape(){let s={...t._zod.def.shape};for(let a in e){if(!(a in r.shape))throw new Error(`Unrecognized key: "${a}"`);e[a]&&delete s[a]}return ms(this,"shape",s),s},checks:[]});return ys(t,o)}function bW(t,e){if(!Ip(e))throw new Error("Invalid input to extend: expected a plain object");let r=t._zod.def.checks;if(r&&r.length>0){let o=t._zod.def.shape;for(let s in e)if(Object.getOwnPropertyDescriptor(o,s)!==void 0)throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}let i=Uo(t._zod.def,{get shape(){let o={...t._zod.def.shape,...e};return ms(this,"shape",o),o}});return ys(t,i)}function SW(t,e){if(!Ip(e))throw new Error("Invalid input to safeExtend: expected a plain object");let r=Uo(t._zod.def,{get shape(){let n={...t._zod.def.shape,...e};return ms(this,"shape",n),n}});return ys(t,r)}function wW(t,e){if(t._zod.def.checks?.length)throw new Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");let r=Uo(t._zod.def,{get shape(){let n={...t._zod.def.shape,...e._zod.def.shape};return ms(this,"shape",n),n},get catchall(){return e._zod.def.catchall},checks:e._zod.def.checks??[]});return ys(t,r)}function BW(t,e,r){let i=e._zod.def.checks;if(i&&i.length>0)throw new Error(".partial() cannot be used on object schemas containing refinements");let s=Uo(e._zod.def,{get shape(){let a=e._zod.def.shape,c={...a};if(r)for(let u in r){if(!(u in a))throw new Error(`Unrecognized key: "${u}"`);r[u]&&(c[u]=t?new t({type:"optional",innerType:a[u]}):a[u])}else for(let u in a)c[u]=t?new t({type:"optional",innerType:a[u]}):a[u];return ms(this,"shape",c),c},checks:[]});return ys(e,s)}function _W(t,e,r){let n=Uo(e._zod.def,{get shape(){let i=e._zod.def.shape,o={...i};if(r)for(let s in r){if(!(s in o))throw new Error(`Unrecognized key: "${s}"`);r[s]&&(o[s]=new t({type:"nonoptional",innerType:i[s]}))}else for(let s in i)o[s]=new t({type:"nonoptional",innerType:i[s]});return ms(this,"shape",o),o}});return ys(e,n)}function QW(t,e=0){if(t.aborted===!0)return!0;for(let r=e;r<t.issues.length;r++)if(t.issues[r]?.continue!==!0)return!0;return!1}function vW(t,e=0){if(t.aborted===!0)return!0;for(let r=e;r<t.issues.length;r++)if(t.issues[r]?.continue===!1)return!0;return!1}function DW(t,e){return e.map(r=>{var n;return(n=r).path??(n.path=[]),r.path.unshift(t),r})}function Ul(t){return typeof t=="string"?t:t?.message}function TW(t,e,r){let n=t.message?t.message:Ul(t.inst?._zod.def?.error?.(t))??Ul(e?.error?.(t))??Ul(r.customError?.(t))??Ul(r.localeError?.(t))??"Invalid input",{inst:i,continue:o,input:s,...a}=t;return a.path??(a.path=[]),a.message=n,e?.reportInput&&(a.input=s),a}function RW(t){return t instanceof Set?"set":t instanceof Map?"map":t instanceof File?"file":"unknown"}function NW(t){return Array.isArray(t)?"array":typeof t=="string"?"string":"unknown"}function kW(t){let e=typeof t;switch(e){case"number":return Number.isNaN(t)?"nan":"number";case"object":{if(t===null)return"null";if(Array.isArray(t))return"array";let r=t;if(r&&Object.getPrototypeOf(r)!==Object.prototype&&"constructor"in r&&r.constructor)return r.constructor.name}}return e}function OW(...t){let[e,r,n]=t;return typeof e=="string"?{message:e,code:"custom",input:r,inst:n}:{...e}}function UW(t){return Object.entries(t).filter(([e,r])=>Number.isNaN(Number.parseInt(e,10))).map(e=>e[1])}function v0(t){let e=atob(t),r=new Uint8Array(e.length);for(let n=0;n<e.length;n++)r[n]=e.charCodeAt(n);return r}function D0(t){let e="";for(let r=0;r<t.length;r++)e+=String.fromCharCode(t[r]);return btoa(e)}function MW(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),r="=".repeat((4-e.length%4)%4);return v0(e+r)}function xW(t){return D0(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function LW(t){let e=t.replace(/^0x/,"");if(e.length%2!==0)throw new Error("Invalid hex string length");let r=new Uint8Array(e.length/2);for(let n=0;n<e.length;n+=2)r[n/2]=Number.parseInt(e.slice(n,n+2),16);return r}function PW(t){return Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("")}var eI=class{constructor(...e){}};V.Class=eI});var tI=m(Jt=>{"use strict";var $W=Jt&&Jt.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),FW=Jt&&Jt.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),jW=Jt&&Jt.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&$W(e,t,r);return FW(e,t),e};Object.defineProperty(Jt,"__esModule",{value:!0});Jt.$ZodRealError=Jt.$ZodError=void 0;Jt.flattenError=HW;Jt.formatError=qW;Jt.treeifyError=GW;Jt.toDotPath=N0;Jt.prettifyError=YW;var T0=ga(),zW=jW(re()),R0=(t,e)=>{t.name="$ZodError",Object.defineProperty(t,"_zod",{value:t._zod,enumerable:!1}),Object.defineProperty(t,"issues",{value:e,enumerable:!1}),t.message=JSON.stringify(e,zW.jsonStringifyReplacer,2),Object.defineProperty(t,"toString",{value:()=>t.message,enumerable:!1})};Jt.$ZodError=(0,T0.$constructor)("$ZodError",R0);Jt.$ZodRealError=(0,T0.$constructor)("$ZodError",R0,{Parent:Error});function HW(t,e=r=>r.message){let r={},n=[];for(let i of t.issues)i.path.length>0?(r[i.path[0]]=r[i.path[0]]||[],r[i.path[0]].push(e(i))):n.push(e(i));return{formErrors:n,fieldErrors:r}}function qW(t,e=r=>r.message){let r={_errors:[]},n=(i,o=[])=>{for(let s of i.issues)if(s.code==="invalid_union"&&s.errors.length)s.errors.map(a=>n({issues:a},[...o,...s.path]));else if(s.code==="invalid_key")n({issues:s.issues},[...o,...s.path]);else if(s.code==="invalid_element")n({issues:s.issues},[...o,...s.path]);else{let a=[...o,...s.path];if(a.length===0)r._errors.push(e(s));else{let c=r,u=0;for(;u<a.length;){let l=a[u];u===a.length-1?(c[l]=c[l]||{_errors:[]},c[l]._errors.push(e(s))):c[l]=c[l]||{_errors:[]},c=c[l],u++}}}};return n(t),r}function GW(t,e=r=>r.message){let r={errors:[]},n=(i,o=[])=>{var s,a;for(let c of i.issues)if(c.code==="invalid_union"&&c.errors.length)c.errors.map(u=>n({issues:u},[...o,...c.path]));else if(c.code==="invalid_key")n({issues:c.issues},[...o,...c.path]);else if(c.code==="invalid_element")n({issues:c.issues},[...o,...c.path]);else{let u=[...o,...c.path];if(u.length===0){r.errors.push(e(c));continue}let l=r,d=0;for(;d<u.length;){let A=u[d],p=d===u.length-1;typeof A=="string"?(l.properties??(l.properties={}),(s=l.properties)[A]??(s[A]={errors:[]}),l=l.properties[A]):(l.items??(l.items=[]),(a=l.items)[A]??(a[A]={errors:[]}),l=l.items[A]),p&&l.errors.push(e(c)),d++}}};return n(t),r}function N0(t){let e=[],r=t.map(n=>typeof n=="object"?n.key:n);for(let n of r)typeof n=="number"?e.push(`[${n}]`):typeof n=="symbol"?e.push(`[${JSON.stringify(String(n))}]`):/[^\w$]/.test(n)?e.push(`[${JSON.stringify(n)}]`):(e.length&&e.push("."),e.push(n));return e.join("")}function YW(t){let e=[],r=[...t.issues].sort((n,i)=>(n.path??[]).length-(i.path??[]).length);for(let n of r)e.push(`\u2716 ${n.message}`),n.path?.length&&e.push(` \u2192 at ${N0(n.path)}`);return e.join(`
2
+ "use strict";var xJ=Object.create;var Ep=Object.defineProperty;var LJ=Object.getOwnPropertyDescriptor;var PJ=Object.getOwnPropertyNames;var $J=Object.getPrototypeOf,FJ=Object.prototype.hasOwnProperty;var Xe=(t,e)=>()=>(t&&(e=t(t=0)),e);var m=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),s0=(t,e)=>{for(var r in e)Ep(t,r,{get:e[r],enumerable:!0})},a0=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of PJ(e))!FJ.call(t,i)&&i!==r&&Ep(t,i,{get:()=>e[i],enumerable:!(n=LJ(e,i))||n.enumerable});return t};var ye=(t,e,r)=>(r=t!=null?xJ($J(t)):{},a0(e||!t||!t.__esModule?Ep(r,"default",{value:t,enumerable:!0}):r,t)),WE=t=>a0(Ep({},"__esModule",{value:!0}),t);var xr=m(k=>{"use strict";Object.defineProperty(k,"__esModule",{value:!0});k.MCP_SERVER_AUTH_MODES=k.OAUTH_POPUP_CLOSED_MESSAGE=k.OAUTH_CONTINUATION_REASON_MAX_CHARS=k.TEAMS_CHANNEL_STARTER_PROMPTS=k.AGENT_REQUEST_BUSY_STATUSES=k.NEXT_STEP_LINK_ACTIONS=k.NEXT_STEP_LINK_PARAMS=k.NEXT_STEP_STATUSES=k.AGENT_SESSION_TEAMS_METADATA_KEY=k.AGENT_SESSION_TASK_PREPARATION_METADATA_KEY=k.AGENT_SESSION_USER_OPENED_METADATA_KEY=k.AGENT_SESSION_RESOURCE_KINDS=k.AGENT_MESSAGE_SCHEMA_VERSION=k.AGENT_APPROVAL_MODES=k.ConfirmationAction=k.LOADABLE_MARKDOWN_NAMES=k.SKILL_REFERENCE_NAMES=k.SKILL_BODY_NAMES=k.AGENT_CHECKLIST_MAX_LABEL_CHARS=k.AGENT_CHECKLIST_MAX_ITEMS=k.AGENT_CHECKLIST_MIN_ITEMS=k.DYNAMIC_AGENT_TOOLS=k.AGENT_TOOLS=k.AGENT_NATIVE_TOOLS=k.MEMORY_AGENT_TYPES=k.PLAYBOOK_PLAYGROUND_DRAFT_ID=k.PLAYGROUND_TOOL_DRAFT_ID=k.AgentType=k.FileStatus=k.MAX_BULK_RESOURCE_SHARE_OPERATIONS=k.MAX_BULK_MUTATION_IDS=k.SERVER_MANAGED_CONFIG_FIELDS=k.RunExecutionKind=k.RequestSource=k.RunStatus=k.CredentialMode=k.UpsertMode=k.LogLevel=k.PaginationType=k.DecompressionMethod=k.AuthType=k.FileType=k.CacheMode=k.HttpMethod=k.SupportedFileType=k.AGENT_SESSION_BACKGROUND_JOBS_METADATA_KEY=k.AGENT_BACKGROUND_JOB_STATUSES=k.RUN_COMMAND_EFFECT_KINDS=k.CONNECTION_PROTOCOLS=k.TURN_CONTEXT_BLOCK_TYPES=void 0;k.PLAYBOOK_LIMITS=void 0;k.isRequestConfig=jJ;k.isTransformConfig=zJ;k.isAgentSessionOpenedByUser=S0;k.isAgentSessionHiddenUntilOpened=HJ;k.TURN_CONTEXT_BLOCK_TYPES=["connections","playbooks","artifacts","project","background-job"];k.CONNECTION_PROTOCOLS=["http","postgres","mssql","redis","mongodb","sftp","smb","odbc","script","suitecloud"];k.RUN_COMMAND_EFFECT_KINDS=["tool","tool_state","system","connection","project","schedule","session","briefing","mcp_server","role","playbook","artifact","share","org_settings","design_system","file","memory","visual"];k.AGENT_BACKGROUND_JOB_STATUSES=["running","completed","failed","stopped","lost"];k.AGENT_SESSION_BACKGROUND_JOBS_METADATA_KEY="backgroundJobs";var c0;(function(t){t.JSON="JSON",t.CSV="CSV",t.XML="XML",t.HTML="HTML",t.YAML="YAML",t.EXCEL="EXCEL",t.PDF="PDF",t.DOCX="DOCX",t.PPTX="PPTX",t.ZIP="ZIP",t.GZIP="GZIP",t.QBM="QBM",t.BINARY="BINARY",t.RAW="RAW",t.AUTO="AUTO"})(c0||(k.SupportedFileType=c0={}));var u0;(function(t){t.GET="GET",t.POST="POST",t.PUT="PUT",t.DELETE="DELETE",t.PATCH="PATCH",t.HEAD="HEAD",t.OPTIONS="OPTIONS"})(u0||(k.HttpMethod=u0={}));var l0;(function(t){t.ENABLED="ENABLED",t.READONLY="READONLY",t.WRITEONLY="WRITEONLY",t.DISABLED="DISABLED"})(l0||(k.CacheMode=l0={}));var d0;(function(t){t.CSV="CSV",t.JSON="JSON",t.XML="XML",t.YAML="YAML",t.EXCEL="EXCEL",t.HTML="HTML",t.PDF="PDF",t.DOCX="DOCX",t.PPTX="PPTX",t.ZIP="ZIP",t.BINARY="BINARY",t.RAW="RAW",t.AUTO="AUTO"})(d0||(k.FileType=d0={}));var A0;(function(t){t.NONE="NONE",t.OAUTH2="OAUTH2",t.HEADER="HEADER",t.QUERY_PARAM="QUERY_PARAM"})(A0||(k.AuthType=A0={}));var p0;(function(t){t.GZIP="GZIP",t.DEFLATE="DEFLATE",t.NONE="NONE",t.AUTO="AUTO",t.ZIP="ZIP"})(p0||(k.DecompressionMethod=p0={}));var f0;(function(t){t.OFFSET_BASED="OFFSET_BASED",t.PAGE_BASED="PAGE_BASED",t.CURSOR_BASED="CURSOR_BASED",t.DISABLED="DISABLED"})(f0||(k.PaginationType=f0={}));var h0;(function(t){t.DEBUG="DEBUG",t.INFO="INFO",t.WARN="WARN",t.ERROR="ERROR"})(h0||(k.LogLevel=h0={}));var g0;(function(t){t.CREATE="CREATE",t.UPDATE="UPDATE",t.UPSERT="UPSERT"})(g0||(k.UpsertMode=g0={}));var m0;(function(t){t.MERGE="MERGE",t.REPLACE="REPLACE"})(m0||(k.CredentialMode=m0={}));var y0;(function(t){t.RUNNING="RUNNING",t.SUCCESS="SUCCESS",t.FAILED="FAILED",t.ABORTED="ABORTED"})(y0||(k.RunStatus=y0={}));var E0;(function(t){t.API="api",t.FRONTEND="frontend",t.AGENT="agent",t.SCHEDULER="scheduler",t.MCP="mcp",t.TOOL_CHAIN="tool-chain",t.WEBHOOK="webhook",t.CLI="cli"})(E0||(k.RequestSource=E0={}));var I0;(function(t){t.FULL="full",t.DRAFT="draft",t.SINGLE_STEP="single-step"})(I0||(k.RunExecutionKind=I0={}));k.SERVER_MANAGED_CONFIG_FIELDS=["version","createdByUserId","createdAt","updatedAt","lastUsedAt"];k.MAX_BULK_MUTATION_IDS=100;k.MAX_BULK_RESOURCE_SHARE_OPERATIONS=1e3;function jJ(t){return!t||typeof t!="object"?!1:t.type==="request"||!("type"in t)||t.type===void 0}function zJ(t){return t?.type==="transform"}var C0;(function(t){t.PENDING="PENDING",t.UPLOADING="UPLOADING",t.PROCESSING="PROCESSING",t.COMPLETED="COMPLETED",t.FAILED="FAILED"})(C0||(k.FileStatus=C0={}));var Yn;(function(t){t.MAIN="main",t.PLAYGROUND="playground",t.PLAYBOOK_PLAYGROUND="playbook_playground",t.ARTIFACT_PLAYGROUND="artifact_playground",t.ACCESS_RULES="access_rules",t.CONNECTION_PLAYGROUND="connection_playground",t.OUTLOOK="outlook"})(Yn||(k.AgentType=Yn={}));k.PLAYGROUND_TOOL_DRAFT_ID="@playground-draft";k.PLAYBOOK_PLAYGROUND_DRAFT_ID="@playground-draft";k.MEMORY_AGENT_TYPES=[Yn.MAIN,Yn.OUTLOOK];k.AGENT_NATIVE_TOOLS=["run_command","load_skill","use_checklist","connect","setup_gateway","request_sign_off"];k.AGENT_TOOLS={[Yn.MAIN]:[...k.AGENT_NATIVE_TOOLS],[Yn.PLAYGROUND]:[...k.AGENT_NATIVE_TOOLS],[Yn.PLAYBOOK_PLAYGROUND]:[...k.AGENT_NATIVE_TOOLS],[Yn.ARTIFACT_PLAYGROUND]:[...k.AGENT_NATIVE_TOOLS],[Yn.ACCESS_RULES]:[...k.AGENT_NATIVE_TOOLS],[Yn.CONNECTION_PLAYGROUND]:[...k.AGENT_NATIVE_TOOLS],[Yn.OUTLOOK]:k.AGENT_NATIVE_TOOLS.filter(t=>t!=="use_checklist")};k.DYNAMIC_AGENT_TOOLS=["web_search"];k.AGENT_CHECKLIST_MIN_ITEMS=4;k.AGENT_CHECKLIST_MAX_ITEMS=15;k.AGENT_CHECKLIST_MAX_LABEL_CHARS=120;k.SKILL_BODY_NAMES=["superglue-info","tools","connections","access-management","tool-deployment","notifications","artifacts","playbooks","projects","superglue-brain","email","workspace-apps","meetings","design-system","demos","chat-visuals","acumatica","netsuite","sage-intacct","microsoft-dynamics"];k.SKILL_REFERENCE_NAMES=["http","graphql","postgres","mssql","odbc","redis","mongodb","sftp-smb","suitecloud","task-preparation","acumatica-configuration","microsoft-dynamics-dependencies","power-automate","sage-intacct-configuration","quickbooks-desktop-files","tool-files","tunnel-handling","artifacts-html","artifacts-excel"];k.LOADABLE_MARKDOWN_NAMES=[...k.SKILL_BODY_NAMES,...k.SKILL_REFERENCE_NAMES];var b0;(function(t){t.CONFIRMED="confirmed",t.DECLINED="declined",t.OAUTH_SUCCESS="oauth_success",t.OAUTH_FAILURE="oauth_failure"})(b0||(k.ConfirmationAction=b0={}));k.AGENT_APPROVAL_MODES=["ask","act"];k.AGENT_MESSAGE_SCHEMA_VERSION=1;k.AGENT_SESSION_RESOURCE_KINDS=["tool","system","playbook","artifact","briefing","credential"];k.AGENT_SESSION_USER_OPENED_METADATA_KEY="userOpened";k.AGENT_SESSION_TASK_PREPARATION_METADATA_KEY="taskPreparation";k.AGENT_SESSION_TEAMS_METADATA_KEY="teams";function S0(t){return t[k.AGENT_SESSION_USER_OPENED_METADATA_KEY]===!0}function HJ(t){return(t.resourceBinding?.kind==="briefing"||t.metadata[k.AGENT_SESSION_TASK_PREPARATION_METADATA_KEY]===!0)&&!S0(t.metadata)}k.NEXT_STEP_STATUSES=["open","started","done"];k.NEXT_STEP_LINK_PARAMS={id:"nextStep",action:"nextStepAction"};k.NEXT_STEP_LINK_ACTIONS=["start","done"];k.AGENT_REQUEST_BUSY_STATUSES=["queued","claimed","running","cancelling"];k.TEAMS_CHANNEL_STARTER_PROMPTS=[{title:"What is the project status?",description:"Progress, blockers, owners and dates"},{title:"What is waiting on me?",description:"Ask superglue anything in plain words"},{title:"Recap the last meeting",description:"Recap a meeting and update the tasks"}];k.OAUTH_CONTINUATION_REASON_MAX_CHARS=500;k.OAUTH_POPUP_CLOSED_MESSAGE="OAuth authentication did not complete.";k.MCP_SERVER_AUTH_MODES=["oauth","creator_api_key"];k.PLAYBOOK_LIMITS={name:120,whenToRun:500,inputs:25e3,instructions:1e5,completionCriteria:25e3,toolRefs:25,credentialRefs:10,fileRefs:15,compiledRender:512e3}});var ga=m(Xt=>{"use strict";var w0;Object.defineProperty(Xt,"__esModule",{value:!0});Xt.globalConfig=Xt.$ZodEncodeError=Xt.$ZodAsyncError=Xt.$brand=Xt.NEVER=void 0;Xt.$constructor=qJ;Xt.config=GJ;Xt.NEVER=Object.freeze({status:"aborted"});function qJ(t,e,r){function n(a,c){if(a._zod||Object.defineProperty(a,"_zod",{value:{def:c,constr:s,traits:new Set},enumerable:!1}),a._zod.traits.has(t))return;a._zod.traits.add(t),e(a,c);let u=s.prototype,l=Object.keys(u);for(let d=0;d<l.length;d++){let A=l[d];A in a||(a[A]=u[A].bind(a))}}let i=r?.Parent??Object;class o extends i{}Object.defineProperty(o,"name",{value:t});function s(a){var c;let u=r?.Parent?new o:this;n(u,a),(c=u._zod).deferred??(c.deferred=[]);for(let l of u._zod.deferred)l();return u}return Object.defineProperty(s,"init",{value:n}),Object.defineProperty(s,Symbol.hasInstance,{value:a=>r?.Parent&&a instanceof r.Parent?!0:a?._zod?.traits?.has(t)}),Object.defineProperty(s,"name",{value:t}),s}Xt.$brand=Symbol("zod_brand");var ZE=class extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}};Xt.$ZodAsyncError=ZE;var KE=class extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name="ZodEncodeError"}};Xt.$ZodEncodeError=KE;(w0=globalThis).__zod_globalConfig??(w0.__zod_globalConfig={});Xt.globalConfig=globalThis.__zod_globalConfig;function GJ(t){return t&&Object.assign(Xt.globalConfig,t),Xt.globalConfig}});var re=m(V=>{"use strict";Object.defineProperty(V,"__esModule",{value:!0});V.Class=V.BIGINT_FORMAT_RANGES=V.NUMBER_FORMAT_RANGES=V.primitiveTypes=V.propertyKeyTypes=V.getParsedType=V.allowsEval=V.captureStackTrace=void 0;V.assertEqual=VJ;V.assertNotEqual=JJ;V.assertIs=WJ;V.assertNever=ZJ;V.assert=KJ;V.getEnumValues=XJ;V.joinValues=eW;V.jsonStringifyReplacer=tW;V.cached=_0;V.nullish=rW;V.cleanRegex=nW;V.floatSafeRemainder=iW;V.defineLazy=oW;V.objectClone=sW;V.assignProp=ms;V.mergeDefs=Uo;V.cloneDef=aW;V.getElementAtPath=cW;V.promiseAllObject=uW;V.randomString=lW;V.esc=dW;V.slugify=AW;V.isObject=XE;V.isPlainObject=Ip;V.shallowClone=pW;V.numKeys=fW;V.escapeRegex=gW;V.clone=ys;V.normalizeParams=mW;V.createTransparentProxy=yW;V.stringifyPrimitive=Q0;V.optionalKeys=EW;V.pick=IW;V.omit=CW;V.extend=bW;V.safeExtend=SW;V.merge=wW;V.partial=BW;V.required=_W;V.aborted=QW;V.explicitlyAborted=vW;V.prefixIssues=DW;V.unwrapMessage=Ul;V.finalizeIssue=TW;V.getSizableOrigin=RW;V.getLengthableOrigin=NW;V.parsedType=kW;V.issue=OW;V.cleanEnum=UW;V.base64ToUint8Array=v0;V.uint8ArrayToBase64=D0;V.base64urlToUint8Array=MW;V.uint8ArrayToBase64url=xW;V.hexToUint8Array=LW;V.uint8ArrayToHex=PW;var YJ=ga();function VJ(t){return t}function JJ(t){return t}function WJ(t){}function ZJ(t){throw new Error("Unexpected value in exhaustive check")}function KJ(t){}function XJ(t){let e=Object.values(t).filter(n=>typeof n=="number");return Object.entries(t).filter(([n,i])=>e.indexOf(+n)===-1).map(([n,i])=>i)}function eW(t,e="|"){return t.map(r=>Q0(r)).join(e)}function tW(t,e){return typeof e=="bigint"?e.toString():e}function _0(t){return{get value(){{let r=t();return Object.defineProperty(this,"value",{value:r}),r}throw new Error("cached value already set")}}}function rW(t){return t==null}function nW(t){let e=t.startsWith("^")?1:0,r=t.endsWith("$")?t.length-1:t.length;return t.slice(e,r)}function iW(t,e){let r=t/e,n=Math.round(r),i=Number.EPSILON*Math.max(Math.abs(r),1);return Math.abs(r-n)<i?0:r-n}var B0=Symbol("evaluating");function oW(t,e,r){let n;Object.defineProperty(t,e,{get(){if(n!==B0)return n===void 0&&(n=B0,n=r()),n},set(i){Object.defineProperty(t,e,{value:i})},configurable:!0})}function sW(t){return Object.create(Object.getPrototypeOf(t),Object.getOwnPropertyDescriptors(t))}function ms(t,e,r){Object.defineProperty(t,e,{value:r,writable:!0,enumerable:!0,configurable:!0})}function Uo(...t){let e={};for(let r of t){let n=Object.getOwnPropertyDescriptors(r);Object.assign(e,n)}return Object.defineProperties({},e)}function aW(t){return Uo(t._zod.def)}function cW(t,e){return e?e.reduce((r,n)=>r?.[n],t):t}function uW(t){let e=Object.keys(t),r=e.map(n=>t[n]);return Promise.all(r).then(n=>{let i={};for(let o=0;o<e.length;o++)i[e[o]]=n[o];return i})}function lW(t=10){let e="abcdefghijklmnopqrstuvwxyz",r="";for(let n=0;n<t;n++)r+=e[Math.floor(Math.random()*e.length)];return r}function dW(t){return JSON.stringify(t)}function AW(t){return t.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}V.captureStackTrace="captureStackTrace"in Error?Error.captureStackTrace:(...t)=>{};function XE(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}V.allowsEval=_0(()=>{if(YJ.globalConfig.jitless||typeof navigator<"u"&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{let t=Function;return new t(""),!0}catch{return!1}});function Ip(t){if(XE(t)===!1)return!1;let e=t.constructor;if(e===void 0||typeof e!="function")return!0;let r=e.prototype;return!(XE(r)===!1||Object.prototype.hasOwnProperty.call(r,"isPrototypeOf")===!1)}function pW(t){return Ip(t)?{...t}:Array.isArray(t)?[...t]:t instanceof Map?new Map(t):t instanceof Set?new Set(t):t}function fW(t){let e=0;for(let r in t)Object.prototype.hasOwnProperty.call(t,r)&&e++;return e}var hW=t=>{let e=typeof t;switch(e){case"undefined":return"undefined";case"string":return"string";case"number":return Number.isNaN(t)?"nan":"number";case"boolean":return"boolean";case"function":return"function";case"bigint":return"bigint";case"symbol":return"symbol";case"object":return Array.isArray(t)?"array":t===null?"null":t.then&&typeof t.then=="function"&&t.catch&&typeof t.catch=="function"?"promise":typeof Map<"u"&&t instanceof Map?"map":typeof Set<"u"&&t instanceof Set?"set":typeof Date<"u"&&t instanceof Date?"date":typeof File<"u"&&t instanceof File?"file":"object";default:throw new Error(`Unknown data type: ${e}`)}};V.getParsedType=hW;V.propertyKeyTypes=new Set(["string","number","symbol"]);V.primitiveTypes=new Set(["string","number","bigint","boolean","symbol","undefined"]);function gW(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ys(t,e,r){let n=new t._zod.constr(e??t._zod.def);return(!e||r?.parent)&&(n._zod.parent=t),n}function mW(t){let e=t;if(!e)return{};if(typeof e=="string")return{error:()=>e};if(e?.message!==void 0){if(e?.error!==void 0)throw new Error("Cannot specify both `message` and `error` params");e.error=e.message}return delete e.message,typeof e.error=="string"?{...e,error:()=>e.error}:e}function yW(t){let e;return new Proxy({},{get(r,n,i){return e??(e=t()),Reflect.get(e,n,i)},set(r,n,i,o){return e??(e=t()),Reflect.set(e,n,i,o)},has(r,n){return e??(e=t()),Reflect.has(e,n)},deleteProperty(r,n){return e??(e=t()),Reflect.deleteProperty(e,n)},ownKeys(r){return e??(e=t()),Reflect.ownKeys(e)},getOwnPropertyDescriptor(r,n){return e??(e=t()),Reflect.getOwnPropertyDescriptor(e,n)},defineProperty(r,n,i){return e??(e=t()),Reflect.defineProperty(e,n,i)}})}function Q0(t){return typeof t=="bigint"?t.toString()+"n":typeof t=="string"?`"${t}"`:`${t}`}function EW(t){return Object.keys(t).filter(e=>t[e]._zod.optin==="optional"&&t[e]._zod.optout==="optional")}V.NUMBER_FORMAT_RANGES={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]};V.BIGINT_FORMAT_RANGES={int64:[BigInt("-9223372036854775808"),BigInt("9223372036854775807")],uint64:[BigInt(0),BigInt("18446744073709551615")]};function IW(t,e){let r=t._zod.def,n=r.checks;if(n&&n.length>0)throw new Error(".pick() cannot be used on object schemas containing refinements");let o=Uo(t._zod.def,{get shape(){let s={};for(let a in e){if(!(a in r.shape))throw new Error(`Unrecognized key: "${a}"`);e[a]&&(s[a]=r.shape[a])}return ms(this,"shape",s),s},checks:[]});return ys(t,o)}function CW(t,e){let r=t._zod.def,n=r.checks;if(n&&n.length>0)throw new Error(".omit() cannot be used on object schemas containing refinements");let o=Uo(t._zod.def,{get shape(){let s={...t._zod.def.shape};for(let a in e){if(!(a in r.shape))throw new Error(`Unrecognized key: "${a}"`);e[a]&&delete s[a]}return ms(this,"shape",s),s},checks:[]});return ys(t,o)}function bW(t,e){if(!Ip(e))throw new Error("Invalid input to extend: expected a plain object");let r=t._zod.def.checks;if(r&&r.length>0){let o=t._zod.def.shape;for(let s in e)if(Object.getOwnPropertyDescriptor(o,s)!==void 0)throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}let i=Uo(t._zod.def,{get shape(){let o={...t._zod.def.shape,...e};return ms(this,"shape",o),o}});return ys(t,i)}function SW(t,e){if(!Ip(e))throw new Error("Invalid input to safeExtend: expected a plain object");let r=Uo(t._zod.def,{get shape(){let n={...t._zod.def.shape,...e};return ms(this,"shape",n),n}});return ys(t,r)}function wW(t,e){if(t._zod.def.checks?.length)throw new Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");let r=Uo(t._zod.def,{get shape(){let n={...t._zod.def.shape,...e._zod.def.shape};return ms(this,"shape",n),n},get catchall(){return e._zod.def.catchall},checks:e._zod.def.checks??[]});return ys(t,r)}function BW(t,e,r){let i=e._zod.def.checks;if(i&&i.length>0)throw new Error(".partial() cannot be used on object schemas containing refinements");let s=Uo(e._zod.def,{get shape(){let a=e._zod.def.shape,c={...a};if(r)for(let u in r){if(!(u in a))throw new Error(`Unrecognized key: "${u}"`);r[u]&&(c[u]=t?new t({type:"optional",innerType:a[u]}):a[u])}else for(let u in a)c[u]=t?new t({type:"optional",innerType:a[u]}):a[u];return ms(this,"shape",c),c},checks:[]});return ys(e,s)}function _W(t,e,r){let n=Uo(e._zod.def,{get shape(){let i=e._zod.def.shape,o={...i};if(r)for(let s in r){if(!(s in o))throw new Error(`Unrecognized key: "${s}"`);r[s]&&(o[s]=new t({type:"nonoptional",innerType:i[s]}))}else for(let s in i)o[s]=new t({type:"nonoptional",innerType:i[s]});return ms(this,"shape",o),o}});return ys(e,n)}function QW(t,e=0){if(t.aborted===!0)return!0;for(let r=e;r<t.issues.length;r++)if(t.issues[r]?.continue!==!0)return!0;return!1}function vW(t,e=0){if(t.aborted===!0)return!0;for(let r=e;r<t.issues.length;r++)if(t.issues[r]?.continue===!1)return!0;return!1}function DW(t,e){return e.map(r=>{var n;return(n=r).path??(n.path=[]),r.path.unshift(t),r})}function Ul(t){return typeof t=="string"?t:t?.message}function TW(t,e,r){let n=t.message?t.message:Ul(t.inst?._zod.def?.error?.(t))??Ul(e?.error?.(t))??Ul(r.customError?.(t))??Ul(r.localeError?.(t))??"Invalid input",{inst:i,continue:o,input:s,...a}=t;return a.path??(a.path=[]),a.message=n,e?.reportInput&&(a.input=s),a}function RW(t){return t instanceof Set?"set":t instanceof Map?"map":t instanceof File?"file":"unknown"}function NW(t){return Array.isArray(t)?"array":typeof t=="string"?"string":"unknown"}function kW(t){let e=typeof t;switch(e){case"number":return Number.isNaN(t)?"nan":"number";case"object":{if(t===null)return"null";if(Array.isArray(t))return"array";let r=t;if(r&&Object.getPrototypeOf(r)!==Object.prototype&&"constructor"in r&&r.constructor)return r.constructor.name}}return e}function OW(...t){let[e,r,n]=t;return typeof e=="string"?{message:e,code:"custom",input:r,inst:n}:{...e}}function UW(t){return Object.entries(t).filter(([e,r])=>Number.isNaN(Number.parseInt(e,10))).map(e=>e[1])}function v0(t){let e=atob(t),r=new Uint8Array(e.length);for(let n=0;n<e.length;n++)r[n]=e.charCodeAt(n);return r}function D0(t){let e="";for(let r=0;r<t.length;r++)e+=String.fromCharCode(t[r]);return btoa(e)}function MW(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),r="=".repeat((4-e.length%4)%4);return v0(e+r)}function xW(t){return D0(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function LW(t){let e=t.replace(/^0x/,"");if(e.length%2!==0)throw new Error("Invalid hex string length");let r=new Uint8Array(e.length/2);for(let n=0;n<e.length;n+=2)r[n/2]=Number.parseInt(e.slice(n,n+2),16);return r}function PW(t){return Array.from(t).map(e=>e.toString(16).padStart(2,"0")).join("")}var eI=class{constructor(...e){}};V.Class=eI});var tI=m(Jt=>{"use strict";var $W=Jt&&Jt.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),FW=Jt&&Jt.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),jW=Jt&&Jt.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&$W(e,t,r);return FW(e,t),e};Object.defineProperty(Jt,"__esModule",{value:!0});Jt.$ZodRealError=Jt.$ZodError=void 0;Jt.flattenError=HW;Jt.formatError=qW;Jt.treeifyError=GW;Jt.toDotPath=N0;Jt.prettifyError=YW;var T0=ga(),zW=jW(re()),R0=(t,e)=>{t.name="$ZodError",Object.defineProperty(t,"_zod",{value:t._zod,enumerable:!1}),Object.defineProperty(t,"issues",{value:e,enumerable:!1}),t.message=JSON.stringify(e,zW.jsonStringifyReplacer,2),Object.defineProperty(t,"toString",{value:()=>t.message,enumerable:!1})};Jt.$ZodError=(0,T0.$constructor)("$ZodError",R0);Jt.$ZodRealError=(0,T0.$constructor)("$ZodError",R0,{Parent:Error});function HW(t,e=r=>r.message){let r={},n=[];for(let i of t.issues)i.path.length>0?(r[i.path[0]]=r[i.path[0]]||[],r[i.path[0]].push(e(i))):n.push(e(i));return{formErrors:n,fieldErrors:r}}function qW(t,e=r=>r.message){let r={_errors:[]},n=(i,o=[])=>{for(let s of i.issues)if(s.code==="invalid_union"&&s.errors.length)s.errors.map(a=>n({issues:a},[...o,...s.path]));else if(s.code==="invalid_key")n({issues:s.issues},[...o,...s.path]);else if(s.code==="invalid_element")n({issues:s.issues},[...o,...s.path]);else{let a=[...o,...s.path];if(a.length===0)r._errors.push(e(s));else{let c=r,u=0;for(;u<a.length;){let l=a[u];u===a.length-1?(c[l]=c[l]||{_errors:[]},c[l]._errors.push(e(s))):c[l]=c[l]||{_errors:[]},c=c[l],u++}}}};return n(t),r}function GW(t,e=r=>r.message){let r={errors:[]},n=(i,o=[])=>{var s,a;for(let c of i.issues)if(c.code==="invalid_union"&&c.errors.length)c.errors.map(u=>n({issues:u},[...o,...c.path]));else if(c.code==="invalid_key")n({issues:c.issues},[...o,...c.path]);else if(c.code==="invalid_element")n({issues:c.issues},[...o,...c.path]);else{let u=[...o,...c.path];if(u.length===0){r.errors.push(e(c));continue}let l=r,d=0;for(;d<u.length;){let A=u[d],p=d===u.length-1;typeof A=="string"?(l.properties??(l.properties={}),(s=l.properties)[A]??(s[A]={errors:[]}),l=l.properties[A]):(l.items??(l.items=[]),(a=l.items)[A]??(a[A]={errors:[]}),l=l.items[A]),p&&l.errors.push(e(c)),d++}}};return n(t),r}function N0(t){let e=[],r=t.map(n=>typeof n=="object"?n.key:n);for(let n of r)typeof n=="number"?e.push(`[${n}]`):typeof n=="symbol"?e.push(`[${JSON.stringify(String(n))}]`):/[^\w$]/.test(n)?e.push(`[${JSON.stringify(n)}]`):(e.length&&e.push("."),e.push(n));return e.join("")}function YW(t){let e=[],r=[...t.issues].sort((n,i)=>(n.path??[]).length-(i.path??[]).length);for(let n of r)e.push(`\u2716 ${n.message}`),n.path?.length&&e.push(` \u2192 at ${N0(n.path)}`);return e.join(`
3
3
  `)}});var nI=m(q=>{"use strict";var VW=q&&q.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),JW=q&&q.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),rI=q&&q.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&VW(e,t,r);return JW(e,t),e};Object.defineProperty(q,"__esModule",{value:!0});q.safeDecodeAsync=q._safeDecodeAsync=q.safeEncodeAsync=q._safeEncodeAsync=q.safeDecode=q._safeDecode=q.safeEncode=q._safeEncode=q.decodeAsync=q._decodeAsync=q.encodeAsync=q._encodeAsync=q.decode=q._decode=q.encode=q._encode=q.safeParseAsync=q._safeParseAsync=q.safeParse=q._safeParse=q.parseAsync=q._parseAsync=q.parse=q._parse=void 0;var xc=rI(ga()),Lr=rI(tI()),Lc=rI(re()),WW=t=>(e,r,n,i)=>{let o=n?{...n,async:!1}:{async:!1},s=e._zod.run({value:r,issues:[]},o);if(s instanceof Promise)throw new xc.$ZodAsyncError;if(s.issues.length){let a=new(i?.Err??t)(s.issues.map(c=>Lc.finalizeIssue(c,o,xc.config())));throw Lc.captureStackTrace(a,i?.callee),a}return s.value};q._parse=WW;q.parse=(0,q._parse)(Lr.$ZodRealError);var ZW=t=>async(e,r,n,i)=>{let o=n?{...n,async:!0}:{async:!0},s=e._zod.run({value:r,issues:[]},o);if(s instanceof Promise&&(s=await s),s.issues.length){let a=new(i?.Err??t)(s.issues.map(c=>Lc.finalizeIssue(c,o,xc.config())));throw Lc.captureStackTrace(a,i?.callee),a}return s.value};q._parseAsync=ZW;q.parseAsync=(0,q._parseAsync)(Lr.$ZodRealError);var KW=t=>(e,r,n)=>{let i=n?{...n,async:!1}:{async:!1},o=e._zod.run({value:r,issues:[]},i);if(o instanceof Promise)throw new xc.$ZodAsyncError;return o.issues.length?{success:!1,error:new(t??Lr.$ZodError)(o.issues.map(s=>Lc.finalizeIssue(s,i,xc.config())))}:{success:!0,data:o.value}};q._safeParse=KW;q.safeParse=(0,q._safeParse)(Lr.$ZodRealError);var XW=t=>async(e,r,n)=>{let i=n?{...n,async:!0}:{async:!0},o=e._zod.run({value:r,issues:[]},i);return o instanceof Promise&&(o=await o),o.issues.length?{success:!1,error:new t(o.issues.map(s=>Lc.finalizeIssue(s,i,xc.config())))}:{success:!0,data:o.value}};q._safeParseAsync=XW;q.safeParseAsync=(0,q._safeParseAsync)(Lr.$ZodRealError);var e4=t=>(e,r,n)=>{let i=n?{...n,direction:"backward"}:{direction:"backward"};return(0,q._parse)(t)(e,r,i)};q._encode=e4;q.encode=(0,q._encode)(Lr.$ZodRealError);var t4=t=>(e,r,n)=>(0,q._parse)(t)(e,r,n);q._decode=t4;q.decode=(0,q._decode)(Lr.$ZodRealError);var r4=t=>async(e,r,n)=>{let i=n?{...n,direction:"backward"}:{direction:"backward"};return(0,q._parseAsync)(t)(e,r,i)};q._encodeAsync=r4;q.encodeAsync=(0,q._encodeAsync)(Lr.$ZodRealError);var n4=t=>async(e,r,n)=>(0,q._parseAsync)(t)(e,r,n);q._decodeAsync=n4;q.decodeAsync=(0,q._decodeAsync)(Lr.$ZodRealError);var i4=t=>(e,r,n)=>{let i=n?{...n,direction:"backward"}:{direction:"backward"};return(0,q._safeParse)(t)(e,r,i)};q._safeEncode=i4;q.safeEncode=(0,q._safeEncode)(Lr.$ZodRealError);var o4=t=>(e,r,n)=>(0,q._safeParse)(t)(e,r,n);q._safeDecode=o4;q.safeDecode=(0,q._safeDecode)(Lr.$ZodRealError);var s4=t=>async(e,r,n)=>{let i=n?{...n,direction:"backward"}:{direction:"backward"};return(0,q._safeParseAsync)(t)(e,r,i)};q._safeEncodeAsync=s4;q.safeEncodeAsync=(0,q._safeEncodeAsync)(Lr.$ZodRealError);var a4=t=>async(e,r,n)=>(0,q._safeParseAsync)(t)(e,r,n);q._safeDecodeAsync=a4;q.safeDecodeAsync=(0,q._safeDecodeAsync)(Lr.$ZodRealError)});var Cp=m(R=>{"use strict";var c4=R&&R.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),u4=R&&R.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),l4=R&&R.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&c4(e,t,r);return u4(e,t),e};Object.defineProperty(R,"__esModule",{value:!0});R.sha256_base64url=R.sha256_base64=R.sha256_hex=R.sha1_base64url=R.sha1_base64=R.sha1_hex=R.md5_base64url=R.md5_base64=R.md5_hex=R.hex=R.uppercase=R.lowercase=R.undefined=R.null=R.boolean=R.number=R.integer=R.bigint=R.string=R.date=R.e164=R.httpProtocol=R.domain=R.hostname=R.base64url=R.base64=R.cidrv6=R.cidrv4=R.mac=R.ipv6=R.ipv4=R.browserEmail=R.idnEmail=R.unicodeEmail=R.rfc5322Email=R.html5Email=R.email=R.uuid7=R.uuid6=R.uuid4=R.uuid=R.guid=R.extendedDuration=R.duration=R.nanoid=R.ksuid=R.xid=R.ulid=R.cuid2=R.cuid=void 0;R.sha512_base64url=R.sha512_base64=R.sha512_hex=R.sha384_base64url=R.sha384_base64=R.sha384_hex=void 0;R.emoji=f4;R.time=g4;R.datetime=m4;var d4=l4(re());R.cuid=/^[cC][0-9a-z]{6,}$/;R.cuid2=/^[0-9a-z]+$/;R.ulid=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/;R.xid=/^[0-9a-vA-V]{20}$/;R.ksuid=/^[A-Za-z0-9]{27}$/;R.nanoid=/^[a-zA-Z0-9_-]{21}$/;R.duration=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;R.extendedDuration=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;R.guid=/^([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})$/;var A4=t=>t?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${t}[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)$/;R.uuid=A4;R.uuid4=(0,R.uuid)(4);R.uuid6=(0,R.uuid)(6);R.uuid7=(0,R.uuid)(7);R.email=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;R.html5Email=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;R.rfc5322Email=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;R.unicodeEmail=/^[^\s@"]{1,64}@[^\s@]{1,255}$/u;R.idnEmail=R.unicodeEmail;R.browserEmail=/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;var p4="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";function f4(){return new RegExp(p4,"u")}R.ipv4=/^(?:(?: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])$/;R.ipv6=/^(([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}|:))$/;var h4=t=>{let e=d4.escapeRegex(t??":");return new RegExp(`^(?:[0-9A-F]{2}${e}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${e}){5}[0-9a-f]{2}$`)};R.mac=h4;R.cidrv4=/^((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])$/;R.cidrv6=/^(([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])$/;R.base64=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;R.base64url=/^[A-Za-z0-9_-]*$/;R.hostname=/^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;R.domain=/^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;R.httpProtocol=/^https?$/;R.e164=/^\+[1-9]\d{6,14}$/;var k0="(?:(?:\\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])))";R.date=new RegExp(`^${k0}$`);function O0(t){let e="(?:[01]\\d|2[0-3]):[0-5]\\d";return typeof t.precision=="number"?t.precision===-1?`${e}`:t.precision===0?`${e}:[0-5]\\d`:`${e}:[0-5]\\d\\.\\d{${t.precision}}`:`${e}(?::[0-5]\\d(?:\\.\\d+)?)?`}function g4(t){return new RegExp(`^${O0(t)}$`)}function m4(t){let e=O0({precision:t.precision}),r=["Z"];t.local&&r.push(""),t.offset&&r.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");let n=`${e}(?:${r.join("|")})`;return new RegExp(`^${k0}T(?:${n})$`)}var y4=t=>{let e=t?`[\\s\\S]{${t?.minimum??0},${t?.maximum??""}}`:"[\\s\\S]*";return new RegExp(`^${e}$`)};R.string=y4;R.bigint=/^-?\d+n?$/;R.integer=/^-?\d+$/;R.number=/^-?\d+(?:\.\d+)?$/;R.boolean=/^(?:true|false)$/i;var E4=/^null$/i;R.null=E4;var I4=/^undefined$/i;R.undefined=I4;R.lowercase=/^[^A-Z]*$/;R.uppercase=/^[^a-z]*$/;R.hex=/^[0-9a-fA-F]*$/;function Ml(t,e){return new RegExp(`^[A-Za-z0-9+/]{${t}}${e}$`)}function xl(t){return new RegExp(`^[A-Za-z0-9_-]{${t}}$`)}R.md5_hex=/^[0-9a-fA-F]{32}$/;R.md5_base64=Ml(22,"==");R.md5_base64url=xl(22);R.sha1_hex=/^[0-9a-fA-F]{40}$/;R.sha1_base64=Ml(27,"=");R.sha1_base64url=xl(27);R.sha256_hex=/^[0-9a-fA-F]{64}$/;R.sha256_base64=Ml(43,"=");R.sha256_base64url=xl(43);R.sha384_hex=/^[0-9a-fA-F]{96}$/;R.sha384_base64=Ml(64,"");R.sha384_base64url=xl(64);R.sha512_hex=/^[0-9a-fA-F]{128}$/;R.sha512_base64=Ml(86,"==");R.sha512_base64url=xl(86)});var bp=m(J=>{"use strict";var C4=J&&J.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),b4=J&&J.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),iI=J&&J.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&C4(e,t,r);return b4(e,t),e};Object.defineProperty(J,"__esModule",{value:!0});J.$ZodCheckOverwrite=J.$ZodCheckMimeType=J.$ZodCheckProperty=J.$ZodCheckEndsWith=J.$ZodCheckStartsWith=J.$ZodCheckIncludes=J.$ZodCheckUpperCase=J.$ZodCheckLowerCase=J.$ZodCheckRegex=J.$ZodCheckStringFormat=J.$ZodCheckLengthEquals=J.$ZodCheckMinLength=J.$ZodCheckMaxLength=J.$ZodCheckSizeEquals=J.$ZodCheckMinSize=J.$ZodCheckMaxSize=J.$ZodCheckBigIntFormat=J.$ZodCheckNumberFormat=J.$ZodCheckMultipleOf=J.$ZodCheckGreaterThan=J.$ZodCheckLessThan=J.$ZodCheck=void 0;var ht=iI(ga()),oI=iI(Cp()),Ut=iI(re());J.$ZodCheck=ht.$constructor("$ZodCheck",(t,e)=>{var r;t._zod??(t._zod={}),t._zod.def=e,(r=t._zod).onattach??(r.onattach=[])});var M0={number:"number",bigint:"bigint",object:"date"};J.$ZodCheckLessThan=ht.$constructor("$ZodCheckLessThan",(t,e)=>{J.$ZodCheck.init(t,e);let r=M0[typeof e.value];t._zod.onattach.push(n=>{let i=n._zod.bag,o=(e.inclusive?i.maximum:i.exclusiveMaximum)??Number.POSITIVE_INFINITY;e.value<o&&(e.inclusive?i.maximum=e.value:i.exclusiveMaximum=e.value)}),t._zod.check=n=>{(e.inclusive?n.value<=e.value:n.value<e.value)||n.issues.push({origin:r,code:"too_big",maximum:typeof e.value=="object"?e.value.getTime():e.value,input:n.value,inclusive:e.inclusive,inst:t,continue:!e.abort})}});J.$ZodCheckGreaterThan=ht.$constructor("$ZodCheckGreaterThan",(t,e)=>{J.$ZodCheck.init(t,e);let r=M0[typeof e.value];t._zod.onattach.push(n=>{let i=n._zod.bag,o=(e.inclusive?i.minimum:i.exclusiveMinimum)??Number.NEGATIVE_INFINITY;e.value>o&&(e.inclusive?i.minimum=e.value:i.exclusiveMinimum=e.value)}),t._zod.check=n=>{(e.inclusive?n.value>=e.value:n.value>e.value)||n.issues.push({origin:r,code:"too_small",minimum:typeof e.value=="object"?e.value.getTime():e.value,input:n.value,inclusive:e.inclusive,inst:t,continue:!e.abort})}});J.$ZodCheckMultipleOf=ht.$constructor("$ZodCheckMultipleOf",(t,e)=>{J.$ZodCheck.init(t,e),t._zod.onattach.push(r=>{var n;(n=r._zod.bag).multipleOf??(n.multipleOf=e.value)}),t._zod.check=r=>{if(typeof r.value!=typeof e.value)throw new Error("Cannot mix number and bigint in multiple_of check.");(typeof r.value=="bigint"?r.value%e.value===BigInt(0):Ut.floatSafeRemainder(r.value,e.value)===0)||r.issues.push({origin:typeof r.value,code:"not_multiple_of",divisor:e.value,input:r.value,inst:t,continue:!e.abort})}});J.$ZodCheckNumberFormat=ht.$constructor("$ZodCheckNumberFormat",(t,e)=>{J.$ZodCheck.init(t,e),e.format=e.format||"float64";let r=e.format?.includes("int"),n=r?"int":"number",[i,o]=Ut.NUMBER_FORMAT_RANGES[e.format];t._zod.onattach.push(s=>{let a=s._zod.bag;a.format=e.format,a.minimum=i,a.maximum=o,r&&(a.pattern=oI.integer)}),t._zod.check=s=>{let a=s.value;if(r){if(!Number.isInteger(a)){s.issues.push({expected:n,format:e.format,code:"invalid_type",continue:!1,input:a,inst:t});return}if(!Number.isSafeInteger(a)){a>0?s.issues.push({input:a,code:"too_big",maximum:Number.MAX_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:t,origin:n,inclusive:!0,continue:!e.abort}):s.issues.push({input:a,code:"too_small",minimum:Number.MIN_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:t,origin:n,inclusive:!0,continue:!e.abort});return}}a<i&&s.issues.push({origin:"number",input:a,code:"too_small",minimum:i,inclusive:!0,inst:t,continue:!e.abort}),a>o&&s.issues.push({origin:"number",input:a,code:"too_big",maximum:o,inclusive:!0,inst:t,continue:!e.abort})}});J.$ZodCheckBigIntFormat=ht.$constructor("$ZodCheckBigIntFormat",(t,e)=>{J.$ZodCheck.init(t,e);let[r,n]=Ut.BIGINT_FORMAT_RANGES[e.format];t._zod.onattach.push(i=>{let o=i._zod.bag;o.format=e.format,o.minimum=r,o.maximum=n}),t._zod.check=i=>{let o=i.value;o<r&&i.issues.push({origin:"bigint",input:o,code:"too_small",minimum:r,inclusive:!0,inst:t,continue:!e.abort}),o>n&&i.issues.push({origin:"bigint",input:o,code:"too_big",maximum:n,inclusive:!0,inst:t,continue:!e.abort})}});J.$ZodCheckMaxSize=ht.$constructor("$ZodCheckMaxSize",(t,e)=>{var r;J.$ZodCheck.init(t,e),(r=t._zod.def).when??(r.when=n=>{let i=n.value;return!Ut.nullish(i)&&i.size!==void 0}),t._zod.onattach.push(n=>{let i=n._zod.bag.maximum??Number.POSITIVE_INFINITY;e.maximum<i&&(n._zod.bag.maximum=e.maximum)}),t._zod.check=n=>{let i=n.value;i.size<=e.maximum||n.issues.push({origin:Ut.getSizableOrigin(i),code:"too_big",maximum:e.maximum,inclusive:!0,input:i,inst:t,continue:!e.abort})}});J.$ZodCheckMinSize=ht.$constructor("$ZodCheckMinSize",(t,e)=>{var r;J.$ZodCheck.init(t,e),(r=t._zod.def).when??(r.when=n=>{let i=n.value;return!Ut.nullish(i)&&i.size!==void 0}),t._zod.onattach.push(n=>{let i=n._zod.bag.minimum??Number.NEGATIVE_INFINITY;e.minimum>i&&(n._zod.bag.minimum=e.minimum)}),t._zod.check=n=>{let i=n.value;i.size>=e.minimum||n.issues.push({origin:Ut.getSizableOrigin(i),code:"too_small",minimum:e.minimum,inclusive:!0,input:i,inst:t,continue:!e.abort})}});J.$ZodCheckSizeEquals=ht.$constructor("$ZodCheckSizeEquals",(t,e)=>{var r;J.$ZodCheck.init(t,e),(r=t._zod.def).when??(r.when=n=>{let i=n.value;return!Ut.nullish(i)&&i.size!==void 0}),t._zod.onattach.push(n=>{let i=n._zod.bag;i.minimum=e.size,i.maximum=e.size,i.size=e.size}),t._zod.check=n=>{let i=n.value,o=i.size;if(o===e.size)return;let s=o>e.size;n.issues.push({origin:Ut.getSizableOrigin(i),...s?{code:"too_big",maximum:e.size}:{code:"too_small",minimum:e.size},inclusive:!0,exact:!0,input:n.value,inst:t,continue:!e.abort})}});J.$ZodCheckMaxLength=ht.$constructor("$ZodCheckMaxLength",(t,e)=>{var r;J.$ZodCheck.init(t,e),(r=t._zod.def).when??(r.when=n=>{let i=n.value;return!Ut.nullish(i)&&i.length!==void 0}),t._zod.onattach.push(n=>{let i=n._zod.bag.maximum??Number.POSITIVE_INFINITY;e.maximum<i&&(n._zod.bag.maximum=e.maximum)}),t._zod.check=n=>{let i=n.value;if(i.length<=e.maximum)return;let s=Ut.getLengthableOrigin(i);n.issues.push({origin:s,code:"too_big",maximum:e.maximum,inclusive:!0,input:i,inst:t,continue:!e.abort})}});J.$ZodCheckMinLength=ht.$constructor("$ZodCheckMinLength",(t,e)=>{var r;J.$ZodCheck.init(t,e),(r=t._zod.def).when??(r.when=n=>{let i=n.value;return!Ut.nullish(i)&&i.length!==void 0}),t._zod.onattach.push(n=>{let i=n._zod.bag.minimum??Number.NEGATIVE_INFINITY;e.minimum>i&&(n._zod.bag.minimum=e.minimum)}),t._zod.check=n=>{let i=n.value;if(i.length>=e.minimum)return;let s=Ut.getLengthableOrigin(i);n.issues.push({origin:s,code:"too_small",minimum:e.minimum,inclusive:!0,input:i,inst:t,continue:!e.abort})}});J.$ZodCheckLengthEquals=ht.$constructor("$ZodCheckLengthEquals",(t,e)=>{var r;J.$ZodCheck.init(t,e),(r=t._zod.def).when??(r.when=n=>{let i=n.value;return!Ut.nullish(i)&&i.length!==void 0}),t._zod.onattach.push(n=>{let i=n._zod.bag;i.minimum=e.length,i.maximum=e.length,i.length=e.length}),t._zod.check=n=>{let i=n.value,o=i.length;if(o===e.length)return;let s=Ut.getLengthableOrigin(i),a=o>e.length;n.issues.push({origin:s,...a?{code:"too_big",maximum:e.length}:{code:"too_small",minimum:e.length},inclusive:!0,exact:!0,input:n.value,inst:t,continue:!e.abort})}});J.$ZodCheckStringFormat=ht.$constructor("$ZodCheckStringFormat",(t,e)=>{var r,n;J.$ZodCheck.init(t,e),t._zod.onattach.push(i=>{let o=i._zod.bag;o.format=e.format,e.pattern&&(o.patterns??(o.patterns=new Set),o.patterns.add(e.pattern))}),e.pattern?(r=t._zod).check??(r.check=i=>{e.pattern.lastIndex=0,!e.pattern.test(i.value)&&i.issues.push({origin:"string",code:"invalid_format",format:e.format,input:i.value,...e.pattern?{pattern:e.pattern.toString()}:{},inst:t,continue:!e.abort})}):(n=t._zod).check??(n.check=()=>{})});J.$ZodCheckRegex=ht.$constructor("$ZodCheckRegex",(t,e)=>{J.$ZodCheckStringFormat.init(t,e),t._zod.check=r=>{e.pattern.lastIndex=0,!e.pattern.test(r.value)&&r.issues.push({origin:"string",code:"invalid_format",format:"regex",input:r.value,pattern:e.pattern.toString(),inst:t,continue:!e.abort})}});J.$ZodCheckLowerCase=ht.$constructor("$ZodCheckLowerCase",(t,e)=>{e.pattern??(e.pattern=oI.lowercase),J.$ZodCheckStringFormat.init(t,e)});J.$ZodCheckUpperCase=ht.$constructor("$ZodCheckUpperCase",(t,e)=>{e.pattern??(e.pattern=oI.uppercase),J.$ZodCheckStringFormat.init(t,e)});J.$ZodCheckIncludes=ht.$constructor("$ZodCheckIncludes",(t,e)=>{J.$ZodCheck.init(t,e);let r=Ut.escapeRegex(e.includes),n=new RegExp(typeof e.position=="number"?`^.{${e.position}}${r}`:r);e.pattern=n,t._zod.onattach.push(i=>{let o=i._zod.bag;o.patterns??(o.patterns=new Set),o.patterns.add(n)}),t._zod.check=i=>{i.value.includes(e.includes,e.position)||i.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:e.includes,input:i.value,inst:t,continue:!e.abort})}});J.$ZodCheckStartsWith=ht.$constructor("$ZodCheckStartsWith",(t,e)=>{J.$ZodCheck.init(t,e);let r=new RegExp(`^${Ut.escapeRegex(e.prefix)}.*`);e.pattern??(e.pattern=r),t._zod.onattach.push(n=>{let i=n._zod.bag;i.patterns??(i.patterns=new Set),i.patterns.add(r)}),t._zod.check=n=>{n.value.startsWith(e.prefix)||n.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:e.prefix,input:n.value,inst:t,continue:!e.abort})}});J.$ZodCheckEndsWith=ht.$constructor("$ZodCheckEndsWith",(t,e)=>{J.$ZodCheck.init(t,e);let r=new RegExp(`.*${Ut.escapeRegex(e.suffix)}$`);e.pattern??(e.pattern=r),t._zod.onattach.push(n=>{let i=n._zod.bag;i.patterns??(i.patterns=new Set),i.patterns.add(r)}),t._zod.check=n=>{n.value.endsWith(e.suffix)||n.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:e.suffix,input:n.value,inst:t,continue:!e.abort})}});function U0(t,e,r){t.issues.length&&e.issues.push(...Ut.prefixIssues(r,t.issues))}J.$ZodCheckProperty=ht.$constructor("$ZodCheckProperty",(t,e)=>{J.$ZodCheck.init(t,e),t._zod.check=r=>{let n=e.schema._zod.run({value:r.value[e.property],issues:[]},{});if(n instanceof Promise)return n.then(i=>U0(i,r,e.property));U0(n,r,e.property)}});J.$ZodCheckMimeType=ht.$constructor("$ZodCheckMimeType",(t,e)=>{J.$ZodCheck.init(t,e);let r=new Set(e.mime);t._zod.onattach.push(n=>{n._zod.bag.mime=e.mime}),t._zod.check=n=>{r.has(n.value.type)||n.issues.push({code:"invalid_value",values:e.mime,input:n.value.type,inst:t,continue:!e.abort})}});J.$ZodCheckOverwrite=ht.$constructor("$ZodCheckOverwrite",(t,e)=>{J.$ZodCheck.init(t,e),t._zod.check=r=>{r.value=e.tx(r.value)}})});var aI=m(Sp=>{"use strict";Object.defineProperty(Sp,"__esModule",{value:!0});Sp.Doc=void 0;var sI=class{constructor(e=[]){this.content=[],this.indent=0,this&&(this.args=e)}indented(e){this.indent+=1,e(this),this.indent-=1}write(e){if(typeof e=="function"){e(this,{execution:"sync"}),e(this,{execution:"async"});return}let n=e.split(`
4
4
  `).filter(s=>s),i=Math.min(...n.map(s=>s.length-s.trimStart().length)),o=n.map(s=>s.slice(i)).map(s=>" ".repeat(this.indent*2)+s);for(let s of o)this.content.push(s)}compile(){let e=Function,r=this?.args,i=[...(this?.content??[""]).map(o=>` ${o}`)];return new e(...r,i.join(`
5
5
  `))}};Sp.Doc=sI});var cI=m(wp=>{"use strict";Object.defineProperty(wp,"__esModule",{value:!0});wp.version=void 0;wp.version={major:4,minor:4,patch:3}});var dI=m(b=>{"use strict";var S4=b&&b.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),w4=b&&b.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),Dp=b&&b.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&S4(e,t,r);return w4(e,t),e};Object.defineProperty(b,"__esModule",{value:!0});b.$ZodTuple=b.$ZodIntersection=b.$ZodDiscriminatedUnion=b.$ZodXor=b.$ZodUnion=b.$ZodObjectJIT=b.$ZodObject=b.$ZodArray=b.$ZodDate=b.$ZodVoid=b.$ZodNever=b.$ZodUnknown=b.$ZodAny=b.$ZodNull=b.$ZodUndefined=b.$ZodSymbol=b.$ZodBigIntFormat=b.$ZodBigInt=b.$ZodBoolean=b.$ZodNumberFormat=b.$ZodNumber=b.$ZodCustomStringFormat=b.$ZodJWT=b.$ZodE164=b.$ZodBase64URL=b.$ZodBase64=b.$ZodCIDRv6=b.$ZodCIDRv4=b.$ZodMAC=b.$ZodIPv6=b.$ZodIPv4=b.$ZodISODuration=b.$ZodISOTime=b.$ZodISODate=b.$ZodISODateTime=b.$ZodKSUID=b.$ZodXID=b.$ZodULID=b.$ZodCUID2=b.$ZodCUID=b.$ZodNanoID=b.$ZodEmoji=b.$ZodURL=b.$ZodEmail=b.$ZodUUID=b.$ZodGUID=b.$ZodStringFormat=b.$ZodString=b.clone=b.$ZodType=void 0;b.$ZodCustom=b.$ZodLazy=b.$ZodPromise=b.$ZodFunction=b.$ZodTemplateLiteral=b.$ZodReadonly=b.$ZodPreprocess=b.$ZodCodec=b.$ZodPipe=b.$ZodNaN=b.$ZodCatch=b.$ZodSuccess=b.$ZodNonOptional=b.$ZodPrefault=b.$ZodDefault=b.$ZodNullable=b.$ZodExactOptional=b.$ZodOptional=b.$ZodTransform=b.$ZodFile=b.$ZodLiteral=b.$ZodEnum=b.$ZodSet=b.$ZodMap=b.$ZodRecord=void 0;b.isValidBase64=lI;b.isValidBase64URL=Z0;b.isValidJWT=K0;var Tp=Dp(bp()),P=Dp(ga()),B4=aI(),Pc=nI(),Le=Dp(Cp()),$=Dp(re()),_4=cI();b.$ZodType=P.$constructor("$ZodType",(t,e)=>{var r;t??(t={}),t._zod.def=e,t._zod.bag=t._zod.bag||{},t._zod.version=_4.version;let n=[...t._zod.def.checks??[]];t._zod.traits.has("$ZodCheck")&&n.unshift(t);for(let i of n)for(let o of i._zod.onattach)o(t);if(n.length===0)(r=t._zod).deferred??(r.deferred=[]),t._zod.deferred?.push(()=>{t._zod.run=t._zod.parse});else{let i=(s,a,c)=>{let u=$.aborted(s),l;for(let d of a){if(d._zod.def.when){if($.explicitlyAborted(s)||!d._zod.def.when(s))continue}else if(u)continue;let A=s.issues.length,p=d._zod.check(s);if(p instanceof Promise&&c?.async===!1)throw new P.$ZodAsyncError;if(l||p instanceof Promise)l=(l??Promise.resolve()).then(async()=>{await p,s.issues.length!==A&&(u||(u=$.aborted(s,A)))});else{if(s.issues.length===A)continue;u||(u=$.aborted(s,A))}}return l?l.then(()=>s):s},o=(s,a,c)=>{if($.aborted(s))return s.aborted=!0,s;let u=i(a,n,c);if(u instanceof Promise){if(c.async===!1)throw new P.$ZodAsyncError;return u.then(l=>t._zod.parse(l,c))}return t._zod.parse(u,c)};t._zod.run=(s,a)=>{if(a.skipChecks)return t._zod.parse(s,a);if(a.direction==="backward"){let u=t._zod.parse({value:s.value,issues:[]},{...a,skipChecks:!0});return u instanceof Promise?u.then(l=>o(l,s,a)):o(u,s,a)}let c=t._zod.parse(s,a);if(c instanceof Promise){if(a.async===!1)throw new P.$ZodAsyncError;return c.then(u=>i(u,n,a))}return i(c,n,a)}}$.defineLazy(t,"~standard",()=>({validate:i=>{try{let o=(0,Pc.safeParse)(t,i);return o.success?{value:o.data}:{issues:o.error?.issues}}catch{return(0,Pc.safeParseAsync)(t,i).then(s=>s.success?{value:s.data}:{issues:s.error?.issues})}},vendor:"zod",version:1}))});var Q4=re();Object.defineProperty(b,"clone",{enumerable:!0,get:function(){return Q4.clone}});b.$ZodString=P.$constructor("$ZodString",(t,e)=>{b.$ZodType.init(t,e),t._zod.pattern=[...t?._zod.bag?.patterns??[]].pop()??Le.string(t._zod.bag),t._zod.parse=(r,n)=>{if(e.coerce)try{r.value=String(r.value)}catch{}return typeof r.value=="string"||r.issues.push({expected:"string",code:"invalid_type",input:r.value,inst:t}),r}});b.$ZodStringFormat=P.$constructor("$ZodStringFormat",(t,e)=>{Tp.$ZodCheckStringFormat.init(t,e),b.$ZodString.init(t,e)});b.$ZodGUID=P.$constructor("$ZodGUID",(t,e)=>{e.pattern??(e.pattern=Le.guid),b.$ZodStringFormat.init(t,e)});b.$ZodUUID=P.$constructor("$ZodUUID",(t,e)=>{if(e.version){let n={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[e.version];if(n===void 0)throw new Error(`Invalid UUID version: "${e.version}"`);e.pattern??(e.pattern=Le.uuid(n))}else e.pattern??(e.pattern=Le.uuid());b.$ZodStringFormat.init(t,e)});b.$ZodEmail=P.$constructor("$ZodEmail",(t,e)=>{e.pattern??(e.pattern=Le.email),b.$ZodStringFormat.init(t,e)});b.$ZodURL=P.$constructor("$ZodURL",(t,e)=>{b.$ZodStringFormat.init(t,e),t._zod.check=r=>{try{let n=r.value.trim();if(!e.normalize&&e.protocol?.source===Le.httpProtocol.source&&!/^https?:\/\//i.test(n)){r.issues.push({code:"invalid_format",format:"url",note:"Invalid URL format",input:r.value,inst:t,continue:!e.abort});return}let i=new URL(n);e.hostname&&(e.hostname.lastIndex=0,e.hostname.test(i.hostname)||r.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:e.hostname.source,input:r.value,inst:t,continue:!e.abort})),e.protocol&&(e.protocol.lastIndex=0,e.protocol.test(i.protocol.endsWith(":")?i.protocol.slice(0,-1):i.protocol)||r.issues.push({code:"invalid_format",format:"url",note:"Invalid protocol",pattern:e.protocol.source,input:r.value,inst:t,continue:!e.abort})),e.normalize?r.value=i.href:r.value=n;return}catch{r.issues.push({code:"invalid_format",format:"url",input:r.value,inst:t,continue:!e.abort})}}});b.$ZodEmoji=P.$constructor("$ZodEmoji",(t,e)=>{e.pattern??(e.pattern=Le.emoji()),b.$ZodStringFormat.init(t,e)});b.$ZodNanoID=P.$constructor("$ZodNanoID",(t,e)=>{e.pattern??(e.pattern=Le.nanoid),b.$ZodStringFormat.init(t,e)});b.$ZodCUID=P.$constructor("$ZodCUID",(t,e)=>{e.pattern??(e.pattern=Le.cuid),b.$ZodStringFormat.init(t,e)});b.$ZodCUID2=P.$constructor("$ZodCUID2",(t,e)=>{e.pattern??(e.pattern=Le.cuid2),b.$ZodStringFormat.init(t,e)});b.$ZodULID=P.$constructor("$ZodULID",(t,e)=>{e.pattern??(e.pattern=Le.ulid),b.$ZodStringFormat.init(t,e)});b.$ZodXID=P.$constructor("$ZodXID",(t,e)=>{e.pattern??(e.pattern=Le.xid),b.$ZodStringFormat.init(t,e)});b.$ZodKSUID=P.$constructor("$ZodKSUID",(t,e)=>{e.pattern??(e.pattern=Le.ksuid),b.$ZodStringFormat.init(t,e)});b.$ZodISODateTime=P.$constructor("$ZodISODateTime",(t,e)=>{e.pattern??(e.pattern=Le.datetime(e)),b.$ZodStringFormat.init(t,e)});b.$ZodISODate=P.$constructor("$ZodISODate",(t,e)=>{e.pattern??(e.pattern=Le.date),b.$ZodStringFormat.init(t,e)});b.$ZodISOTime=P.$constructor("$ZodISOTime",(t,e)=>{e.pattern??(e.pattern=Le.time(e)),b.$ZodStringFormat.init(t,e)});b.$ZodISODuration=P.$constructor("$ZodISODuration",(t,e)=>{e.pattern??(e.pattern=Le.duration),b.$ZodStringFormat.init(t,e)});b.$ZodIPv4=P.$constructor("$ZodIPv4",(t,e)=>{e.pattern??(e.pattern=Le.ipv4),b.$ZodStringFormat.init(t,e),t._zod.bag.format="ipv4"});b.$ZodIPv6=P.$constructor("$ZodIPv6",(t,e)=>{e.pattern??(e.pattern=Le.ipv6),b.$ZodStringFormat.init(t,e),t._zod.bag.format="ipv6",t._zod.check=r=>{try{new URL(`http://[${r.value}]`)}catch{r.issues.push({code:"invalid_format",format:"ipv6",input:r.value,inst:t,continue:!e.abort})}}});b.$ZodMAC=P.$constructor("$ZodMAC",(t,e)=>{e.pattern??(e.pattern=Le.mac(e.delimiter)),b.$ZodStringFormat.init(t,e),t._zod.bag.format="mac"});b.$ZodCIDRv4=P.$constructor("$ZodCIDRv4",(t,e)=>{e.pattern??(e.pattern=Le.cidrv4),b.$ZodStringFormat.init(t,e)});b.$ZodCIDRv6=P.$constructor("$ZodCIDRv6",(t,e)=>{e.pattern??(e.pattern=Le.cidrv6),b.$ZodStringFormat.init(t,e),t._zod.check=r=>{let n=r.value.split("/");try{if(n.length!==2)throw new Error;let[i,o]=n;if(!o)throw new Error;let s=Number(o);if(`${s}`!==o)throw new Error;if(s<0||s>128)throw new Error;new URL(`http://[${i}]`)}catch{r.issues.push({code:"invalid_format",format:"cidrv6",input:r.value,inst:t,continue:!e.abort})}}});function lI(t){if(t==="")return!0;if(/\s/.test(t)||t.length%4!==0)return!1;try{return atob(t),!0}catch{return!1}}b.$ZodBase64=P.$constructor("$ZodBase64",(t,e)=>{e.pattern??(e.pattern=Le.base64),b.$ZodStringFormat.init(t,e),t._zod.bag.contentEncoding="base64",t._zod.check=r=>{lI(r.value)||r.issues.push({code:"invalid_format",format:"base64",input:r.value,inst:t,continue:!e.abort})}});function Z0(t){if(!Le.base64url.test(t))return!1;let e=t.replace(/[-_]/g,n=>n==="-"?"+":"/"),r=e.padEnd(Math.ceil(e.length/4)*4,"=");return lI(r)}b.$ZodBase64URL=P.$constructor("$ZodBase64URL",(t,e)=>{e.pattern??(e.pattern=Le.base64url),b.$ZodStringFormat.init(t,e),t._zod.bag.contentEncoding="base64url",t._zod.check=r=>{Z0(r.value)||r.issues.push({code:"invalid_format",format:"base64url",input:r.value,inst:t,continue:!e.abort})}});b.$ZodE164=P.$constructor("$ZodE164",(t,e)=>{e.pattern??(e.pattern=Le.e164),b.$ZodStringFormat.init(t,e)});function K0(t,e=null){try{let r=t.split(".");if(r.length!==3)return!1;let[n]=r;if(!n)return!1;let i=JSON.parse(atob(n));return!("typ"in i&&i?.typ!=="JWT"||!i.alg||e&&(!("alg"in i)||i.alg!==e))}catch{return!1}}b.$ZodJWT=P.$constructor("$ZodJWT",(t,e)=>{b.$ZodStringFormat.init(t,e),t._zod.check=r=>{K0(r.value,e.alg)||r.issues.push({code:"invalid_format",format:"jwt",input:r.value,inst:t,continue:!e.abort})}});b.$ZodCustomStringFormat=P.$constructor("$ZodCustomStringFormat",(t,e)=>{b.$ZodStringFormat.init(t,e),t._zod.check=r=>{e.fn(r.value)||r.issues.push({code:"invalid_format",format:e.format,input:r.value,inst:t,continue:!e.abort})}});b.$ZodNumber=P.$constructor("$ZodNumber",(t,e)=>{b.$ZodType.init(t,e),t._zod.pattern=t._zod.bag.pattern??Le.number,t._zod.parse=(r,n)=>{if(e.coerce)try{r.value=Number(r.value)}catch{}let i=r.value;if(typeof i=="number"&&!Number.isNaN(i)&&Number.isFinite(i))return r;let o=typeof i=="number"?Number.isNaN(i)?"NaN":Number.isFinite(i)?void 0:"Infinity":void 0;return r.issues.push({expected:"number",code:"invalid_type",input:i,inst:t,...o?{received:o}:{}}),r}});b.$ZodNumberFormat=P.$constructor("$ZodNumberFormat",(t,e)=>{Tp.$ZodCheckNumberFormat.init(t,e),b.$ZodNumber.init(t,e)});b.$ZodBoolean=P.$constructor("$ZodBoolean",(t,e)=>{b.$ZodType.init(t,e),t._zod.pattern=Le.boolean,t._zod.parse=(r,n)=>{if(e.coerce)try{r.value=!!r.value}catch{}let i=r.value;return typeof i=="boolean"||r.issues.push({expected:"boolean",code:"invalid_type",input:i,inst:t}),r}});b.$ZodBigInt=P.$constructor("$ZodBigInt",(t,e)=>{b.$ZodType.init(t,e),t._zod.pattern=Le.bigint,t._zod.parse=(r,n)=>{if(e.coerce)try{r.value=BigInt(r.value)}catch{}return typeof r.value=="bigint"||r.issues.push({expected:"bigint",code:"invalid_type",input:r.value,inst:t}),r}});b.$ZodBigIntFormat=P.$constructor("$ZodBigIntFormat",(t,e)=>{Tp.$ZodCheckBigIntFormat.init(t,e),b.$ZodBigInt.init(t,e)});b.$ZodSymbol=P.$constructor("$ZodSymbol",(t,e)=>{b.$ZodType.init(t,e),t._zod.parse=(r,n)=>{let i=r.value;return typeof i=="symbol"||r.issues.push({expected:"symbol",code:"invalid_type",input:i,inst:t}),r}});b.$ZodUndefined=P.$constructor("$ZodUndefined",(t,e)=>{b.$ZodType.init(t,e),t._zod.pattern=Le.undefined,t._zod.values=new Set([void 0]),t._zod.parse=(r,n)=>{let i=r.value;return typeof i>"u"||r.issues.push({expected:"undefined",code:"invalid_type",input:i,inst:t}),r}});b.$ZodNull=P.$constructor("$ZodNull",(t,e)=>{b.$ZodType.init(t,e),t._zod.pattern=Le.null,t._zod.values=new Set([null]),t._zod.parse=(r,n)=>{let i=r.value;return i===null||r.issues.push({expected:"null",code:"invalid_type",input:i,inst:t}),r}});b.$ZodAny=P.$constructor("$ZodAny",(t,e)=>{b.$ZodType.init(t,e),t._zod.parse=r=>r});b.$ZodUnknown=P.$constructor("$ZodUnknown",(t,e)=>{b.$ZodType.init(t,e),t._zod.parse=r=>r});b.$ZodNever=P.$constructor("$ZodNever",(t,e)=>{b.$ZodType.init(t,e),t._zod.parse=(r,n)=>(r.issues.push({expected:"never",code:"invalid_type",input:r.value,inst:t}),r)});b.$ZodVoid=P.$constructor("$ZodVoid",(t,e)=>{b.$ZodType.init(t,e),t._zod.parse=(r,n)=>{let i=r.value;return typeof i>"u"||r.issues.push({expected:"void",code:"invalid_type",input:i,inst:t}),r}});b.$ZodDate=P.$constructor("$ZodDate",(t,e)=>{b.$ZodType.init(t,e),t._zod.parse=(r,n)=>{if(e.coerce)try{r.value=new Date(r.value)}catch{}let i=r.value,o=i instanceof Date;return o&&!Number.isNaN(i.getTime())||r.issues.push({expected:"date",code:"invalid_type",input:i,...o?{received:"Invalid Date"}:{},inst:t}),r}});function x0(t,e,r){t.issues.length&&e.issues.push(...$.prefixIssues(r,t.issues)),e.value[r]=t.value}b.$ZodArray=P.$constructor("$ZodArray",(t,e)=>{b.$ZodType.init(t,e),t._zod.parse=(r,n)=>{let i=r.value;if(!Array.isArray(i))return r.issues.push({expected:"array",code:"invalid_type",input:i,inst:t}),r;r.value=Array(i.length);let o=[];for(let s=0;s<i.length;s++){let a=i[s],c=e.element._zod.run({value:a,issues:[]},n);c instanceof Promise?o.push(c.then(u=>x0(u,r,s))):x0(c,r,s)}return o.length?Promise.all(o).then(()=>r):r}});function vp(t,e,r,n,i,o){let s=r in n;if(t.issues.length){if(i&&o&&!s)return;e.issues.push(...$.prefixIssues(r,t.issues))}if(!s&&!i){t.issues.length||e.issues.push({code:"invalid_type",expected:"nonoptional",input:void 0,path:[r]});return}t.value===void 0?s&&(e.value[r]=void 0):e.value[r]=t.value}function X0(t){let e=Object.keys(t.shape);for(let n of e)if(!t.shape?.[n]?._zod?.traits?.has("$ZodType"))throw new Error(`Invalid element at key "${n}": expected a Zod schema`);let r=$.optionalKeys(t.shape);return{...t,keys:e,keySet:new Set(e),numKeys:e.length,optionalKeys:new Set(r)}}function eD(t,e,r,n,i,o){let s=[],a=i.keySet,c=i.catchall._zod,u=c.def.type,l=c.optin==="optional",d=c.optout==="optional";for(let A in e){if(A==="__proto__"||a.has(A))continue;if(u==="never"){s.push(A);continue}let p=c.run({value:e[A],issues:[]},n);p instanceof Promise?t.push(p.then(h=>vp(h,r,A,e,l,d))):vp(p,r,A,e,l,d)}return s.length&&r.issues.push({code:"unrecognized_keys",keys:s,input:e,inst:o}),t.length?Promise.all(t).then(()=>r):r}b.$ZodObject=P.$constructor("$ZodObject",(t,e)=>{if(b.$ZodType.init(t,e),!Object.getOwnPropertyDescriptor(e,"shape")?.get){let a=e.shape;Object.defineProperty(e,"shape",{get:()=>{let c={...a};return Object.defineProperty(e,"shape",{value:c}),c}})}let n=$.cached(()=>X0(e));$.defineLazy(t._zod,"propValues",()=>{let a=e.shape,c={};for(let u in a){let l=a[u]._zod;if(l.values){c[u]??(c[u]=new Set);for(let d of l.values)c[u].add(d)}}return c});let i=$.isObject,o=e.catchall,s;t._zod.parse=(a,c)=>{s??(s=n.value);let u=a.value;if(!i(u))return a.issues.push({expected:"object",code:"invalid_type",input:u,inst:t}),a;a.value={};let l=[],d=s.shape;for(let A of s.keys){let p=d[A],h=p._zod.optin==="optional",g=p._zod.optout==="optional",w=p._zod.run({value:u[A],issues:[]},c);w instanceof Promise?l.push(w.then(B=>vp(B,a,A,u,h,g))):vp(w,a,A,u,h,g)}return o?eD(l,u,a,c,n.value,t):l.length?Promise.all(l).then(()=>a):a}});b.$ZodObjectJIT=P.$constructor("$ZodObjectJIT",(t,e)=>{b.$ZodObject.init(t,e);let r=t._zod.parse,n=$.cached(()=>X0(e)),i=A=>{let p=new B4.Doc(["shape","payload","ctx"]),h=n.value,g=Q=>{let U=$.esc(Q);return`shape[${U}]._zod.run({ value: input[${U}], issues: [] }, ctx)`};p.write("const input = payload.value;");let w=Object.create(null),B=0;for(let Q of h.keys)w[Q]=`key_${B++}`;p.write("const newResult = {};");for(let Q of h.keys){let U=w[Q],x=$.esc(Q),z=A[Q],Te=z?._zod?.optin==="optional",ee=z?._zod?.optout==="optional";p.write(`const ${U} = ${g(Q)};`),Te&&ee?p.write(`
@@ -109,8 +109,8 @@ attempted value: ${s}
109
109
 
110
110
  `)}function Ub(t){return(t.parts||[]).flatMap(e=>e.type==="tool"&&e.tool?[e.tool]:[])}function ux(t){return Ob(t)?!0:Ub(t).length>0}function Mb(t){return t.role==="assistant"&&!t.isStreaming&&!ux(t)}function uAe(t){return t.role==="system"||t.isHidden?!1:!Mb(t)}function lAe(t){return t.filter(e=>!Mb(e))}function dAe(t){return t.filter(e=>{let r=Ob(e),n=Ub(e).length>0;return(r||n)&&!(e.id==="1"&&!r)})}function AAe(t,e=5e3,r=10){if(t==null)return"null";if(typeof t=="string")return t.length<=e?t:t.slice(0,e)+"... [truncated]";let n=Rb(t);if(n.length<=e)return n;let i=ox(t,r),o=Rb(i);return o.length<=e?o:o.slice(0,e)+"... [truncated]"}function pAe(t,e){if(t.length<=e)return t;let r=Math.ceil(e/2),n=Math.floor(e/2),i=t.length-r-n;return`${t.slice(0,r)}
111
111
  ... [${i} characters omitted] ...
112
- ${t.slice(t.length-n)}`}function fAe(t){return t instanceof Error?t.message:typeof t=="string"?t:typeof t=="object"&&t!==null&&"message"in t?String(t.message):String(t)}function hAe(t,e){if(!e||Object.keys(e).length===0)return{};let r=/file::([^,\s)}\]"']+)/g,n=typeof t=="string"?t:JSON.stringify(t||{}),i=[...new Set([...n.matchAll(r)].map(o=>{let s=o[1];return s.endsWith(".raw")?s=s.slice(0,-4):s.endsWith(".base64")?s=s.slice(0,-7):s.endsWith(".extracted")&&(s=s.slice(0,-10)),s}))];return Object.fromEntries(i.flatMap(o=>e[o]?[[o,e[o]]]:[]))}function gAe(t){if(!t)return null;let e=t.indexOf(":");if(e===-1)return{source:"simpleicons",name:t};let r=t.substring(0,e),n=t.substring(e+1);return r!=="simpleicons"&&r!=="lucide"?{source:"simpleicons",name:t}:{source:r,name:n}}function mAe(t){return t?typeof t=="string"?t.indexOf(":")!==-1?t:`simpleicons:${t}`:`${t.source}:${t.name}`:null}function lx(t){if(t.op==="remove"||t.value===void 0||typeof t.value!="string")return t;if(t.path==="/inputSchema"||t.path==="/outputSchema"||t.path.startsWith("/inputSchema/properties/")||t.path.startsWith("/outputSchema/properties/")||t.path.match(/^\/steps\/\d+\/config\/pagination$/)||t.path.match(/^\/steps\/\d+\/config\/headers$/)||t.path.match(/^\/steps\/\d+\/config\/queryParams$/))try{return{...t,value:JSON.parse(t.value)}}catch{return t}return t}function yAe(t){return t.map(e=>lx(e))}function EAe(t,e){t||(t=""),e||(e=""),/^(https?|postgres(ql)?|ftp(s)?|sftp|smb|file):\/\//i.test(t)||(t=`https://${t}`);let r=t.endsWith("/")?t.slice(0,-1):t,n=e.startsWith("/")?e.slice(1):e;return`${r}/${n}`}var IAe=new Set(["data","stepResults","toolPayload","rawData","transformedData"]),CAe=8e4;function bAe(t,e=CAe){if(t==null)return t;let r=t;if(typeof t=="string"){if(t.length<=e)return t;try{r=JSON.parse(t)}catch{return{_truncated:!0,_message:"String result too large to parse",_size:t.length}}}if(typeof r!="object")return r;let n=0,i=0,o=(s,a=0)=>{if(a>20||s===null||typeof s!="object")return s;if(Array.isArray(s))return s.map(u=>o(u,a+1));let c={};for(let[u,l]of Object.entries(s))if(IAe.has(u)&&l!==null&&typeof l=="object"){let d=JSON.stringify(l);if(d.length>e){i+=d.length;try{let{jsonString:A,truncatedProps:p}=(0,Cde.default)(d,e);c[u]=JSON.parse(A),n+=p.length}catch{c[u]=l}}else c[u]=l}else c[u]=o(l,a+1);return c};try{if(JSON.stringify(r).length<=e)return r;let a=o(r);return n>0&&typeof a=="object"&&a!==null&&(a._note=`Result truncated: ${n} items omitted (original ${i} characters)`),a}catch{return{_truncated:!0,_message:"Result too large to display"}}}function SAe(t){if(!t.steps)return[];let e=new Set;for(let r of t.steps)r.config&&(0,GM.isRequestConfig)(r.config)&&r.config.systemId&&e.add(r.config.systemId);return Array.from(e)}function hg(t,e,r=new WeakSet){if(typeof t=="string"){e.push(t);return}if(!(!t||typeof t!="object")&&!r.has(t)){if(r.add(t),Array.isArray(t)){for(let n of t)hg(n,e,r);return}for(let n of Object.values(t))hg(n,e,r)}}function wAe(t){let e=[];for(let r of t.matchAll(/<<([\s\S]*?)>>/g)){let n=r[1].trim();n&&e.push(n)}for(let r of t.matchAll(/{{\s*([^{}\s]+)\s*}}/g)){let n=r[1].trim();n&&e.push(n)}return e}function dx(t,e){let r=[];hg(t,r);let n=`${e}_`,i=new Set;for(let o of r)for(let s of wAe(o)){if(!s.startsWith(n))continue;let a=s.slice(n.length);!a||a==="url"||!O.CREDENTIAL_KEY_PATTERN.test(a)||i.add(a)}return[...i]}var BAe=/^\s*(async\s+)?(\([^)]*\)|[a-zA-Z_$][a-zA-Z0-9_$]*)\s*=>/,_Ae=new Set(["sg_auth_email","sg_auth_jwt"]);function QAe({config:t,systemId:e}){let r=[];hg(t,r);let n=e?`${e}_`:null,i=new Set;for(let u of r)for(let l of u.matchAll(/<<([\s\S]*?)>>/g)){let d=l[1].trim();d&&(n&&d.startsWith(n)||BAe.test(d)||_Ae.has(d)||i.add(d))}if(i.size===0)return null;let o=[...i].map(u=>`<<${u}>>`).join(", "),s=`Unresolved placeholder${i.size===1?"":"s"} ${o}`;if(!n)return`${s}. Credential placeholders need systemId and the form <<systemId_secretName>>. Nothing was sent.`;let a=[...i].filter(u=>O.CREDENTIAL_KEY_PATTERN.test(u)).map(u=>`<<${n}${u}>>`),c=a.length>0?`Credential placeholders are namespaced by system: use ${a.join(", ")}.`:`Credential placeholders are namespaced by system as <<${n}secretName>>.`;return`${s}. ${c} Nothing was sent.`}function vAe(t){let e={};if(!t.steps)return e;for(let r of t.steps){if(!r.config||!(0,GM.isRequestConfig)(r.config)||!r.config.systemId)continue;let n=dx(r.config,r.config.systemId);if(n.length===0)continue;let i=new Set(e[r.config.systemId]||[]);for(let o of n)i.add(o);e[r.config.systemId]=[...i]}return e}});var gx=m(mt=>{"use strict";Object.defineProperty(mt,"__esModule",{value:!0});mt.AGENT_CONTEXT_MEMORY_MESSAGE_ID_PREFIX=void 0;mt.applyToolMutation=Ax;mt.mutateToolCallInMessages=TAe;mt.buildStreamingAssistantMessage=px;mt.parseToolOutput=fx;mt.parseAgentStreamEventLine=NAe;mt.stopActiveTool=hx;mt.appendContentToMessage=xb;mt.updateMessageWithData=mu;mt.findAwaitingConfirmationToolCallIds=kAe;mt.declineAwaitingConfirmationTools=OAe;mt.findAndResumeMessageWithTool=UAe;mt.serializeMessageForPersistence=xAe;mt.isTurnContextBlockMessage=Lb;mt.normalizeAgentSessionForkMessages=LAe;mt.normalizeAgentSessionImportMessages=PAe;mt.createAgentTranscriptState=$Ae;mt.applyAgentStreamChunk=FAe;var DAe=xr(),yg=Dn();function Ax(t,e){let r=e.frontendOutput!==void 0?e.frontendOutput:t.frontendOutput;return{...t,...e.input!==void 0?{input:e.input}:{},...e.result!==void 0?{result:e.result}:{},...e.status!==void 0?{status:e.status}:{},...e.startTime!==void 0?{startTime:e.startTime}:{},...e.endTime!==void 0?{endTime:e.endTime}:{},...e.error!==void 0?{error:e.error||void 0}:{},...r!==void 0?{frontendOutput:r}:{},...e.llmOutput!==void 0?{llmOutput:e.llmOutput}:{},...e.resultMetadata!==void 0?{resultMetadata:e.resultMetadata}:{},...e.confirmationState!==void 0?{confirmationState:e.confirmationState===null?void 0:e.confirmationState}:{},...e.confirmationData!==void 0?{confirmationData:e.confirmationData===null?void 0:e.confirmationData}:{}}}function TAe(t,e,r){return t.map(n=>{let i=!1,o=n.parts?.map(s=>s.type!=="tool"||!s.tool||s.tool.id!==e?s:(i=!0,{...s,tool:Ax(s.tool,r)}));return i&&o?{...n,parts:o}:n})}function px(t){return{id:t,content:"",role:"assistant",timestamp:new Date,parts:[{type:"content",content:"",id:"content-0"}],isStreaming:!0}}function RAe(){return{status:"declined",endTime:new Date,confirmationState:"declined",confirmationData:{reason:"new_user_message",message:"Rejected: the user sent a new message instead of confirming this action. The proposed changes were NOT applied."}}}function fx(t){if(!t)return null;if(typeof t=="string")try{let e=JSON.parse(t);return e&&typeof e=="object"&&!Array.isArray(e)?e:null}catch{return null}return typeof t=="object"&&!Array.isArray(t)?t:null}function NAe(t){if(!t.startsWith("data: "))return null;try{let e=JSON.parse(t.slice(6));return e&&typeof e=="object"&&!Array.isArray(e)?e:null}catch{return null}}function hx(t){return t.status==="running"||t.status==="pending"||t.status==="awaiting_confirmation"?{...t,status:"stopped",endTime:new Date,confirmationState:void 0,confirmationData:void 0}:t}function xb(t,e){if(!e)return t;let r=[...t.parts||[]],n=r[r.length-1];return n?.type==="content"?r[r.length-1]={...n,content:(n.content||"")+e}:r.push({type:"content",content:e,id:`content-${r.length}`}),{...t,parts:r,content:""}}function mu(t,e,r){if(t.id!==r.id)return t;switch(e.type){case"content":return xb(t,e.content||"");case"tool_call_start":{let n=t.parts?.find(u=>u.type==="tool"&&u.tool?.id===e.toolCall.id)?.tool,i=e.toolCall.input??n?.input,o=e.executionMode==="confirm"?"awaiting_confirmation":i?"running":"pending",s={...n,id:e.toolCall.id,name:e.toolCall.name,input:i,status:o,startTime:n?.startTime||new Date,...n?.confirmationState!==void 0?{confirmationState:n.confirmationState}:{},...n?.confirmationData!==void 0?{confirmationData:n.confirmationData}:{}},a=[...t.parts||[]],c=a.findIndex(u=>u.type==="tool"&&u.tool?.id===e.toolCall.id);return c===-1?a.push({type:"tool",tool:s,id:`tool-${e.toolCall.id}`}):a[c]={...a[c],tool:s},{...t,parts:a,content:""}}case"tool_call_input":{let n=i=>i.id===e.toolCall.id&&e.toolCall.input!==void 0?{...i,input:e.toolCall.input}:i;return{...t,parts:t.parts?.map(i=>i.type==="tool"&&i.tool?{...i,tool:n(i.tool)}:i)}}case"run_command_effect":{let n=e.effect;if(n?.kind!=="visual"||typeof e.toolCallId!="string")return t;let i=o=>{if(o.id!==e.toolCallId)return o;let s=fx(o.frontendOutput)??{},a=(s.effects??[]).filter(c=>c.id!==n.id);return{...o,frontendOutput:{...s,effects:[...a,n]}}};return{...t,parts:t.parts?.map(o=>o.type==="tool"&&o.tool?{...o,tool:i(o.tool)}:o)}}case"tool_call_update":{let n=t.parts?.map(i=>i.type==="tool"&&i.tool?.id===e.toolCall.id?{...i,tool:{...i.tool,executionTraceId:e.toolCall.executionTraceId??i.tool.executionTraceId,status:i.tool.status==="pending"?"running":i.tool.status}}:i)||[];return{...t,parts:n}}case"tool_call_complete":{let n=t.parts?.find(h=>h.type==="tool"&&h.tool?.id===e.toolCall.id)?.tool,i=n?.status==="completed"||n?.status==="declined",o=e.toolCall.result!==void 0||e.toolCall.frontendOutput!==void 0||e.toolCall.status!==void 0||e.toolCall.confirmationState!==void 0||e.toolCall.confirmationData!==void 0;if(i&&!o)return t;let s=null;try{s=typeof e.toolCall.frontendOutput=="string"?JSON.parse(e.toolCall.frontendOutput):e.toolCall.frontendOutput}catch{}let a=s?.success===!1&&s?.error,c=e.toolCall.result?.outcome,u=c==="failure"?"error":c==="rejected"?"declined":c==="aborted"?"stopped":c==="success"?"completed":void 0,l=e.toolCall.status||u||"completed";a&&l==="completed"&&(l="error");let d=l==="awaiting_confirmation",A={...e.toolCall.input!==void 0?{input:e.toolCall.input}:{},...e.toolCall.result!==void 0?{result:e.toolCall.result}:{},status:l,frontendOutput:e.toolCall.frontendOutput,llmOutput:e.toolCall.llmOutput,resultMetadata:e.toolCall.resultMetadata,error:c==="failure"?e.toolCall.result.error.message:a?s.error:null,endTime:d?void 0:new Date,...e.toolCall.confirmationState!==void 0?{confirmationState:e.toolCall.confirmationState}:{},...e.toolCall.confirmationData!==void 0?{confirmationData:e.toolCall.confirmationData}:{}},p=t.parts?.map(h=>h.type==="tool"&&h.tool?.id===e.toolCall.id?{...h,tool:{...h.tool,...A}}:h)||[];return{...t,parts:p}}case"done":{if(!t.isStreaming)return t;let n=(t.parts||[]).map(i=>i.type==="tool"&&i.tool&&i.tool.status!=="awaiting_confirmation"?{...i,tool:hx(i.tool)}:i);return{...t,isStreaming:!1,parts:n,content:""}}default:return t}}function kAe(t){let e=new Set;for(let r of t)for(let n of(0,yg.getMessageToolCalls)(r))n.status==="awaiting_confirmation"&&e.add(n.id);return[...e]}function OAe(t){let e=RAe();return t.map(r=>({...r,parts:r.parts?.map(n=>n.type==="tool"&&n.tool?.status==="awaiting_confirmation"?{...n,tool:{...n.tool,...e}}:n)}))}function UAe(t,e){let r=t.find(i=>i.parts?.some(o=>o.type==="tool"&&o.tool?.id===e));return r?{messages:t.map(i=>i.id===r.id?{...i,isStreaming:!0}:i),targetMessage:{...r,isStreaming:!0}}:{messages:t,targetMessage:null}}function MAe(t){return{id:t.id,name:t.name,status:t.status,input:t.input,result:t.result,frontendOutput:t.frontendOutput,llmOutput:t.llmOutput,resultMetadata:t.resultMetadata,error:t.error,startTime:t.startTime,endTime:t.endTime,confirmationState:t.confirmationState,confirmationData:t.confirmationData}}function xAe(t){let{isStreaming:e,tools:r,...n}=t;return JSON.parse((0,yg.safeStringify)({...n,...t.parts?{parts:t.parts.map(i=>i.type==="tool"&&i.tool?{...i,tool:MAe(i.tool)}:i)}:{}},0))}mt.AGENT_CONTEXT_MEMORY_MESSAGE_ID_PREFIX="context-memory-";function Lb(t){return DAe.TURN_CONTEXT_BLOCK_TYPES.includes(t.contextType??"")}function LAe(t){return t.filter(e=>e.role!=="system"&&e.contextType!=="memory_notes"&&!Lb(e)&&!e.id.startsWith(mt.AGENT_CONTEXT_MEMORY_MESSAGE_ID_PREFIX)).map(e=>({...e,stale:void 0,isStreaming:void 0}))}function PAe(t){return t.filter(e=>!e.stale&&!e.isStreaming&&e.contextType!=="memory_notes"&&!Lb(e)&&!!e.id)}function $Ae(t=[],e=null){return{messages:t,assistantMessageId:e,outcome:"streaming"}}function mg(t,e){return(0,yg.getMessageToolCalls)(t).some(r=>r.id===e)}function gu(t,e){let r=t.assistantMessageId?t.messages.find(i=>i.id===t.assistantMessageId):void 0;if(r)return{state:t,target:r};let n=px(t.assistantMessageId??e.createAssistantMessageId());return{state:{...t,messages:[...t.messages,n],assistantMessageId:n.id},target:n}}function FAe(t,e,r){switch(e.type){case"system_message":{if(!e.systemMessage)return t;let n={id:e.systemMessage.id,role:"system",content:e.systemMessage.content,timestamp:new Date};return{...t,messages:[n,...t.messages]}}case"assistant_message_start":{if(!e.assistantMessageId)return t;let n=t.assistantMessageId?t.messages.find(o=>o.id===t.assistantMessageId):void 0;return t.messages.find(o=>o.id===e.assistantMessageId)?{...t,assistantMessageId:e.assistantMessageId,messages:t.messages.filter(o=>!n||n.id===e.assistantMessageId||o.id!==n.id).map(o=>o.id===e.assistantMessageId?{...o,isStreaming:!0}:o)}:n?{...t,assistantMessageId:e.assistantMessageId,messages:t.messages.map(o=>o.id===n.id?{...o,id:e.assistantMessageId,isStreaming:!0}:o)}:{...t,assistantMessageId:e.assistantMessageId}}case"context_message":{if(!e.contextMessage)return t;let n={id:e.contextMessage.id,role:"user",content:e.contextMessage.content,timestamp:new Date,...e.contextMessage.isHidden?{isHidden:!0}:{},...e.contextMessage.attachedFiles?.length?{attachedFiles:e.contextMessage.attachedFiles}:{}};return{...t,assistantMessageId:null,messages:[...t.messages.map(i=>i.id===t.assistantMessageId?{...i,isStreaming:!1}:i),n]}}case"context_usage":case"compaction_start":return t;case"compaction_complete":{if(!e.compaction)return t;let n=(0,yg.applyAgentCompactionToMessages)(t.messages,e.compaction),i=e.compaction.memoryMessage?t.assistantMessageId:null;return!i||!n.some(o=>o.id===i)?{...t,messages:n}:{...t,assistantMessageId:null,messages:n.map(o=>o.id===i?{...o,isStreaming:!1}:o)}}case"content":{let n=gu(t,r);return{...n.state,messages:n.state.messages.map(i=>i.id===n.target.id?xb(i,e.content||""):i)}}case"error":{let n=gu(t,r);return{...n.state,outcome:"failed",messages:n.state.messages.map(i=>i.id!==n.target.id?i:{...i,parts:[...i.parts||[],{type:"error",content:e.content,errorDetails:e.errorDetails,id:`error-${i.parts?.length??0}`}],isStreaming:!1})}}case"tool_call_start":case"tool_call_update":{if(!e.toolCall)return t;let n=e.type==="tool_call_start"?null:t.messages.find(o=>mg(o,e.toolCall.id))??null,i=n?{state:t,target:n}:gu(t,r);return{...i.state,messages:i.state.messages.map(o=>mu(o,e,i.target))}}case"run_command_effect":{let n=e.toolCallId;if(!n)return t;let i=t.messages.find(o=>mg(o,n));return i?{...t,messages:t.messages.map(o=>mu(o,e,i))}:t}case"tool_call_input":{if(!e.toolCall)return t;let n=t.messages.find(i=>mg(i,e.toolCall.id));return n?{...t,messages:t.messages.map(i=>mu(i,e,n))}:t}case"tool_call_complete":{if(!e.toolCall)return t;let n=t.messages.find(o=>mg(o,e.toolCall.id)),i=n?{state:t,target:n}:gu(t,r);return{...i.state,messages:i.state.messages.map(o=>mu(o,e,i.target))}}case"paused":{let n=gu(t,r);return{...n.state,outcome:"paused",messages:n.state.messages.map(i=>i.id===n.target.id?{...i,isStreaming:!1}:i)}}case"done":{let n=gu(t,r);return{...n.state,outcome:t.outcome==="failed"?"failed":"completed",messages:n.state.messages.map(i=>mu(i,e,n.target))}}default:return t}}});var Eg=m(Dt=>{"use strict";Object.defineProperty(Dt,"__esModule",{value:!0});Dt.PROJECT_LABEL_COLOR_PATTERN=Dt.PROJECT_LABEL_COLORS=Dt.PROJECT_LIMITS=Dt.PROJECT_TASK_STATUSES=Dt.PROJECT_RESOURCE_TYPES=void 0;Dt.nextProjectLabelColor=jAe;Dt.projectResourceKey=zAe;Dt.daysUntilTaskDue=yx;Dt.formatTaskDueDate=HAe;Dt.groupByContext=qAe;Dt.PROJECT_RESOURCE_TYPES=["playbook","artifact","file","tool"];Dt.PROJECT_TASK_STATUSES=["not_started","in_progress","waiting","done"];Dt.PROJECT_LIMITS={name:80,description:500,taskName:120,taskDescription:1e4,taskResources:100,labelName:40,labels:50,taskLabels:10};Dt.PROJECT_LABEL_COLORS=["#6b7280","#ef4444","#f97316","#eab308","#22c55e","#14b8a6","#3b82f6","#6366f1","#a855f7","#ec4899"];Dt.PROJECT_LABEL_COLOR_PATTERN=/^#[0-9a-f]{6}$/;function jAe(t){let e=new Set(t.map(r=>r.color));return Dt.PROJECT_LABEL_COLORS.find(r=>!e.has(r))??Dt.PROJECT_LABEL_COLORS[t.length%Dt.PROJECT_LABEL_COLORS.length]}function zAe(t){return`${t.type}:${t.id}`}function mx(t){let e=new Intl.DateTimeFormat("en-CA",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit"}).format(new Date);return new Date(`${e}T00:00:00Z`)}function yx(t,e){let r=new Date(`${t}T00:00:00Z`);return Math.round((r.getTime()-mx(e).getTime())/864e5)}function HAe(t,e){let r=new Date(`${t}T00:00:00Z`),n=mx(e),i=yx(t,e);return i===0?"Due today":i===1?"Due tomorrow":i===-1?"Due yesterday":i<-1?`${-i} days overdue`:i<7?`Due ${r.toLocaleDateString(void 0,{weekday:"long",timeZone:"UTC"})}`:`Due ${r.toLocaleDateString(void 0,{day:"numeric",month:"short",timeZone:"UTC",...r.getUTCFullYear()===n.getUTCFullYear()?{}:{year:"numeric"}})}`}function qAe(t){let e=new Map;for(let r of t)e.set(r.context,[...e.get(r.context)??[],r]);return[...e].map(([r,n])=>({context:r,items:n})).sort((r,n)=>+!!r.context-+!!n.context)}});var Ig=m(qr=>{"use strict";Object.defineProperty(qr,"__esModule",{value:!0});qr.RESOURCE_KINDS=qr.RESOURCE_DEFINITIONS=void 0;qr.isResourceKind=GAe;qr.getResourceDefinition=YAe;qr.getResourceAppPath=VAe;qr.RESOURCE_DEFINITIONS={tool:{label:"Tool",pluralLabel:"Tools",collectionKey:"tools",appPath:"/tools",hasDetailPage:!0,memberDefaultPermission:"editor",pickerDefaultPermission:"editor"},credential:{label:"Connection",pluralLabel:"Connections",collectionKey:"credentials",appPath:"/connections",hasDetailPage:!0,pickerDefaultPermission:"viewer"},playbook:{label:"Playbook",pluralLabel:"Playbooks",collectionKey:"playbooks",appPath:"/playbooks",hasDetailPage:!0,pickerDefaultPermission:"editor"},artifact:{label:"Artifact",pluralLabel:"Artifacts",collectionKey:"artifacts",appPath:"/artifacts",hasDetailPage:!0,pickerDefaultPermission:"editor"},file:{label:"File",pluralLabel:"Files",collectionKey:"files",appPath:"/files",hasDetailPage:!1,pickerDefaultPermission:"viewer"},project:{label:"Project",pluralLabel:"Projects",collectionKey:"projects",appPath:"/projects",hasDetailPage:!0,pickerDefaultPermission:"viewer"}};qr.RESOURCE_KINDS=Object.keys(qr.RESOURCE_DEFINITIONS);function GAe(t){return typeof t=="string"&&Object.prototype.hasOwnProperty.call(qr.RESOURCE_DEFINITIONS,t)}function YAe(t){return qr.RESOURCE_DEFINITIONS[t]}function VAe(t,e){let r=qr.RESOURCE_DEFINITIONS[t];return r.hasDetailPage?`${r.appPath}/${encodeURIComponent(e)}`:r.appPath}});var bx=m(Ma=>{"use strict";Object.defineProperty(Ma,"__esModule",{value:!0});Ma.SDK_ERROR_DETAILS_SCHEMA=Ma.SDK_OUTPUT_CONTRACTS=void 0;Ma.toSdkJsonSchema=KAe;var y=ma(),JAe=Eg(),WAe=Ig(),ZAe=xr();function KAe({schema:t}){return y.z.toJSONSchema(t,{target:"draft-7",io:"output",unrepresentable:"any"})}var Ex=y.z.looseObject({statusCode:y.z.number(),headers:y.z.record(y.z.string(),y.z.union([y.z.string(),y.z.array(y.z.string())])),omittedHeaderCount:y.z.number().optional()}),Ix=y.z.looseObject({vfsPath:y.z.string(),storedBytes:y.z.number(),originalOutputBytes:y.z.number(),storageTruncated:y.z.boolean()}),Cx=y.z.object({action:y.z.enum(["approve","reject","oauth_success","oauth_failure"]),source:y.z.enum(["user","automatic"])});function Tn(t){return y.z.looseObject({toolCallId:y.z.string(),toolName:y.z.string(),outcome:y.z.literal("success"),confirmation:Cx.optional(),data:t})}var Pb={http:Ex.optional(),credential:y.z.looseObject({id:y.z.string(),name:y.z.string(),isOwner:y.z.boolean()}).optional().describe("The credential the call ran with."),auth:y.z.looseObject({applied:y.z.enum(["bearer","basic","explicit","none","unavailable"]),header:y.z.string().optional(),placeholders:y.z.array(y.z.string()),reason:y.z.string().optional()}).optional().describe("How authentication was sent: a default Bearer or Basic header, the request's own explicit placeholders, none, or unavailable with the reason. placeholders lists the credential's <<systemId_secretName>> strings."),credentialPlaceholders:y.z.looseObject({keys:y.z.array(y.z.string()),resolved:y.z.boolean()}).optional()},XAe=y.z.discriminatedUnion("protocol",[y.z.looseObject({protocol:y.z.enum(["postgres","odbc"]),data:y.z.array(y.z.record(y.z.string(),y.z.unknown())).describe("Returned database rows."),...Pb}),y.z.looseObject({protocol:y.z.literal("mssql"),data:y.z.union([y.z.array(y.z.record(y.z.string(),y.z.unknown())),y.z.array(y.z.array(y.z.record(y.z.string(),y.z.unknown()))),y.z.looseObject({rowsAffected:y.z.array(y.z.number())})]).describe("One recordset, multiple recordsets, or affected row counts."),...Pb}),y.z.looseObject({protocol:y.z.enum(ZAe.CONNECTION_PROTOCOLS.filter(t=>t!=="postgres"&&t!=="mssql"&&t!=="odbc")),data:y.z.unknown().describe("Complete protocol response payload. Preserve sibling fields, including files and metadata; do not unwrap a nested data field."),...Pb})]),epe=y.z.union([y.z.looseObject({tools:y.z.array(y.z.unknown()).describe("All tools from every tools/list page, each with name and inputSchema.")}),y.z.looseObject({result:y.z.looseObject({content:y.z.array(y.z.unknown()).optional(),structuredContent:y.z.unknown().optional(),isError:y.z.boolean().optional()}).describe("The tools/call result with content blocks and optional structuredContent.")})]),tpe=y.z.looseObject({url:y.z.string().describe("The requested URL."),status:y.z.number(),statusText:y.z.string(),headers:y.z.record(y.z.string(),y.z.string()),body:y.z.string().describe("Response body bytes, base64-encoded."),systemId:y.z.string().optional().describe("The system whose credential authenticated the request."),credential:y.z.looseObject({id:y.z.string(),name:y.z.string(),isOwner:y.z.boolean()}).optional().describe("The credential the request ran with.")}),rpe=y.z.looseObject({stepId:y.z.string(),success:y.z.boolean(),data:y.z.unknown().optional(),error:y.z.string().nullable().optional(),http:Ex.optional(),stepFileKeys:y.z.array(y.z.string()).optional()}),npe=y.z.looseObject({toolId:y.z.string(),success:y.z.boolean(),run:y.z.looseObject({id:y.z.string()}).optional(),data:y.z.unknown().optional().describe("Tool output, determined by its output transform."),error:y.z.string().optional(),stepResults:y.z.array(rpe),fileArtifacts:y.z.array(y.z.looseObject({fileKey:y.z.string(),filename:y.z.string(),contentType:y.z.string(),size:y.z.number(),downloadUrl:y.z.string().optional()})).optional(),warnings:y.z.array(y.z.string()).optional(),inputSchema:y.z.unknown().optional(),resultMetadata:Ix.optional()}),ipe=Tn(y.z.looseObject({resource:y.z.looseObject({id:y.z.string(),name:y.z.string().optional(),version:y.z.union([y.z.number(),y.z.string()]).optional()}),created:y.z.boolean(),projectId:y.z.string().optional(),addedFiles:y.z.array(y.z.looseObject({id:y.z.string(),fileName:y.z.string()})).optional(),projectAttribution:y.z.looseObject({attached:y.z.boolean(),projectId:y.z.string(),projectName:y.z.string().optional(),resource:y.z.looseObject({type:y.z.enum(JAe.PROJECT_RESOURCE_TYPES),id:y.z.string()}),error:y.z.string().optional()}).optional()}));Ma.SDK_OUTPUT_CONTRACTS={assignSessionToProject:{name:"SuperglueSessionProjectResult",schema:Tn(y.z.object({sessionId:y.z.string(),projectId:y.z.string().nullable()})),description:"Returns the saved session ID and project ID, or null when unassigned. Throws SuperglueError on failure."},callSystem:{name:"SuperglueCallSystemResult",schema:XAe,description:"Returns the complete protocol payload in data, available HTTP metadata, the credential used, and how authentication was sent. Throws SuperglueError on failure; details contains the canonical result and unprojected execution output."},callMcp:{name:"SuperglueCallMcpResult",schema:epe,description:"Returns { tools } when tool is omitted, or { result } from tools/call. Throws SuperglueError on HTTP, JSON-RPC, or result.isError failures; details.result.data contains statusCode, rpcError, or the failed result."},systemFetch:{name:"SuperglueSystemFetchResult",schema:tpe,description:"Returns the raw HTTP response: status, headers, and the base64 body. HTTP error statuses are returned, not thrown. Throws SuperglueError when the request cannot be authenticated or sent."},runTool:{name:"SuperglueRunToolResult",schema:npe,description:"Returns successful tool output, step results, files, and available result reference. Throws SuperglueError on failure; details.result.data preserves this result shape with success: false, the error, and available run and step results. details.resultMetadata references the saved failed result when available."},writeResource:{name:"SuperglueWriteResult",schema:ipe,description:"Returns saved resource identity, creation status, and available project attribution or added files. Throws SuperglueError on failure."},installBundle:{name:"SuperglueBundleInstallResult",schema:Tn(y.z.looseObject({bundleId:y.z.string(),system:y.z.looseObject({id:y.z.string(),name:y.z.string(),requiredCredentialKeys:y.z.array(y.z.string()),hasUserCredentials:y.z.boolean()}),tools:y.z.array(y.z.looseObject({id:y.z.string(),name:y.z.string().optional()})),mcpServer:y.z.looseObject({id:y.z.string(),name:y.z.string()}).optional(),playbook:y.z.looseObject({id:y.z.string(),name:y.z.string()}).optional()})),description:"Returns the installed system ID, tool, MCP server, and playbook identities, the secret names the user must supply, and whether the user has a complete connection. Throws SuperglueError on failure."},stopBackgroundJob:{name:"SuperglueStopBackgroundJobResult",schema:Tn(y.z.looseObject({job:y.z.looseObject({id:y.z.string(),status:y.z.string(),elapsedMs:y.z.number(),exitCode:y.z.number().optional()})})),description:"Returns the job's status, run time, and exit code after it ended, or status running when the stop is still in progress. Throws SuperglueError when the session has no such running job."},setToolState:{name:"SuperglueToolStateResult",schema:Tn(y.z.looseObject({resource:y.z.looseObject({id:y.z.string()}),action:y.z.enum(["set","reset"])})),description:"Returns the saved tool identity and state action. Throws SuperglueError on failure."},shareResource:{name:"SuperglueShareResult",schema:Tn(y.z.looseObject({resource:y.z.looseObject({kind:y.z.enum(WAe.RESOURCE_KINDS),id:y.z.string()})})),description:"Returns the shared resource identity. Throws SuperglueError on failure."},showVisual:{name:"SuperglueShowVisualResult",schema:Tn(y.z.looseObject({visualId:y.z.string(),check:y.z.looseObject({errors:y.z.array(y.z.string()),blockedRequests:y.z.array(y.z.string()),dataCalls:y.z.array(y.z.string()),contentHeight:y.z.number().optional(),timedOut:y.z.boolean()}).optional(),checkSkipped:y.z.string().optional(),screenshots:y.z.array(y.z.string()).optional()})),description:"Returns the visualId shown to the user. For a custom visual, check holds the test-browser result, and screenshots lists the labels of the screenshots attached to this command's result for you. Throws SuperglueError ETOOL when the visual fails its check; error.details.result.data.check then holds the errors."},notifyUser:{name:"SuperglueNotifyResult",schema:Tn(y.z.looseObject({nextStepIds:y.z.array(y.z.string())})),description:"Returns the nextStepIds of the saved actions, in action order. Throws SuperglueError on failure."},writeOrgSettings:{name:"SuperglueOrgSettingsResult",schema:Tn(y.z.looseObject({updated:y.z.array(y.z.enum(["name","preferences","notifications"])),notificationTest:y.z.looseObject({channel:y.z.enum(["slack","email"]),sent:y.z.boolean(),error:y.z.string().optional()}).optional()})),description:"Returns updated settings and any notification test result. Throws SuperglueError on failure."},writeDesignSystem:{name:"SuperglueDesignSystemResult",schema:Tn(y.z.looseObject({updated:y.z.array(y.z.enum(["tokens","guidelines","logo"])),added:y.z.array(y.z.looseObject({id:y.z.string(),kind:y.z.enum(["logo","font","template","reference"]),name:y.z.string()})),changed:y.z.array(y.z.string()),removed:y.z.array(y.z.string())})),description:"Returns the changed design-system parts and file ids. Throws SuperglueError on failure."},importDesignSystemFromUrl:{name:"SuperglueDesignSystemImportResult",schema:Tn(y.z.looseObject({url:y.z.string(),title:y.z.string().nullable(),tokens:y.z.looseObject({}),palette:y.z.array(y.z.looseObject({color:y.z.string(),weight:y.z.number()})),fonts:y.z.array(y.z.looseObject({family:y.z.string(),usage:y.z.array(y.z.string()),source:y.z.string()})),fontFiles:y.z.array(y.z.looseObject({file:y.z.string(),family:y.z.string().describe("CSS family name the website uses"),roles:y.z.array(y.z.string()),weight:y.z.string(),style:y.z.enum(["normal","italic"])})),logos:y.z.array(y.z.looseObject({file:y.z.string(),source:y.z.string(),width:y.z.number(),height:y.z.number(),light:y.z.boolean().describe("Light artwork meant for dark backgrounds")})),screenshot:y.z.string().nullable()})),description:"Returns a proposed design system from the website; font files, logos, and the screenshot are file:: session uploads. Throws SuperglueError on failure."},readQbm:{name:"SuperglueReadQbmResult",schema:Tn(y.z.looseObject({folder:y.z.string(),objects:y.z.array(y.z.looseObject({type:y.z.string(),files:y.z.array(y.z.string()),records:y.z.number()})),rawTables:y.z.array(y.z.looseObject({table:y.z.string(),files:y.z.array(y.z.string()),rows:y.z.number()})),encryptedValues:y.z.array(y.z.looseObject({table:y.z.string(),column:y.z.string(),values:y.z.number()})),unmappedCodes:y.z.array(y.z.looseObject({field:y.z.string(),code:y.z.string(),records:y.z.number()})).optional(),attachments:y.z.looseObject({documents:y.z.number(),note:y.z.string()}).optional(),rejectedRows:y.z.array(y.z.looseObject({table:y.z.string(),rows:y.z.number()})).optional()})),description:"Returns the folder that holds the extracted files, record counts per object type and raw table, encrypted columns, codes the reader cannot decode, and expected attachments. The folder also holds coverage.json.raw with the same summary plus the mapped source tables. Throws SuperglueError on failure."},previewArtifact:{name:"SuperglueArtifactPreviewResult",schema:y.z.looseObject({draftId:y.z.string(),bytes:y.z.number()}),description:"Returns the artifact draft identity and byte count. Throws SuperglueError on failure."}};var ope=y.z.looseObject({code:y.z.string(),path:y.z.array(y.z.union([y.z.string(),y.z.number(),y.z.symbol()])),message:y.z.string()});Ma.SDK_ERROR_DETAILS_SCHEMA=y.z.discriminatedUnion("kind",[y.z.looseObject({kind:y.z.literal("tool_result"),resultMetadata:Ix.optional(),result:y.z.looseObject({toolCallId:y.z.string(),toolName:y.z.string(),outcome:y.z.enum(["success","failure","rejected","aborted"]),confirmation:Cx.optional(),error:y.z.looseObject({message:y.z.string()}).optional(),data:y.z.unknown().optional()}),output:y.z.unknown().describe("Unprojected execution output, including the original error and any available response data or metadata.")}),y.z.looseObject({kind:y.z.enum(["input_validation","output_validation"]),toolName:y.z.string(),issues:y.z.array(ope),output:y.z.unknown().optional()})])});var Ox=m(we=>{"use strict";Object.defineProperty(we,"__esModule",{value:!0});we.SERVER_OWNED_SESSION_RESOURCE_KINDS=we.AgentRequestValidationError=we.AGENT_TOOL_CONTINUATION_ACTION_BY_CONFIRMATION_STATE=we.AGENT_TOOL_CONTINUATION_ACTIONS=we.AGENT_IDENTIFIER_PATTERN=we.AGENT_REQUEST_LIMITS=void 0;we.validateAgentRequestPayload=Dx;we.validateResourceBinding=Tx;we.validateClientResourceBinding=Rx;we.validateAgentSessionIdentity=Nx;we.validateAgentSessionTarget=kx;we.validateAgentRequestSubmission=Ape;we.isAgentMessagePayload=ppe;we.isAgentToolContinuationPayload=fpe;var Ho=xr();we.AGENT_REQUEST_LIMITS={messageContentChars:5e4,identifierChars:256,attachedFiles:20,toolContinuations:20,continuationInputChars:1e5,frontendDraftsChars:2e6,accessRulesContextChars:2e6,pendingMessagesPerSession:10};we.AGENT_IDENTIFIER_PATTERN=/^[A-Za-z0-9._-]+$/;we.AGENT_TOOL_CONTINUATION_ACTIONS=["approve","reject","oauth_success","oauth_failure"];we.AGENT_TOOL_CONTINUATION_ACTION_BY_CONFIRMATION_STATE={[Ho.ConfirmationAction.CONFIRMED]:"approve",[Ho.ConfirmationAction.DECLINED]:"reject",[Ho.ConfirmationAction.OAUTH_SUCCESS]:"oauth_success",[Ho.ConfirmationAction.OAUTH_FAILURE]:"oauth_failure"};var Cg=class extends Error{constructor(e){super(e),this.name="AgentRequestValidationError"}};we.AgentRequestValidationError=Cg;function Ye(t){throw new Cg(t)}function po(t,e){return(!t||typeof t!="object"||Array.isArray(t))&&Ye(`${e} must be an object`),t}function xa(t,e){(typeof t!="string"||!t.trim())&&Ye(`${e} must be a non-empty string`);let r=t.trim();return r.length>we.AGENT_REQUEST_LIMITS.identifierChars&&Ye(`${e} exceeds ${we.AGENT_REQUEST_LIMITS.identifierChars} characters`),we.AGENT_IDENTIFIER_PATTERN.test(r)||Ye(`${e} may only contain letters, numbers, dots, underscores, and hyphens`),r}function spe(t,e){return typeof t!="boolean"&&Ye(`${e} must be a boolean`),t}function $b(t,e){try{return JSON.stringify(t).length}catch{return Ye(`${e} must be JSON-serializable`)}}function ape(t,e){if(t!==void 0)return Array.isArray(t)||Ye(`${e} must be an array`),t.length>we.AGENT_REQUEST_LIMITS.attachedFiles&&Ye(`${e} exceeds ${we.AGENT_REQUEST_LIMITS.attachedFiles} entries`),t.map((r,n)=>{let i=po(r,`${e}[${n}]`);return{...i,key:xa(i.key,`${e}[${n}].key`)}})}function Sx({value:t,label:e,requireHidden:r}){let n=po(t,e),i=xa(n.id,`${e}.id`);typeof n.content!="string"&&Ye(`${e}.content must be a string`);let o=n.content;o.length>we.AGENT_REQUEST_LIMITS.messageContentChars&&Ye(`${e}.content exceeds ${we.AGENT_REQUEST_LIMITS.messageContentChars} characters`);let s=spe(n.isHidden,`${e}.isHidden`);r&&!s&&Ye(`${e}.isHidden must be true`);let a=ape(n.attachedFiles,`${e}.attachedFiles`);return!o.trim()&&!a?.length&&Ye(`${e}.content may only be empty when an attachment is present`),{id:i,content:o,isHidden:s,...a?{attachedFiles:a}:{}}}function Bx(t){if(t===void 0)return;let e=po(t,"frontendDrafts");return $b(e,"frontendDrafts")>we.AGENT_REQUEST_LIMITS.frontendDraftsChars&&Ye(`frontendDrafts exceeds ${we.AGENT_REQUEST_LIMITS.frontendDraftsChars} characters`),e}function _x(t){if(t===void 0)return;let e=po(t,"accessRulesContext");return $b(e,"accessRulesContext")>we.AGENT_REQUEST_LIMITS.accessRulesContextChars&&Ye(`accessRulesContext exceeds ${we.AGENT_REQUEST_LIMITS.accessRulesContextChars} characters`),e}function Qx(t){if(t!==void 0)return(typeof t!="string"||!Ho.AGENT_APPROVAL_MODES.includes(t))&&Ye(`request.approvalMode must be one of: ${Ho.AGENT_APPROVAL_MODES.join(", ")}`),t}function vx(t,e){let r=po(t,e),n=xa(r.toolCallId,`${e}.toolCallId`);return(typeof r.action!="string"||!we.AGENT_TOOL_CONTINUATION_ACTIONS.includes(r.action))&&Ye(`${e}.action must be one of: ${we.AGENT_TOOL_CONTINUATION_ACTIONS.join(", ")}`),r.input!==void 0&&$b(r.input,`${e}.input`)>we.AGENT_REQUEST_LIMITS.continuationInputChars&&Ye(`${e}.input exceeds ${we.AGENT_REQUEST_LIMITS.continuationInputChars} characters`),{toolCallId:n,action:r.action,...r.input!==void 0?{input:r.input}:{}}}function cpe(t){if(t===void 0)return;(!Array.isArray(t)||t.length===0)&&Ye("request.toolContinuations must be a non-empty array"),t.length>we.AGENT_REQUEST_LIMITS.toolContinuations&&Ye(`request.toolContinuations exceeds ${we.AGENT_REQUEST_LIMITS.toolContinuations} entries`);let e=t.map((r,n)=>vx(r,`request.toolContinuations[${n}]`));return new Set(e.map(({toolCallId:r})=>r)).size!==e.length&&Ye("request.toolContinuations must not contain duplicate toolCallId values"),e}function wx(t,e){if(t===void 0)return;(typeof t!="string"||!t.trim())&&Ye(`${e} must be a non-empty string`);let r=t.trim();return r.length>we.AGENT_REQUEST_LIMITS.messageContentChars&&Ye(`${e} exceeds ${we.AGENT_REQUEST_LIMITS.messageContentChars} characters`),r}var upe=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function lpe(t){let e=Sx({value:t.message,label:"request.message"}),r=wx(t.title,"request.title"),n=wx(t.titleInput,"request.titleInput"),i=t.hiddenSteeringMessage===void 0?void 0:Sx({value:t.hiddenSteeringMessage,label:"request.hiddenSteeringMessage",requireHidden:!0});i&&i.id===e.id&&Ye("request.hiddenSteeringMessage.id must differ from request.message.id");let o=cpe(t.toolContinuations),s=Qx(t.approvalMode),a=Bx(t.frontendDrafts),c=_x(t.accessRulesContext);return t.nextStepId!==void 0&&(typeof t.nextStepId!="string"||!upe.test(t.nextStepId))&&Ye("request.nextStepId must be a UUID"),{kind:"message",message:e,...t.nextStepId?{nextStepId:t.nextStepId}:{},...i?{hiddenSteeringMessage:i}:{},...r?{title:r}:{},...n?{titleInput:n}:{},...o?{toolContinuations:o}:{},...s?{approvalMode:s}:{},...a?{frontendDrafts:a}:{},...c?{accessRulesContext:c}:{}}}function dpe(t){let e=vx(t,"request"),r=Qx(t.approvalMode),n=Bx(t.frontendDrafts),i=_x(t.accessRulesContext);return{kind:"tool_continuation",...e,...r?{approvalMode:r}:{},...n?{frontendDrafts:n}:{},...i?{accessRulesContext:i}:{}}}function Dx(t){let e=po(t,"request");return e.kind==="message"?lpe(e):e.kind==="tool_continuation"?dpe(e):Ye('request.kind must be "message" or "tool_continuation"')}function Tx(t,e){let r=po(t,e);return(typeof r.kind!="string"||!Ho.AGENT_SESSION_RESOURCE_KINDS.includes(r.kind))&&Ye(`${e}.kind must be one of: ${Ho.AGENT_SESSION_RESOURCE_KINDS.join(", ")}`),{kind:r.kind,id:xa(r.id,`${e}.id`)}}we.SERVER_OWNED_SESSION_RESOURCE_KINDS=["briefing"];function Rx(t,e){let r=Tx(t,e);return we.SERVER_OWNED_SESSION_RESOURCE_KINDS.includes(r.kind)&&Ye(`${e}.kind "${r.kind}" is assigned by the server`),r}function Nx(t,e="session.createIfMissing"){let r=po(t,e),n=r.projectId===void 0?void 0:xa(r.projectId,`${e}.projectId`),i=r.taskId===void 0?void 0:xa(r.taskId,`${e}.taskId`);i&&!n&&Ye(`${e}.taskId requires ${e}.projectId`);let o=Object.values(Ho.AgentType);(typeof r.agentId!="string"||!o.includes(r.agentId))&&Ye(`${e}.agentId must be one of: ${o.join(", ")}`);let s=r.resourceBinding===void 0?void 0:Rx(r.resourceBinding,`${e}.resourceBinding`);return{agentId:r.agentId,...n?{projectId:n}:{},...i?{taskId:i}:{},...s?{resourceBinding:s}:{}}}function kx(t){let e=po(t,"session"),r=e.createIfMissing===void 0?void 0:Nx(e.createIfMissing);return{id:xa(e.id,"session.id"),...r?{createIfMissing:r}:{}}}function Ape(t){let e=po(t,"body");return{session:kx(e.session),request:Dx(e.request)}}function ppe(t){return t.kind==="message"}function fpe(t){return t.kind==="tool_continuation"}});var Mx=m(Ve=>{"use strict";Object.defineProperty(Ve,"__esModule",{value:!0});Ve.ARTIFACT_EXPORT_FORMATS=Ve.ARTIFACT_RESPONSE_RESERVED_FIELD_NAMES=Ve.ARTIFACT_RESPONSE_PATCH_DEBOUNCE_MS=Ve.MAX_SPREADSHEET_ARTIFACT_BYTES=Ve.MAX_HTML_ARTIFACT_IMAGE_BYTES=Ve.MAX_HTML_ARTIFACT_BYTES=Ve.MAX_SPREADSHEET_CELL_TEXT_LENGTH=Ve.MAX_SPREADSHEET_SHEET_NAME_LENGTH=Ve.MAX_SPREADSHEET_GRID_CELLS=Ve.MAX_SPREADSHEET_SHEETS=Ve.SPREADSHEET_CELL_TYPES=void 0;Ve.isValidSpreadsheetCell=mpe;Ve.isArtifactExportFormat=ype;Ve.isArtifactExportFormatForKind=Epe;var Ux=ma();Ve.SPREADSHEET_CELL_TYPES=["text","integer","number","percent","currency","boolean","date","datetime"];Ve.MAX_SPREADSHEET_SHEETS=20;Ve.MAX_SPREADSHEET_GRID_CELLS=1e6;Ve.MAX_SPREADSHEET_SHEET_NAME_LENGTH=31;Ve.MAX_SPREADSHEET_CELL_TEXT_LENGTH=32767;var hpe=Ux.z.iso.date(),gpe=Ux.z.iso.datetime({offset:!0});function mpe(t,e){return t===null?!0:e==="text"?typeof t=="string"&&t.length<=Ve.MAX_SPREADSHEET_CELL_TEXT_LENGTH:e==="boolean"?typeof t=="boolean":["integer","number","percent","currency"].includes(e)?typeof t=="number"&&Number.isFinite(t)&&(e!=="integer"||Number.isInteger(t)):typeof t!="string"?!1:(e==="datetime"?gpe:hpe).safeParse(t).success}Ve.MAX_HTML_ARTIFACT_BYTES=1024*1024;Ve.MAX_HTML_ARTIFACT_IMAGE_BYTES=12*1024*1024;Ve.MAX_SPREADSHEET_ARTIFACT_BYTES=10*1024*1024;Ve.ARTIFACT_RESPONSE_PATCH_DEBOUNCE_MS=300;Ve.ARTIFACT_RESPONSE_RESERVED_FIELD_NAMES=new Set(["__proto__","constructor","prototype"]);Ve.ARTIFACT_EXPORT_FORMATS=["html","pdf","docx","xlsx","pptx"];function ype(t){return Ve.ARTIFACT_EXPORT_FORMATS.some(e=>e===t)}function Epe(t,e,r=!1){return t==="spreadsheet"?e==="xlsx":r?e==="html"||e==="pdf"||e==="pptx":e!=="pptx"}});var Fx=m(ze=>{"use strict";Object.defineProperty(ze,"__esModule",{value:!0});ze.API_KEY_ACTION_LABELS=ze.API_KEY_SURFACE_LABELS=ze.API_KEY_SCOPES=ze.API_KEY_SURFACE_ACTIONS=ze.API_KEY_ACTIONS=ze.API_KEY_SURFACES=void 0;ze.getApiKeySurface=Lx;ze.getApiKeyAction=Px;ze.getApiKeySurfaceActions=Fb;ze.parseApiKeyScopes=$x;ze.validateApiKeyScopesInput=Spe;ze.isApiKeyScopeAllowed=wpe;ze.formatApiKeyScopes=Bpe;ze.API_KEY_SURFACES=["api","mcp"];ze.API_KEY_ACTIONS=["read","write","execute"];ze.API_KEY_SURFACE_ACTIONS={api:ze.API_KEY_ACTIONS,mcp:["execute"]};ze.API_KEY_SCOPES=ze.API_KEY_SURFACES.flatMap(t=>ze.API_KEY_SURFACE_ACTIONS[t].map(e=>`${t}:${e}`));ze.API_KEY_SURFACE_LABELS={api:"API & CLI",mcp:"MCP"};ze.API_KEY_ACTION_LABELS={read:"Read",write:"Write",execute:"Execute"};var xx=new Set(ze.API_KEY_SCOPES),Ipe={"/v1/tools":["read"],"/v1/tools/:toolId/run":["execute"],"/v1/authenticate":["write"],"/v1/memory-notes":["read","write"]},Cpe=new Set(["/v1/api-keys","/v1/api-keys/:id","/v1/api-keys/:id/reveal"]),bpe=new Set(["/v1/me"]);function Lx(t){let e=t.split("?")[0];return e==="/mcp"||e.startsWith("/mcp/")?"mcp":"api"}function Px(t){return t==="read"?"read":t==="execute"?"execute":"write"}function Fb(t,e){return ze.API_KEY_SURFACE_ACTIONS[e].filter(r=>(t||[]).includes(`${e}:${r}`))}function $x(t){if(!Array.isArray(t))return null;let e=[...new Set(t.filter(r=>xx.has(r)))];return e.length>0?e:null}function Spe(t){if(t==null)return{scopes:null};let e=`Valid scopes: ${ze.API_KEY_SCOPES.join(", ")}. Use null for full access.`;if(!Array.isArray(t)||t.length===0)return{error:`scopes must be a non-empty array of API key scopes. ${e}`};let r=t.filter(n=>!xx.has(n));return r.length>0?{error:`Unknown API key scope(s): ${r.map(String).join(", ")}. ${e}`}:{scopes:$x(t)}}function wpe({scopes:t,path:e,type:r}){if(!t||t.length===0)return!0;let n=e.split("?")[0];if(Cpe.has(n))return!1;if(bpe.has(n))return!0;let i=Px(r),o=Lx(n);return o==="api"&&Ipe[n]?.some(s=>s===r)&&Fb(t,"mcp").length>0?!0:t.includes(`${o}:${i}`)}function Bpe(t){return!t||t.length===0?"Full access":ze.API_KEY_SURFACES.map(e=>({surface:e,actions:Fb(t,e)})).filter(e=>e.actions.length>0).map(e=>ze.API_KEY_SURFACE_ACTIONS[e.surface].length===1?ze.API_KEY_SURFACE_LABELS[e.surface]:`${ze.API_KEY_SURFACE_LABELS[e.surface]} ${e.actions.join("/")}`).join(", ")}});var jx=m(jb=>{"use strict";Object.defineProperty(jb,"__esModule",{value:!0});jb.isValidEmail=_pe;function _pe(t){return/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*\.[a-zA-Z]{1,}$/.test(t)}});var Hx=m(yt=>{"use strict";Object.defineProperty(yt,"__esModule",{value:!0});yt.GATEWAY_UNINSTALL_COMMANDS=yt.GATEWAY_API_KEY_NAME_PREFIX=yt.GATEWAY_TARGET_NAME_PATTERN=yt.GATEWAY_SETUP_GUIDE_URL=yt.GATEWAY_DOWNLOAD_BASE_URL=yt.GATEWAY_INSTALL_TOKEN_PREFIX=void 0;yt.getGatewayServerUrl=zx;yt.buildGatewayInstallToken=vpe;yt.buildGatewayInstallCommand=Dpe;yt.getGatewayApiKeyName=Tpe;yt.GATEWAY_INSTALL_TOKEN_PREFIX="sgi1.";yt.GATEWAY_DOWNLOAD_BASE_URL="https://downloads.superglue.cloud";yt.GATEWAY_SETUP_GUIDE_URL="https://superglue.ai/docs/guides/secure-gateway/";yt.GATEWAY_TARGET_NAME_PATTERN=/^[a-z0-9]([a-z0-9_-]{0,61}[a-z0-9])?$/;function zx(t){let e=new URL(t);return e.protocol=e.protocol==="http:"?"ws:":"wss:",e.pathname=`${e.pathname.replace(/\/+$/,"")}/ws/tunnels`,e.search="",e.hash="",e.toString()}function Qpe(t){let e=new TextEncoder().encode(t),r="";for(let n of e)r+=String.fromCharCode(n);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function vpe(t){let e={v:1,serverUrl:zx(t.apiEndpoint),tunnelId:t.tunnelId,apiKey:t.apiKey,targets:t.targets,enableScriptRunner:t.enableScriptRunner};return yt.GATEWAY_INSTALL_TOKEN_PREFIX+Qpe(JSON.stringify(e))}function Dpe(t,e){return t==="windows"?['$ErrorActionPreference = "Stop"',"[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor 3072",'$ProgressPreference = "SilentlyContinue"','$gateway = "$env:TEMP\\superglue-gateway.exe"',"Remove-Item $gateway -Force -ErrorAction SilentlyContinue",`Invoke-WebRequest -UseBasicParsing "${yt.GATEWAY_DOWNLOAD_BASE_URL}/superglue-gateway-windows.exe" -OutFile $gateway`,`"${e}" | & $gateway install -`].join("; "):["d=$(mktemp -d)",`u="${yt.GATEWAY_DOWNLOAD_BASE_URL}/superglue-gateway-linux-$(uname -m | sed 's/aarch64/arm64/')"`,'s=$([ "$(id -u)" -eq 0 ] || echo sudo)','{ if command -v curl >/dev/null; then curl -fsSL -o "$d/superglue-gateway" "$u"; else wget -qO "$d/superglue-gateway" "$u"; fi; }','$s install -m 0755 "$d/superglue-gateway" /usr/local/bin/superglue-gateway',`echo '${e}' | $s /usr/local/bin/superglue-gateway install -`].join(" && ")}yt.GATEWAY_API_KEY_NAME_PREFIX="Gateway: ";function Tpe(t){return yt.GATEWAY_API_KEY_NAME_PREFIX+t}yt.GATEWAY_UNINSTALL_COMMANDS={windows:'& "C:\\Program Files\\superglue Gateway\\superglue-gateway.exe" uninstall',linux:"sudo /usr/local/bin/superglue-gateway uninstall"}});var Sg=m(Ce=>{"use strict";Object.defineProperty(Ce,"__esModule",{value:!0});Ce.OAUTH_CONFIG_CREDENTIAL_KEYS=void 0;Ce.hasMeaningfulValue=Et;Ce.stringValue=qt;Ce.validateOAuthConnection=Fpe;Ce.formatOAuthConnectionDisabledReason=zpe;Ce.objectValue=Go;Ce.parseScopes=jd;Ce.normalizeGrantType=zd;Ce.normalizeOAuthClientMode=qb;Ce.normalizeSystemAuthentication=Ar;Ce.resolveOAuthClientMode=qpe;Ce.flattenSystemAuthentication=Jx;Ce.maskedFlatSystemAuthentication=Gpe;Ce.isMaskedSecretValue=Wx;Ce.pickAgentAuthInputFields=Ype;Ce.maskSystemAuthenticationForResponse=Vpe;Ce.restoreMaskedClientSecret=Jpe;Ce.mapAgentAuthInput=Zx;Ce.mergeAgentAuthInput=ofe;Ce.getAuthenticationConfigCredentialKeys=Kx;Ce.buildAuthenticationEditorModel=sfe;Ce.getCredentialRequirements=afe;Ce.isCredentialRequirementSatisfied=Xx;Ce.hasUnsatisfiedCredentialRequirements=cfe;Ce.updateAuthenticationEditorField=ufe;Ce.validateOAuthAuthenticationConfigPlacement=eL;Ce.authenticationToLegacyCredentials=tL;Ce.isRuntimeCredentialMetadataKey=lfe;Ce.resolveCredentialAuthentication=dfe;Ce.buildRuntimeCredentialsFromAuthentication=Afe;Ce.resolveOAuthConfigFromAuthentication=pfe;Ce.toCredentialInputValue=Gb;Ce.getCredentialEntries=ffe;Ce.getCredentialInputValues=hfe;Ce.getCredentialDisplayHiddenKeys=gfe;Ce.hasOAuthTokenCredentials=mfe;Ce.getOAuthExpiryText=yfe;Ce.hasRuntimeCredentialValues=Efe;Ce.validateCredentialObjectKeys=Ife;Ce.validateCredentialKeyList=Cfe;Ce.mapOAuthMissingFieldsForAgent=bfe;Ce.validateOAuthAuthenticationAndCredentialInputs=Sfe;var Tt=Dn(),Rpe=pu();Ce.OAUTH_CONFIG_CREDENTIAL_KEYS=["auth_url","authUrl","token_url","tokenUrl","token_uri","scopes","scope","grant_type","grantType","oauthClientMode","client_id","clientId","client_secret","clientSecret","tokenAuthMethod","tokenContentType","usePKCE","extraHeaders","extraBodyParams"];var bg=["host","port","database","path","homeDirectory"],Vx=["type","oauthClientMode","grantType","authUrl","tokenUrl","scopes","clientId","clientSecret","tokenAuthMethod","tokenContentType","usePKCE","extraHeaders","extraBodyParams","resource","protocol",...bg],Npe=new Set(Vx),kpe="type, oauthClientMode, grantType, authUrl, tokenUrl, scopes, clientId, clientSecret, tokenAuthMethod, tokenContentType, usePKCE, extraHeaders, extraBodyParams, resource, protocol, host, port, database, path, homeDirectory",Ope=["grantType","authUrl","tokenUrl","scopes","clientId","clientSecret"],Upe={grantType:["grantType","grant_type"],authUrl:["authUrl","auth_url"],tokenUrl:["tokenUrl","token_url","token_uri"],scopes:["scopes","scope"],clientId:["clientId","client_id"],clientSecret:["clientSecret","client_secret"]},Fd=["tokenAuthMethod","tokenContentType","usePKCE","extraHeaders","extraBodyParams","resource"],Mpe=new Set(Ope),xpe=new Set(["access_token","accessToken","refresh_token","refreshToken","expires_at","expiresAt","expires_in","expiresIn","expiry","token_type","tokenType"]),Lpe=["access_token","refresh_token","api_key","bearer_token","token","client_id","client_secret","auth_url","token_url","scopes","grant_type","token_type","expires_at","expiry","expires_in","host","hostname","port","database","dbname","db","username","password"],qx=new Map(Lpe.map((t,e)=>[(0,Tt.normalizeCredentialKey)(t),e]));function La(t){return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}function zb({config:t,key:e,value:r}){let n={...t||{}};return Et(r)?n[e]=r:delete n[e],Object.keys(n).length>0?n:void 0}function Et(t){return(0,Tt.hasCredentialValue)(t)}function qt(t){if(Et(t))return typeof t=="string"?t:String(t)}var Ppe={"grant_type authorization_code or client_credentials":"authorization_code or client_credentials",client_id:"client ID",token_url:"token URL",auth_url:"authorization URL","client_secret or usePKCE":"client secret or PKCE","client_secret or oauth_cert + oauth_key":"client secret or OAuth certificate and key"};function qo(...t){return t.find(e=>Et(e))}function $pe(t){return t===!0||t==="true"}function Fpe(t){let e=t||{},r=qt(qo(e.grant_type,e.grantType)),n=r==="client_credentials"?"client_credentials":"authorization_code",i=r&&r!=="authorization_code"&&r!=="client_credentials",o=qo(e.client_id,e.clientId),s=qo(e.client_secret,e.clientSecret),a=qo(e.auth_url,e.authUrl),c=qo(e.token_url,e.tokenUrl,e.token_uri),u=qo(e.oauth_cert,e.oauthCert),l=qo(e.oauth_key,e.oauthKey),d=Et(u)&&Et(l)||e.hasServerSideCertificateCredentials===!0,A=e.hasServerSideClientSecret===!0,p=Et(s)||A,h=$pe(qo(e.usePKCE,e.usePkce)),g=[];return i&&g.push("grant_type authorization_code or client_credentials"),Et(o)||g.push("client_id"),Et(c)||g.push("token_url"),n==="client_credentials"?!p&&!d&&g.push("client_secret or oauth_cert + oauth_key"):(Et(a)||g.push("auth_url"),!p&&!h&&g.push("client_secret or usePKCE")),{grantType:n,hasAccessToken:Et(qo(e.access_token,e.accessToken)),hasCertificateCredentials:d,isReadyToConnect:g.length===0,missingFields:g,usePKCE:h}}function jpe(t){return t.length<=1?t[0]||"":t.length===2?`${t[0]} and ${t[1]}`:`${t.slice(0,-1).join(", ")}, and ${t[t.length-1]}`}function zpe(t){if(!t||t.isReadyToConnect)return null;let e=t.missingFields.map(r=>Ppe[r]||r);return`OAuth connection is disabled because ${jpe(e)} ${e.length===1?"is":"are"} missing.`}function Go(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function fo(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function jd(t){if(Array.isArray(t))return t.map(String).filter(Boolean);if(Et(t)){if(typeof t=="string"){let e=t.trim().split(/[,\s]+/).map(r=>r.trim()).filter(Boolean);return e.length>0?e:void 0}return[String(t)]}}function zd(t){let e=qt(t);if(e==="authorization_code"||e==="client_credentials"||e==="password"||e==="service_account"||e==="custom")return e;if(e)return"custom"}function qb(t){return t==="managed"||t==="dynamic"||t==="custom"?t:void 0}function Hpe(t){let e=Object.entries(t).filter(([r])=>!Mpe.has(r));return e.length>0?Object.fromEntries(e):void 0}function yu(t,e,r){for(let i of Upe[r])if(r==="scopes"&&Array.isArray(t[i])||Et(t[i]))return t[i];let n=Go(t.client);return r==="clientId"&&Et(n?.id)?n.id:r==="clientSecret"&&Et(n?.secret)?n.secret:e[r]}function Ar(t){if(!t)return;let e=t;if(e.type==="oauth2"){let r=Go(e.config)||{},n=Hpe(r)||{};return La({type:"oauth2",oauthClientMode:qb(e.oauthClientMode),grantType:zd(yu(e,r,"grantType")),authUrl:qt(yu(e,r,"authUrl")),tokenUrl:qt(yu(e,r,"tokenUrl")),scopes:jd(yu(e,r,"scopes")),oauthAppId:qt(e.oauthAppId),clientId:qt(yu(e,r,"clientId")),clientSecret:qt(yu(e,r,"clientSecret")),config:Object.keys(n).length>0?n:void 0})}return e.type==="connection_string"?La({type:"connection_string",protocol:e.protocol,config:Go(e.config??e.components)}):e.type==="api_key"||e.type==="basic_auth"||e.type==="none"?La({type:e.type,config:Go(e.config)}):{type:"none"}}function qpe({authentication:t,templateManaged:e,templateRegistrationUrl:r}){let n=Ar(t);return n?.type!=="oauth2"?"custom":n.oauthAppId?.startsWith("managed:")?"managed":n.oauthClientMode?n.oauthClientMode==="managed"&&!e?"custom":n.oauthClientMode:r?"dynamic":e&&!n.clientSecret?"managed":"custom"}function Jx(t){let e=Ar(t);if(!e)return;let{config:r,scopes:n,oauthAppId:i,...o}=e,s={};return r&&typeof r=="object"&&Object.assign(s,r),Object.assign(s,o),Array.isArray(n)?s.scopes=n.join(" "):n!==void 0&&(s.scopes=n),s}function Hb(t,e=""){return t==null?t:Array.isArray(t)?t.map(r=>Hb(r)):typeof t=="object"?Object.fromEntries(Object.entries(t).map(([r,n])=>[r,Hb(n,r)])):e&&(0,Tt.isSensitiveCredentialKey)(e)?(0,Tt.maskCredentialValue)(e,t):t}function Gpe(t){let e=Jx(t);if(e)return Hb(e)}function Wx(t){return(0,Tt.isMaskedValue)(t)||(0,Tt.isFullyMaskedCredentialValue)(t)}function Ype(t){let e=Go(t);if(!e)return;let r={};for(let n of Vx){if(!fo(e,n))continue;let i=e[n];i!==void 0&&(r[n]=i)}return r}function Vpe(t){return!t||t.type!=="oauth2"||!Et(t.clientSecret)?t:{...t,clientSecret:Tt.FULLY_MASKED_CREDENTIAL_VALUE}}function Jpe({incoming:t,existing:e}){if(!t||t.type!=="oauth2"||!Wx(t.clientSecret))return t;let r=e?.type==="oauth2"?e.clientSecret:void 0;return{...t,clientSecret:r}}function Wpe(t){if(t==="none"||t==="api_key"||t==="basic_auth"||t==="oauth2"||t==="connection_string")return t}function Zpe(t){let e=bg.flatMap(r=>{if(!fo(t,r))return[];let n=t[r];return Et(n)?[[r,n]]:[]});return e.length>0?Object.fromEntries(e):void 0}function Kpe(t){return bg.filter(e=>fo(t,e))}function Xpe(t){let e=bg.flatMap(r=>fo(t,r)?[[r,t[r]]]:[]);return e.length>0?Object.fromEntries(e):void 0}function efe(t){let e=new Set(["oauthClientMode","grantType","authUrl","tokenUrl","scopes","clientId","clientSecret",...Fd]);return Object.keys(t).filter(r=>e.has(r))}function Zx(t){if(t==null)return{};let e=Go(t);if(!e)return{error:"auth must be an object."};let r=Wpe(e.type);if(!r)return{error:"auth.type is required."};let n=Object.keys(e).filter(a=>!Npe.has(a));if(n.length>0)return{error:`Unknown auth field(s): ${n.join(", ")}. Accepted: ${kpe}.`};let i=Kpe(e);if(r!=="connection_string"&&i.length>0)return{error:`Connection auth field(s) require auth.type 'connection_string': ${i.join(", ")}.`};let o=efe(e);if(r!=="oauth2"&&o.length>0)return{error:`OAuth auth field(s) require auth.type 'oauth2': ${o.join(", ")}.`};if(r!=="oauth2"){let a=Zpe(e);return{authentication:La({type:r,protocol:r==="connection_string"?e.protocol:void 0,config:a})}}let s={...Object.fromEntries(Fd.flatMap(a=>{if(!fo(e,a))return[];let c=e[a];return Et(c)?[[a,c]]:[]}))};return{authentication:La({type:"oauth2",oauthClientMode:qb(e.oauthClientMode),grantType:zd(e.grantType),authUrl:qt(e.authUrl),tokenUrl:qt(e.tokenUrl),scopes:jd(e.scopes),clientId:qt(e.clientId),clientSecret:qt(e.clientSecret),config:Object.keys(s).length>0?s:void 0})}}function Pa(t){return t===""||t===null||t===void 0}function $d(t,e,r,n){if(fo(e,r)){if(Pa(e[r])){delete t[n];return}t[n]=qt(e[r])}}function tfe(t,e){if(fo(e,"scopes")){if(Pa(e.scopes)){delete t.scopes;return}t.scopes=jd(e.scopes)}}function rfe(t,e){if(fo(e,"grantType")){if(Pa(e.grantType)){delete t.grantType;return}t.grantType=zd(e.grantType)}}function nfe(t,e,r){if(fo(e,r)){if(Pa(e[r])){delete t[r];return}t[r]=e[r]}}function ife(t,e){if(Pa(e))return;let r=Go(e);if(!r)return t;let n={...t||{}};for(let[i,o]of Object.entries(r))Pa(o)?delete n[i]:n[i]=o;return Object.keys(n).length>0?n:void 0}function ofe(t,e){let r=Zx(e);if(r.error)return Ar(t)||{type:"none"};let n=r.authentication||{type:"none"},i=Go(e)||{},o=Ar(t),s=o?.type===n.type;if(n.type!=="oauth2"){let d=Xpe(i),A=s&&o?{...o}:{type:n.type};return n.type==="connection_string"&&fo(i,"protocol")&&(Pa(i.protocol)?delete A.protocol:A.protocol=i.protocol),d&&(A.config=ife(o?.config,d)),Ar(A)||{type:n.type}}let c={...s&&o?.type==="oauth2"?{...o,config:{...o.config||{}}}:{type:"oauth2",config:{}}};$d(c,i,"oauthClientMode","oauthClientMode"),rfe(c,i),$d(c,i,"authUrl","authUrl"),$d(c,i,"tokenUrl","tokenUrl"),tfe(c,i),$d(c,i,"clientId","clientId"),$d(c,i,"clientSecret","clientSecret");let l={...c.config||{}};for(let d of Fd)nfe(l,i,d);return c.config=Object.keys(l).length>0?l:void 0,Ar(c)||{type:"oauth2"}}function Kx(t){let e=Ar(t);if(!e)return[];let r=new Set;for(let n of Object.keys(e.config||{}))r.add(n);return e.type==="oauth2"&&(e.grantType&&(r.add("grant_type"),r.add("grantType")),e.authUrl&&(r.add("auth_url"),r.add("authUrl")),e.tokenUrl&&(r.add("token_url"),r.add("tokenUrl"),r.add("token_uri")),e.scopes&&(r.add("scopes"),r.add("scope")),e.clientId&&(r.add("client_id"),r.add("clientId")),e.clientSecret&&(r.add("client_secret"),r.add("clientSecret"))),[...r]}function Gx(t,e,r){if(r)for(let[n,i]of Object.entries(r))t.push({path:`${e}.${n}`,label:n,value:i})}function sfe({authentication:t}){let e=Ar(t)||{type:"none"},r=[];if(e.type==="oauth2"){r.push({path:"oauth2.clientId",label:"clientId",value:e.clientId},{path:"oauth2.clientSecret",label:"clientSecret",value:e.clientSecret},{path:"oauth2.grantType",label:"grantType",value:e.grantType||"authorization_code"},{path:"oauth2.authUrl",label:"authUrl",value:e.authUrl},{path:"oauth2.tokenUrl",label:"tokenUrl",value:e.tokenUrl},{path:"oauth2.scopes",label:"scopes",value:e.scopes?.join(" ")});for(let n of Fd)r.push({path:`oauth2.config.${n}`,label:n,value:e.config?.[n]});for(let[n,i]of Object.entries(e.config||{}))Fd.includes(n)||r.push({path:`oauth2.config.${n}`,label:n,value:i})}else e.type==="connection_string"?(e.protocol&&r.push({path:"connection.protocol",label:"protocol",value:e.protocol}),Gx(r,"connection.config",e.config)):Gx(r,`${e.type}.config`,e.config);return{type:e.type,authentication:e,configFields:r,hiddenCredentialKeys:Kx(e)}}function afe(t){let e=Ar(t);if(!e||e.type!=="connection_string")return[];let r={type:"field",field:{key:"username",aliases:["user"]}},n={type:"field",field:{key:"password"}};switch(e.protocol){case"sftp":return[r,{type:"oneOf",fields:[{key:"password"},{key:"privateKey"}]},{type:"field",field:{key:"passphrase"},optional:!0}];case"smb":return[r,n,{type:"field",field:{key:"domain"},optional:!0}];case"sqlserver":return[{type:"field",field:{key:"user",aliases:["username"]}},n];default:return[r,n]}}function Yx(t,e){return(0,Tt.hasCredentialValue)(e[t.key])?!0:(t.aliases??[]).some(r=>(0,Tt.hasCredentialValue)(e[r]))}function Xx(t,e){return t.optional?!0:t.type==="field"?Yx(t.field,e):t.fields.some(r=>Yx(r,e))}function cfe(t,e){let r=e||{};return t.some(n=>!Xx(n,r))}function ufe({authentication:t,path:e,value:r}){let n=Ar(t)||{type:"none"};if(n.type==="oauth2"){if(e==="oauth2.grantType")return{...n,grantType:zd(r)};if(e==="oauth2.authUrl")return{...n,authUrl:qt(r)};if(e==="oauth2.tokenUrl")return{...n,tokenUrl:qt(r)};if(e==="oauth2.scopes")return{...n,scopes:jd(r)??[]};if(e==="oauth2.clientId")return{...n,clientId:qt(r)};if(e==="oauth2.clientSecret")return{...n,clientSecret:qt(r)};if(e.startsWith("oauth2.config.")){let o=e.slice(14);return{...n,config:zb({config:n.config,key:o,value:r})}}}if(n.type==="connection_string"){if(e==="connection.protocol")return{...n,protocol:qt(r)};if(e.startsWith("connection.config.")){let o=e.slice(18);return{...n,config:zb({config:n.config,key:o,value:r})}}}let i=`${n.type}.config.`;if(e.startsWith(i)){let o=e.slice(i.length);return{...n,config:zb({config:n.config,key:o,value:r})}}return n}function eL({authentication:t,credentials:e}){if(Ar(t)?.type!=="oauth2"||!e||typeof e!="object"||Array.isArray(e))return null;let n=Object.keys(e).filter(i=>Ce.OAUTH_CONFIG_CREDENTIAL_KEYS.includes(i));return n.length===0?null:`OAuth configuration keys belong in auth, not credentials: ${n.join(", ")}. Move OAuth client ID to auth.clientId, client secret to auth.clientSecret, auth URL to auth.authUrl, token URL to auth.tokenUrl, scopes to auth.scopes, grant type to auth.grantType, and token request settings to auth fields such as tokenAuthMethod/usePKCE/extraHeaders. Runtime OAuth access and refresh tokens are created by create_connection OAuth authorization.`}function tL(t){let e=Ar(t);return e?e.type==="oauth2"?La({...e.config||{},grant_type:e.grantType,auth_url:e.authUrl,token_url:e.tokenUrl,scopes:e.scopes?.join(" "),client_id:e.clientId,client_secret:e.clientSecret}):e.type==="connection_string"?e.config||{}:e.config||{}:{}}function lfe(t){return xpe.has(t.trim())}function dfe({credential:t,system:e}){return t?.authentication??e?.authentication??void 0}function Afe({authentication:t,credentials:e}){let r=tL(t);return Ar(t)?.type==="oauth2"?{...e||{},...r}:{...r,...e||{}}}function pfe({input:t,authentication:e,templateOAuth:r}){let n=Ar(e),i=n?.type==="oauth2"?n:void 0,o=i?.config||{},s=t||{},a=(...c)=>c.find(u=>u!=null);return La({grant_type:a(s.grantType,s.grant_type,i?.grantType,r?.grant_type)||"authorization_code",scopes:a(s.scopes,i?.scopes?.join(" "),r?.scopes),client_id:a(s.clientId,s.client_id,i?.clientId),client_secret:a(s.clientSecret,s.client_secret,i?.clientSecret),auth_url:a(s.authUrl,s.auth_url,i?.authUrl,r?.authUrl),token_url:a(s.tokenUrl,s.token_url,i?.tokenUrl,r?.tokenUrl),resource:a(s.resource,o.resource,r?.resource),tokenAuthMethod:a(s.tokenAuthMethod,o.tokenAuthMethod,r?.tokenAuthMethod),tokenContentType:a(s.tokenContentType,o.tokenContentType,r?.tokenContentType),usePKCE:a(s.usePKCE,o.usePKCE,r?.usePKCE),extraHeaders:a(s.extraHeaders,o.extraHeaders,r?.extraHeaders),extraBodyParams:a(s.extraBodyParams,o.extraBodyParams,r?.extraBodyParams)})}function Gb(t){if(t==null)return"";if(typeof t=="string")return t;let e=JSON.stringify(t);return e===void 0?String(t):e}function ffe(t,e={}){let r=new Set((e.hiddenKeys||[]).map(Tt.normalizeCredentialKey));return Object.entries(t).filter(([n])=>!r.has((0,Tt.normalizeCredentialKey)(n))).sort(([n],[i])=>{let o=qx.get((0,Tt.normalizeCredentialKey)(n))??Number.MAX_SAFE_INTEGER,s=qx.get((0,Tt.normalizeCredentialKey)(i))??Number.MAX_SAFE_INTEGER;if(o!==s)return o-s;let a=(0,Tt.isSensitiveCredentialKey)(n),c=(0,Tt.isSensitiveCredentialKey)(i);return a!==c?a?-1:1:n.localeCompare(i)}).map(([n,i])=>({key:n,value:Gb(i),isReservedMasked:e.maskAll||(0,Tt.isSensitiveCredentialKey)(n)}))}function hfe(t){return Object.fromEntries(Object.entries(t).map(([e,r])=>[e,Gb(r)]))}function gfe({hideOAuthFiles:t=!1,configKeys:e=[]}){return[...e,...t?["oauth_cert","oauth_key"]:[]]}function mfe(t){return Et(t.access_token)||Et(t.refresh_token)}function yfe(t){let e=t.expires_at??t.expiry;if(e){let n=(0,Rpe.parseUTCDate)(e);if(n)return`Expires ${n.toLocaleString()}`}let r=t.expires_in;return Et(r)?`Expires in ${r} seconds`:null}function Efe(t){return!!(t&&typeof t=="object"&&!Array.isArray(t)&&Object.values(t).some(e=>Et(e)))}function Ife(t){if(!t||typeof t!="object"||Array.isArray(t))return null;let e=(0,Tt.getInvalidCredentialKeyNames)(Object.keys(t));return e.length===0?null:`${Tt.CREDENTIAL_KEY_VALIDATION_DESCRIPTION} Invalid keys: ${e.join(", ")}`}function Cfe(t){let e=(0,Tt.getInvalidCredentialKeyNames)(t);return e.length===0?null:`${Tt.CREDENTIAL_KEY_VALIDATION_DESCRIPTION} Invalid keys: ${e.join(", ")}`}function bfe(t){let e={"grant_type authorization_code or client_credentials":"grantType authorization_code or client_credentials",client_id:"clientId",token_url:"tokenUrl",auth_url:"authUrl","client_secret or usePKCE":"clientSecret or usePKCE","client_secret or oauth_cert + oauth_key":"clientSecret or oauth_cert + oauth_key"};return t.map(r=>e[r]||r)}function Sfe({authentication:t,credentials:e}){return eL({authentication:t,credentials:e})}});var CL=m(ho=>{"use strict";Object.defineProperty(ho,"__esModule",{value:!0});ho.bundles=void 0;ho.buildBundleAgentLaunch=Ufe;ho.getBundle=Mfe;ho.listBundles=xfe;var wfe="https://sandbox.api.sap.com/s4hanacloud/sap/opu/odata/sap",Bfe="<<(p) => { const value = p['sage_intacct_entity_id']; if (!value) return ''; const escaped = String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;').replaceAll(\"'\", '&apos;'); return `<locationid>${escaped}</locationid>`; }>>",rL="<<() => crypto.randomUUID()>>";function It(t){return`<?xml version="1.0" encoding="UTF-8"?><request><control><senderid><<sage_intacct_sender_id>></senderid><password><<sage_intacct_sender_password>></password><controlid>${rL}</controlid><uniqueid>false</uniqueid><dtdversion>3.0</dtdversion></control><operation><authentication><login><userid><<sage_intacct_user_id>></userid><companyid><<sage_intacct_company_id>></companyid><password><<sage_intacct_user_password>></password>${Bfe}</login></authentication><content><function controlid="${rL}">${t}</function></content></operation></request>`}function vs({stepId:t,objectNameExpression:e,collectionName:r,mapExpression:n,includeTotalCount:i=!1}){let o=i?"Number(data && data.TOTALCOUNT ? data.TOTALCOUNT : rows.length)":"rows.length",s=n?`rows.map(${n})`:"rows";return`(sourceData) => { const response = sourceData.${t} && sourceData.${t}.data ? sourceData.${t}.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? \` Sage support ID: \${supportIds.join(', ')}.\` : ''; throw new Error(\`Sage Intacct request failed\${details.length ? \`: \${details.join('; ')}\` : '.'}\${suffix}\`); } const data = result ? result.DATA : undefined; const objectName = ${e}; const raw = data ? data[objectName] : undefined; const rows = (Array.isArray(raw) ? raw : (raw ? [raw] : [])).slice(0, (sourceData && sourceData.maxResults) ?? ${i?"1000":"200"}); return { total: ${o}, ${r}: ${s} }; }`}var Ds=`const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;');`,nL="const toIntacctDate = (value) => { const match = String(value).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (!match) throw new Error('Dates must be in YYYY-MM-DD format.'); return match[2] + '/' + match[3] + '/' + match[1]; };",iL="const assertBalanced = (lines) => { const balance = lines.reduce((sum, line) => sum + (line.type === 'credit' ? -1 : 1) * Math.abs(Number(line.amount)), 0); if (Math.abs(balance) > 0.005) throw new Error('Journal lines must balance: debits minus credits is ' + balance.toFixed(2) + '.'); };",oL=`const lineXml = (line) => { const amount = Number(line.amount); if (!Number.isFinite(amount) || amount <= 0) throw new Error('Every journal line needs a positive amount.'); const type = line.type === 'credit' ? -1 : line.type === 'debit' ? 1 : null; if (type === null) throw new Error("Every journal line needs type 'debit' or 'credit'."); if (!line.accountNo) throw new Error('Every journal line needs accountNo.'); let xml = '<GLENTRY><ACCOUNTNO>' + esc(line.accountNo) + '</ACCOUNTNO><TR_TYPE>' + type + '</TR_TYPE><TRX_AMOUNT>' + amount + '</TRX_AMOUNT>'; if (line.department) xml += '<DEPARTMENT>' + esc(line.department) + '</DEPARTMENT>'; if (line.location) xml += '<LOCATION>' + esc(line.location) + '</LOCATION>'; if (line.memo) xml += '<DESCRIPTION>' + esc(line.memo) + '</DESCRIPTION>'; return xml + '</GLENTRY>'; };`;function Eu({stepId:t,objectName:e}){return`(sourceData) => { const response = sourceData.${t} && sourceData.${t}.data ? sourceData.${t}.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? \` Sage support ID: \${supportIds.join(', ')}.\` : ''; throw new Error(\`Sage Intacct request failed\${details.length ? \`: \${details.join('; ')}\` : '.'}\${suffix}\`); } const data = result ? result.DATA : undefined; const raw = data ? (data.${e} || data.${e.toLowerCase()}) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }`}var Yd="netsuite",Jb=100,Gd=1e4,Tg=String.raw`<<(p) => { const url = String(p['netsuite_url'] || ''); if (!url || url.includes('{accountId}')) throw new Error('NetSuite is not connected yet: set the account ID so the system URL is https://<account>.suitetalk.api.netsuite.com/services/rest'); return url.replace(/\/+$/, ''); }>>`,Rg={Authorization:"Bearer <<netsuite_access_token>>",Accept:"application/json"},Wb=String.raw`const has = (value) => value !== undefined && value !== null && value !== ''; const nsId = (value, name) => { const text = String(value ?? '').trim(); if (!/^-?\d+$/.test(text)) throw new Error(name + ' must be a NetSuite internal ID.'); return text; }; const nsDate = (value, name) => { const text = String(value ?? '').trim(); if (!/^\d{4}-\d{2}-\d{2}$/.test(text)) throw new Error(name + ' must be a date in YYYY-MM-DD format.'); return text; }; const ref = (value, name) => ({ id: nsId(value, name) });`,_fe=String.raw`const str = (value) => (value === undefined || value === null || value === '' ? null : String(value)); const num = (value) => (value === undefined || value === null || value === '' ? null : Number(value)); const bool = (value) => value === 'T' || value === true; const ids = (value) => (value === undefined || value === null || value === '' ? [] : String(value).split(',').map((part) => part.trim()).filter(Boolean)); const status = (value) => (value ? String(value).replace(/^[^:]*:\s*/, '') : null);`,sL=String.raw`const stripLinks = (value) => { if (Array.isArray(value)) return value.map(stripLinks); if (value && typeof value === 'object') { const result = {}; for (const [key, entry] of Object.entries(value)) { if (key !== 'links') result[key] = stripLinks(entry); } return result; } return value; };`,Qfe={type:"integer",minimum:1,maximum:Gd,description:`Maximum number of records to return (max ${Gd}). Defaults to ${Jb}. The result always reports the full match count in total, so use maxResults 1 to count. Prefer filters over large values: big results can exceed an AI client's tool output limit.`},vfe={type:"boolean",description:"Only return active records. Defaults to false (inactive records are included)."},Dfe={type:"string",description:"Optional subsidiary internal ID to filter by."},Tfe={type:"string",description:"Optional earliest transaction date as YYYY-MM-DD."},Rfe={type:"string",description:"Optional latest transaction date as YYYY-MM-DD."},Nfe={type:"object",description:"Optional extra NetSuite REST field values merged into the record body as-is, e.g. custom fields like { custentity_region: 'EMEA' } or references like { terms: { id: '2' } }. Fields that this tool's own inputs set are rejected; use those inputs instead.",properties:{},additionalProperties:!0},Hd=t=>({input:"activeOnly",kind:"flag",clause:`${t}.isinactive = 'F'`,schema:vfe}),qd=t=>({input:"subsidiaryId",kind:"id",clause:`${t}.subsidiary = $`,schema:Dfe}),Yb=[{input:"fromDate",kind:"date",clause:"t.trandate >= TO_DATE('$', 'YYYY-MM-DD')",schema:Tfe},{input:"toDate",kind:"date",clause:"t.trandate <= TO_DATE('$', 'YYYY-MM-DD')",schema:Rfe}];function kfe(t){let e=`p[${JSON.stringify(t.input)}]`;if(t.kind==="flag")return`if (${e} === true || ${e} === 'true') where.push(${JSON.stringify(t.clause)});`;let[r,n]=t.clause.split("$");if(t.kind==="enum")return`if (has(${e})) { const allowed = ${JSON.stringify(t.values)}; if (!allowed.includes(String(${e}))) throw new Error(${JSON.stringify(`${t.input} must be one of: ${t.values.join(", ")}.`)}); where.push(${JSON.stringify(r)} + String(${e}) + ${JSON.stringify(n)}); }`;if(t.kind==="prefix")return`if (has(${e})) { const text = String(${e}).trim(); if (!/^[A-Za-z0-9._-]{1,40}$/.test(text)) throw new Error(${JSON.stringify(`${t.input} may only contain letters, digits, dots, underscores and hyphens.`)}); where.push(${JSON.stringify(r)} + text + ${JSON.stringify(n)}); }`;let i=t.kind==="id"?"nsId":"nsDate";return`if (has(${e})) where.push(${JSON.stringify(r)} + ${i}(${e}, ${JSON.stringify(t.input)}) + ${JSON.stringify(n)});`}function Ts({id:t,name:e,shortName:r,instruction:n,stepId:i,collection:o,select:s,baseWhere:a=[],orderBy:c,filters:u=[],properties:l={},required:d=[],mapRow:A}){let p=typeof s=="string"?JSON.stringify(s):s.js,h=`<<(p) => { ${Wb} const where = ${JSON.stringify(a)}; ${u.map(kfe).join(" ")} return JSON.stringify({ q: ${p} + (where.length ? ' WHERE ' + where.join(' AND ') : '') + ${JSON.stringify(` ORDER BY ${c}`)} }); }>>`;return{id:t,name:e,shortName:r,instruction:`${n} Rows are ordered by internal ID. If more than ${Gd} rows match, narrow with the filters or page with the SuiteQL query tool (ORDER BY id, WHERE id > last id).`,inputSchema:{type:"object",properties:{...l,maxResults:Qfe,...Object.fromEntries(u.map(g=>[g.input,g.schema]))},...d.length>0?{required:d}:{},additionalProperties:!1},steps:[{id:i,instruction:"Run the SuiteQL query page by page.",config:{type:"request",systemId:Yd,url:`${Tg}/query/v1/suiteql`,method:"POST",headers:{...Rg,"Content-Type":"application/json",Prefer:"transient"},queryParams:{limit:"1000",offset:"<<offset>>"},body:h,pagination:{type:"offsetBased",pageSize:"1000",stopCondition:`(response, pageInfo, sourceData) => { if (sourceData && ["offset", "limit", "page"].some((key) => sourceData[key] !== undefined)) throw new Error("offset, limit and page are not inputs of this tool: use maxResults and the filters."); const page = response && response.data ? response.data : {}; const merged = pageInfo && pageInfo.mergedResult && Array.isArray(pageInfo.mergedResult.items) ? pageInfo.mergedResult.items.length : 0; const max = Math.min(Math.max(Math.floor(Number(sourceData && sourceData.maxResults)) || ${Jb}, 1), ${Gd}); return page.hasMore !== true || merged >= max; }`}}}],outputTransform:`(sourceData) => { ${_fe} const raw = sourceData.${i} ? sourceData.${i}.data : undefined; const pages = Array.isArray(raw) ? raw : (raw ? [raw] : []); const items = pages.flatMap((page) => (page && Array.isArray(page.items) ? page.items : [])); const last = pages.length ? pages[pages.length - 1] : {}; const max = Math.min(Math.max(Math.floor(Number(sourceData.maxResults)) || ${Jb}, 1), ${Gd}); const rows = items.slice(0, max).map(${A}).map((row) => Object.fromEntries(Object.entries(row).filter((entry) => entry[1] !== null))); const total = last && last.totalResults !== undefined ? Number(last.totalResults) : items.length; return { total, returned: rows.length, hasMore: total > rows.length, ${o}: rows }; }`}}function _r({id:t,name:e,shortName:r,instruction:n,stepId:i,recordType:o,mode:s,properties:a,required:c,body:u,replaceSublist:l}){let d=[...new Set(Array.from(u.matchAll(/record\.([A-Za-z0-9_]+)\s*=/g)).map(p=>p[1]))],A=s==="create"?`/record/v1/${o}`:`/record/v1/${o}/<<(p) => { ${Wb} return nsId(p.internalId, 'internalId'); }>>`;return{id:t,name:e,shortName:r,instruction:n,inputSchema:{type:"object",properties:{...s==="update"?{internalId:{type:"string",description:`Internal ID of the ${o} to update.`}}:{},...a,fields:Nfe},required:s==="update"?["internalId",...c]:c,additionalProperties:!1},steps:[{id:i,instruction:`${s==="create"?"Create":"Update"} the ${o} record.`,modify:!0,config:{type:"request",systemId:Yd,url:`${Tg}${A}`,method:s==="create"?"POST":"PATCH",headers:{...Rg,"Content-Type":"application/json","X-NetSuite-idempotency-key":"<<() => crypto.randomUUID()>>"},...l?{queryParams:{replace:`<<(p) => (Array.isArray(p[${JSON.stringify(l.input)}]) && p[${JSON.stringify(l.input)}].length > 0 ? ${JSON.stringify(l.sublist)} : undefined)>>`}}:{},body:`<<(p) => { ${Wb} const record = {}; ${u} if (p.fields && typeof p.fields === 'object' && !Array.isArray(p.fields)) { const managed = ${JSON.stringify(d)}; const reserved = Object.keys(p.fields).filter((key) => managed.includes(key)); if (reserved.length > 0) throw new Error('fields may not set ' + reserved.join(', ') + ': use this tool\\'s own inputs for them.'); Object.assign(record, p.fields); } if (Object.keys(record).length === 0) throw new Error('Provide at least one field to ${s}.'); return JSON.stringify(record); }>>`,captureHttpResponse:!0}}],outputTransform:s==="create"?`(sourceData) => { const step = sourceData.${i} || {}; const location = step.http && step.http.headers ? String(step.http.headers.location || '') : ''; const match = location.match(/\\/record\\/v1\\/[^/]+\\/([^/?#]+)/); if (!match) throw new Error('NetSuite did not return the location of the new ${o}.'); return { id: decodeURIComponent(match[1]), recordType: '${o}' }; }`:`(sourceData) => ({ id: String(sourceData.internalId).trim(), recordType: '${o}', updated: true })`}}var aL=String.raw`const lines = Array.isArray(p.lines) ? p.lines : []; let balance = 0; const items = lines.map((line, index) => { const amount = Number(line && line.amount); if (!Number.isFinite(amount) || amount <= 0) throw new Error('lines[' + index + '].amount must be a positive number.'); if (line.type !== 'debit' && line.type !== 'credit') throw new Error("lines[" + index + "].type must be 'debit' or 'credit'."); balance += line.type === 'debit' ? amount : -amount; const item = { account: ref(line.accountId, 'lines[' + index + '].accountId') }; item[line.type] = amount; if (has(line.memo)) item.memo = String(line.memo); if (has(line.departmentId)) item.department = ref(line.departmentId, 'lines[' + index + '].departmentId'); if (has(line.classId)) item.class = ref(line.classId, 'lines[' + index + '].classId'); if (has(line.locationId)) item.location = ref(line.locationId, 'lines[' + index + '].locationId'); if (has(line.entityId)) item.entity = ref(line.entityId, 'lines[' + index + '].entityId'); return item; }); if (lines.length > 0 && Math.abs(balance) > 0.005) throw new Error('Journal lines must balance: debits minus credits is ' + balance.toFixed(2) + '.'); if (items.length > 0) record.line = { items };`,cL=String.raw`if (has(p.subsidiaryId)) record.subsidiary = ref(p.subsidiaryId, 'subsidiaryId'); if (has(p.date)) record.tranDate = nsDate(p.date, 'date'); if (has(p.memo)) record.memo = String(p.memo); if (has(p.currencyId)) record.currency = ref(p.currencyId, 'currencyId'); if (has(p.externalId)) record.externalId = String(p.externalId);`,uL={type:"object",properties:{accountId:{type:"string",description:"GL account internal ID."},type:{type:"string",enum:["debit","credit"]},amount:{type:"number",description:"Positive amount."},memo:{type:"string",description:"Optional line memo."},departmentId:{type:"string",description:"Optional department internal ID."},classId:{type:"string",description:"Optional class internal ID."},locationId:{type:"string",description:"Optional location internal ID."},entityId:{type:"string",description:"Optional customer, vendor or employee internal ID for the line."}},required:["accountId","type","amount"],additionalProperties:!1},lL=t=>({subsidiaryId:{type:"string",description:t==="create"?"Subsidiary internal ID. Required in OneWorld accounts.":"Optional new subsidiary internal ID."},date:{type:"string",description:t==="create"?"Transaction date as YYYY-MM-DD.":"Optional new transaction date as YYYY-MM-DD."},memo:{type:"string",description:"Journal entry memo."},currencyId:{type:"string",description:"Optional currency internal ID."},externalId:{type:"string",description:"Optional external ID."}}),wg=String.raw`if (p.isPerson === true || p.isPerson === 'true') record.isPerson = true; if (p.isPerson === false || p.isPerson === 'false') record.isPerson = false; if (has(p.entityId)) record.entityId = String(p.entityId); if (has(p.companyName)) record.companyName = String(p.companyName); if (has(p.firstName)) record.firstName = String(p.firstName); if (has(p.lastName)) record.lastName = String(p.lastName); if (has(p.subsidiaryId)) record.subsidiary = ref(p.subsidiaryId, 'subsidiaryId'); if (has(p.email)) record.email = String(p.email); if (has(p.phone)) record.phone = String(p.phone); if (has(p.currencyId)) record.currency = ref(p.currencyId, 'currencyId'); if (has(p.externalId)) record.externalId = String(p.externalId); if (p.isInactive === true || p.isInactive === 'true') record.isInactive = true; if (p.isInactive === false || p.isInactive === 'false') record.isInactive = false;`;function Bg(t){return{companyName:{type:"string",description:`Company name of the ${t}.`},isPerson:{type:"boolean",description:`True when the ${t} is an individual; then set firstName and lastName.`},firstName:{type:"string",description:"First name for an individual."},lastName:{type:"string",description:"Last name for an individual."},entityId:{type:"string",description:`${t==="customer"?"Customer":"Vendor"} ID. Omit when auto-numbering assigns it.`},subsidiaryId:{type:"string",description:"Primary subsidiary internal ID. Required on create in OneWorld accounts."},email:{type:"string",description:"Email address."},phone:{type:"string",description:"Phone number."},currencyId:{type:"string",description:"Primary currency internal ID."},externalId:{type:"string",description:"Optional external ID."}}}var _g={isInactive:{type:"boolean",description:"Set true to inactivate, false to reactivate."}},Qg=String.raw`if (Array.isArray(p.subsidiaryIds) && p.subsidiaryIds.length > 0) record.subsidiary = { items: p.subsidiaryIds.map((value, index) => ref(value, 'subsidiaryIds[' + index + ']')) }; if (p.includeChildren === true || p.includeChildren === 'true') record.includeChildren = true; if (p.includeChildren === false || p.includeChildren === 'false') record.includeChildren = false;`,EL={subsidiaryIds:{type:"array",items:{type:"string"},description:"Subsidiary internal IDs the record is available in. On update the list replaces the current subsidiaries."},includeChildren:{type:"boolean",description:"Also make the record available to child subsidiaries."}},Zb=["AcctPay","AcctRec","Bank","COGS","CredCard","DeferExpense","DeferRevenue","Equity","Expense","FixedAsset","Income","LongTermLiab","NonPosting","OthAsset","OthCurrAsset","OthCurrLiab","OthExpense","OthIncome","Stat","UnbilledRec"],dL=String.raw`if (has(p.acctNumber)) record.acctNumber = String(p.acctNumber); if (has(p.acctName)) record.acctName = String(p.acctName); if (has(p.acctType)) record.acctType = { id: String(p.acctType) }; if (has(p.parentId)) record.parent = ref(p.parentId, 'parentId'); if (has(p.description)) record.description = String(p.description); if (has(p.currencyId)) record.currency = ref(p.currencyId, 'currencyId'); if (has(p.externalId)) record.externalId = String(p.externalId); if (p.isInactive === true || p.isInactive === 'true') record.isInactive = true; if (p.isInactive === false || p.isInactive === 'false') record.isInactive = false;`,AL={acctNumber:{type:"string",description:"Account number."},acctName:{type:"string",description:"Account name."},acctType:{type:"string",enum:Zb,description:"NetSuite account type."},parentId:{type:"string",description:"Optional parent account internal ID."},description:{type:"string",description:"Optional description."},currencyId:{type:"string",description:"Optional currency internal ID (bank and credit card accounts)."},externalId:{type:"string",description:"Optional external ID."},...EL},pL=String.raw`if (has(p.name)) record.name = String(p.name); if (has(p.parentId)) record.parent = ref(p.parentId, 'parentId'); if (has(p.externalId)) record.externalId = String(p.externalId); if (p.isInactive === true || p.isInactive === 'true') record.isInactive = true; if (p.isInactive === false || p.isInactive === 'false') record.isInactive = false;`,fL={name:{type:"string",description:"Department name."},parentId:{type:"string",description:"Optional parent department internal ID."},externalId:{type:"string",description:"Optional external ID."},...EL},vg=t=>String.raw`if (has(p.${t})) record.entity = ref(p.${t}, '${t}'); if (has(p.subsidiaryId)) record.subsidiary = ref(p.subsidiaryId, 'subsidiaryId'); if (has(p.date)) record.tranDate = nsDate(p.date, 'date'); if (has(p.dueDate)) record.dueDate = nsDate(p.dueDate, 'dueDate'); if (has(p.memo)) record.memo = String(p.memo); if (has(p.currencyId)) record.currency = ref(p.currencyId, 'currencyId'); if (has(p.termsId)) record.terms = ref(p.termsId, 'termsId'); if (has(p.departmentId)) record.department = ref(p.departmentId, 'departmentId'); if (has(p.classId)) record.class = ref(p.classId, 'classId'); if (has(p.locationId)) record.location = ref(p.locationId, 'locationId'); if (has(p.externalId)) record.externalId = String(p.externalId);`,Dg=t=>({subsidiaryId:{type:"string",description:t==="create"?"Optional subsidiary internal ID; defaults to the entity's subsidiary.":"Optional new subsidiary internal ID."},date:{type:"string",description:t==="create"?"Transaction date as YYYY-MM-DD.":"Optional new transaction date as YYYY-MM-DD."},dueDate:{type:"string",description:"Optional due date as YYYY-MM-DD."},memo:{type:"string",description:"Optional memo."},currencyId:{type:"string",description:"Optional currency internal ID."},termsId:{type:"string",description:"Optional payment terms internal ID."},departmentId:{type:"string",description:"Optional header department internal ID."},classId:{type:"string",description:"Optional header class internal ID."},locationId:{type:"string",description:"Optional header location internal ID."},externalId:{type:"string",description:"Optional external ID."}}),IL=String.raw`if (has(line.departmentId)) item.department = ref(line.departmentId, 'lines[' + index + '].departmentId'); if (has(line.classId)) item.class = ref(line.classId, 'lines[' + index + '].classId'); if (has(line.locationId)) item.location = ref(line.locationId, 'lines[' + index + '].locationId');`,hL=String.raw`if (Array.isArray(p.lines) && p.lines.length > 0) record.item = { items: p.lines.map((line, index) => { const item = { item: ref(line && line.itemId, 'lines[' + index + '].itemId') }; if (has(line.quantity)) { const quantity = Number(line.quantity); if (!Number.isFinite(quantity)) throw new Error('lines[' + index + '].quantity must be a number.'); item.quantity = quantity; } if (has(line.rate)) { const rate = Number(line.rate); if (!Number.isFinite(rate)) throw new Error('lines[' + index + '].rate must be a number.'); item.rate = rate; } if (has(line.amount)) { const amount = Number(line.amount); if (!Number.isFinite(amount)) throw new Error('lines[' + index + '].amount must be a number.'); item.amount = amount; } if (has(line.description)) item.description = String(line.description); if (has(line.taxCodeId)) item.taxCode = ref(line.taxCodeId, 'lines[' + index + '].taxCodeId'); ${IL} return item; }) };`,gL={type:"object",properties:{itemId:{type:"string",description:"Item internal ID."},quantity:{type:"number",description:"Optional quantity. Defaults to 1."},rate:{type:"number",description:"Optional unit price; defaults to the item price."},amount:{type:"number",description:"Optional line amount."},description:{type:"string",description:"Optional line description."},taxCodeId:{type:"string",description:"Optional tax code internal ID."},departmentId:{type:"string",description:"Optional department internal ID."},classId:{type:"string",description:"Optional class internal ID. Some accounts ignore line classes on invoices; check the saved record."},locationId:{type:"string",description:"Optional location internal ID."}},required:["itemId"],additionalProperties:!1},mL=String.raw`if (Array.isArray(p.lines) && p.lines.length > 0) record.expense = { items: p.lines.map((line, index) => { const amount = Number(line && line.amount); if (!Number.isFinite(amount) || amount <= 0) throw new Error('lines[' + index + '].amount must be a positive number.'); const item = { account: ref(line.accountId, 'lines[' + index + '].accountId'), amount }; if (has(line.memo)) item.memo = String(line.memo); ${IL} return item; }) };`,yL={type:"object",properties:{accountId:{type:"string",description:"Expense account internal ID."},amount:{type:"number",description:"Positive amount."},memo:{type:"string",description:"Optional line memo."},departmentId:{type:"string",description:"Optional department internal ID."},classId:{type:"string",description:"Optional class internal ID."},locationId:{type:"string",description:"Optional location internal ID."}},required:["accountId","amount"],additionalProperties:!1},$a="Re-running this tool creates another record; it is not idempotent.",Ofe=[Ts({id:"netsuite-list-accounts",name:"List NetSuite chart of accounts",shortName:"Chart of accounts",instruction:"Lists general ledger accounts (the chart of accounts) from NetSuite with number, name, type, parent and subsidiaries. Useful for validating an imported chart of accounts.",stepId:"queryAccounts",collection:"accounts",select:"SELECT a.id, a.acctnumber, a.accountsearchdisplaynamecopy AS name, a.fullname, a.accttype, a.parent, a.subsidiary, cur.symbol AS currency, a.description, a.issummary, a.isinactive FROM account a LEFT JOIN currency cur ON cur.id = a.currency",orderBy:"a.id",filters:[Hd("a"),{input:"accountType",kind:"enum",values:Zb,clause:"a.accttype = '$'",schema:{type:"string",enum:Zb,description:"Only accounts of this NetSuite account type, e.g. Bank or Expense."}},{input:"numberPrefix",kind:"prefix",clause:"a.acctnumber LIKE '$%'",schema:{type:"string",description:"Only accounts whose number starts with this value, e.g. 1000 or 60."}}],mapRow:"(row) => ({ id: row.id, number: str(row.acctnumber), name: str(row.name), fullName: str(row.fullname), type: str(row.accttype), parentId: str(row.parent), subsidiaryIds: ids(row.subsidiary), currency: str(row.currency), description: str(row.description), isSummary: bool(row.issummary), isInactive: bool(row.isinactive) })"}),Ts({id:"netsuite-list-customers",name:"List NetSuite customers",shortName:"Customers",instruction:"Lists customer records from NetSuite with subsidiary, currency and open balance. Useful for verifying migrated AR master data.",stepId:"queryCustomers",collection:"customers",select:"SELECT c.id, c.entityid, c.companyname, c.isperson, c.firstname, c.lastname, c.email, c.phone, c.subsidiary, BUILTIN.DF(c.subsidiary) AS subsidiaryname, cur.symbol AS currency, c.balancesearch, c.overduebalancesearch, c.isinactive, TO_CHAR(c.datecreated, 'YYYY-MM-DD') AS datecreated, TO_CHAR(c.lastmodifieddate, 'YYYY-MM-DD') AS lastmodified FROM customer c LEFT JOIN currency cur ON cur.id = c.currency",orderBy:"c.id",filters:[Hd("c"),qd("c")],mapRow:"(row) => ({ id: row.id, entityId: str(row.entityid), companyName: str(row.companyname), isPerson: bool(row.isperson), firstName: str(row.firstname), lastName: str(row.lastname), email: str(row.email), phone: str(row.phone), subsidiaryId: str(row.subsidiary), subsidiary: str(row.subsidiaryname), currency: str(row.currency), balance: num(row.balancesearch), overdueBalance: num(row.overduebalancesearch), isInactive: bool(row.isinactive), createdOn: str(row.datecreated), modifiedOn: str(row.lastmodified) })"}),Ts({id:"netsuite-list-vendors",name:"List NetSuite vendors",shortName:"Vendors",instruction:"Lists vendor records from NetSuite with subsidiary, currency and balance. Useful for verifying migrated AP master data.",stepId:"queryVendors",collection:"vendors",select:"SELECT v.id, v.entityid, v.companyname, v.isperson, v.firstname, v.lastname, v.email, v.phone, v.subsidiary, BUILTIN.DF(v.subsidiary) AS subsidiaryname, cur.symbol AS currency, v.balance, v.isinactive, TO_CHAR(v.datecreated, 'YYYY-MM-DD') AS datecreated, TO_CHAR(v.lastmodifieddate, 'YYYY-MM-DD') AS lastmodified FROM vendor v LEFT JOIN currency cur ON cur.id = v.currency",orderBy:"v.id",filters:[Hd("v"),qd("v")],mapRow:"(row) => ({ id: row.id, entityId: str(row.entityid), companyName: str(row.companyname), isPerson: bool(row.isperson), firstName: str(row.firstname), lastName: str(row.lastname), email: str(row.email), phone: str(row.phone), subsidiaryId: str(row.subsidiary), subsidiary: str(row.subsidiaryname), currency: str(row.currency), balance: num(row.balance), isInactive: bool(row.isinactive), createdOn: str(row.datecreated), modifiedOn: str(row.lastmodified) })"}),Ts({id:"netsuite-list-journal-entries",name:"List NetSuite journal entries",shortName:"Journal entries",instruction:"Lists journal entry lines from NetSuite, one row per GL line and accounting book with journal, date, period, account, debit, credit and dimensions. Useful for verifying opening balances and postings at cutover.",stepId:"queryJournalLines",collection:"journalLines",select:"SELECT t.id AS journalid, t.tranid, TO_CHAR(t.trandate, 'YYYY-MM-DD') AS trandate, BUILTIN.DF(t.postingperiod) AS period, t.subsidiary, BUILTIN.DF(t.status) AS status, t.posting, t.memo AS journalmemo, cur.symbol AS currency, tl.id AS lineid, tal.accountingbook, tal.account, a.acctnumber, a.accountsearchdisplaynamecopy AS accountname, tal.debit, tal.credit, tl.memo, tl.department, tl.class, tl.location, tl.entity FROM transaction t JOIN transactionline tl ON tl.transaction = t.id JOIN transactionaccountingline tal ON tal.transaction = tl.transaction AND tal.transactionline = tl.id JOIN account a ON a.id = tal.account LEFT JOIN currency cur ON cur.id = t.currency",baseWhere:["t.type = 'Journal'"],orderBy:"t.id, tl.id, tal.accountingbook",filters:[...Yb,qd("t")],mapRow:"(row) => ({ journalId: row.journalid, tranId: str(row.tranid), date: str(row.trandate), period: str(row.period), subsidiaryId: str(row.subsidiary), status: status(row.status), posting: bool(row.posting), journalMemo: str(row.journalmemo), currency: str(row.currency), line: num(row.lineid), accountingBookId: str(row.accountingbook), accountId: str(row.account), accountNumber: str(row.acctnumber), accountName: str(row.accountname), debit: num(row.debit), credit: num(row.credit), memo: str(row.memo), departmentId: str(row.department), classId: str(row.class), locationId: str(row.location), entityId: str(row.entity) })"}),Ts({id:"netsuite-list-invoices",name:"List NetSuite invoices",shortName:"Invoices",instruction:"Lists customer invoices from NetSuite with customer, dates, status, total and amount due. Useful for verifying migrated open AR at go-live.",stepId:"queryInvoices",collection:"invoices",select:"SELECT t.id, t.tranid, t.entity, BUILTIN.DF(t.entity) AS customername, TO_CHAR(t.trandate, 'YYYY-MM-DD') AS trandate, TO_CHAR(t.duedate, 'YYYY-MM-DD') AS duedate, BUILTIN.DF(t.status) AS status, cur.symbol AS currency, t.foreigntotal, t.foreignamountunpaid, t.subsidiary, t.memo FROM transaction t LEFT JOIN currency cur ON cur.id = t.currency",baseWhere:["t.type = 'CustInvc'"],orderBy:"t.id",filters:[...Yb,qd("t"),{input:"openOnly",kind:"flag",clause:"t.status = 'A'",schema:{type:"boolean",description:"Only return open (unpaid) invoices."}}],mapRow:"(row) => ({ id: row.id, tranId: str(row.tranid), customerId: str(row.entity), customer: str(row.customername), date: str(row.trandate), dueDate: str(row.duedate), status: status(row.status), currency: str(row.currency), total: num(row.foreigntotal), amountDue: num(row.foreignamountunpaid), subsidiaryId: str(row.subsidiary), memo: str(row.memo) })"}),Ts({id:"netsuite-list-vendor-bills",name:"List NetSuite vendor bills",shortName:"Vendor bills",instruction:"Lists vendor bills from NetSuite with vendor, dates, status, approval status, total and amount due. Useful for verifying migrated open AP at go-live.",stepId:"queryBills",collection:"bills",select:"SELECT t.id, t.tranid, t.entity, BUILTIN.DF(t.entity) AS vendorname, TO_CHAR(t.trandate, 'YYYY-MM-DD') AS trandate, TO_CHAR(t.duedate, 'YYYY-MM-DD') AS duedate, BUILTIN.DF(t.status) AS status, BUILTIN.DF(t.approvalstatus) AS approvalstatus, cur.symbol AS currency, t.foreigntotal, t.foreignamountunpaid, t.subsidiary, t.memo FROM transaction t LEFT JOIN currency cur ON cur.id = t.currency",baseWhere:["t.type = 'VendBill'"],orderBy:"t.id",filters:[...Yb,qd("t"),{input:"openOnly",kind:"flag",clause:"t.status = 'A'",schema:{type:"boolean",description:"Only return open bills (approved and not fully paid)."}}],mapRow:"(row) => ({ id: row.id, referenceNo: str(row.tranid), vendorId: str(row.entity), vendor: str(row.vendorname), date: str(row.trandate), dueDate: str(row.duedate), status: status(row.status), approvalStatus: str(row.approvalstatus), currency: str(row.currency), total: row.foreigntotal === undefined ? null : Math.abs(Number(row.foreigntotal)), amountDue: num(row.foreignamountunpaid), subsidiaryId: str(row.subsidiary), memo: str(row.memo) })"}),Ts({id:"netsuite-list-dimensions",name:"List NetSuite departments, classes or locations",shortName:"Departments, classes, locations",instruction:"Lists department, class or location records from NetSuite with hierarchy and subsidiaries. Useful for validating the dimension setup after an implementation and for finding the internal IDs the write tools need.",stepId:"queryDimensions",collection:"records",properties:{dimension:{type:"string",enum:["department","class","location"],description:"Which dimension to list."}},required:["dimension"],select:{js:String.raw`'SELECT d.id, d.name, d.fullname, d.parent, d.subsidiary, d.includechildren, d.isinactive FROM ' + (() => { const table = { department: 'department', class: 'classification', location: 'location' }[String(p.dimension || '')]; if (!table) throw new Error("dimension must be 'department', 'class' or 'location'."); return table; })() + ' d'`},orderBy:"d.id",filters:[Hd("d")],mapRow:"(row) => ({ id: row.id, name: str(row.name), fullName: str(row.fullname), parentId: str(row.parent), subsidiaryIds: ids(row.subsidiary), includeChildren: bool(row.includechildren), isInactive: bool(row.isinactive) })"}),Ts({id:"netsuite-list-subsidiaries",name:"List NetSuite subsidiaries",shortName:"Subsidiaries",instruction:"Lists subsidiaries from NetSuite with hierarchy, country, base currency and elimination flag. Most create tools need a subsidiary ID from this list in OneWorld accounts.",stepId:"querySubsidiaries",collection:"subsidiaries",select:"SELECT s.id, s.name, s.fullname, s.parent, s.country, cur.symbol AS currency, s.iselimination, s.isinactive FROM subsidiary s LEFT JOIN currency cur ON cur.id = s.currency",orderBy:"s.id",filters:[Hd("s")],mapRow:"(row) => ({ id: row.id, name: str(row.name), fullName: str(row.fullname), parentId: str(row.parent), country: str(row.country), currency: str(row.currency), isElimination: bool(row.iselimination), isInactive: bool(row.isinactive) })"}),{id:"netsuite-suiteql-query",name:"Run a NetSuite SuiteQL query",shortName:"SuiteQL query",instruction:"Runs a read-only SuiteQL SELECT query against NetSuite, for any record type, join or aggregate outside the prebuilt lists (for example items, employees, transaction lines or custom records). The workhorse tool for migration validation. Returns up to 1000 rows in one call with the total row count and hasMore; values are strings as NetSuite returns them.",inputSchema:{type:"object",properties:{query:{type:"string",description:`SuiteQL SELECT statement, e.g. "SELECT id, itemid, displayname FROM item WHERE isinactive = 'F' ORDER BY id". Dates come back in the user's date format; use TO_CHAR(field, 'YYYY-MM-DD') for ISO dates and BUILTIN.DF(field) for display names. For more than 1000 rows, page by key: ORDER BY id and add WHERE id > <last id>. Common columns: account (id, acctnumber, accountsearchdisplaynamecopy as the name, fullname, accttype, isinactive; there is no acctname column), customer (id, entityid, companyname, email, subsidiary, balancesearch, isinactive), vendor (id, entityid, companyname, email, subsidiary, balance, isinactive), transaction (id, tranid, type, trandate, entity, status, foreigntotal, foreignamountunpaid, subsidiary). Alias tables and qualify columns: FROM transaction t ... t.subsidiary works, an unqualified subsidiary fails.`},maxResults:{type:"integer",minimum:1,maximum:1e3,description:"Maximum number of rows to return (max 1000). Defaults to 100."}},required:["query"],additionalProperties:!1},steps:[{id:"runSuiteQl",instruction:"Run the SuiteQL query.",config:{type:"request",systemId:Yd,url:`${Tg}/query/v1/suiteql`,method:"POST",headers:{...Rg,"Content-Type":"application/json",Prefer:"transient"},queryParams:{limit:"<<(p) => Math.min(Math.max(Math.floor(Number(p.maxResults)) || 100, 2), 1000)>>",offset:"0"},body:String.raw`<<(p) => { const query = String(p.query || '').trim(); if (!/^(select|with)\b/i.test(query)) throw new Error('query must be a SuiteQL SELECT statement.'); return JSON.stringify({ q: query }); }>>`}}],outputTransform:`(sourceData) => { ${sL} const data = sourceData.runSuiteQl && sourceData.runSuiteQl.data ? sourceData.runSuiteQl.data : {}; const items = Array.isArray(data.items) ? data.items : []; const max = Math.min(Math.max(Math.floor(Number(sourceData.maxResults)) || 100, 1), 1000); const records = stripLinks(items.slice(0, max)); const total = data.totalResults !== undefined ? Number(data.totalResults) : items.length; return { total, returned: records.length, hasMore: total > records.length, records }; }`},{id:"netsuite-get-record",name:"Get a NetSuite record",shortName:"Get record",instruction:"Fetches one NetSuite record of any type by internal ID or external ID through the REST record API, including its sublists such as transaction lines. Useful for inspecting a record in full before or after a write.",inputSchema:{type:"object",properties:{recordType:{type:"string",description:'REST record type, e.g. "customer", "vendor", "invoice", "vendorbill", "journalentry", "account", "department" or a custom record like "customrecord_x".'},internalId:{type:"string",description:"Internal ID of the record."},externalId:{type:"string",description:"External ID of the record, used when internalId is not set."},expandSubResources:{type:"boolean",description:"Include sublists and subrecords inline. Defaults to true."}},required:["recordType"],additionalProperties:!1},steps:[{id:"getRecord",instruction:"Fetch the record from the REST record API.",config:{type:"request",systemId:Yd,url:`${Tg}/record/v1/<<(p) => { const type = String(p.recordType || '').trim().toLowerCase(); if (!/^[a-z][a-z0-9_]*$/.test(type)) throw new Error('recordType must contain only letters, numbers and underscores.'); return type; }>>/<<(p) => { if (p.internalId !== undefined && p.internalId !== null && p.internalId !== '') { const id = String(p.internalId).trim(); if (!/^-?\\d+$/.test(id)) throw new Error('internalId must be a NetSuite internal ID.'); return id; } if (p.externalId !== undefined && p.externalId !== null && p.externalId !== '') return 'eid:' + encodeURIComponent(String(p.externalId)); throw new Error('Provide internalId or externalId.'); }>>`,method:"GET",headers:Rg,queryParams:{expandSubResources:"<<(p) => (p.expandSubResources === false || p.expandSubResources === 'false' ? 'false' : 'true')>>"}}}],outputTransform:`(sourceData) => { ${sL} const record = sourceData.getRecord ? sourceData.getRecord.data : undefined; if (!record || typeof record !== 'object') throw new Error('NetSuite returned no record.'); return { record: stripLinks(record) }; }`},_r({id:"netsuite-create-journal-entry",name:"Create NetSuite journal entry",shortName:"Create journal entry",instruction:`Creates a journal entry in NetSuite through the REST record API. Debit and credit lines must balance. Returns the new internal ID. ${$a}`,stepId:"createJournalEntry",recordType:"journalentry",mode:"create",properties:{...lL("create"),lines:{type:"array",description:"Journal lines. Debit and credit totals must balance.",items:uL}},required:["date","lines"],body:`${cL} if (!Array.isArray(p.lines) || p.lines.length < 2) throw new Error('lines must contain at least two journal lines.'); ${aL}`}),_r({id:"netsuite-update-journal-entry",name:"Update NetSuite journal entry",shortName:"Update journal entry",instruction:"Updates an existing NetSuite journal entry by internal ID. Only the provided fields change. When lines are provided they replace all existing lines and must balance. Entries in closed periods refuse updates.",stepId:"updateJournalEntry",recordType:"journalentry",mode:"update",properties:{...lL("update"),lines:{type:"array",description:"Optional replacement lines. When set, they replace every existing line and must balance.",items:uL}},required:[],body:`${cL} if (Array.isArray(p.lines) && p.lines.length < 2) throw new Error('lines must contain at least two journal lines; omit lines to keep the current ones.'); ${aL}`,replaceSublist:{input:"lines",sublist:"line"}}),_r({id:"netsuite-create-vendor",name:"Create NetSuite vendor",shortName:"Create vendor",instruction:`Creates a vendor record in NetSuite. OneWorld accounts need a subsidiaryId. Omit entityId when auto-numbering assigns it. ${$a}`,stepId:"createVendor",recordType:"vendor",mode:"create",properties:Bg("vendor"),required:[],body:`if (!has(p.companyName) && !((p.isPerson === true || p.isPerson === 'true') && has(p.lastName))) throw new Error('Provide companyName, or isPerson with lastName.'); ${wg}`}),_r({id:"netsuite-update-vendor",name:"Update NetSuite vendor",shortName:"Update vendor",instruction:"Updates an existing NetSuite vendor by internal ID. Only the provided fields change; set isInactive to inactivate or reactivate it.",stepId:"updateVendor",recordType:"vendor",mode:"update",properties:{...Bg("vendor"),..._g},required:[],body:wg}),_r({id:"netsuite-create-customer",name:"Create NetSuite customer",shortName:"Create customer",instruction:`Creates a customer record in NetSuite. OneWorld accounts need a subsidiaryId. Omit entityId when auto-numbering assigns it. ${$a}`,stepId:"createCustomer",recordType:"customer",mode:"create",properties:Bg("customer"),required:[],body:`if (!has(p.companyName) && !((p.isPerson === true || p.isPerson === 'true') && has(p.lastName))) throw new Error('Provide companyName, or isPerson with lastName.'); ${wg}`}),_r({id:"netsuite-update-customer",name:"Update NetSuite customer",shortName:"Update customer",instruction:"Updates an existing NetSuite customer by internal ID. Only the provided fields change; set isInactive to inactivate or reactivate it.",stepId:"updateCustomer",recordType:"customer",mode:"update",properties:{...Bg("customer"),..._g},required:[],body:wg}),_r({id:"netsuite-create-account",name:"Create NetSuite GL account",shortName:"Create GL account",instruction:`Creates a general ledger account in NetSuite's chart of accounts. ${$a}`,stepId:"createAccount",recordType:"account",mode:"create",properties:AL,required:["acctName","acctType"],body:`if (!has(p.acctName) || !has(p.acctType)) throw new Error('acctName and acctType are required.'); ${dL} ${Qg}`}),_r({id:"netsuite-update-account",name:"Update NetSuite GL account",shortName:"Update GL account",instruction:"Updates an existing NetSuite GL account by internal ID. Only the provided fields change; set isInactive to inactivate or reactivate it. Accounts with transactions may refuse a type change.",stepId:"updateAccount",recordType:"account",mode:"update",properties:{...AL,..._g},required:[],body:`${dL} ${Qg}`}),_r({id:"netsuite-create-invoice",name:"Create NetSuite invoice",shortName:"Create invoice",instruction:`Creates a customer invoice in NetSuite with item lines. Item, tax and posting rules of the account apply. ${$a}`,stepId:"createInvoice",recordType:"invoice",mode:"create",properties:{customerId:{type:"string",description:"Customer internal ID."},...Dg("create"),lines:{type:"array",description:"Item lines.",items:gL}},required:["customerId","lines"],body:`if (!Array.isArray(p.lines) || p.lines.length === 0) throw new Error('lines must contain at least one item line.'); ${vg("customerId")} ${hL}`}),_r({id:"netsuite-update-invoice",name:"Update NetSuite invoice",shortName:"Update invoice",instruction:"Updates an existing NetSuite invoice by internal ID. Only the provided fields change. When lines are provided they replace all existing item lines. Paid invoices and closed periods may refuse updates.",stepId:"updateInvoice",recordType:"invoice",mode:"update",properties:{customerId:{type:"string",description:"Optional new customer internal ID."},...Dg("update"),lines:{type:"array",description:"Optional replacement item lines; they replace every existing item line.",items:gL}},required:[],body:`if (Array.isArray(p.lines) && p.lines.length === 0) throw new Error('lines must contain at least one item line; omit lines to keep the current ones.'); ${vg("customerId")} ${hL}`,replaceSublist:{input:"lines",sublist:"item"}}),_r({id:"netsuite-create-vendor-bill",name:"Create NetSuite vendor bill",shortName:"Create vendor bill",instruction:`Creates a vendor bill in NetSuite with expense lines. Approval routing of the account applies. ${$a}`,stepId:"createVendorBill",recordType:"vendorbill",mode:"create",properties:{vendorId:{type:"string",description:"Vendor internal ID."},referenceNo:{type:"string",description:"Optional vendor invoice reference number."},...Dg("create"),lines:{type:"array",description:"Expense lines.",items:yL}},required:["vendorId","lines"],body:`if (!Array.isArray(p.lines) || p.lines.length === 0) throw new Error('lines must contain at least one expense line.'); ${vg("vendorId")} if (has(p.referenceNo)) record.tranId = String(p.referenceNo); ${mL}`}),_r({id:"netsuite-update-vendor-bill",name:"Update NetSuite vendor bill",shortName:"Update vendor bill",instruction:"Updates an existing NetSuite vendor bill by internal ID. Only the provided fields change. When lines are provided they replace all existing expense lines. Paid bills and closed periods may refuse updates.",stepId:"updateVendorBill",recordType:"vendorbill",mode:"update",properties:{vendorId:{type:"string",description:"Optional new vendor internal ID."},referenceNo:{type:"string",description:"Optional vendor invoice reference number."},...Dg("update"),lines:{type:"array",description:"Optional replacement expense lines; they replace every existing expense line.",items:yL}},required:[],body:`if (Array.isArray(p.lines) && p.lines.length === 0) throw new Error('lines must contain at least one expense line; omit lines to keep the current ones.'); ${vg("vendorId")} if (has(p.referenceNo)) record.tranId = String(p.referenceNo); ${mL}`,replaceSublist:{input:"lines",sublist:"expense"}}),_r({id:"netsuite-create-department",name:"Create NetSuite department",shortName:"Create department",instruction:`Creates a department in NetSuite. Without subsidiaryIds NetSuite assigns the parent subsidiary. ${$a}`,stepId:"createDepartment",recordType:"department",mode:"create",properties:fL,required:["name"],body:`if (!has(p.name)) throw new Error('name is required.'); ${pL} ${Qg}`}),_r({id:"netsuite-update-department",name:"Update NetSuite department",shortName:"Update department",instruction:"Updates an existing NetSuite department by internal ID. Only the provided fields change; set isInactive to inactivate or reactivate it.",stepId:"updateDepartment",recordType:"department",mode:"update",properties:{...fL,..._g},required:[],body:`${pL} ${Qg}`})],Vb={sap_s4hana:{bundleId:"sap_s4hana",templateId:"sap_s4hana",systemId:"sap_s4hana",displayName:"SAP S/4HANA",description:"Read business partners, sales orders, products and purchase orders from SAP.",systemUrl:wfe,credentialHint:"Works instantly with SAP's demo data. Add your own key later for your live system.",requiredCredentialKeys:["api_key"],demoCredentials:{api_key:"K8reTgiKCCaqvAPWC4cOjqqiLdLE8dqz"},mcpServer:{name:"sap",displayName:"SAP S/4HANA",description:"Business partners, sales orders, products and purchase orders from SAP."},installMcpServer:!0,agentLaunch:{userPrompt:"I just installed the SAP S/4HANA bundle. What can I do with it?",nextSteps:"Your first reply must be short: SAP is connected to free demo data and works right now, so offer to run one tool immediately as proof. No credential collection is needed to start. If they want their own data: their own free key comes from https://api.sap.com (SAP Business Accelerator Hub), collected and saved directly with create_connection askForUserInputs, never as chat text and never via the Connections page; the system URL can then be switched to their own SAP host. Do not list the installed tools, do not add tips or explain SAP concepts unless asked."},tools:[{id:"sap-list-business-partners",name:"List SAP business partners",shortName:"Business partners",instruction:"Lists business partners (customers, suppliers, contacts) from SAP S/4HANA. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "BusinessPartnerCategory eq '2'" for organizations.`},maxResults:{type:"integer",description:"Maximum number of business partners to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchBusinessPartners",instruction:"Fetch business partners, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_BUSINESS_PARTNER/A_BusinessPartner",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"BusinessPartner,BusinessPartnerFullName,BusinessPartnerCategory,BusinessPartnerGrouping,CreationDate"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchBusinessPartners?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, businessPartners: rows.map((r) => ({ id: r.BusinessPartner, name: r.BusinessPartnerFullName, category: r.BusinessPartnerCategory, grouping: r.BusinessPartnerGrouping, createdOn: d(r.CreationDate) })) }; }"},{id:"sap-list-sales-orders",name:"List SAP sales orders",shortName:"Sales orders",instruction:"Lists sales orders from SAP S/4HANA with their net amount, currency and sold-to party. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "SalesOrderType eq 'OR'" or "TotalNetAmount gt 1000".`},maxResults:{type:"integer",description:"Maximum number of sales orders to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchSalesOrders",instruction:"Fetch sales orders, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_SALES_ORDER_SRV/A_SalesOrder",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"SalesOrder,SalesOrderType,SoldToParty,TotalNetAmount,TransactionCurrency,SalesOrderDate,OverallSDProcessStatus"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchSalesOrders?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, salesOrders: rows.map((r) => ({ id: r.SalesOrder, type: r.SalesOrderType, soldToParty: r.SoldToParty, netAmount: Number(r.TotalNetAmount), currency: r.TransactionCurrency, orderDate: d(r.SalesOrderDate), status: r.OverallSDProcessStatus })) }; }"},{id:"sap-list-products",name:"List SAP products",shortName:"Products",instruction:"Lists products (materials) from SAP S/4HANA with their type, group and base unit. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "ProductType eq 'FERT'" for finished goods.`},maxResults:{type:"integer",description:"Maximum number of products to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchProducts",instruction:"Fetch products, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_PRODUCT_SRV/A_Product",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$expand:"to_Description",$select:"Product,ProductType,ProductGroup,BaseUnit,GrossWeight,WeightUnit,CreationDate,to_Description/Language,to_Description/ProductDescription"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const nameOf = (r) => { const list = r.to_Description?.results ?? []; const hit = list.find((x) => x.Language === 'EN') ?? list[0]; return hit?.ProductDescription; }; const rows = (sourceData.fetchProducts?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, products: rows.map((r) => ({ id: r.Product, name: nameOf(r), type: r.ProductType, group: r.ProductGroup, baseUnit: r.BaseUnit, grossWeight: Number(r.GrossWeight), weightUnit: r.WeightUnit, createdOn: d(r.CreationDate) })) }; }"},{id:"sap-list-purchase-orders",name:"List SAP purchase orders",shortName:"Purchase orders",instruction:"Lists purchase orders from SAP S/4HANA with their supplier, currency and creation date. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "PurchaseOrderType eq 'NB'" for standard orders.`},maxResults:{type:"integer",description:"Maximum number of purchase orders to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchPurchaseOrders",instruction:"Fetch purchase orders, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_PURCHASEORDER_PROCESS_SRV/A_PurchaseOrder",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"PurchaseOrder,PurchaseOrderType,Supplier,PurchaseOrderDate,DocumentCurrency,CreatedByUser"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchPurchaseOrders?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, purchaseOrders: rows.map((r) => ({ id: r.PurchaseOrder, type: r.PurchaseOrderType, supplier: r.Supplier, orderDate: d(r.PurchaseOrderDate), currency: r.DocumentCurrency, createdBy: r.CreatedByUser })) }; }"},{id:"sap-list-gl-accounts",name:"List SAP chart of accounts",shortName:"Chart of accounts",instruction:"Lists general ledger accounts (the chart of accounts) from SAP S/4HANA. Supports an optional OData $filter, e.g. by ChartOfAccounts.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "ChartOfAccounts eq 'YCOA'" or "GLAccountType eq 'X'".`},maxResults:{type:"integer",description:"Maximum number of accounts to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchGLAccounts",instruction:"Fetch GL accounts, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_GLACCOUNTINCHARTOFACCOUNTS_SRV/A_GLAccountInChartOfAccounts",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:`<<(p) => p.filter ? "ChartOfAccounts ne '' and (" + p.filter + ")" : "ChartOfAccounts ne ''">>`,$expand:"to_Text",$select:"GLAccount,ChartOfAccounts,GLAccountType,GLAccountGroup,IsBalanceSheetAccount,AccountIsBlockedForPosting,to_Text/Language,to_Text/GLAccountName"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const nameOf = (r) => { const list = r.to_Text?.results ?? []; const hit = list.find((x) => x.Language === 'EN') ?? list[0]; return hit?.GLAccountName; }; const rows = (sourceData.fetchGLAccounts?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, accounts: rows.map((r) => ({ account: r.GLAccount, name: nameOf(r), chartOfAccounts: r.ChartOfAccounts, type: r.GLAccountType, group: r.GLAccountGroup, isBalanceSheet: r.IsBalanceSheetAccount, blockedForPosting: r.AccountIsBlockedForPosting })) }; }"},{id:"sap-list-billing-documents",name:"List SAP billing documents",shortName:"Billing documents",instruction:"Lists billing documents (invoices, credit memos) from SAP S/4HANA with amount, currency and sold-to party. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "BillingDocumentType eq 'F2'" or "TotalNetAmount gt 1000".`},maxResults:{type:"integer",description:"Maximum number of billing documents to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchBillingDocuments",instruction:"Fetch billing documents, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_BILLING_DOCUMENT_SRV/A_BillingDocument",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"BillingDocument,BillingDocumentType,SoldToParty,TotalNetAmount,TransactionCurrency,BillingDocumentDate"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchBillingDocuments?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, billingDocuments: rows.map((r) => ({ id: r.BillingDocument, type: r.BillingDocumentType, soldToParty: r.SoldToParty, netAmount: Number(r.TotalNetAmount), currency: r.TransactionCurrency, date: d(r.BillingDocumentDate) })) }; }"},{id:"sap-list-journal-entry-items",name:"List SAP journal entry line items",shortName:"Journal entries",instruction:"Lists journal entry line items (accounting document items) from SAP S/4HANA with company code, GL account, amount and posting date. Filter by CompanyCode, FiscalYear or PostingDate to keep results focused. Useful for verifying opening balances at cutover.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "CompanyCode eq '1010' and FiscalYear eq '2026'".`},maxResults:{type:"integer",description:"Maximum number of line items to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchJournalItems",instruction:"Fetch accounting document line items, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_OPLACCTGDOCITEMCUBE_SRV/A_OperationalAcctgDocItemCube",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"AccountingDocument,CompanyCode,FiscalYear,GLAccount,AmountInCompanyCodeCurrency,PostingDate"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchJournalItems?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, journalItems: rows.map((r) => ({ document: r.AccountingDocument, companyCode: r.CompanyCode, fiscalYear: r.FiscalYear, account: r.GLAccount, amount: Number(r.AmountInCompanyCodeCurrency), postingDate: d(r.PostingDate) })) }; }"},{id:"sap-query-odata",name:"Query any SAP OData service",shortName:"Query any service",instruction:"Queries any SAP S/4HANA OData service and entity set (for example API_PRODUCT_SRV/A_ProductDescription or API_SALES_ORDER_SRV/A_SalesOrderItem) with optional $select and $filter. The workhorse tool for data checks beyond the prebuilt lists.",inputSchema:{type:"object",properties:{servicePath:{type:"string",description:'Service and entity set in SERVICE/EntitySet form, e.g. "API_SALES_ORDER_SRV/A_SalesOrderItem".'},select:{type:"string",description:"Comma-separated OData $select field list. Omit for all fields."},filter:{type:"string",description:"Optional OData $filter expression."},maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 100."}},required:["servicePath"],additionalProperties:!0},steps:[{id:"queryService",instruction:"Query the requested OData service and entity set.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/<<servicePath>>",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$select:"<<select>>",$filter:"<<filter>>",$top:"<<pageSize>>",$skip:"<<offset>>"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 100; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const rows = (sourceData.queryService?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 100); return { total: rows.length, records: rows.map((r) => { const { __metadata, ...rest } = r; return rest; }) }; }"}]},sage100:{bundleId:"sage100",templateId:"sage100",systemId:"sage100",displayName:"Sage 100",description:"Connect on-premises Sage 100 through the superglue Secure Gateway, with a guided setup playbook and a connection test against the Business Object Interface.",systemUrl:"script://runner/vbs32",credentialHint:"Your assistant first helps you connect a Secure Gateway on your Sage 100 server, then collects your Sage company and user details.",requiredCredentialKeys:["sage_home","sage_company","sage_user","sage_password"],mcpServer:{name:"sage-100",displayName:"Sage 100",description:"Sage 100 Business Object Interface access through the Secure Gateway."},installMcpServer:!1,playbook:{id:"sage100-native-integration",name:"Sage 100 Native Integration (BOI)",whenToRun:"Use when connecting a Sage 100 installation to superglue, testing that connection, or building tools that read or write Sage 100 data through the Business Object Interface.",inputs:"A Sage 100 installation on a Windows machine the user can access; a superglue API key for the gateway; the Sage company code, a Sage user with module access, and the path to the MAS90\\Home directory; the business outcome once connected.",instructions:"First check /org/tunnels for a connected gateway with a runner target. If none is connected, guide the user step by step: download the Windows gateway from https://downloads.superglue.cloud/superglue-gateway-windows.exe onto the machine where Sage 100 and Workstation Setup are installed (the gateway must run there, ProvideX.Script is a local 32-bit COM class), create a config.yaml next to it with a tunnel_id, the server_url ending in /ws/tunnels (wss://api.superglue.cloud/ws/tunnels for hosted superglue), an API key from the API Keys page, and the line enable_script_runner: true, then run the executable. That flag is required: it opts the gateway into running Sage scripts (it is code execution on their machine, so it is off by default), and it is what registers the built-in runner target. No targets section is needed. If a tunnel is connected but has no runner target, the gateway is either missing enable_script_runner: true or is an outdated build; have the user add the flag and restart, or download the current gateway from the same URL. When the tunnel with the runner target appears, attach it to the Sage 100 connection with tools.writeConnection (tunnel with that tunnelId) and keep the URL script://runner/vbs32. Collect sage_home (full path to the MAS90\\Home directory, for example C:\\Sage\\Sage100\\MAS90\\Home, not the MAS90 directory itself), sage_company, sage_user and sage_password through the secure credential form, never as chat text. Then run the Test Sage 100 connection tool once and interpret the result: retVal 0 failures carry the Sage reason in sLastErrorMsg (wrong credentials, missing role access, wrong company code); COM error 0x80040154 means the gateway is not running on a machine with Sage 100 Workstation Setup; a no-license message means all Sage user seats are in use. For new capabilities, build tools whose steps use the script protocol with VBScript in the body: log on with SY_Session, set module context before touching data (nSetDate with YYYYMMDD dates, nSetModule, nLookupTask, nSetProgram), use _svc service objects for reads and _bus business objects for writes, and always release the session with nCleanup and DropObject so the license seat frees up. For reads, set each key segment with nSetKeyValue then nFind for a single record, or browse with nMoveFirst and nMoveNext, and read each field with nGetValue passing a variable that receives the value. To write a document that has lines, such as a sales order, get the header _bus object, set the header fields, get its oLines object, call nAddLine, set the line fields, then call nWrite on the header to commit the header and its lines together. A write fails with a lock error if the record is open in the Sage desktop or held by another session, so report the lock message instead of retrying. Each running script briefly consumes a Sage user seat. Ask for explicit approval before any script that writes to Sage, and warn that records open in the Sage desktop UI cause lock errors.",completionCriteria:"The gateway is connected, the installed Sage 100 system has the tunnel attached and credentials saved, and the connection test returned company data from Sage 100. Any additional requested capability works end to end, with writes explicitly approved before they ran."},agentLaunch:{userPrompt:"I just installed the Sage 100 integration. Help me connect my Sage 100 server.",nextSteps:"Your first reply must be short: one line confirming the Sage 100 integration and setup playbook are installed, then start the connection flow. Check /org/tunnels for a connected gateway with a runner target first. If none exists, walk the user through it one step at a time: download https://downloads.superglue.cloud/superglue-gateway-windows.exe onto the Windows machine where Sage 100 is installed and Workstation Setup has run, create a config.yaml next to it with tunnel_id, server_url (wss://api.superglue.cloud/ws/tunnels for hosted superglue), an API key from the API Keys page, and the line enable_script_runner: true, then run it. That flag is required: it opts the gateway into running scripts on their machine (off by default because it is code execution) and is what registers the runner target. No targets are needed in the config. If a tunnel is connected but has no runner target, the gateway is missing enable_script_runner: true or is an outdated build: have the user add the flag and restart, or download the current one from the same URL. Wait for the user to confirm, then verify the tunnel appears and attach it to the Sage 100 connection with tools.writeConnection tunnel, keeping the URL script://runner/vbs32. Use create_connection with the connection id and askForUserInputs to save sage_home (full path to the MAS90\\Home directory, for example C:\\Sage\\Sage100\\MAS90\\Home, not MAS90 itself), sage_company (for example ABC for the demo company), sage_user and sage_password. Never send the user to the Connections page and never accept secrets as chat text. Then run the Test Sage 100 connection tool once. If it fails, explain the specific cause in plain language before retrying. Mention that each test briefly uses one Sage user license seat. Do not list tools or add tips unless asked."},tools:[{id:"sage100-test-connection",name:"Test Sage 100 connection",shortName:"Connection test",instruction:"Logs on to Sage 100 through the Secure Gateway, opens the configured company, and reads the first customer record to verify the Business Object Interface end to end. Briefly consumes one Sage user license seat.",steps:[{id:"testConnection",instruction:"Run a VBScript through the gateway script runner that logs on via SY_Session, sets A/R module context, and reads the first customer.",config:{type:"request",systemId:"sage100",url:"<<sage100_url>>",method:"POST",body:["Option Explicit","On Error Resume Next","Dim oScript, oSS, oCust, retVal, custNo, custName, today",'Set oScript = CreateObject("ProvideX.Script")','FailOnErr "CREATE", " (Sage 100 Workstation Setup has not registered ProvideX.Script on this machine; the gateway must run on a prepared Sage 100 machine)"','oScript.Init "<<sage100_sage_home>>"','FailOnErr "INIT", " (sage_home must be the full path to the MAS90\\Home directory, not MAS90 itself)"','Set oSS = oScript.NewObject("SY_Session")','FailOnErr "SESSION", ""','retVal = oSS.nSetUser("<<sage100_sage_user>>", "<<sage100_sage_password>>")','FailOnErr "LOGON", ""',"If retVal = 0 Then",' WScript.Echo "LOGON FAILED: " & oSS.sLastErrorMsg'," WScript.Quit 1","End If",'retVal = oSS.nSetCompany("<<sage100_sage_company>>")','FailOnErr "COMPANY", ""',"If retVal = 0 Then",' WScript.Echo "COMPANY FAILED: " & oSS.sLastErrorMsg'," oSS.nCleanup"," oSS.DropObject"," WScript.Quit 1","End If",'today = Year(Date) & Right("0" & Month(Date), 2) & Right("0" & Day(Date), 2)','retVal = oSS.nSetDate("A/R", today)','FailOnErr "DATE", ""','retVal = oSS.nSetModule("A/R")','FailOnErr "MODULE", ""','retVal = oSS.nSetProgram(oSS.nLookupTask("AR_Customer_ui"))','FailOnErr "TASK", ""',"If retVal = 0 Then",' WScript.Echo "TASK FAILED: " & oSS.sLastErrorMsg'," oSS.nCleanup"," oSS.DropObject"," WScript.Quit 1","End If",'Set oCust = oScript.NewObject("AR_Customer_svc", oSS)','FailOnErr "CUSTOMER OBJECT", ""',"retVal = oCust.nMoveFirst()",'FailOnErr "READ", ""',"If retVal = 0 Then",' WScript.Echo "READ FAILED: " & oCust.sLastErrorMsg',"Else",' custNo = "" : custName = ""',' retVal = oCust.nGetValue("CustomerNo$", custNo)',' retVal = oCust.nGetValue("CustomerName$", custName)',' FailOnErr "READ VALUE", " (ByRef value marshalling failed)"',' WScript.Echo "CONNECTED - company <<sage100_sage_company>>, first customer: " & custNo & " / " & custName',"End If","oCust.DropObject","oSS.nCleanup","oSS.DropObject","If retVal = 0 Then WScript.Quit 1","","Sub FailOnErr(stage, hint)"," If Err.Number <> 0 Then",' WScript.Echo stage & " FAILED: [0x" & Hex(Err.Number) & "] " & Err.Description & hint'," WScript.Quit 1"," End If","End Sub"].join(`
113
- `)}}]}]},sage_intacct:{bundleId:"sage_intacct",templateId:"sage_intacct",systemId:"sage_intacct",displayName:"Sage Intacct",description:"Install a Sage Intacct system, eight read/query tools, fourteen write tools and a native integration playbook.",systemUrl:"https://api.intacct.com/ia/xml/xmlgw.phtml",credentialHint:"Works instantly with a Sage Intacct demo company. Enter your company ID and API user credentials to use your own company. Web Services sender credentials are preconfigured.",requiredCredentialKeys:["sender_id","sender_password","user_id","user_password","company_id"],demoCredentials:{company_id:"IndexCommerceMPP-DEV",user_id:"superglue",user_password:"Linux123___"},mcpServer:{name:"sage-intacct",displayName:"Sage Intacct",description:"Chart of accounts, customers, vendors, journal entries and ad-hoc object queries from Sage Intacct, plus create and update tools for GL accounts, journal entries, invoices, bills, departments, vendors and customers."},installMcpServer:!1,playbook:{id:"sage-intacct-native-integration",name:"Sage Intacct Native Integration",whenToRun:"Use when connecting, validating, querying or extending a Sage Intacct integration through XML Web Services.",inputs:"A configured Sage Intacct system; the object or business process to work with; optional Location/Entity ID for multi-entity companies; validation criteria and desired output.",instructions:"Use the installed read-only tools for chart of accounts, customers, vendors, journal entries, invoices, bills and departments. Use Query any Sage Intacct object for supported objects outside the named library. Use the installed create and update tools for GL accounts, journal entries, invoices, bills, departments, vendors and customers only after the user explicitly confirms the exact records to write; the create tools are not idempotent and re-running them duplicates records. Apply the configured Location/Entity ID when present. Verify every XML Web Services response at control, authentication and function-result level, and preserve Sage support IDs in failures. For other objects or operations, inspect Sage object documentation, create separate least-privilege tools, validate them in a development company and require explicit user confirmation before modifying Sage data.",completionCriteria:"The requested Sage data, write result or validation result is returned; entity scope is correct; Sage XML failures are surfaced as failures with support IDs; no Sage data is modified unless the user explicitly requested and confirmed the write."},agentLaunch:{userPrompt:"I just installed the Sage Intacct integration. What can I do with it?",nextSteps:"Your first reply must be short: one line confirming the Sage Intacct integration and native integration playbook are installed, then collect credentials. The Web Services sender credentials are already configured. Use create_connection with this system's connection id and askForUserInputs to save user_id, user_password and company_id, plus optional entity_id when the user wants to target one entity in a multi-entity company. Never send the user to the Connections page and never accept secrets as chat text. The user id and password are an API user login in the company; company id is the Intacct company id. Once saved, offer one read-only test run. Do not list the installed tools or add tips unless asked. The query tool accepts other supported Intacct object names, and additional read or write tools can be built beyond the default library. The installed create and update tools modify Sage data; run them only after the user confirms the exact records to write."},tools:[{id:"sage-intacct-list-accounts",name:"List Sage Intacct chart of accounts",shortName:"Chart of accounts",instruction:"Lists general ledger accounts (the chart of accounts) from Sage Intacct via the XML Web Services API. Useful for validating an imported chart of accounts after a migration.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryAccounts",instruction:"Query GLACCOUNT records via readByQuery-style paging.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>GLACCOUNT</object><select><field>RECORDNO</field><field>ACCOUNTNO</field><field>TITLE</field><field>ACCOUNTTYPE</field><field>NORMALBALANCE</field><field>STATUS</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.GLACCOUNT : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.GLACCOUNT : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryAccounts",objectNameExpression:"'GLACCOUNT'",collectionName:"accounts",mapExpression:"(record) => ({ recordNo: record.RECORDNO, account: record.ACCOUNTNO, name: record.TITLE, type: record.ACCOUNTTYPE, normalBalance: record.NORMALBALANCE, status: record.STATUS })"})},{id:"sage-intacct-list-customers",name:"List Sage Intacct customers",shortName:"Customers",instruction:"Lists customer master records from Sage Intacct accounts receivable. Useful for verifying migrated AR master data.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryCustomers",instruction:"Query CUSTOMER records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>CUSTOMER</object><select><field>RECORDNO</field><field>CUSTOMERID</field><field>NAME</field><field>STATUS</field><field>WHENCREATED</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.CUSTOMER : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.CUSTOMER : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryCustomers",objectNameExpression:"'CUSTOMER'",collectionName:"customers",mapExpression:"(record) => ({ recordNo: record.RECORDNO, customerId: record.CUSTOMERID, name: record.NAME, status: record.STATUS, createdOn: record.WHENCREATED })"})},{id:"sage-intacct-list-vendors",name:"List Sage Intacct vendors",shortName:"Vendors",instruction:"Lists vendor master records from Sage Intacct accounts payable. Useful for verifying migrated AP master data.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryVendors",instruction:"Query VENDOR records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>VENDOR</object><select><field>RECORDNO</field><field>VENDORID</field><field>NAME</field><field>STATUS</field><field>WHENCREATED</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.VENDOR : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.VENDOR : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryVendors",objectNameExpression:"'VENDOR'",collectionName:"vendors",mapExpression:"(record) => ({ recordNo: record.RECORDNO, vendorId: record.VENDORID, name: record.NAME, status: record.STATUS, createdOn: record.WHENCREATED })"})},{id:"sage-intacct-list-journal-entries",name:"List Sage Intacct journal entries",shortName:"Journal entries",instruction:"Lists general ledger entries from Sage Intacct with account, type and amount. Useful for verifying opening balances and postings at cutover.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryJournalEntries",instruction:"Query GLENTRY records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>GLENTRY</object><select><field>RECORDNO</field><field>BATCHNO</field><field>ACCOUNTNO</field><field>TR_TYPE</field><field>AMOUNT</field><field>ENTRY_DATE</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.GLENTRY : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.GLENTRY : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryJournalEntries",objectNameExpression:"'GLENTRY'",collectionName:"journalEntries",mapExpression:"(record) => ({ recordNo: record.RECORDNO, batch: record.BATCHNO, account: record.ACCOUNTNO, type: record.TR_TYPE, amount: Number(record.AMOUNT), date: record.ENTRY_DATE })"})},{id:"sage-intacct-list-invoices",name:"List Sage Intacct invoices",shortName:"Invoices",instruction:"Lists accounts receivable invoices from Sage Intacct. Useful for verifying migrated open AR at go-live.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryInvoices",instruction:"Query ARINVOICE records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>ARINVOICE</object><select><field>RECORDNO</field><field>RECORDID</field><field>CUSTOMERID</field><field>TOTALDUE</field><field>WHENCREATED</field><field>STATE</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.ARINVOICE : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.ARINVOICE : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryInvoices",objectNameExpression:"'ARINVOICE'",collectionName:"invoices",mapExpression:"(record) => ({ recordNo: record.RECORDNO, invoiceId: record.RECORDID, customerId: record.CUSTOMERID, totalDue: Number(record.TOTALDUE), createdOn: record.WHENCREATED, state: record.STATE })"})},{id:"sage-intacct-list-bills",name:"List Sage Intacct bills",shortName:"Bills",instruction:"Lists accounts payable bills from Sage Intacct. Useful for verifying migrated open AP at go-live.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryBills",instruction:"Query APBILL records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>APBILL</object><select><field>RECORDNO</field><field>RECORDID</field><field>VENDORID</field><field>TOTALDUE</field><field>WHENCREATED</field><field>STATE</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.APBILL : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.APBILL : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryBills",objectNameExpression:"'APBILL'",collectionName:"bills",mapExpression:"(record) => ({ recordNo: record.RECORDNO, billId: record.RECORDID, vendorId: record.VENDORID, totalDue: Number(record.TOTALDUE), createdOn: record.WHENCREATED, state: record.STATE })"})},{id:"sage-intacct-list-departments",name:"List Sage Intacct departments",shortName:"Departments",instruction:"Lists department dimensions from Sage Intacct. Useful for validating the dimension setup after an implementation.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryDepartments",instruction:"Query DEPARTMENT records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>DEPARTMENT</object><select><field>RECORDNO</field><field>DEPARTMENTID</field><field>TITLE</field><field>STATUS</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.DEPARTMENT : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.DEPARTMENT : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryDepartments",objectNameExpression:"'DEPARTMENT'",collectionName:"departments",mapExpression:"(record) => ({ recordNo: record.RECORDNO, departmentId: record.DEPARTMENTID, name: record.TITLE, status: record.STATUS })"})},{id:"sage-intacct-query-object",name:"Query any Sage Intacct object",shortName:"Query any object",instruction:"Queries any Sage Intacct object by name (for example GLACCOUNT, PROJECT, GLENTRY, ARINVOICE) using the XML Web Services readByQuery, with an optional Intacct query filter. The workhorse tool for migration validation beyond the prebuilt lists. Returns up to 1000 records in one call.",inputSchema:{type:"object",properties:{object:{type:"string",description:'Intacct object name, e.g. "GLACCOUNT", "PROJECT", "GLENTRY", "ARINVOICE".'},query:{type:"string",description:`Optional Intacct query filter, e.g. "STATUS = 'active'". Leave empty to return all records.`},maxResults:{type:"integer",description:"Maximum number of records to return (max 1000). Defaults to 100."}},required:["object"],additionalProperties:!0},steps:[{id:"queryObject",instruction:"Run readByQuery for the requested object.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<readByQuery><object><<(p) => { const value = String(p.object || '').toUpperCase(); if (!/^[A-Z][A-Z0-9_]*$/.test(value)) throw new Error('Sage Intacct object must contain only letters, numbers, and underscores.'); return value; }>></object><fields>*</fields><query><<(p) => String(p.query || '').replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;')>></query><pagesize><<(p) => Math.min(Math.max(Number(p.maxResults) || 100, 1), 1000)>></pagesize></readByQuery>")}}],outputTransform:vs({stepId:"queryObject",objectNameExpression:"(sourceData && sourceData.object ? String(sourceData.object) : '').toUpperCase()",collectionName:"records",includeTotalCount:!0})},{id:"sage-intacct-create-journal-entry",name:"Create Sage Intacct journal entry",shortName:"Create journal entry",instruction:"Creates a journal entry (GLBATCH with GLENTRY lines) in Sage Intacct via the XML Web Services API. Debits and credits must balance. Re-running this tool creates another journal entry; it is not idempotent.",inputSchema:{type:"object",properties:{journal:{type:"string",description:'Journal symbol, e.g. "GJ". Defaults to GJ.'},date:{type:"string",description:"Posting date as YYYY-MM-DD."},title:{type:"string",description:"Journal entry description."},lines:{type:"array",description:"Journal lines. Debit and credit totals must balance.",items:{type:"object",properties:{accountNo:{type:"string",description:"GL account number."},type:{type:"string",enum:["debit","credit"]},amount:{type:"number",description:"Positive amount."},department:{type:"string",description:"Optional department ID."},location:{type:"string",description:"Optional location ID."},memo:{type:"string",description:"Optional line description."}},required:["accountNo","type","amount"],additionalProperties:!0}}},required:["date","title","lines"],additionalProperties:!0},steps:[{id:"createJournalEntry",instruction:"Create the GLBATCH record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><GLBATCH><JOURNAL><<(sourceData) => { ${Ds} return esc(sourceData.journal || 'GJ'); }>></JOURNAL><BATCH_DATE><<(sourceData) => { ${nL} return toIntacctDate(sourceData.date); }>></BATCH_DATE><BATCH_TITLE><<(sourceData) => { ${Ds} return esc(sourceData.title); }>></BATCH_TITLE><ENTRIES><<(sourceData) => { ${Ds} ${oL} ${iL} const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length === 0) throw new Error('lines must contain at least one journal line.'); assertBalanced(lines); return lines.map(lineXml).join(''); }>></ENTRIES></GLBATCH></create>`)}}],outputTransform:Eu({stepId:"createJournalEntry",objectName:"GLBATCH"})},{id:"sage-intacct-update-journal-entry",name:"Update Sage Intacct journal entry",shortName:"Update journal entry",instruction:"Updates an existing journal entry (GLBATCH) in Sage Intacct by record number. Posted or locked entries may refuse updates. When lines are provided they replace all existing lines of the entry.",inputSchema:{type:"object",properties:{recordNo:{type:"integer",description:"RECORDNO of the journal entry to update."},journal:{type:"string",description:"Optional new journal symbol."},date:{type:"string",description:"Optional new posting date as YYYY-MM-DD."},title:{type:"string",description:"Optional new description."},lines:{type:"array",description:"Optional replacement lines. When set, they replace every existing line and must balance.",items:{type:"object",properties:{accountNo:{type:"string",description:"GL account number."},type:{type:"string",enum:["debit","credit"]},amount:{type:"number",description:"Positive amount."},department:{type:"string",description:"Optional department ID."},location:{type:"string",description:"Optional location ID."},memo:{type:"string",description:"Optional line description."}},required:["accountNo","type","amount"],additionalProperties:!0}}},required:["recordNo"],additionalProperties:!0},steps:[{id:"updateJournalEntry",instruction:"Update the GLBATCH record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><GLBATCH><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { ${Ds} ${nL} ${oL} ${iL} let xml = ''; if (sourceData.journal) xml += '<JOURNAL>' + esc(sourceData.journal) + '</JOURNAL>'; if (sourceData.date) xml += '<BATCH_DATE>' + toIntacctDate(sourceData.date) + '</BATCH_DATE>'; if (sourceData.title) xml += '<BATCH_TITLE>' + esc(sourceData.title) + '</BATCH_TITLE>'; if (Array.isArray(sourceData.lines) && sourceData.lines.length > 0) { assertBalanced(sourceData.lines); xml += '<ENTRIES>' + sourceData.lines.map(lineXml).join('') + '</ENTRIES>'; } if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></GLBATCH></update>`)}}],outputTransform:Eu({stepId:"updateJournalEntry",objectName:"GLBATCH"})},{id:"sage-intacct-create-vendor",name:"Create Sage Intacct vendor",shortName:"Create vendor",instruction:"Creates a vendor master record in Sage Intacct via the XML Web Services API. Omit vendorId when the company uses vendor auto-numbering. Re-running this tool creates another vendor; it is not idempotent.",inputSchema:{type:"object",properties:{vendorId:{type:"string",description:"Vendor ID. Omit when auto-numbering assigns it."},name:{type:"string",description:"Vendor name."},taxId:{type:"string",description:"Optional tax ID."}},required:["name"],additionalProperties:!0},steps:[{id:"createVendor",instruction:"Create the VENDOR record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><VENDOR><<(sourceData) => { ${Ds} if (!sourceData.name) throw new Error('name is required.'); let xml = ''; if (sourceData.vendorId) xml += '<VENDORID>' + esc(sourceData.vendorId) + '</VENDORID>'; xml += '<NAME>' + esc(sourceData.name) + '</NAME>'; if (sourceData.taxId) xml += '<TAXID>' + esc(sourceData.taxId) + '</TAXID>'; return xml; }>></VENDOR></create>`)}}],outputTransform:Eu({stepId:"createVendor",objectName:"VENDOR"})},{id:"sage-intacct-update-vendor",name:"Update Sage Intacct vendor",shortName:"Update vendor",instruction:"Updates an existing vendor master record in Sage Intacct by record number. Only the provided fields change.",inputSchema:{type:"object",properties:{recordNo:{type:"integer",description:"RECORDNO of the vendor to update."},name:{type:"string",description:"Optional new vendor name."},status:{type:"string",enum:["active","inactive"]},taxId:{type:"string",description:"Optional new tax ID."}},required:["recordNo"],additionalProperties:!0},steps:[{id:"updateVendor",instruction:"Update the VENDOR record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><VENDOR><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { ${Ds} let xml = ''; if (sourceData.name) xml += '<NAME>' + esc(sourceData.name) + '</NAME>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; if (sourceData.taxId) xml += '<TAXID>' + esc(sourceData.taxId) + '</TAXID>'; if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></VENDOR></update>`)}}],outputTransform:Eu({stepId:"updateVendor",objectName:"VENDOR"})},{id:"sage-intacct-create-customer",name:"Create Sage Intacct customer",shortName:"Create customer",instruction:"Creates a customer master record in Sage Intacct via the XML Web Services API. Omit customerId when the company uses customer auto-numbering. Re-running this tool creates another customer; it is not idempotent.",inputSchema:{type:"object",properties:{customerId:{type:"string",description:"Customer ID. Omit when auto-numbering assigns it."},name:{type:"string",description:"Customer name."},taxId:{type:"string",description:"Optional tax ID."}},required:["name"],additionalProperties:!0},steps:[{id:"createCustomer",instruction:"Create the CUSTOMER record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><CUSTOMER><<(sourceData) => { ${Ds} if (!sourceData.name) throw new Error('name is required.'); let xml = ''; if (sourceData.customerId) xml += '<CUSTOMERID>' + esc(sourceData.customerId) + '</CUSTOMERID>'; xml += '<NAME>' + esc(sourceData.name) + '</NAME>'; if (sourceData.taxId) xml += '<TAXID>' + esc(sourceData.taxId) + '</TAXID>'; return xml; }>></CUSTOMER></create>`)}}],outputTransform:Eu({stepId:"createCustomer",objectName:"CUSTOMER"})},{id:"sage-intacct-update-customer",name:"Update Sage Intacct customer",shortName:"Update customer",instruction:"Updates an existing customer master record in Sage Intacct by record number. Only the provided fields change.",inputSchema:{type:"object",properties:{recordNo:{type:"integer",description:"RECORDNO of the customer to update."},name:{type:"string",description:"Optional new customer name."},status:{type:"string",enum:["active","inactive"]},taxId:{type:"string",description:"Optional new tax ID."}},required:["recordNo"],additionalProperties:!0},steps:[{id:"updateCustomer",instruction:"Update the CUSTOMER record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><CUSTOMER><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { ${Ds} let xml = ''; if (sourceData.name) xml += '<NAME>' + esc(sourceData.name) + '</NAME>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; if (sourceData.taxId) xml += '<TAXID>' + esc(sourceData.taxId) + '</TAXID>'; if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></CUSTOMER></update>`)}}],outputTransform:Eu({stepId:"updateCustomer",objectName:"CUSTOMER"})},{id:"sage-intacct-create-account",name:"Create Sage Intacct GL account",shortName:"Create GL account",instruction:"Creates a general ledger account in Sage Intacct via the XML Web Services API. Re-running this tool creates another account; it is not idempotent.",inputSchema:{type:"object",required:["accountNo","title","normalBalance","accountType"],properties:{title:{type:"string"},accountNo:{type:"string"},accountType:{type:"string",enum:["balancesheet","incomestatement"]},normalBalance:{type:"string",enum:["debit","credit"]},closingType:{type:"string",enum:["non-closing account","closing account"],description:"Period-end closing type. Defaults to non-closing account."},closingAccountNo:{type:"string",description:"Account to close into. Sage requires it when closingType is closing account."}}},steps:[{id:"createAccount",instruction:"Create the GLACCOUNT record via the Sage Intacct XML API.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><GLACCOUNT><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); if (!sourceData.accountNo) throw new Error('accountNo is required.'); if (!sourceData.title) throw new Error('title is required.'); let xml = '<ACCOUNTNO>' + esc(sourceData.accountNo) + '</ACCOUNTNO>'; xml += '<TITLE>' + esc(sourceData.title) + '</TITLE>'; xml += '<NORMALBALANCE>' + esc(sourceData.normalBalance || 'debit') + '</NORMALBALANCE>'; xml += '<ACCOUNTTYPE>' + esc(sourceData.accountType || 'balancesheet') + '</ACCOUNTTYPE>'; xml += '<CLOSINGTYPE>' + esc(sourceData.closingType || 'non-closing account') + '</CLOSINGTYPE>'; if (sourceData.closingAccountNo) xml += '<CLOSINGACCOUNTNO>' + esc(sourceData.closingAccountNo) + '</CLOSINGACCOUNTNO>'; return xml; }>></GLACCOUNT></create>`)}}],outputTransform:"(sourceData) => { const response = sourceData.createAccount && sourceData.createAccount.data ? sourceData.createAccount.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.GLACCOUNT || data.glaccount) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }"},{id:"sage-intacct-update-account",name:"Update Sage Intacct GL account",shortName:"Update GL account",instruction:"Updates an existing general ledger account in Sage Intacct by account number. Only the provided fields change.",inputSchema:{type:"object",required:["accountNo"],properties:{title:{type:"string"},accountNo:{type:"string"},accountType:{type:"string",enum:["balancesheet","incomestatement"]},normalBalance:{type:"string",enum:["debit","credit"]},status:{type:"string",enum:["active","inactive"]}}},steps:[{id:"updateAccount",instruction:"Update the GLACCOUNT record by account number.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><GLACCOUNT><ACCOUNTNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); if (!sourceData.accountNo) throw new Error('accountNo is required.'); return esc(sourceData.accountNo); }>></ACCOUNTNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); let xml = ''; if (sourceData.title) xml += '<TITLE>' + esc(sourceData.title) + '</TITLE>'; if (sourceData.normalBalance) xml += '<NORMALBALANCE>' + esc(sourceData.normalBalance) + '</NORMALBALANCE>'; if (sourceData.accountType) xml += '<ACCOUNTTYPE>' + esc(sourceData.accountType) + '</ACCOUNTTYPE>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></GLACCOUNT></update>`)}}],outputTransform:"(sourceData) => { const response = sourceData.updateAccount && sourceData.updateAccount.data ? sourceData.updateAccount.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.GLACCOUNT || data.glaccount) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { accountNo: sourceData.accountNo, record }; }"},{id:"sage-intacct-create-invoice",name:"Create Sage Intacct AR invoice",shortName:"Create invoice",instruction:"Creates an AR invoice in Sage Intacct via the XML Web Services API. Requires a customer ID, transaction date, and at least one line item with a GL account and amount. Re-running creates another invoice; it is not idempotent.",inputSchema:{type:"object",required:["customerId","dateCreated","dateDue","lines"],properties:{lines:{type:"array",items:{type:"object",required:["glAccountNo","amount"],properties:{memo:{type:"string"},amount:{type:"number"},glAccountNo:{type:"string"},departmentId:{type:"string"},locationId:{type:"string"},vendorId:{type:"string"},customerId:{type:"string"},projectId:{type:"string"}}}},dateDue:{type:"string"},customerId:{type:"string"},dateCreated:{type:"string"},datePosted:{type:"string"},termName:{type:"string"},description:{type:"string"}}},steps:[{id:"createInvoice",instruction:"Create the ARINVOICE record with line items.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<create><ARINVOICE><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;').replaceAll(\"'\", '&apos;'); if (!sourceData.customerId) throw new Error('customerId is required.'); if (!sourceData.dateCreated) throw new Error('dateCreated is required (YYYY-MM-DD).'); const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length === 0) throw new Error('lines must contain at least one invoice line.'); const match = String(sourceData.dateCreated).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); const dateXml = match ? `<WHENCREATED><YEAR>${match[1]}</YEAR><MONTH>${match[2]}</MONTH><DAY>${match[3]}</DAY></WHENCREATED>` : `<WHENCREATED>${esc(sourceData.dateCreated)}</WHENCREATED>`; let xml = '<CUSTOMERID>' + esc(sourceData.customerId) + '</CUSTOMERID>'; xml += dateXml; if (sourceData.datePosted) { const mp = String(sourceData.datePosted).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (mp) xml += `<WHENPOSTED><YEAR>${mp[1]}</YEAR><MONTH>${mp[2]}</MONTH><DAY>${mp[3]}</DAY></WHENPOSTED>`; } if (sourceData.dateDue) { const md = String(sourceData.dateDue).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (md) xml += `<WHENDUE><YEAR>${md[1]}</YEAR><MONTH>${md[2]}</MONTH><DAY>${md[3]}</DAY></WHENDUE>`; } else if (sourceData.termName) { xml += '<TERMNAME>' + esc(sourceData.termName) + '</TERMNAME>'; } if (sourceData.description) xml += '<DESCRIPTION>' + esc(sourceData.description) + '</DESCRIPTION>'; xml += '<ARINVOICEITEMS>'; lines.forEach((line) => { if (!line.glAccountNo) throw new Error('Each line requires glAccountNo.'); if (line.amount == null) throw new Error('Each line requires amount.'); xml += '<ARINVOICEITEM>'; xml += '<ACCOUNTNO>' + esc(line.glAccountNo) + '</ACCOUNTNO>'; xml += '<AMOUNT>' + Number(line.amount) + '</AMOUNT>'; if (line.memo) xml += '<MEMO>' + esc(line.memo) + '</MEMO>'; if (line.departmentId) xml += '<DEPARTMENTID>' + esc(line.departmentId) + '</DEPARTMENTID>'; if (line.locationId) xml += '<LOCATIONID>' + esc(line.locationId) + '</LOCATIONID>'; if (line.vendorId) xml += '<VENDORID>' + esc(line.vendorId) + '</VENDORID>'; if (line.customerId) xml += '<CUSTOMERID>' + esc(line.customerId) + '</CUSTOMERID>'; if (line.projectId) xml += '<PROJECTID>' + esc(line.projectId) + '</PROJECTID>'; xml += '</ARINVOICEITEM>'; }); xml += '</ARINVOICEITEMS>'; return xml; }>></ARINVOICE></create>")}}],outputTransform:"(sourceData) => { const response = sourceData.createInvoice && sourceData.createInvoice.data ? sourceData.createInvoice.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.ARINVOICE || data.arinvoice) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }"},{id:"sage-intacct-update-invoice",name:"Update Sage Intacct AR invoice",shortName:"Update invoice",instruction:"Updates an existing AR invoice in Sage Intacct by record number. Only the provided fields change. Line items can be added or updated by line number.",inputSchema:{type:"object",required:["recordNo"],properties:{recordNo:{type:"integer"},description:{type:"string"},customerId:{type:"string"},dateCreated:{type:"string"},dateDue:{type:"string"},termName:{type:"string"},lines:{type:"array",items:{type:"object",properties:{lineNo:{type:"integer"},memo:{type:"string"},amount:{type:"number"},glAccountNo:{type:"string"},departmentId:{type:"string"},locationId:{type:"string"},vendorId:{type:"string"},customerId:{type:"string"},projectId:{type:"string"}}}}}},steps:[{id:"updateInvoice",instruction:"Update the ARINVOICE record by RECORDNO.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<update><ARINVOICE><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;').replaceAll(\"'\", '&apos;'); let xml = ''; if (sourceData.customerId) xml += '<CUSTOMERID>' + esc(sourceData.customerId) + '</CUSTOMERID>'; if (sourceData.dateCreated) { const match = String(sourceData.dateCreated).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (match) xml += `<WHENCREATED><YEAR>${match[1]}</YEAR><MONTH>${match[2]}</MONTH><DAY>${match[3]}</DAY></WHENCREATED>`; } if (sourceData.dateDue) { const md = String(sourceData.dateDue).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (md) xml += `<WHENDUE><YEAR>${md[1]}</YEAR><MONTH>${md[2]}</MONTH><DAY>${md[3]}</DAY></WHENDUE>`; } if (sourceData.termName) xml += '<TERMNAME>' + esc(sourceData.termName) + '</TERMNAME>'; if (sourceData.description) xml += '<DESCRIPTION>' + esc(sourceData.description) + '</DESCRIPTION>'; const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length > 0) { xml += '<ARINVOICEITEMS>'; lines.forEach((line) => { xml += '<ARINVOICEITEM>'; if (line.lineNo) xml += '<LINE_NO>' + Number(line.lineNo) + '</LINE_NO>'; if (line.glAccountNo) xml += '<ACCOUNTNO>' + esc(line.glAccountNo) + '</ACCOUNTNO>'; if (line.amount != null) xml += '<AMOUNT>' + Number(line.amount) + '</AMOUNT>'; if (line.memo) xml += '<MEMO>' + esc(line.memo) + '</MEMO>'; if (line.departmentId) xml += '<DEPARTMENTID>' + esc(line.departmentId) + '</DEPARTMENTID>'; if (line.locationId) xml += '<LOCATIONID>' + esc(line.locationId) + '</LOCATIONID>'; if (line.vendorId) xml += '<VENDORID>' + esc(line.vendorId) + '</VENDORID>'; if (line.customerId) xml += '<CUSTOMERID>' + esc(line.customerId) + '</CUSTOMERID>'; if (line.projectId) xml += '<PROJECTID>' + esc(line.projectId) + '</PROJECTID>'; xml += '</ARINVOICEITEM>'; }); xml += '</ARINVOICEITEMS>'; } if (!xml && lines.length === 0) throw new Error('Provide at least one field to update.'); return xml; }>></ARINVOICE></update>")}}],outputTransform:"(sourceData) => { const response = sourceData.updateInvoice && sourceData.updateInvoice.data ? sourceData.updateInvoice.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.ARINVOICE || data.arinvoice) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: sourceData.recordNo, record }; }"},{id:"sage-intacct-create-bill",name:"Create Sage Intacct AP bill",shortName:"Create bill",instruction:"Creates an AP bill in Sage Intacct via the XML Web Services API. Requires a vendor ID, transaction date, and at least one line item with a GL account and amount. Re-running creates another bill; it is not idempotent.",inputSchema:{type:"object",required:["lines","dateDue","vendorId","dateCreated"],properties:{lines:{type:"array",items:{type:"object",required:["glAccountNo","amount"],properties:{memo:{type:"string"},amount:{type:"number"},glAccountNo:{type:"string"},departmentId:{type:"string"},locationId:{type:"string"},vendorId:{type:"string"},customerId:{type:"string"},projectId:{type:"string"}}}},dateDue:{type:"string"},vendorId:{type:"string"},dateCreated:{type:"string"},datePosted:{type:"string"},termName:{type:"string"},description:{type:"string"}}},steps:[{id:"createBill",instruction:"Create the APBILL record with line items.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><APBILL><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); if (!sourceData.vendorId) throw new Error('vendorId is required.'); if (!sourceData.dateCreated) throw new Error('dateCreated is required (YYYY-MM-DD).'); const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length === 0) throw new Error('lines must contain at least one bill line.'); const match = String(sourceData.dateCreated).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); const dateStr = match ? match[2] + '/' + match[3] + '/' + match[1] : sourceData.dateCreated; let xml = '<VENDORID>' + esc(sourceData.vendorId) + '</VENDORID>'; xml += '<WHENCREATED>' + esc(dateStr) + '</WHENCREATED>'; if (sourceData.datePosted) { const mp = String(sourceData.datePosted).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); xml += '<WHENPOSTED>' + esc(mp ? mp[2] + '/' + mp[3] + '/' + mp[1] : sourceData.datePosted) + '</WHENPOSTED>'; } if (sourceData.dateDue) { const md = String(sourceData.dateDue).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); xml += '<WHENDUE>' + esc(md ? md[2] + '/' + md[3] + '/' + md[1] : sourceData.dateDue) + '</WHENDUE>'; } else if (sourceData.termName) { xml += '<TERMNAME>' + esc(sourceData.termName) + '</TERMNAME>'; } if (sourceData.description) xml += '<DESCRIPTION>' + esc(sourceData.description) + '</DESCRIPTION>'; xml += '<APBILLITEMS>'; lines.forEach((line) => { if (!line.glAccountNo) throw new Error('Each line requires glAccountNo.'); if (line.amount == null) throw new Error('Each line requires amount.'); xml += '<APBILLITEM>'; xml += '<ACCOUNTNO>' + esc(line.glAccountNo) + '</ACCOUNTNO>'; xml += '<AMOUNT>' + Number(line.amount) + '</AMOUNT>'; if (line.memo) xml += '<MEMO>' + esc(line.memo) + '</MEMO>'; if (line.departmentId) xml += '<DEPARTMENTID>' + esc(line.departmentId) + '</DEPARTMENTID>'; if (line.locationId) xml += '<LOCATIONID>' + esc(line.locationId) + '</LOCATIONID>'; if (line.vendorId) xml += '<VENDORID>' + esc(line.vendorId) + '</VENDORID>'; if (line.customerId) xml += '<CUSTOMERID>' + esc(line.customerId) + '</CUSTOMERID>'; if (line.projectId) xml += '<PROJECTID>' + esc(line.projectId) + '</PROJECTID>'; xml += '</APBILLITEM>'; }); xml += '</APBILLITEMS>'; return xml; }>></APBILL></create>`)}}],outputTransform:"(sourceData) => { const response = sourceData.createBill && sourceData.createBill.data ? sourceData.createBill.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.APBILL || data.apbill) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }"},{id:"sage-intacct-update-bill",name:"Update Sage Intacct AP bill",shortName:"Update bill",instruction:"Updates an existing AP bill in Sage Intacct by record number. Only the provided fields change. Line items can be added or updated by line number.",inputSchema:{type:"object",required:["recordNo"],properties:{recordNo:{type:"integer"},description:{type:"string"},vendorId:{type:"string"},dateCreated:{type:"string"},dateDue:{type:"string"},termName:{type:"string"},lines:{type:"array",items:{type:"object",properties:{lineNo:{type:"integer"},memo:{type:"string"},amount:{type:"number"},glAccountNo:{type:"string"},departmentId:{type:"string"},locationId:{type:"string"},vendorId:{type:"string"},customerId:{type:"string"},projectId:{type:"string"}}}}}},steps:[{id:"updateBill",instruction:"Update the APBILL record by RECORDNO.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><APBILL><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); let xml = ''; if (sourceData.vendorId) xml += '<VENDORID>' + esc(sourceData.vendorId) + '</VENDORID>'; if (sourceData.dateCreated) { const match = String(sourceData.dateCreated).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); xml += '<WHENCREATED>' + esc(match ? match[2] + '/' + match[3] + '/' + match[1] : sourceData.dateCreated) + '</WHENCREATED>'; } if (sourceData.dateDue) { const md = String(sourceData.dateDue).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); xml += '<WHENDUE>' + esc(md ? md[2] + '/' + md[3] + '/' + md[1] : sourceData.dateDue) + '</WHENDUE>'; } if (sourceData.termName) xml += '<TERMNAME>' + esc(sourceData.termName) + '</TERMNAME>'; if (sourceData.description) xml += '<DESCRIPTION>' + esc(sourceData.description) + '</DESCRIPTION>'; const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length > 0) { xml += '<APBILLITEMS>'; lines.forEach((line) => { xml += '<APBILLITEM>'; if (line.lineNo) xml += '<LINE_NO>' + Number(line.lineNo) + '</LINE_NO>'; if (line.glAccountNo) xml += '<ACCOUNTNO>' + esc(line.glAccountNo) + '</ACCOUNTNO>'; if (line.amount != null) xml += '<AMOUNT>' + Number(line.amount) + '</AMOUNT>'; if (line.memo) xml += '<MEMO>' + esc(line.memo) + '</MEMO>'; if (line.departmentId) xml += '<DEPARTMENTID>' + esc(line.departmentId) + '</DEPARTMENTID>'; if (line.locationId) xml += '<LOCATIONID>' + esc(line.locationId) + '</LOCATIONID>'; if (line.vendorId) xml += '<VENDORID>' + esc(line.vendorId) + '</VENDORID>'; if (line.customerId) xml += '<CUSTOMERID>' + esc(line.customerId) + '</CUSTOMERID>'; if (line.projectId) xml += '<PROJECTID>' + esc(line.projectId) + '</PROJECTID>'; xml += '</APBILLITEM>'; }); xml += '</APBILLITEMS>'; } if (!xml && lines.length === 0) throw new Error('Provide at least one field to update.'); return xml; }>></APBILL></update>`)}}],outputTransform:"(sourceData) => { const response = sourceData.updateBill && sourceData.updateBill.data ? sourceData.updateBill.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.APBILL || data.apbill) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: sourceData.recordNo, record }; }"},{id:"sage-intacct-create-department",name:"Create Sage Intacct department",shortName:"Create department",instruction:"Creates a department in Sage Intacct via the XML Web Services API. Requires a department ID and title. Re-running creates another department; it is not idempotent.",inputSchema:{type:"object",required:["departmentId","title"],properties:{title:{type:"string"},departmentId:{type:"string"}}},steps:[{id:"createDepartment",instruction:"Create the DEPARTMENT record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><DEPARTMENT><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); if (!sourceData.departmentId) throw new Error('departmentId is required.'); if (!sourceData.title) throw new Error('title is required.'); let xml = '<DEPARTMENTID>' + esc(sourceData.departmentId) + '</DEPARTMENTID>'; xml += '<TITLE>' + esc(sourceData.title) + '</TITLE>'; if (sourceData.parentId) xml += '<PARENTID>' + esc(sourceData.parentId) + '</PARENTID>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; return xml; }>></DEPARTMENT></create>`)}}],outputTransform:"(sourceData) => { const response = sourceData.createDepartment && sourceData.createDepartment.data ? sourceData.createDepartment.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.DEPARTMENT || data.department) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }"},{id:"sage-intacct-update-department",name:"Update Sage Intacct department",shortName:"Update department",instruction:"Updates an existing department in Sage Intacct by record number. Only the provided fields change.",inputSchema:{type:"object",required:["recordNo"],properties:{title:{type:"string"},recordNo:{type:"integer"},parentId:{type:"string"},status:{type:"string",enum:["active","inactive"]}}},steps:[{id:"updateDepartment",instruction:"Update the DEPARTMENT record by RECORDNO.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><DEPARTMENT><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); let xml = ''; if (sourceData.title) xml += '<TITLE>' + esc(sourceData.title) + '</TITLE>'; if (sourceData.parentId) xml += '<PARENTID>' + esc(sourceData.parentId) + '</PARENTID>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></DEPARTMENT></update>`)}}],outputTransform:"(sourceData) => { const response = sourceData.updateDepartment && sourceData.updateDepartment.data ? sourceData.updateDepartment.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.DEPARTMENT || data.department) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: sourceData.recordNo, record }; }"}]},dynamics365_sales:{bundleId:"dynamics365_sales",templateId:"dynamics365_sales",systemId:"dynamics365_sales",displayName:"Dynamics 365 Sales",description:"Read accounts, contacts and the sales pipeline from Dynamics 365 Sales.",systemUrl:"https://<<api_host>>/api/data/v9.2",credentialHint:"Set api_host to your environment host, then connect with Microsoft OAuth. Your assistant walks you through it.",requiredCredentialKeys:["api_host","access_token"],mcpServer:{name:"dynamics-sales",displayName:"Dynamics 365 Sales",description:"Accounts, contacts, opportunity pipeline and ad-hoc Dataverse queries from Dynamics 365 Sales."},installMcpServer:!0,agentLaunch:{userPrompt:"I just installed the Dynamics 365 Sales bundle. What can I do with it?",nextSteps:'Your first reply must be short: one line confirming the Dynamics MCP server is installed, then ask for their environment host in chat (like contoso.crm.dynamics.com \u2014 it is not a secret, so never collect it through a secure form; form values are redacted and you cannot read them back). When they reply, save it with tools.writeConnection passing secrets: { api_host: "<their host>" } directly, without asking for secure inputs. Then start Microsoft OAuth with create_connection and substitute the same host into the scopes yourself \u2014 set auth.scopes to "https://<host>/user_impersonation offline_access", never the <<api_host>> placeholder, which Microsoft rejects. OAuth fills access_token automatically; never send the user to the Connections page, never ask for a token as chat text, and never suggest the az CLI. Once connected, the MCP server is ready; offer one test run. Do not list the installed tools, do not add tips unless asked. If asked later: OAuth refresh is automatic, the query tool accepts any Dataverse entity set, and record totals above 5000 are reported as capped by Dataverse rather than exact.'},tools:[{id:"dynamics-list-accounts",name:"List Dynamics 365 accounts",shortName:"Accounts",instruction:"Lists account records from Dynamics 365 with name, account number and creation date. Supports an optional OData $filter. Useful for validating migrated accounts.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "createdon gt 2026-01-01T00:00:00Z" or "contains(name,'GmbH')".`},maxResults:{type:"integer",description:"Maximum number of accounts to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchAccounts",instruction:"Fetch accounts from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/accounts",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"name,accountnumber,telephone1,websiteurl,createdon,modifiedon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchAccounts?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, accounts: rows.map((r) => ({ id: r.accountid, name: r.name, accountNumber: r.accountnumber, phone: r.telephone1, website: r.websiteurl, createdOn: r.createdon, modifiedOn: r.modifiedon })) }; }'},{id:"dynamics-list-contacts",name:"List Dynamics 365 contacts",shortName:"Contacts",instruction:"Lists contact records from Dynamics 365 with name, email and creation date. Supports an optional OData $filter. Useful for validating migrated contacts.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "emailaddress1 eq null" to find contacts missing an email.'},maxResults:{type:"integer",description:"Maximum number of contacts to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchContacts",instruction:"Fetch contacts from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/contacts",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"fullname,emailaddress1,telephone1,jobtitle,createdon,modifiedon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchContacts?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, contacts: rows.map((r) => ({ id: r.contactid, name: r.fullname, email: r.emailaddress1, phone: r.telephone1, jobTitle: r.jobtitle, createdOn: r.createdon, modifiedOn: r.modifiedon })) }; }'},{id:"dynamics-open-opportunities",name:"List Dynamics 365 open opportunities",shortName:"Open opportunities",instruction:"Lists open opportunities from Dynamics 365 with estimated value and close date. Supports an optional additional OData $filter. Useful for pipeline verification during UAT.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional additional OData $filter combined with the open-state filter, e.g. "estimatedvalue gt 10000".'},maxResults:{type:"integer",description:"Maximum number of opportunities to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchOpportunities",instruction:"Fetch open opportunities from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/opportunities",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"name,estimatedvalue,estimatedclosedate,createdon,statecode,_parentaccountid_value",$filter:'<<(p) => p.filter ? "statecode eq 0 and (" + p.filter + ")" : "statecode eq 0">>',$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchOpportunities?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, opportunities: rows.map((r) => ({ id: r.opportunityid, name: r.name, estimatedValue: r.estimatedvalue, estimatedCloseDate: r.estimatedclosedate, accountId: r._parentaccountid_value, createdOn: r.createdon })) }; }'},{id:"dynamics-list-leads",name:"List Dynamics 365 leads",shortName:"Leads",instruction:"Lists lead records from Dynamics 365 with subject, name and company. Supports an optional OData $filter. Useful for validating migrated leads.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "statecode eq 0" for open leads.'},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchLeads",instruction:"Fetch leads from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/leads",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"subject,fullname,companyname,statecode,createdon,modifiedon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchLeads?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows.map((r) => ({ id: r.leadid, subject: r.subject, name: r.fullname, company: r.companyname, state: r.statecode, createdOn: r.createdon, modifiedOn: r.modifiedon })) }; }'},{id:"dynamics-list-cases",name:"List Dynamics 365 cases",shortName:"Cases",instruction:"Lists case (incident) records from Dynamics 365 with title, ticket number and status. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "statecode eq 0" for active cases.'},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchCases",instruction:"Fetch incidents from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/incidents",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"title,ticketnumber,statecode,createdon,_customerid_value",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchCases?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows.map((r) => ({ id: r.incidentid, title: r.title, ticketNumber: r.ticketnumber, state: r.statecode, customerId: r._customerid_value, createdOn: r.createdon })) }; }'},{id:"dynamics-list-users",name:"List Dynamics 365 users",shortName:"Users",instruction:"Lists system users from Dynamics 365 with name, email and disabled state. Useful for owner-mapping checks during migrations.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "isdisabled eq false" for active users.'},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchUsers",instruction:"Fetch systemusers from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/systemusers",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"fullname,internalemailaddress,isdisabled,createdon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchUsers?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows.map((r) => ({ id: r.systemuserid, name: r.fullname, email: r.internalemailaddress, disabled: r.isdisabled, createdOn: r.createdon })) }; }'},{id:"dynamics-list-products",name:"List Dynamics 365 products",shortName:"Products",instruction:"Lists product catalog records from Dynamics 365 with name, number and state. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "statecode eq 0" for active products.'},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchProducts",instruction:"Fetch products from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/products",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"name,productnumber,statecode,createdon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchProducts?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows.map((r) => ({ id: r.productid, name: r.name, number: r.productnumber, state: r.statecode, createdOn: r.createdon })) }; }'},{id:"dynamics-query-dataverse",name:"Query any Dynamics 365 entity",shortName:"Query any entity",instruction:'Queries any Dataverse entity set. Required input: entitySet \u2014 the plural entity set name, e.g. "leads", "systemusers", "incidents". Optional inputs: select (OData $select field list), filter (OData $filter expression), maxResults (record cap, default 100). The workhorse tool for CRM migration validation and data quality checks beyond the prebuilt lists.',inputSchema:{type:"object",properties:{entitySet:{type:"string",description:'Dataverse entity set name (plural), e.g. "leads", "systemusers", "incidents".'},select:{type:"string",description:'Comma-separated OData $select field list, e.g. "subject,createdon". Omit for all fields.'},filter:{type:"string",description:"Optional OData $filter expression."},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},required:["entitySet"],additionalProperties:!0},steps:[{id:"queryEntity",instruction:"Query the requested Dataverse entity set.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/<<entitySet>>",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"<<select>>",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.queryEntity?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows }; }'}]},dynamics365_business_central:{bundleId:"dynamics365_business_central",templateId:"dynamics365_business_central",systemId:"dynamics365_business_central",displayName:"Dynamics 365 Business Central",description:"Read companies, customers, vendors and the chart of accounts from Business Central.",systemUrl:"https://api.businesscentral.dynamics.com/v2.0/<<environment>>/api/v2.0",credentialHint:"Connect your Business Central environment. Your assistant walks you through it.",requiredCredentialKeys:["environment","access_token"],oauthSignIn:!0,mcpServer:{name:"business-central",displayName:"Dynamics 365 Business Central",description:"Companies, customers, vendors, chart of accounts and ad-hoc entity queries from Business Central."},installMcpServer:!0,agentLaunch:{userPrompt:"I just installed the Dynamics 365 Business Central bundle. What can I do with it?",nextSteps:"Your first reply must be short: one line confirming the Business Central MCP server is installed, then collect the credentials. Use create_connection with this system's connection id and askForUserInputs to save environment (their BC environment name, usually production or sandbox) and access_token; never send the user to the Connections page and never accept secrets as chat text. Fastest token: az account get-access-token --resource https://api.businesscentral.dynamics.com. Once saved, the MCP server is ready; run the companies tool as the test, because its result contains the company id every other tool needs. Do not list the installed tools, do not add tips unless asked. If asked later: tokens expire after about an hour, so a 401 means refresh access_token; the query tool accepts any Business Central entity set like items or salesInvoices."},tools:[{id:"business-central-list-companies",name:"List Business Central companies",shortName:"Companies",instruction:"Lists the companies in the Business Central environment. Run this first: every other Business Central tool needs a companyId from this list.",inputSchema:{type:"object",properties:{},additionalProperties:!0},steps:[{id:"fetchCompanies",instruction:"Fetch the companies in this environment.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"}}}],outputTransform:"(sourceData) => { const rows = sourceData.fetchCompanies?.data?.value ?? []; return { total: rows.length, companies: rows.map((r) => ({ companyId: r.id, name: r.name, displayName: r.displayName })) }; }"},{id:"business-central-list-customers",name:"List Business Central customers",shortName:"Customers",instruction:"Lists customer master records from a Business Central company. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:`Optional OData $filter expression, e.g. "blocked ne ''" or "contains(displayName,'GmbH')".`},maxResults:{type:"integer",description:"Maximum number of customers to return in one call. Defaults to 100."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchCustomers",instruction:"Fetch customers for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/customers",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,displayName,email,phoneNumber,blocked,lastModifiedDateTime",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchCustomers?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, customers: rows.map((r) => ({ id: r.id, number: r.number, name: r.displayName, email: r.email, phone: r.phoneNumber, blocked: r.blocked, lastModified: r.lastModifiedDateTime })) }; }'},{id:"business-central-list-vendors",name:"List Business Central vendors",shortName:"Vendors",instruction:"Lists vendor master records from a Business Central company. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:"Optional OData $filter expression."},maxResults:{type:"integer",description:"Maximum number of vendors to return in one call. Defaults to 100."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchVendors",instruction:"Fetch vendors for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/vendors",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,displayName,email,phoneNumber,blocked,lastModifiedDateTime",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchVendors?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, vendors: rows.map((r) => ({ id: r.id, number: r.number, name: r.displayName, email: r.email, phone: r.phoneNumber, blocked: r.blocked, lastModified: r.lastModifiedDateTime })) }; }'},{id:"business-central-list-accounts",name:"List Business Central chart of accounts",shortName:"Chart of accounts",instruction:"Lists general ledger accounts (the chart of accounts) from a Business Central company. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:`Optional OData $filter expression, e.g. "category eq 'Assets'".`},maxResults:{type:"integer",description:"Maximum number of accounts to return in one call. Defaults to 200."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchAccounts",instruction:"Fetch general ledger accounts for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/accounts",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,displayName,category,subCategory,blocked,accountType",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 200>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchAccounts?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, accounts: rows.map((r) => ({ id: r.id, number: r.number, name: r.displayName, category: r.category, subCategory: r.subCategory, type: r.accountType, blocked: r.blocked })) }; }'},{id:"business-central-list-items",name:"List Business Central items",shortName:"Items",instruction:"Lists item (product) master records from a Business Central company. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:`Optional OData $filter expression, e.g. "type eq 'Inventory'".`},maxResults:{type:"integer",description:"Maximum number of items to return in one call. Defaults to 100."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchItems",instruction:"Fetch items for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/items",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,displayName,type,unitPrice,inventory,blocked,lastModifiedDateTime",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchItems?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, items: rows.map((r) => ({ id: r.id, number: r.number, name: r.displayName, type: r.type, unitPrice: r.unitPrice, inventory: r.inventory, blocked: r.blocked })) }; }'},{id:"business-central-list-sales-invoices",name:"List Business Central sales invoices",shortName:"Sales invoices",instruction:"Lists sales invoices from a Business Central company with customer, total and status. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:`Optional OData $filter expression, e.g. "status eq 'Open'".`},maxResults:{type:"integer",description:"Maximum number of invoices to return in one call. Defaults to 100."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchSalesInvoices",instruction:"Fetch sales invoices for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/salesInvoices",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,customerName,invoiceDate,totalAmountIncludingTax,currencyCode,status",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchSalesInvoices?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, invoices: rows.map((r) => ({ id: r.id, number: r.number, customer: r.customerName, date: r.invoiceDate, total: r.totalAmountIncludingTax, currency: r.currencyCode, status: r.status })) }; }'},{id:"business-central-list-gl-entries",name:"List Business Central general ledger entries",shortName:"GL entries",instruction:"Lists general ledger entries from a Business Central company with account, amounts and posting date. Requires a companyId from the companies tool. Filter by postingDate to verify opening balances at cutover.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:'Optional OData $filter expression, e.g. "postingDate ge 2026-01-01".'},maxResults:{type:"integer",description:"Maximum number of entries to return in one call. Defaults to 200."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchGLEntries",instruction:"Fetch general ledger entries for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/generalLedgerEntries",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,entryNumber,postingDate,documentNumber,accountNumber,description,debitAmount,creditAmount",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 200>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchGLEntries?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, entries: rows.map((r) => ({ entryNumber: r.entryNumber, postingDate: r.postingDate, document: r.documentNumber, account: r.accountNumber, description: r.description, debit: r.debitAmount, credit: r.creditAmount })) }; }'},{id:"business-central-query-entity",name:"Query any Business Central entity",shortName:"Query any entity",instruction:"Queries any Business Central entity set by name (for example items, salesInvoices, generalLedgerEntries) within a company, with optional OData $select and $filter. The workhorse tool for migration validation beyond the prebuilt lists.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},entitySet:{type:"string",description:'Business Central entity set name, e.g. "items", "salesInvoices", "generalLedgerEntries".'},select:{type:"string",description:"Comma-separated OData $select field list. Omit for all fields."},filter:{type:"string",description:"Optional OData $filter expression."},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},required:["companyId","entitySet"],additionalProperties:!0},steps:[{id:"queryEntity",instruction:"Query the requested entity set for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/<<entitySet>>",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"<<select>>",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.queryEntity?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, records: rows }; }'}]},netsuite:{bundleId:"netsuite",templateId:"netsuite",systemId:Yd,displayName:"NetSuite",description:"Install a NetSuite system, ten read/query tools, fourteen write tools and a native integration playbook.",systemUrl:"https://{accountId}.suitetalk.api.netsuite.com/services/rest",credentialHint:"Connects through your own NetSuite integration record with OAuth 2.0. Your assistant asks for the account ID and the integration record's client ID and secret, then opens the NetSuite sign-in.",requiredCredentialKeys:["access_token"],oauthSignIn:!0,mcpServer:{name:"netsuite",displayName:"NetSuite",description:"Chart of accounts, customers, vendors, journal entries, invoices, vendor bills, subsidiaries and dimensions from NetSuite, SuiteQL queries and record lookups, plus create and update tools for journal entries, vendors, customers, GL accounts, invoices, vendor bills and departments."},installMcpServer:!1,playbook:{id:"netsuite-native-integration",name:"NetSuite Native Integration",whenToRun:"Use when connecting, validating, querying or extending a NetSuite integration through REST Web Services and SuiteQL.",inputs:"A NetSuite connection with an OAuth sign-in; the record type or business process to work with; subsidiary scope for OneWorld accounts; validation criteria and desired output.",instructions:"Use the installed read-only tools for the chart of accounts, customers, vendors, journal entry lines, invoices, vendor bills, departments, subsidiaries, classes and locations. Use the SuiteQL query tool for any other record type, join or aggregate, and the get-record tool to inspect one record in full. Use the installed create and update tools for journal entries, vendors, customers, GL accounts, invoices, vendor bills and departments only after the user explicitly confirms the exact records to write; the create tools are not idempotent and re-running them duplicates records. Reference other records by internal ID from the list tools, and pass a subsidiary on OneWorld accounts. Surface NetSuite error details (o:errorDetails) as failures. For other record types or operations, inspect the account's metadata catalog, create separate least-privilege tools, validate them in a sandbox account and require explicit user confirmation before modifying NetSuite data.",completionCriteria:"The requested NetSuite data, write result or validation result is returned; subsidiary scope is correct; NetSuite errors are surfaced as failures with their details; no NetSuite data is modified unless the user explicitly requested and confirmed the write."},agentLaunch:{userPrompt:"I just installed the NetSuite integration. What can I do with it?",nextSteps:`Your first reply must be short: one line confirming the NetSuite integration and native integration playbook are installed. If the user already has a NetSuite connection with an OAuth sign-in under this system id, offer one read-only test run and stop. Otherwise connect it in this order. 1) Ask in chat for the NetSuite account ID (Setup > Company > Company Information, like 1234567 or 1234567_SB1 for a sandbox; it is not a secret). 2) Build the host from it in lowercase with "_" replaced by "-" (1234567_SB1 becomes 1234567-sb1). 3) Call create_connection with this system id, the user's existing NetSuite connection id if one exists, url https://<host>.suitetalk.api.netsuite.com/services/rest, and auth type oauth2 with oauthClientMode custom, authUrl https://<host>.app.netsuite.com/app/login/oauth2/authorize.nl and tokenUrl https://<host>.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token. Confirm no {accountId} remains in url, authUrl, or tokenUrl before calling it. If /org/oauth-apps/ lists an app for this NetSuite account, pass its oauthAppId; otherwise the card collects the client ID and client secret of their NetSuite integration record and then runs the OAuth sign-in. Never ask for the client secret or a token in chat. If they have no integration record yet, explain before calling create_connection: Setup > Integration > Manage Integrations > New, enable Authorization Code Grant with the REST Web Services and RESTlets scopes, set the redirect URI to the superglue OAuth callback URL exactly, and copy the client ID and secret shown once after saving; the NetSuite role needs REST Web Services and Log in using OAuth 2.0 Access Tokens permissions. Once connected, the integration is ready; offer one read-only test run. Do not list the installed tools or add tips unless asked. If asked later: the sign-in lasts seven days and a 401 means signing in again through create_connection with the connection id; the SuiteQL tool reads any record type; the installed create and update tools modify NetSuite data, so run them only after the user confirms the exact records to write.`},tools:Ofe}};ho.bundles={...Vb,sage_intacct_mcp:{...Vb.sage_intacct,bundleId:"sage_intacct_mcp",description:"Install the Sage Intacct integration and an OAuth-protected MCP server for its read/query and write tools.",installMcpServer:!0},netsuite_mcp:{...Vb.netsuite,bundleId:"netsuite_mcp",description:"Install the NetSuite integration and an OAuth-protected MCP server for its read/query and write tools.",installMcpServer:!0}};function Ufe({bundle:t,install:e}){let r=e.tools.map(s=>` - ${s.id}${s.name?` (${s.name})`:""}`).join(`
112
+ ${t.slice(t.length-n)}`}function fAe(t){return t instanceof Error?t.message:typeof t=="string"?t:typeof t=="object"&&t!==null&&"message"in t?String(t.message):String(t)}function hAe(t,e){if(!e||Object.keys(e).length===0)return{};let r=/file::([^,\s)}\]"']+)/g,n=typeof t=="string"?t:JSON.stringify(t||{}),i=[...new Set([...n.matchAll(r)].map(o=>{let s=o[1];return s.endsWith(".raw")?s=s.slice(0,-4):s.endsWith(".base64")?s=s.slice(0,-7):s.endsWith(".extracted")&&(s=s.slice(0,-10)),s}))];return Object.fromEntries(i.flatMap(o=>e[o]?[[o,e[o]]]:[]))}function gAe(t){if(!t)return null;let e=t.indexOf(":");if(e===-1)return{source:"simpleicons",name:t};let r=t.substring(0,e),n=t.substring(e+1);return r!=="simpleicons"&&r!=="lucide"?{source:"simpleicons",name:t}:{source:r,name:n}}function mAe(t){return t?typeof t=="string"?t.indexOf(":")!==-1?t:`simpleicons:${t}`:`${t.source}:${t.name}`:null}function lx(t){if(t.op==="remove"||t.value===void 0||typeof t.value!="string")return t;if(t.path==="/inputSchema"||t.path==="/outputSchema"||t.path.startsWith("/inputSchema/properties/")||t.path.startsWith("/outputSchema/properties/")||t.path.match(/^\/steps\/\d+\/config\/pagination$/)||t.path.match(/^\/steps\/\d+\/config\/headers$/)||t.path.match(/^\/steps\/\d+\/config\/queryParams$/))try{return{...t,value:JSON.parse(t.value)}}catch{return t}return t}function yAe(t){return t.map(e=>lx(e))}function EAe(t,e){t||(t=""),e||(e=""),/^(https?|postgres(ql)?|ftp(s)?|sftp|smb|file):\/\//i.test(t)||(t=`https://${t}`);let r=t.endsWith("/")?t.slice(0,-1):t,n=e.startsWith("/")?e.slice(1):e;return`${r}/${n}`}var IAe=new Set(["data","stepResults","toolPayload","rawData","transformedData"]),CAe=8e4;function bAe(t,e=CAe){if(t==null)return t;let r=t;if(typeof t=="string"){if(t.length<=e)return t;try{r=JSON.parse(t)}catch{return{_truncated:!0,_message:"String result too large to parse",_size:t.length}}}if(typeof r!="object")return r;let n=0,i=0,o=(s,a=0)=>{if(a>20||s===null||typeof s!="object")return s;if(Array.isArray(s))return s.map(u=>o(u,a+1));let c={};for(let[u,l]of Object.entries(s))if(IAe.has(u)&&l!==null&&typeof l=="object"){let d=JSON.stringify(l);if(d.length>e){i+=d.length;try{let{jsonString:A,truncatedProps:p}=(0,Cde.default)(d,e);c[u]=JSON.parse(A),n+=p.length}catch{c[u]=l}}else c[u]=l}else c[u]=o(l,a+1);return c};try{if(JSON.stringify(r).length<=e)return r;let a=o(r);return n>0&&typeof a=="object"&&a!==null&&(a._note=`Result truncated: ${n} items omitted (original ${i} characters)`),a}catch{return{_truncated:!0,_message:"Result too large to display"}}}function SAe(t){if(!t.steps)return[];let e=new Set;for(let r of t.steps)r.config&&(0,GM.isRequestConfig)(r.config)&&r.config.systemId&&e.add(r.config.systemId);return Array.from(e)}function hg(t,e,r=new WeakSet){if(typeof t=="string"){e.push(t);return}if(!(!t||typeof t!="object")&&!r.has(t)){if(r.add(t),Array.isArray(t)){for(let n of t)hg(n,e,r);return}for(let n of Object.values(t))hg(n,e,r)}}function wAe(t){let e=[];for(let r of t.matchAll(/<<([\s\S]*?)>>/g)){let n=r[1].trim();n&&e.push(n)}for(let r of t.matchAll(/{{\s*([^{}\s]+)\s*}}/g)){let n=r[1].trim();n&&e.push(n)}return e}function dx(t,e){let r=[];hg(t,r);let n=`${e}_`,i=new Set;for(let o of r)for(let s of wAe(o)){if(!s.startsWith(n))continue;let a=s.slice(n.length);!a||a==="url"||!O.CREDENTIAL_KEY_PATTERN.test(a)||i.add(a)}return[...i]}var BAe=/^\s*(async\s+)?(\([^)]*\)|[a-zA-Z_$][a-zA-Z0-9_$]*)\s*=>/,_Ae=new Set(["sg_auth_email","sg_auth_jwt"]);function QAe({config:t,systemId:e}){let r=[];hg(t,r);let n=e?`${e}_`:null,i=new Set;for(let u of r)for(let l of u.matchAll(/<<([\s\S]*?)>>/g)){let d=l[1].trim();d&&(n&&d.startsWith(n)||BAe.test(d)||_Ae.has(d)||i.add(d))}if(i.size===0)return null;let o=[...i].map(u=>`<<${u}>>`).join(", "),s=`Unresolved placeholder${i.size===1?"":"s"} ${o}`;if(!n)return`${s}. Credential placeholders need systemId and the form <<systemId_secretName>>. Nothing was sent.`;let a=[...i].filter(u=>O.CREDENTIAL_KEY_PATTERN.test(u)).map(u=>`<<${n}${u}>>`),c=a.length>0?`Credential placeholders are namespaced by system: use ${a.join(", ")}.`:`Credential placeholders are namespaced by system as <<${n}secretName>>.`;return`${s}. ${c} Nothing was sent.`}function vAe(t){let e={};if(!t.steps)return e;for(let r of t.steps){if(!r.config||!(0,GM.isRequestConfig)(r.config)||!r.config.systemId)continue;let n=dx(r.config,r.config.systemId);if(n.length===0)continue;let i=new Set(e[r.config.systemId]||[]);for(let o of n)i.add(o);e[r.config.systemId]=[...i]}return e}});var gx=m(mt=>{"use strict";Object.defineProperty(mt,"__esModule",{value:!0});mt.AGENT_CONTEXT_MEMORY_MESSAGE_ID_PREFIX=void 0;mt.applyToolMutation=Ax;mt.mutateToolCallInMessages=TAe;mt.buildStreamingAssistantMessage=px;mt.parseToolOutput=fx;mt.parseAgentStreamEventLine=NAe;mt.stopActiveTool=hx;mt.appendContentToMessage=xb;mt.updateMessageWithData=mu;mt.findAwaitingConfirmationToolCallIds=kAe;mt.declineAwaitingConfirmationTools=OAe;mt.findAndResumeMessageWithTool=UAe;mt.serializeMessageForPersistence=xAe;mt.isTurnContextBlockMessage=Lb;mt.normalizeAgentSessionForkMessages=LAe;mt.normalizeAgentSessionImportMessages=PAe;mt.createAgentTranscriptState=$Ae;mt.applyAgentStreamChunk=FAe;var DAe=xr(),yg=Dn();function Ax(t,e){let r=e.frontendOutput!==void 0?e.frontendOutput:t.frontendOutput;return{...t,...e.input!==void 0?{input:e.input}:{},...e.result!==void 0?{result:e.result}:{},...e.status!==void 0?{status:e.status}:{},...e.startTime!==void 0?{startTime:e.startTime}:{},...e.endTime!==void 0?{endTime:e.endTime}:{},...e.error!==void 0?{error:e.error||void 0}:{},...r!==void 0?{frontendOutput:r}:{},...e.llmOutput!==void 0?{llmOutput:e.llmOutput}:{},...e.resultMetadata!==void 0?{resultMetadata:e.resultMetadata}:{},...e.confirmationState!==void 0?{confirmationState:e.confirmationState===null?void 0:e.confirmationState}:{},...e.confirmationData!==void 0?{confirmationData:e.confirmationData===null?void 0:e.confirmationData}:{}}}function TAe(t,e,r){return t.map(n=>{let i=!1,o=n.parts?.map(s=>s.type!=="tool"||!s.tool||s.tool.id!==e?s:(i=!0,{...s,tool:Ax(s.tool,r)}));return i&&o?{...n,parts:o}:n})}function px(t){return{id:t,content:"",role:"assistant",timestamp:new Date,parts:[{type:"content",content:"",id:"content-0"}],isStreaming:!0}}function RAe(){return{status:"declined",endTime:new Date,confirmationState:"declined",confirmationData:{reason:"new_user_message",message:"Rejected: the user sent a new message instead of confirming this action. The proposed changes were NOT applied."}}}function fx(t){if(!t)return null;if(typeof t=="string")try{let e=JSON.parse(t);return e&&typeof e=="object"&&!Array.isArray(e)?e:null}catch{return null}return typeof t=="object"&&!Array.isArray(t)?t:null}function NAe(t){if(!t.startsWith("data: "))return null;try{let e=JSON.parse(t.slice(6));return e&&typeof e=="object"&&!Array.isArray(e)?e:null}catch{return null}}function hx(t){return t.status==="running"||t.status==="pending"||t.status==="awaiting_confirmation"?{...t,status:"stopped",endTime:new Date,confirmationState:void 0,confirmationData:void 0}:t}function xb(t,e){if(!e)return t;let r=[...t.parts||[]],n=r[r.length-1];return n?.type==="content"?r[r.length-1]={...n,content:(n.content||"")+e}:r.push({type:"content",content:e,id:`content-${r.length}`}),{...t,parts:r,content:""}}function mu(t,e,r){if(t.id!==r.id)return t;switch(e.type){case"content":return xb(t,e.content||"");case"tool_call_start":{let n=t.parts?.find(u=>u.type==="tool"&&u.tool?.id===e.toolCall.id)?.tool,i=e.toolCall.input??n?.input,o=e.executionMode==="confirm"?"awaiting_confirmation":i?"running":"pending",s={...n,id:e.toolCall.id,name:e.toolCall.name,input:i,status:o,startTime:n?.startTime||new Date,...n?.confirmationState!==void 0?{confirmationState:n.confirmationState}:{},...n?.confirmationData!==void 0?{confirmationData:n.confirmationData}:{}},a=[...t.parts||[]],c=a.findIndex(u=>u.type==="tool"&&u.tool?.id===e.toolCall.id);return c===-1?a.push({type:"tool",tool:s,id:`tool-${e.toolCall.id}`}):a[c]={...a[c],tool:s},{...t,parts:a,content:""}}case"tool_call_input":{let n=i=>i.id===e.toolCall.id&&e.toolCall.input!==void 0?{...i,input:e.toolCall.input}:i;return{...t,parts:t.parts?.map(i=>i.type==="tool"&&i.tool?{...i,tool:n(i.tool)}:i)}}case"run_command_effect":{let n=e.effect;if(n?.kind!=="visual"||typeof e.toolCallId!="string")return t;let i=o=>{if(o.id!==e.toolCallId)return o;let s=fx(o.frontendOutput)??{},a=(s.effects??[]).filter(c=>c.id!==n.id);return{...o,frontendOutput:{...s,effects:[...a,n]}}};return{...t,parts:t.parts?.map(o=>o.type==="tool"&&o.tool?{...o,tool:i(o.tool)}:o)}}case"tool_call_update":{let n=t.parts?.map(i=>i.type==="tool"&&i.tool?.id===e.toolCall.id?{...i,tool:{...i.tool,executionTraceId:e.toolCall.executionTraceId??i.tool.executionTraceId,status:i.tool.status==="pending"?"running":i.tool.status}}:i)||[];return{...t,parts:n}}case"tool_call_complete":{let n=t.parts?.find(h=>h.type==="tool"&&h.tool?.id===e.toolCall.id)?.tool,i=n?.status==="completed"||n?.status==="declined",o=e.toolCall.result!==void 0||e.toolCall.frontendOutput!==void 0||e.toolCall.status!==void 0||e.toolCall.confirmationState!==void 0||e.toolCall.confirmationData!==void 0;if(i&&!o)return t;let s=null;try{s=typeof e.toolCall.frontendOutput=="string"?JSON.parse(e.toolCall.frontendOutput):e.toolCall.frontendOutput}catch{}let a=s?.success===!1&&s?.error,c=e.toolCall.result?.outcome,u=c==="failure"?"error":c==="rejected"?"declined":c==="aborted"?"stopped":c==="success"?"completed":void 0,l=e.toolCall.status||u||"completed";a&&l==="completed"&&(l="error");let d=l==="awaiting_confirmation",A={...e.toolCall.input!==void 0?{input:e.toolCall.input}:{},...e.toolCall.result!==void 0?{result:e.toolCall.result}:{},status:l,frontendOutput:e.toolCall.frontendOutput,llmOutput:e.toolCall.llmOutput,resultMetadata:e.toolCall.resultMetadata,error:c==="failure"?e.toolCall.result.error.message:a?s.error:null,endTime:d?void 0:new Date,...e.toolCall.confirmationState!==void 0?{confirmationState:e.toolCall.confirmationState}:{},...e.toolCall.confirmationData!==void 0?{confirmationData:e.toolCall.confirmationData}:{}},p=t.parts?.map(h=>h.type==="tool"&&h.tool?.id===e.toolCall.id?{...h,tool:{...h.tool,...A}}:h)||[];return{...t,parts:p}}case"done":{if(!t.isStreaming)return t;let n=(t.parts||[]).map(i=>i.type==="tool"&&i.tool&&i.tool.status!=="awaiting_confirmation"?{...i,tool:hx(i.tool)}:i);return{...t,isStreaming:!1,parts:n,content:""}}default:return t}}function kAe(t){let e=new Set;for(let r of t)for(let n of(0,yg.getMessageToolCalls)(r))n.status==="awaiting_confirmation"&&e.add(n.id);return[...e]}function OAe(t){let e=RAe();return t.map(r=>({...r,parts:r.parts?.map(n=>n.type==="tool"&&n.tool?.status==="awaiting_confirmation"?{...n,tool:{...n.tool,...e}}:n)}))}function UAe(t,e){let r=t.find(i=>i.parts?.some(o=>o.type==="tool"&&o.tool?.id===e));return r?{messages:t.map(i=>i.id===r.id?{...i,isStreaming:!0}:i),targetMessage:{...r,isStreaming:!0}}:{messages:t,targetMessage:null}}function MAe(t){return{id:t.id,name:t.name,status:t.status,input:t.input,result:t.result,frontendOutput:t.frontendOutput,llmOutput:t.llmOutput,resultMetadata:t.resultMetadata,error:t.error,startTime:t.startTime,endTime:t.endTime,confirmationState:t.confirmationState,confirmationData:t.confirmationData}}function xAe(t){let{isStreaming:e,tools:r,...n}=t;return JSON.parse((0,yg.safeStringify)({...n,...t.parts?{parts:t.parts.map(i=>i.type==="tool"&&i.tool?{...i,tool:MAe(i.tool)}:i)}:{}},0))}mt.AGENT_CONTEXT_MEMORY_MESSAGE_ID_PREFIX="context-memory-";function Lb(t){return DAe.TURN_CONTEXT_BLOCK_TYPES.includes(t.contextType??"")}function LAe(t){return t.filter(e=>e.role!=="system"&&e.contextType!=="memory_notes"&&!Lb(e)&&!e.id.startsWith(mt.AGENT_CONTEXT_MEMORY_MESSAGE_ID_PREFIX)).map(e=>({...e,stale:void 0,isStreaming:void 0}))}function PAe(t){return t.filter(e=>!e.stale&&!e.isStreaming&&e.contextType!=="memory_notes"&&!Lb(e)&&!!e.id)}function $Ae(t=[],e=null){return{messages:t,assistantMessageId:e,outcome:"streaming"}}function mg(t,e){return(0,yg.getMessageToolCalls)(t).some(r=>r.id===e)}function gu(t,e){let r=t.assistantMessageId?t.messages.find(i=>i.id===t.assistantMessageId):void 0;if(r)return{state:t,target:r};let n=px(t.assistantMessageId??e.createAssistantMessageId());return{state:{...t,messages:[...t.messages,n],assistantMessageId:n.id},target:n}}function FAe(t,e,r){switch(e.type){case"system_message":{if(!e.systemMessage)return t;let n={id:e.systemMessage.id,role:"system",content:e.systemMessage.content,timestamp:new Date};return{...t,messages:[n,...t.messages]}}case"assistant_message_start":{if(!e.assistantMessageId)return t;let n=t.assistantMessageId?t.messages.find(o=>o.id===t.assistantMessageId):void 0;return t.messages.find(o=>o.id===e.assistantMessageId)?{...t,assistantMessageId:e.assistantMessageId,messages:t.messages.filter(o=>!n||n.id===e.assistantMessageId||o.id!==n.id).map(o=>o.id===e.assistantMessageId?{...o,isStreaming:!0}:o)}:n?{...t,assistantMessageId:e.assistantMessageId,messages:t.messages.map(o=>o.id===n.id?{...o,id:e.assistantMessageId,isStreaming:!0}:o)}:{...t,assistantMessageId:e.assistantMessageId}}case"context_message":{if(!e.contextMessage)return t;let n={id:e.contextMessage.id,role:"user",content:e.contextMessage.content,timestamp:new Date,...e.contextMessage.isHidden?{isHidden:!0}:{},...e.contextMessage.attachedFiles?.length?{attachedFiles:e.contextMessage.attachedFiles}:{}};return{...t,assistantMessageId:null,messages:[...t.messages.map(i=>i.id===t.assistantMessageId?{...i,isStreaming:!1}:i),n]}}case"context_usage":case"compaction_start":return t;case"compaction_complete":{if(!e.compaction)return t;let n=(0,yg.applyAgentCompactionToMessages)(t.messages,e.compaction),i=e.compaction.memoryMessage?t.assistantMessageId:null;return!i||!n.some(o=>o.id===i)?{...t,messages:n}:{...t,assistantMessageId:null,messages:n.map(o=>o.id===i?{...o,isStreaming:!1}:o)}}case"content":{let n=gu(t,r);return{...n.state,messages:n.state.messages.map(i=>i.id===n.target.id?xb(i,e.content||""):i)}}case"error":{let n=gu(t,r);return{...n.state,outcome:"failed",messages:n.state.messages.map(i=>i.id!==n.target.id?i:{...i,parts:[...i.parts||[],{type:"error",content:e.content,errorDetails:e.errorDetails,id:`error-${i.parts?.length??0}`}],isStreaming:!1})}}case"tool_call_start":case"tool_call_update":{if(!e.toolCall)return t;let n=e.type==="tool_call_start"?null:t.messages.find(o=>mg(o,e.toolCall.id))??null,i=n?{state:t,target:n}:gu(t,r);return{...i.state,messages:i.state.messages.map(o=>mu(o,e,i.target))}}case"run_command_effect":{let n=e.toolCallId;if(!n)return t;let i=t.messages.find(o=>mg(o,n));return i?{...t,messages:t.messages.map(o=>mu(o,e,i))}:t}case"tool_call_input":{if(!e.toolCall)return t;let n=t.messages.find(i=>mg(i,e.toolCall.id));return n?{...t,messages:t.messages.map(i=>mu(i,e,n))}:t}case"tool_call_complete":{if(!e.toolCall)return t;let n=t.messages.find(o=>mg(o,e.toolCall.id)),i=n?{state:t,target:n}:gu(t,r);return{...i.state,messages:i.state.messages.map(o=>mu(o,e,i.target))}}case"paused":{let n=gu(t,r);return{...n.state,outcome:"paused",messages:n.state.messages.map(i=>i.id===n.target.id?{...i,isStreaming:!1}:i)}}case"done":{let n=gu(t,r);return{...n.state,outcome:t.outcome==="failed"?"failed":"completed",messages:n.state.messages.map(i=>mu(i,e,n.target))}}default:return t}}});var Eg=m(Dt=>{"use strict";Object.defineProperty(Dt,"__esModule",{value:!0});Dt.PROJECT_LABEL_COLOR_PATTERN=Dt.PROJECT_LABEL_COLORS=Dt.PROJECT_LIMITS=Dt.PROJECT_TASK_STATUSES=Dt.PROJECT_RESOURCE_TYPES=void 0;Dt.nextProjectLabelColor=jAe;Dt.projectResourceKey=zAe;Dt.daysUntilTaskDue=yx;Dt.formatTaskDueDate=HAe;Dt.groupByContext=qAe;Dt.PROJECT_RESOURCE_TYPES=["playbook","artifact","file","tool"];Dt.PROJECT_TASK_STATUSES=["not_started","in_progress","waiting","done"];Dt.PROJECT_LIMITS={name:80,description:500,taskName:120,taskDescription:1e4,taskResources:100,labelName:40,labels:50,taskLabels:10};Dt.PROJECT_LABEL_COLORS=["#6b7280","#ef4444","#f97316","#eab308","#22c55e","#14b8a6","#3b82f6","#6366f1","#a855f7","#ec4899"];Dt.PROJECT_LABEL_COLOR_PATTERN=/^#[0-9a-f]{6}$/;function jAe(t){let e=new Set(t.map(r=>r.color));return Dt.PROJECT_LABEL_COLORS.find(r=>!e.has(r))??Dt.PROJECT_LABEL_COLORS[t.length%Dt.PROJECT_LABEL_COLORS.length]}function zAe(t){return`${t.type}:${t.id}`}function mx(t){let e=new Intl.DateTimeFormat("en-CA",{timeZone:t,year:"numeric",month:"2-digit",day:"2-digit"}).format(new Date);return new Date(`${e}T00:00:00Z`)}function yx(t,e){let r=new Date(`${t}T00:00:00Z`);return Math.round((r.getTime()-mx(e).getTime())/864e5)}function HAe(t,e){let r=new Date(`${t}T00:00:00Z`),n=mx(e),i=yx(t,e);return i===0?"Due today":i===1?"Due tomorrow":i===-1?"Due yesterday":i<-1?`${-i} days overdue`:i<7?`Due ${r.toLocaleDateString(void 0,{weekday:"long",timeZone:"UTC"})}`:`Due ${r.toLocaleDateString(void 0,{day:"numeric",month:"short",timeZone:"UTC",...r.getUTCFullYear()===n.getUTCFullYear()?{}:{year:"numeric"}})}`}function qAe(t){let e=new Map;for(let r of t)e.set(r.context,[...e.get(r.context)??[],r]);return[...e].map(([r,n])=>({context:r,items:n})).sort((r,n)=>+!!r.context-+!!n.context)}});var Ig=m(qr=>{"use strict";Object.defineProperty(qr,"__esModule",{value:!0});qr.RESOURCE_KINDS=qr.RESOURCE_DEFINITIONS=void 0;qr.isResourceKind=GAe;qr.getResourceDefinition=YAe;qr.getResourceAppPath=VAe;qr.RESOURCE_DEFINITIONS={tool:{label:"Tool",pluralLabel:"Tools",collectionKey:"tools",appPath:"/tools",hasDetailPage:!0,memberDefaultPermission:"editor",pickerDefaultPermission:"editor"},credential:{label:"Connection",pluralLabel:"Connections",collectionKey:"credentials",appPath:"/connections",hasDetailPage:!0,pickerDefaultPermission:"viewer"},playbook:{label:"Playbook",pluralLabel:"Playbooks",collectionKey:"playbooks",appPath:"/playbooks",hasDetailPage:!0,pickerDefaultPermission:"editor"},artifact:{label:"Artifact",pluralLabel:"Artifacts",collectionKey:"artifacts",appPath:"/artifacts",hasDetailPage:!0,pickerDefaultPermission:"editor"},file:{label:"File",pluralLabel:"Files",collectionKey:"files",appPath:"/files",hasDetailPage:!1,pickerDefaultPermission:"viewer"},project:{label:"Project",pluralLabel:"Projects",collectionKey:"projects",appPath:"/projects",hasDetailPage:!0,pickerDefaultPermission:"viewer"}};qr.RESOURCE_KINDS=Object.keys(qr.RESOURCE_DEFINITIONS);function GAe(t){return typeof t=="string"&&Object.prototype.hasOwnProperty.call(qr.RESOURCE_DEFINITIONS,t)}function YAe(t){return qr.RESOURCE_DEFINITIONS[t]}function VAe(t,e){let r=qr.RESOURCE_DEFINITIONS[t];return r.hasDetailPage?`${r.appPath}/${encodeURIComponent(e)}`:r.appPath}});var bx=m(Ma=>{"use strict";Object.defineProperty(Ma,"__esModule",{value:!0});Ma.SDK_ERROR_DETAILS_SCHEMA=Ma.SDK_OUTPUT_CONTRACTS=void 0;Ma.toSdkJsonSchema=KAe;var y=ma(),JAe=Eg(),WAe=Ig(),ZAe=xr();function KAe({schema:t}){return y.z.toJSONSchema(t,{target:"draft-7",io:"output",unrepresentable:"any"})}var Ex=y.z.looseObject({statusCode:y.z.number(),headers:y.z.record(y.z.string(),y.z.union([y.z.string(),y.z.array(y.z.string())])),omittedHeaderCount:y.z.number().optional()}),Ix=y.z.looseObject({vfsPath:y.z.string(),storedBytes:y.z.number(),originalOutputBytes:y.z.number(),storageTruncated:y.z.boolean()}),Cx=y.z.object({action:y.z.enum(["approve","reject","oauth_success","oauth_failure"]),source:y.z.enum(["user","automatic"])});function Tn(t){return y.z.looseObject({toolCallId:y.z.string(),toolName:y.z.string(),outcome:y.z.literal("success"),confirmation:Cx.optional(),data:t})}var Pb={http:Ex.optional(),credential:y.z.looseObject({id:y.z.string(),name:y.z.string(),isOwner:y.z.boolean()}).optional().describe("The credential the call ran with."),auth:y.z.looseObject({applied:y.z.enum(["bearer","basic","explicit","none","unavailable"]),header:y.z.string().optional(),placeholders:y.z.array(y.z.string()),reason:y.z.string().optional()}).optional().describe("How authentication was sent: a default Bearer or Basic header, the request's own explicit placeholders, none, or unavailable with the reason. placeholders lists the credential's <<systemId_secretName>> strings."),credentialPlaceholders:y.z.looseObject({keys:y.z.array(y.z.string()),resolved:y.z.boolean()}).optional()},XAe=y.z.discriminatedUnion("protocol",[y.z.looseObject({protocol:y.z.enum(["postgres","odbc"]),data:y.z.array(y.z.record(y.z.string(),y.z.unknown())).describe("Returned database rows."),...Pb}),y.z.looseObject({protocol:y.z.literal("mssql"),data:y.z.union([y.z.array(y.z.record(y.z.string(),y.z.unknown())),y.z.array(y.z.array(y.z.record(y.z.string(),y.z.unknown()))),y.z.looseObject({rowsAffected:y.z.array(y.z.number())})]).describe("One recordset, multiple recordsets, or affected row counts."),...Pb}),y.z.looseObject({protocol:y.z.enum(ZAe.CONNECTION_PROTOCOLS.filter(t=>t!=="postgres"&&t!=="mssql"&&t!=="odbc")),data:y.z.unknown().describe("Complete protocol response payload. Preserve sibling fields, including files and metadata; do not unwrap a nested data field."),...Pb})]),epe=y.z.union([y.z.looseObject({tools:y.z.array(y.z.unknown()).describe("All tools from every tools/list page, each with name and inputSchema.")}),y.z.looseObject({result:y.z.looseObject({content:y.z.array(y.z.unknown()).optional(),structuredContent:y.z.unknown().optional(),isError:y.z.boolean().optional()}).describe("The tools/call result with content blocks and optional structuredContent.")})]),tpe=y.z.looseObject({url:y.z.string().describe("The requested URL."),status:y.z.number(),statusText:y.z.string(),headers:y.z.record(y.z.string(),y.z.string()),body:y.z.string().describe("Response body bytes, base64-encoded."),systemId:y.z.string().optional().describe("The system whose credential authenticated the request."),credential:y.z.looseObject({id:y.z.string(),name:y.z.string(),isOwner:y.z.boolean()}).optional().describe("The credential the request ran with.")}),rpe=y.z.looseObject({stepId:y.z.string(),success:y.z.boolean(),data:y.z.unknown().optional(),error:y.z.string().nullable().optional(),http:Ex.optional(),stepFileKeys:y.z.array(y.z.string()).optional()}),npe=y.z.looseObject({toolId:y.z.string(),success:y.z.boolean(),run:y.z.looseObject({id:y.z.string()}).optional(),data:y.z.unknown().optional().describe("Tool output, determined by its output transform."),error:y.z.string().optional(),stepResults:y.z.array(rpe),fileArtifacts:y.z.array(y.z.looseObject({fileKey:y.z.string(),filename:y.z.string(),contentType:y.z.string(),size:y.z.number(),downloadUrl:y.z.string().optional()})).optional(),warnings:y.z.array(y.z.string()).optional(),inputSchema:y.z.unknown().optional(),resultMetadata:Ix.optional()}),ipe=Tn(y.z.looseObject({resource:y.z.looseObject({id:y.z.string(),name:y.z.string().optional(),version:y.z.union([y.z.number(),y.z.string()]).optional()}),created:y.z.boolean(),projectId:y.z.string().optional(),addedFiles:y.z.array(y.z.looseObject({id:y.z.string(),fileName:y.z.string()})).optional(),projectAttribution:y.z.looseObject({attached:y.z.boolean(),projectId:y.z.string(),projectName:y.z.string().optional(),resource:y.z.looseObject({type:y.z.enum(JAe.PROJECT_RESOURCE_TYPES),id:y.z.string()}),error:y.z.string().optional()}).optional()}));Ma.SDK_OUTPUT_CONTRACTS={assignSessionToProject:{name:"SuperglueSessionProjectResult",schema:Tn(y.z.object({sessionId:y.z.string(),projectId:y.z.string().nullable()})),description:"Returns the saved session ID and project ID, or null when unassigned. Throws SuperglueError on failure."},callSystem:{name:"SuperglueCallSystemResult",schema:XAe,description:"Returns the complete protocol payload in data, available HTTP metadata, the credential used, and how authentication was sent. Throws SuperglueError on failure; details contains the canonical result and unprojected execution output."},callMcp:{name:"SuperglueCallMcpResult",schema:epe,description:"Returns { tools } when tool is omitted, or { result } from tools/call. Throws SuperglueError on HTTP, JSON-RPC, or result.isError failures; details.result.data contains statusCode, rpcError, or the failed result."},systemFetch:{name:"SuperglueSystemFetchResult",schema:tpe,description:"Returns the raw HTTP response: status, headers, and the base64 body. HTTP error statuses are returned, not thrown. Throws SuperglueError when the request cannot be authenticated or sent."},runTool:{name:"SuperglueRunToolResult",schema:npe,description:"Returns successful tool output, step results, files, and available result reference. Throws SuperglueError on failure; details.result.data preserves this result shape with success: false, the error, and available run and step results. details.resultMetadata references the saved failed result when available."},writeResource:{name:"SuperglueWriteResult",schema:ipe,description:"Returns saved resource identity, creation status, and available project attribution or added files. Throws SuperglueError on failure."},installBundle:{name:"SuperglueBundleInstallResult",schema:Tn(y.z.looseObject({bundleId:y.z.string(),system:y.z.looseObject({id:y.z.string(),name:y.z.string(),requiredCredentialKeys:y.z.array(y.z.string()),hasUserCredentials:y.z.boolean()}),tools:y.z.array(y.z.looseObject({id:y.z.string(),name:y.z.string().optional()})),mcpServer:y.z.looseObject({id:y.z.string(),name:y.z.string()}).optional(),playbook:y.z.looseObject({id:y.z.string(),name:y.z.string()}).optional()})),description:"Returns the installed system ID, tool, MCP server, and playbook identities, the secret names the user must supply, and whether the user has a complete connection. Throws SuperglueError on failure."},stopBackgroundJob:{name:"SuperglueStopBackgroundJobResult",schema:Tn(y.z.looseObject({job:y.z.looseObject({id:y.z.string(),status:y.z.string(),elapsedMs:y.z.number(),exitCode:y.z.number().optional()})})),description:"Returns the job's status, run time, and exit code after it ended, or status running when the stop is still in progress. Throws SuperglueError when the session has no such running job."},setToolState:{name:"SuperglueToolStateResult",schema:Tn(y.z.looseObject({resource:y.z.looseObject({id:y.z.string()}),action:y.z.enum(["set","reset"])})),description:"Returns the saved tool identity and state action. Throws SuperglueError on failure."},shareResource:{name:"SuperglueShareResult",schema:Tn(y.z.looseObject({resource:y.z.looseObject({kind:y.z.enum(WAe.RESOURCE_KINDS),id:y.z.string()})})),description:"Returns the shared resource identity. Throws SuperglueError on failure."},showVisual:{name:"SuperglueShowVisualResult",schema:Tn(y.z.looseObject({visualId:y.z.string(),check:y.z.looseObject({errors:y.z.array(y.z.string()),blockedRequests:y.z.array(y.z.string()),dataCalls:y.z.array(y.z.string()),contentHeight:y.z.number().optional(),timedOut:y.z.boolean()}).optional(),checkSkipped:y.z.string().optional(),screenshots:y.z.array(y.z.string()).optional()})),description:"Returns the visualId shown to the user. For a custom visual, check holds the test-browser result, and screenshots lists the labels of the screenshots attached to this command's result for you. Throws SuperglueError ETOOL when the visual fails its check; error.details.result.data.check then holds the errors."},notifyUser:{name:"SuperglueNotifyResult",schema:Tn(y.z.looseObject({nextStepIds:y.z.array(y.z.string())})),description:"Returns the nextStepIds of the saved actions, in action order. Throws SuperglueError on failure."},writeOrgSettings:{name:"SuperglueOrgSettingsResult",schema:Tn(y.z.looseObject({updated:y.z.array(y.z.enum(["name","preferences","notifications"])),notificationTest:y.z.looseObject({channel:y.z.enum(["slack","email"]),sent:y.z.boolean(),error:y.z.string().optional()}).optional()})),description:"Returns updated settings and any notification test result. Throws SuperglueError on failure."},writeDesignSystem:{name:"SuperglueDesignSystemResult",schema:Tn(y.z.looseObject({updated:y.z.array(y.z.enum(["tokens","guidelines","logo"])),added:y.z.array(y.z.looseObject({id:y.z.string(),kind:y.z.enum(["logo","font","template","reference"]),name:y.z.string()})),changed:y.z.array(y.z.string()),removed:y.z.array(y.z.string())})),description:"Returns the changed design-system parts and file ids. Throws SuperglueError on failure."},importDesignSystemFromUrl:{name:"SuperglueDesignSystemImportResult",schema:Tn(y.z.looseObject({url:y.z.string(),title:y.z.string().nullable(),tokens:y.z.looseObject({}),palette:y.z.array(y.z.looseObject({color:y.z.string(),weight:y.z.number()})),fonts:y.z.array(y.z.looseObject({family:y.z.string(),usage:y.z.array(y.z.string()),source:y.z.string()})),fontFiles:y.z.array(y.z.looseObject({file:y.z.string(),family:y.z.string().describe("CSS family name the website uses"),roles:y.z.array(y.z.string()),weight:y.z.string(),style:y.z.enum(["normal","italic"])})),logos:y.z.array(y.z.looseObject({file:y.z.string(),source:y.z.string(),width:y.z.number(),height:y.z.number(),light:y.z.boolean().describe("Light artwork meant for dark backgrounds")})),screenshot:y.z.string().nullable()})),description:"Returns a proposed design system from the website; font files, logos, and the screenshot are file:: session uploads. Throws SuperglueError on failure."},readQbm:{name:"SuperglueReadQbmResult",schema:Tn(y.z.looseObject({folder:y.z.string(),objects:y.z.array(y.z.looseObject({type:y.z.string(),files:y.z.array(y.z.string()),records:y.z.number()})),rawTables:y.z.array(y.z.looseObject({table:y.z.string(),files:y.z.array(y.z.string()),rows:y.z.number()})),encryptedValues:y.z.array(y.z.looseObject({table:y.z.string(),column:y.z.string(),values:y.z.number()})),unmappedCodes:y.z.array(y.z.looseObject({field:y.z.string(),code:y.z.string(),records:y.z.number()})).optional(),attachments:y.z.looseObject({documents:y.z.number(),note:y.z.string()}).optional(),rejectedRows:y.z.array(y.z.looseObject({table:y.z.string(),rows:y.z.number()})).optional()})),description:"Returns the folder that holds the extracted files, record counts per object type and raw table, encrypted columns, codes the reader cannot decode, and expected attachments. The folder also holds coverage.json.raw with the same summary plus the mapped source tables. Throws SuperglueError on failure."},previewArtifact:{name:"SuperglueArtifactPreviewResult",schema:y.z.looseObject({draftId:y.z.string(),bytes:y.z.number()}),description:"Returns the artifact draft identity and byte count. Throws SuperglueError on failure."}};var ope=y.z.looseObject({code:y.z.string(),path:y.z.array(y.z.union([y.z.string(),y.z.number(),y.z.symbol()])),message:y.z.string()});Ma.SDK_ERROR_DETAILS_SCHEMA=y.z.discriminatedUnion("kind",[y.z.looseObject({kind:y.z.literal("tool_result"),resultMetadata:Ix.optional(),result:y.z.looseObject({toolCallId:y.z.string(),toolName:y.z.string(),outcome:y.z.enum(["success","failure","rejected","aborted"]),confirmation:Cx.optional(),error:y.z.looseObject({message:y.z.string()}).optional(),data:y.z.unknown().optional()}),output:y.z.unknown().describe("Unprojected execution output, including the original error and any available response data or metadata.")}),y.z.looseObject({kind:y.z.enum(["input_validation","output_validation"]),toolName:y.z.string(),issues:y.z.array(ope),output:y.z.unknown().optional()})])});var Ox=m(we=>{"use strict";Object.defineProperty(we,"__esModule",{value:!0});we.SERVER_OWNED_SESSION_RESOURCE_KINDS=we.AgentRequestValidationError=we.AGENT_TOOL_CONTINUATION_ACTION_BY_CONFIRMATION_STATE=we.AGENT_TOOL_CONTINUATION_ACTIONS=we.AGENT_IDENTIFIER_PATTERN=we.AGENT_REQUEST_LIMITS=void 0;we.validateAgentRequestPayload=Dx;we.validateResourceBinding=Tx;we.validateClientResourceBinding=Rx;we.validateAgentSessionIdentity=Nx;we.validateAgentSessionTarget=kx;we.validateAgentRequestSubmission=Ape;we.isAgentMessagePayload=ppe;we.isAgentToolContinuationPayload=fpe;var Ho=xr();we.AGENT_REQUEST_LIMITS={messageContentChars:5e4,identifierChars:256,attachedFiles:20,toolContinuations:20,continuationInputChars:1e5,frontendDraftsChars:2e6,accessRulesContextChars:2e6,pendingMessagesPerSession:10};we.AGENT_IDENTIFIER_PATTERN=/^[A-Za-z0-9._-]+$/;we.AGENT_TOOL_CONTINUATION_ACTIONS=["approve","reject","oauth_success","oauth_failure"];we.AGENT_TOOL_CONTINUATION_ACTION_BY_CONFIRMATION_STATE={[Ho.ConfirmationAction.CONFIRMED]:"approve",[Ho.ConfirmationAction.DECLINED]:"reject",[Ho.ConfirmationAction.OAUTH_SUCCESS]:"oauth_success",[Ho.ConfirmationAction.OAUTH_FAILURE]:"oauth_failure"};var Cg=class extends Error{constructor(e){super(e),this.name="AgentRequestValidationError"}};we.AgentRequestValidationError=Cg;function Ye(t){throw new Cg(t)}function po(t,e){return(!t||typeof t!="object"||Array.isArray(t))&&Ye(`${e} must be an object`),t}function xa(t,e){(typeof t!="string"||!t.trim())&&Ye(`${e} must be a non-empty string`);let r=t.trim();return r.length>we.AGENT_REQUEST_LIMITS.identifierChars&&Ye(`${e} exceeds ${we.AGENT_REQUEST_LIMITS.identifierChars} characters`),we.AGENT_IDENTIFIER_PATTERN.test(r)||Ye(`${e} may only contain letters, numbers, dots, underscores, and hyphens`),r}function spe(t,e){return typeof t!="boolean"&&Ye(`${e} must be a boolean`),t}function $b(t,e){try{return JSON.stringify(t).length}catch{return Ye(`${e} must be JSON-serializable`)}}function ape(t,e){if(t!==void 0)return Array.isArray(t)||Ye(`${e} must be an array`),t.length>we.AGENT_REQUEST_LIMITS.attachedFiles&&Ye(`${e} exceeds ${we.AGENT_REQUEST_LIMITS.attachedFiles} entries`),t.map((r,n)=>{let i=po(r,`${e}[${n}]`);return{...i,key:xa(i.key,`${e}[${n}].key`)}})}function Sx({value:t,label:e,requireHidden:r}){let n=po(t,e),i=xa(n.id,`${e}.id`);typeof n.content!="string"&&Ye(`${e}.content must be a string`);let o=n.content;o.length>we.AGENT_REQUEST_LIMITS.messageContentChars&&Ye(`${e}.content exceeds ${we.AGENT_REQUEST_LIMITS.messageContentChars} characters`);let s=spe(n.isHidden,`${e}.isHidden`);r&&!s&&Ye(`${e}.isHidden must be true`);let a=ape(n.attachedFiles,`${e}.attachedFiles`);return!o.trim()&&!a?.length&&Ye(`${e}.content may only be empty when an attachment is present`),{id:i,content:o,isHidden:s,...a?{attachedFiles:a}:{}}}function Bx(t){if(t===void 0)return;let e=po(t,"frontendDrafts");return $b(e,"frontendDrafts")>we.AGENT_REQUEST_LIMITS.frontendDraftsChars&&Ye(`frontendDrafts exceeds ${we.AGENT_REQUEST_LIMITS.frontendDraftsChars} characters`),e}function _x(t){if(t===void 0)return;let e=po(t,"accessRulesContext");return $b(e,"accessRulesContext")>we.AGENT_REQUEST_LIMITS.accessRulesContextChars&&Ye(`accessRulesContext exceeds ${we.AGENT_REQUEST_LIMITS.accessRulesContextChars} characters`),e}function Qx(t){if(t!==void 0)return(typeof t!="string"||!Ho.AGENT_APPROVAL_MODES.includes(t))&&Ye(`request.approvalMode must be one of: ${Ho.AGENT_APPROVAL_MODES.join(", ")}`),t}function vx(t,e){let r=po(t,e),n=xa(r.toolCallId,`${e}.toolCallId`);return(typeof r.action!="string"||!we.AGENT_TOOL_CONTINUATION_ACTIONS.includes(r.action))&&Ye(`${e}.action must be one of: ${we.AGENT_TOOL_CONTINUATION_ACTIONS.join(", ")}`),r.input!==void 0&&$b(r.input,`${e}.input`)>we.AGENT_REQUEST_LIMITS.continuationInputChars&&Ye(`${e}.input exceeds ${we.AGENT_REQUEST_LIMITS.continuationInputChars} characters`),{toolCallId:n,action:r.action,...r.input!==void 0?{input:r.input}:{}}}function cpe(t){if(t===void 0)return;(!Array.isArray(t)||t.length===0)&&Ye("request.toolContinuations must be a non-empty array"),t.length>we.AGENT_REQUEST_LIMITS.toolContinuations&&Ye(`request.toolContinuations exceeds ${we.AGENT_REQUEST_LIMITS.toolContinuations} entries`);let e=t.map((r,n)=>vx(r,`request.toolContinuations[${n}]`));return new Set(e.map(({toolCallId:r})=>r)).size!==e.length&&Ye("request.toolContinuations must not contain duplicate toolCallId values"),e}function wx(t,e){if(t===void 0)return;(typeof t!="string"||!t.trim())&&Ye(`${e} must be a non-empty string`);let r=t.trim();return r.length>we.AGENT_REQUEST_LIMITS.messageContentChars&&Ye(`${e} exceeds ${we.AGENT_REQUEST_LIMITS.messageContentChars} characters`),r}var upe=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function lpe(t){let e=Sx({value:t.message,label:"request.message"}),r=wx(t.title,"request.title"),n=wx(t.titleInput,"request.titleInput"),i=t.hiddenSteeringMessage===void 0?void 0:Sx({value:t.hiddenSteeringMessage,label:"request.hiddenSteeringMessage",requireHidden:!0});i&&i.id===e.id&&Ye("request.hiddenSteeringMessage.id must differ from request.message.id");let o=cpe(t.toolContinuations),s=Qx(t.approvalMode),a=Bx(t.frontendDrafts),c=_x(t.accessRulesContext);return t.nextStepId!==void 0&&(typeof t.nextStepId!="string"||!upe.test(t.nextStepId))&&Ye("request.nextStepId must be a UUID"),{kind:"message",message:e,...t.nextStepId?{nextStepId:t.nextStepId}:{},...i?{hiddenSteeringMessage:i}:{},...r?{title:r}:{},...n?{titleInput:n}:{},...o?{toolContinuations:o}:{},...s?{approvalMode:s}:{},...a?{frontendDrafts:a}:{},...c?{accessRulesContext:c}:{}}}function dpe(t){let e=vx(t,"request"),r=Qx(t.approvalMode),n=Bx(t.frontendDrafts),i=_x(t.accessRulesContext);return{kind:"tool_continuation",...e,...r?{approvalMode:r}:{},...n?{frontendDrafts:n}:{},...i?{accessRulesContext:i}:{}}}function Dx(t){let e=po(t,"request");return e.kind==="message"?lpe(e):e.kind==="tool_continuation"?dpe(e):Ye('request.kind must be "message" or "tool_continuation"')}function Tx(t,e){let r=po(t,e);return(typeof r.kind!="string"||!Ho.AGENT_SESSION_RESOURCE_KINDS.includes(r.kind))&&Ye(`${e}.kind must be one of: ${Ho.AGENT_SESSION_RESOURCE_KINDS.join(", ")}`),{kind:r.kind,id:xa(r.id,`${e}.id`)}}we.SERVER_OWNED_SESSION_RESOURCE_KINDS=["briefing"];function Rx(t,e){let r=Tx(t,e);return we.SERVER_OWNED_SESSION_RESOURCE_KINDS.includes(r.kind)&&Ye(`${e}.kind "${r.kind}" is assigned by the server`),r}function Nx(t,e="session.createIfMissing"){let r=po(t,e),n=r.projectId===void 0?void 0:xa(r.projectId,`${e}.projectId`),i=r.taskId===void 0?void 0:xa(r.taskId,`${e}.taskId`);i&&!n&&Ye(`${e}.taskId requires ${e}.projectId`);let o=Object.values(Ho.AgentType);(typeof r.agentId!="string"||!o.includes(r.agentId))&&Ye(`${e}.agentId must be one of: ${o.join(", ")}`);let s=r.resourceBinding===void 0?void 0:Rx(r.resourceBinding,`${e}.resourceBinding`);return{agentId:r.agentId,...n?{projectId:n}:{},...i?{taskId:i}:{},...s?{resourceBinding:s}:{}}}function kx(t){let e=po(t,"session"),r=e.createIfMissing===void 0?void 0:Nx(e.createIfMissing);return{id:xa(e.id,"session.id"),...r?{createIfMissing:r}:{}}}function Ape(t){let e=po(t,"body");return{session:kx(e.session),request:Dx(e.request)}}function ppe(t){return t.kind==="message"}function fpe(t){return t.kind==="tool_continuation"}});var Mx=m(Ve=>{"use strict";Object.defineProperty(Ve,"__esModule",{value:!0});Ve.ARTIFACT_EXPORT_FORMATS=Ve.ARTIFACT_RESPONSE_RESERVED_FIELD_NAMES=Ve.ARTIFACT_RESPONSE_PATCH_DEBOUNCE_MS=Ve.MAX_SPREADSHEET_ARTIFACT_BYTES=Ve.MAX_HTML_ARTIFACT_IMAGE_BYTES=Ve.MAX_HTML_ARTIFACT_BYTES=Ve.MAX_SPREADSHEET_CELL_TEXT_LENGTH=Ve.MAX_SPREADSHEET_SHEET_NAME_LENGTH=Ve.MAX_SPREADSHEET_GRID_CELLS=Ve.MAX_SPREADSHEET_SHEETS=Ve.SPREADSHEET_CELL_TYPES=void 0;Ve.isValidSpreadsheetCell=mpe;Ve.isArtifactExportFormat=ype;Ve.isArtifactExportFormatForKind=Epe;var Ux=ma();Ve.SPREADSHEET_CELL_TYPES=["text","integer","number","percent","currency","boolean","date","datetime"];Ve.MAX_SPREADSHEET_SHEETS=20;Ve.MAX_SPREADSHEET_GRID_CELLS=1e6;Ve.MAX_SPREADSHEET_SHEET_NAME_LENGTH=31;Ve.MAX_SPREADSHEET_CELL_TEXT_LENGTH=32767;var hpe=Ux.z.iso.date(),gpe=Ux.z.iso.datetime({offset:!0});function mpe(t,e){return t===null?!0:e==="text"?typeof t=="string"&&t.length<=Ve.MAX_SPREADSHEET_CELL_TEXT_LENGTH:e==="boolean"?typeof t=="boolean":["integer","number","percent","currency"].includes(e)?typeof t=="number"&&Number.isFinite(t)&&(e!=="integer"||Number.isInteger(t)):typeof t!="string"?!1:(e==="datetime"?gpe:hpe).safeParse(t).success}Ve.MAX_HTML_ARTIFACT_BYTES=1024*1024;Ve.MAX_HTML_ARTIFACT_IMAGE_BYTES=12*1024*1024;Ve.MAX_SPREADSHEET_ARTIFACT_BYTES=10*1024*1024;Ve.ARTIFACT_RESPONSE_PATCH_DEBOUNCE_MS=300;Ve.ARTIFACT_RESPONSE_RESERVED_FIELD_NAMES=new Set(["__proto__","constructor","prototype"]);Ve.ARTIFACT_EXPORT_FORMATS=["html","pdf","docx","xlsx","pptx"];function ype(t){return Ve.ARTIFACT_EXPORT_FORMATS.some(e=>e===t)}function Epe(t,e,r=!1){return t==="spreadsheet"?e==="xlsx":r?e==="html"||e==="pdf"||e==="pptx":e!=="pptx"}});var Fx=m(ze=>{"use strict";Object.defineProperty(ze,"__esModule",{value:!0});ze.API_KEY_ACTION_LABELS=ze.API_KEY_SURFACE_LABELS=ze.API_KEY_SCOPES=ze.API_KEY_SURFACE_ACTIONS=ze.API_KEY_ACTIONS=ze.API_KEY_SURFACES=void 0;ze.getApiKeySurface=Lx;ze.getApiKeyAction=Px;ze.getApiKeySurfaceActions=Fb;ze.parseApiKeyScopes=$x;ze.validateApiKeyScopesInput=Spe;ze.isApiKeyScopeAllowed=wpe;ze.formatApiKeyScopes=Bpe;ze.API_KEY_SURFACES=["api","mcp"];ze.API_KEY_ACTIONS=["read","write","execute"];ze.API_KEY_SURFACE_ACTIONS={api:ze.API_KEY_ACTIONS,mcp:["execute"]};ze.API_KEY_SCOPES=ze.API_KEY_SURFACES.flatMap(t=>ze.API_KEY_SURFACE_ACTIONS[t].map(e=>`${t}:${e}`));ze.API_KEY_SURFACE_LABELS={api:"API & CLI",mcp:"MCP"};ze.API_KEY_ACTION_LABELS={read:"Read",write:"Write",execute:"Execute"};var xx=new Set(ze.API_KEY_SCOPES),Ipe={"/v1/tools":["read"],"/v1/tools/:toolId/run":["execute"],"/v1/authenticate":["write"],"/v1/memory-notes":["read","write"]},Cpe=new Set(["/v1/api-keys","/v1/api-keys/:id","/v1/api-keys/:id/reveal"]),bpe=new Set(["/v1/me"]);function Lx(t){let e=t.split("?")[0];return e==="/mcp"||e.startsWith("/mcp/")?"mcp":"api"}function Px(t){return t==="read"?"read":t==="execute"?"execute":"write"}function Fb(t,e){return ze.API_KEY_SURFACE_ACTIONS[e].filter(r=>(t||[]).includes(`${e}:${r}`))}function $x(t){if(!Array.isArray(t))return null;let e=[...new Set(t.filter(r=>xx.has(r)))];return e.length>0?e:null}function Spe(t){if(t==null)return{scopes:null};let e=`Valid scopes: ${ze.API_KEY_SCOPES.join(", ")}. Use null for full access.`;if(!Array.isArray(t)||t.length===0)return{error:`scopes must be a non-empty array of API key scopes. ${e}`};let r=t.filter(n=>!xx.has(n));return r.length>0?{error:`Unknown API key scope(s): ${r.map(String).join(", ")}. ${e}`}:{scopes:$x(t)}}function wpe({scopes:t,path:e,type:r}){if(!t||t.length===0)return!0;let n=e.split("?")[0];if(Cpe.has(n))return!1;if(bpe.has(n))return!0;let i=Px(r),o=Lx(n);return o==="api"&&Ipe[n]?.some(s=>s===r)&&Fb(t,"mcp").length>0?!0:t.includes(`${o}:${i}`)}function Bpe(t){return!t||t.length===0?"Full access":ze.API_KEY_SURFACES.map(e=>({surface:e,actions:Fb(t,e)})).filter(e=>e.actions.length>0).map(e=>ze.API_KEY_SURFACE_ACTIONS[e.surface].length===1?ze.API_KEY_SURFACE_LABELS[e.surface]:`${ze.API_KEY_SURFACE_LABELS[e.surface]} ${e.actions.join("/")}`).join(", ")}});var jx=m(jb=>{"use strict";Object.defineProperty(jb,"__esModule",{value:!0});jb.isValidEmail=_pe;function _pe(t){return/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*\.[a-zA-Z]{1,}$/.test(t)}});var Hx=m(yt=>{"use strict";Object.defineProperty(yt,"__esModule",{value:!0});yt.GATEWAY_UNINSTALL_COMMANDS=yt.GATEWAY_API_KEY_NAME_PREFIX=yt.GATEWAY_TARGET_NAME_PATTERN=yt.GATEWAY_SETUP_GUIDE_URL=yt.GATEWAY_DOWNLOAD_BASE_URL=yt.GATEWAY_INSTALL_TOKEN_PREFIX=void 0;yt.getGatewayServerUrl=zx;yt.buildGatewayInstallToken=vpe;yt.buildGatewayInstallCommand=Dpe;yt.getGatewayApiKeyName=Tpe;yt.GATEWAY_INSTALL_TOKEN_PREFIX="sgi1.";yt.GATEWAY_DOWNLOAD_BASE_URL="https://downloads.superglue.cloud";yt.GATEWAY_SETUP_GUIDE_URL="https://superglue.ai/docs/guides/secure-gateway/";yt.GATEWAY_TARGET_NAME_PATTERN=/^[a-z0-9]([a-z0-9_-]{0,61}[a-z0-9])?$/;function zx(t){let e=new URL(t);return e.protocol=e.protocol==="http:"?"ws:":"wss:",e.pathname=`${e.pathname.replace(/\/+$/,"")}/ws/tunnels`,e.search="",e.hash="",e.toString()}function Qpe(t){let e=new TextEncoder().encode(t),r="";for(let n of e)r+=String.fromCharCode(n);return btoa(r).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function vpe(t){let e={v:1,serverUrl:zx(t.apiEndpoint),tunnelId:t.tunnelId,apiKey:t.apiKey,targets:t.targets,enableScriptRunner:t.enableScriptRunner};return yt.GATEWAY_INSTALL_TOKEN_PREFIX+Qpe(JSON.stringify(e))}function Dpe(t,e){return t==="windows"?['$ErrorActionPreference = "Stop"',"[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor 3072",'$ProgressPreference = "SilentlyContinue"','$gateway = "$env:TEMP\\superglue-gateway.exe"',"Remove-Item $gateway -Force -ErrorAction SilentlyContinue",`Invoke-WebRequest -UseBasicParsing "${yt.GATEWAY_DOWNLOAD_BASE_URL}/superglue-gateway-windows.exe" -OutFile $gateway`,`"${e}" | & $gateway install -`].join("; "):["d=$(mktemp -d)",`u="${yt.GATEWAY_DOWNLOAD_BASE_URL}/superglue-gateway-linux-$(uname -m | sed 's/aarch64/arm64/')"`,'s=$([ "$(id -u)" -eq 0 ] || echo sudo)','{ if command -v curl >/dev/null; then curl -fsSL -o "$d/superglue-gateway" "$u"; else wget -qO "$d/superglue-gateway" "$u"; fi; }','$s install -m 0755 "$d/superglue-gateway" /usr/local/bin/superglue-gateway',`echo '${e}' | $s /usr/local/bin/superglue-gateway install -`].join(" && ")}yt.GATEWAY_API_KEY_NAME_PREFIX="Gateway: ";function Tpe(t){return yt.GATEWAY_API_KEY_NAME_PREFIX+t}yt.GATEWAY_UNINSTALL_COMMANDS={windows:'& "C:\\Program Files\\superglue Gateway\\superglue-gateway.exe" uninstall',linux:"sudo /usr/local/bin/superglue-gateway uninstall"}});var Sg=m(Ce=>{"use strict";Object.defineProperty(Ce,"__esModule",{value:!0});Ce.OAUTH_CONFIG_CREDENTIAL_KEYS=void 0;Ce.hasMeaningfulValue=Et;Ce.stringValue=qt;Ce.validateOAuthConnection=Fpe;Ce.formatOAuthConnectionDisabledReason=zpe;Ce.objectValue=Go;Ce.parseScopes=jd;Ce.normalizeGrantType=zd;Ce.normalizeOAuthClientMode=qb;Ce.normalizeSystemAuthentication=Ar;Ce.resolveOAuthClientMode=qpe;Ce.flattenSystemAuthentication=Jx;Ce.maskedFlatSystemAuthentication=Gpe;Ce.isMaskedSecretValue=Wx;Ce.pickAgentAuthInputFields=Ype;Ce.maskSystemAuthenticationForResponse=Vpe;Ce.restoreMaskedClientSecret=Jpe;Ce.mapAgentAuthInput=Zx;Ce.mergeAgentAuthInput=ofe;Ce.getAuthenticationConfigCredentialKeys=Kx;Ce.buildAuthenticationEditorModel=sfe;Ce.getCredentialRequirements=afe;Ce.isCredentialRequirementSatisfied=Xx;Ce.hasUnsatisfiedCredentialRequirements=cfe;Ce.updateAuthenticationEditorField=ufe;Ce.validateOAuthAuthenticationConfigPlacement=eL;Ce.authenticationToLegacyCredentials=tL;Ce.isRuntimeCredentialMetadataKey=lfe;Ce.resolveCredentialAuthentication=dfe;Ce.buildRuntimeCredentialsFromAuthentication=Afe;Ce.resolveOAuthConfigFromAuthentication=pfe;Ce.toCredentialInputValue=Gb;Ce.getCredentialEntries=ffe;Ce.getCredentialInputValues=hfe;Ce.getCredentialDisplayHiddenKeys=gfe;Ce.hasOAuthTokenCredentials=mfe;Ce.getOAuthExpiryText=yfe;Ce.hasRuntimeCredentialValues=Efe;Ce.validateCredentialObjectKeys=Ife;Ce.validateCredentialKeyList=Cfe;Ce.mapOAuthMissingFieldsForAgent=bfe;Ce.validateOAuthAuthenticationAndCredentialInputs=Sfe;var Tt=Dn(),Rpe=pu();Ce.OAUTH_CONFIG_CREDENTIAL_KEYS=["auth_url","authUrl","token_url","tokenUrl","token_uri","scopes","scope","grant_type","grantType","oauthClientMode","client_id","clientId","client_secret","clientSecret","tokenAuthMethod","tokenContentType","usePKCE","extraHeaders","extraBodyParams"];var bg=["host","port","database","path","homeDirectory"],Vx=["type","oauthClientMode","grantType","authUrl","tokenUrl","scopes","clientId","clientSecret","tokenAuthMethod","tokenContentType","usePKCE","extraHeaders","extraBodyParams","resource","protocol",...bg],Npe=new Set(Vx),kpe="type, oauthClientMode, grantType, authUrl, tokenUrl, scopes, clientId, clientSecret, tokenAuthMethod, tokenContentType, usePKCE, extraHeaders, extraBodyParams, resource, protocol, host, port, database, path, homeDirectory",Ope=["grantType","authUrl","tokenUrl","scopes","clientId","clientSecret"],Upe={grantType:["grantType","grant_type"],authUrl:["authUrl","auth_url"],tokenUrl:["tokenUrl","token_url","token_uri"],scopes:["scopes","scope"],clientId:["clientId","client_id"],clientSecret:["clientSecret","client_secret"]},Fd=["tokenAuthMethod","tokenContentType","usePKCE","extraHeaders","extraBodyParams","resource"],Mpe=new Set(Ope),xpe=new Set(["access_token","accessToken","refresh_token","refreshToken","expires_at","expiresAt","expires_in","expiresIn","expiry","token_type","tokenType"]),Lpe=["access_token","refresh_token","api_key","bearer_token","token","client_id","client_secret","auth_url","token_url","scopes","grant_type","token_type","expires_at","expiry","expires_in","host","hostname","port","database","dbname","db","username","password"],qx=new Map(Lpe.map((t,e)=>[(0,Tt.normalizeCredentialKey)(t),e]));function La(t){return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}function zb({config:t,key:e,value:r}){let n={...t||{}};return Et(r)?n[e]=r:delete n[e],Object.keys(n).length>0?n:void 0}function Et(t){return(0,Tt.hasCredentialValue)(t)}function qt(t){if(Et(t))return typeof t=="string"?t:String(t)}var Ppe={"grant_type authorization_code or client_credentials":"authorization_code or client_credentials",client_id:"client ID",token_url:"token URL",auth_url:"authorization URL","client_secret or usePKCE":"client secret or PKCE","client_secret or oauth_cert + oauth_key":"client secret or OAuth certificate and key"};function qo(...t){return t.find(e=>Et(e))}function $pe(t){return t===!0||t==="true"}function Fpe(t){let e=t||{},r=qt(qo(e.grant_type,e.grantType)),n=r==="client_credentials"?"client_credentials":"authorization_code",i=r&&r!=="authorization_code"&&r!=="client_credentials",o=qo(e.client_id,e.clientId),s=qo(e.client_secret,e.clientSecret),a=qo(e.auth_url,e.authUrl),c=qo(e.token_url,e.tokenUrl,e.token_uri),u=qo(e.oauth_cert,e.oauthCert),l=qo(e.oauth_key,e.oauthKey),d=Et(u)&&Et(l)||e.hasServerSideCertificateCredentials===!0,A=e.hasServerSideClientSecret===!0,p=Et(s)||A,h=$pe(qo(e.usePKCE,e.usePkce)),g=[];return i&&g.push("grant_type authorization_code or client_credentials"),Et(o)||g.push("client_id"),Et(c)||g.push("token_url"),n==="client_credentials"?!p&&!d&&g.push("client_secret or oauth_cert + oauth_key"):(Et(a)||g.push("auth_url"),!p&&!h&&g.push("client_secret or usePKCE")),{grantType:n,hasAccessToken:Et(qo(e.access_token,e.accessToken)),hasCertificateCredentials:d,isReadyToConnect:g.length===0,missingFields:g,usePKCE:h}}function jpe(t){return t.length<=1?t[0]||"":t.length===2?`${t[0]} and ${t[1]}`:`${t.slice(0,-1).join(", ")}, and ${t[t.length-1]}`}function zpe(t){if(!t||t.isReadyToConnect)return null;let e=t.missingFields.map(r=>Ppe[r]||r);return`OAuth connection is disabled because ${jpe(e)} ${e.length===1?"is":"are"} missing.`}function Go(t){if(!(!t||typeof t!="object"||Array.isArray(t)))return t}function fo(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function jd(t){if(Array.isArray(t))return t.map(String).filter(Boolean);if(Et(t)){if(typeof t=="string"){let e=t.trim().split(/[,\s]+/).map(r=>r.trim()).filter(Boolean);return e.length>0?e:void 0}return[String(t)]}}function zd(t){let e=qt(t);if(e==="authorization_code"||e==="client_credentials"||e==="password"||e==="service_account"||e==="custom")return e;if(e)return"custom"}function qb(t){return t==="managed"||t==="dynamic"||t==="custom"?t:void 0}function Hpe(t){let e=Object.entries(t).filter(([r])=>!Mpe.has(r));return e.length>0?Object.fromEntries(e):void 0}function yu(t,e,r){for(let i of Upe[r])if(r==="scopes"&&Array.isArray(t[i])||Et(t[i]))return t[i];let n=Go(t.client);return r==="clientId"&&Et(n?.id)?n.id:r==="clientSecret"&&Et(n?.secret)?n.secret:e[r]}function Ar(t){if(!t)return;let e=t;if(e.type==="oauth2"){let r=Go(e.config)||{},n=Hpe(r)||{};return La({type:"oauth2",oauthClientMode:qb(e.oauthClientMode),grantType:zd(yu(e,r,"grantType")),authUrl:qt(yu(e,r,"authUrl")),tokenUrl:qt(yu(e,r,"tokenUrl")),scopes:jd(yu(e,r,"scopes")),oauthAppId:qt(e.oauthAppId),clientId:qt(yu(e,r,"clientId")),clientSecret:qt(yu(e,r,"clientSecret")),config:Object.keys(n).length>0?n:void 0})}return e.type==="connection_string"?La({type:"connection_string",protocol:e.protocol,config:Go(e.config??e.components)}):e.type==="api_key"||e.type==="basic_auth"||e.type==="none"?La({type:e.type,config:Go(e.config)}):{type:"none"}}function qpe({authentication:t,templateManaged:e,templateRegistrationUrl:r}){let n=Ar(t);return n?.type!=="oauth2"?"custom":n.oauthAppId?.startsWith("managed:")?"managed":n.oauthClientMode?n.oauthClientMode==="managed"&&!e?"custom":n.oauthClientMode:r?"dynamic":e&&!n.clientSecret?"managed":"custom"}function Jx(t){let e=Ar(t);if(!e)return;let{config:r,scopes:n,oauthAppId:i,...o}=e,s={};return r&&typeof r=="object"&&Object.assign(s,r),Object.assign(s,o),Array.isArray(n)?s.scopes=n.join(" "):n!==void 0&&(s.scopes=n),s}function Hb(t,e=""){return t==null?t:Array.isArray(t)?t.map(r=>Hb(r)):typeof t=="object"?Object.fromEntries(Object.entries(t).map(([r,n])=>[r,Hb(n,r)])):e&&(0,Tt.isSensitiveCredentialKey)(e)?(0,Tt.maskCredentialValue)(e,t):t}function Gpe(t){let e=Jx(t);if(e)return Hb(e)}function Wx(t){return(0,Tt.isMaskedValue)(t)||(0,Tt.isFullyMaskedCredentialValue)(t)}function Ype(t){let e=Go(t);if(!e)return;let r={};for(let n of Vx){if(!fo(e,n))continue;let i=e[n];i!==void 0&&(r[n]=i)}return r}function Vpe(t){return!t||t.type!=="oauth2"||!Et(t.clientSecret)?t:{...t,clientSecret:Tt.FULLY_MASKED_CREDENTIAL_VALUE}}function Jpe({incoming:t,existing:e}){if(!t||t.type!=="oauth2"||!Wx(t.clientSecret))return t;let r=e?.type==="oauth2"?e.clientSecret:void 0;return{...t,clientSecret:r}}function Wpe(t){if(t==="none"||t==="api_key"||t==="basic_auth"||t==="oauth2"||t==="connection_string")return t}function Zpe(t){let e=bg.flatMap(r=>{if(!fo(t,r))return[];let n=t[r];return Et(n)?[[r,n]]:[]});return e.length>0?Object.fromEntries(e):void 0}function Kpe(t){return bg.filter(e=>fo(t,e))}function Xpe(t){let e=bg.flatMap(r=>fo(t,r)?[[r,t[r]]]:[]);return e.length>0?Object.fromEntries(e):void 0}function efe(t){let e=new Set(["oauthClientMode","grantType","authUrl","tokenUrl","scopes","clientId","clientSecret",...Fd]);return Object.keys(t).filter(r=>e.has(r))}function Zx(t){if(t==null)return{};let e=Go(t);if(!e)return{error:"auth must be an object."};let r=Wpe(e.type);if(!r)return{error:"auth.type is required."};let n=Object.keys(e).filter(a=>!Npe.has(a));if(n.length>0)return{error:`Unknown auth field(s): ${n.join(", ")}. Accepted: ${kpe}.`};let i=Kpe(e);if(r!=="connection_string"&&i.length>0)return{error:`Connection auth field(s) require auth.type 'connection_string': ${i.join(", ")}.`};let o=efe(e);if(r!=="oauth2"&&o.length>0)return{error:`OAuth auth field(s) require auth.type 'oauth2': ${o.join(", ")}.`};if(r!=="oauth2"){let a=Zpe(e);return{authentication:La({type:r,protocol:r==="connection_string"?e.protocol:void 0,config:a})}}let s={...Object.fromEntries(Fd.flatMap(a=>{if(!fo(e,a))return[];let c=e[a];return Et(c)?[[a,c]]:[]}))};return{authentication:La({type:"oauth2",oauthClientMode:qb(e.oauthClientMode),grantType:zd(e.grantType),authUrl:qt(e.authUrl),tokenUrl:qt(e.tokenUrl),scopes:jd(e.scopes),clientId:qt(e.clientId),clientSecret:qt(e.clientSecret),config:Object.keys(s).length>0?s:void 0})}}function Pa(t){return t===""||t===null||t===void 0}function $d(t,e,r,n){if(fo(e,r)){if(Pa(e[r])){delete t[n];return}t[n]=qt(e[r])}}function tfe(t,e){if(fo(e,"scopes")){if(Pa(e.scopes)){delete t.scopes;return}t.scopes=jd(e.scopes)}}function rfe(t,e){if(fo(e,"grantType")){if(Pa(e.grantType)){delete t.grantType;return}t.grantType=zd(e.grantType)}}function nfe(t,e,r){if(fo(e,r)){if(Pa(e[r])){delete t[r];return}t[r]=e[r]}}function ife(t,e){if(Pa(e))return;let r=Go(e);if(!r)return t;let n={...t||{}};for(let[i,o]of Object.entries(r))Pa(o)?delete n[i]:n[i]=o;return Object.keys(n).length>0?n:void 0}function ofe(t,e){let r=Zx(e);if(r.error)return Ar(t)||{type:"none"};let n=r.authentication||{type:"none"},i=Go(e)||{},o=Ar(t),s=o?.type===n.type;if(n.type!=="oauth2"){let d=Xpe(i),A=s&&o?{...o}:{type:n.type};return n.type==="connection_string"&&fo(i,"protocol")&&(Pa(i.protocol)?delete A.protocol:A.protocol=i.protocol),d&&(A.config=ife(o?.config,d)),Ar(A)||{type:n.type}}let c={...s&&o?.type==="oauth2"?{...o,config:{...o.config||{}}}:{type:"oauth2",config:{}}};$d(c,i,"oauthClientMode","oauthClientMode"),rfe(c,i),$d(c,i,"authUrl","authUrl"),$d(c,i,"tokenUrl","tokenUrl"),tfe(c,i),$d(c,i,"clientId","clientId"),$d(c,i,"clientSecret","clientSecret");let l={...c.config||{}};for(let d of Fd)nfe(l,i,d);return c.config=Object.keys(l).length>0?l:void 0,Ar(c)||{type:"oauth2"}}function Kx(t){let e=Ar(t);if(!e)return[];let r=new Set;for(let n of Object.keys(e.config||{}))r.add(n);return e.type==="oauth2"&&(e.grantType&&(r.add("grant_type"),r.add("grantType")),e.authUrl&&(r.add("auth_url"),r.add("authUrl")),e.tokenUrl&&(r.add("token_url"),r.add("tokenUrl"),r.add("token_uri")),e.scopes&&(r.add("scopes"),r.add("scope")),e.clientId&&(r.add("client_id"),r.add("clientId")),e.clientSecret&&(r.add("client_secret"),r.add("clientSecret"))),[...r]}function Gx(t,e,r){if(r)for(let[n,i]of Object.entries(r))t.push({path:`${e}.${n}`,label:n,value:i})}function sfe({authentication:t}){let e=Ar(t)||{type:"none"},r=[];if(e.type==="oauth2"){r.push({path:"oauth2.clientId",label:"clientId",value:e.clientId},{path:"oauth2.clientSecret",label:"clientSecret",value:e.clientSecret},{path:"oauth2.grantType",label:"grantType",value:e.grantType||"authorization_code"},{path:"oauth2.authUrl",label:"authUrl",value:e.authUrl},{path:"oauth2.tokenUrl",label:"tokenUrl",value:e.tokenUrl},{path:"oauth2.scopes",label:"scopes",value:e.scopes?.join(" ")});for(let n of Fd)r.push({path:`oauth2.config.${n}`,label:n,value:e.config?.[n]});for(let[n,i]of Object.entries(e.config||{}))Fd.includes(n)||r.push({path:`oauth2.config.${n}`,label:n,value:i})}else e.type==="connection_string"?(e.protocol&&r.push({path:"connection.protocol",label:"protocol",value:e.protocol}),Gx(r,"connection.config",e.config)):Gx(r,`${e.type}.config`,e.config);return{type:e.type,authentication:e,configFields:r,hiddenCredentialKeys:Kx(e)}}function afe(t){let e=Ar(t);if(!e||e.type!=="connection_string")return[];let r={type:"field",field:{key:"username",aliases:["user"]}},n={type:"field",field:{key:"password"}};switch(e.protocol){case"sftp":return[r,{type:"oneOf",fields:[{key:"password"},{key:"privateKey"}]},{type:"field",field:{key:"passphrase"},optional:!0}];case"smb":return[r,n,{type:"field",field:{key:"domain"},optional:!0}];case"sqlserver":return[{type:"field",field:{key:"user",aliases:["username"]}},n];default:return[r,n]}}function Yx(t,e){return(0,Tt.hasCredentialValue)(e[t.key])?!0:(t.aliases??[]).some(r=>(0,Tt.hasCredentialValue)(e[r]))}function Xx(t,e){return t.optional?!0:t.type==="field"?Yx(t.field,e):t.fields.some(r=>Yx(r,e))}function cfe(t,e){let r=e||{};return t.some(n=>!Xx(n,r))}function ufe({authentication:t,path:e,value:r}){let n=Ar(t)||{type:"none"};if(n.type==="oauth2"){if(e==="oauth2.grantType")return{...n,grantType:zd(r)};if(e==="oauth2.authUrl")return{...n,authUrl:qt(r)};if(e==="oauth2.tokenUrl")return{...n,tokenUrl:qt(r)};if(e==="oauth2.scopes")return{...n,scopes:jd(r)??[]};if(e==="oauth2.clientId")return{...n,clientId:qt(r)};if(e==="oauth2.clientSecret")return{...n,clientSecret:qt(r)};if(e.startsWith("oauth2.config.")){let o=e.slice(14);return{...n,config:zb({config:n.config,key:o,value:r})}}}if(n.type==="connection_string"){if(e==="connection.protocol")return{...n,protocol:qt(r)};if(e.startsWith("connection.config.")){let o=e.slice(18);return{...n,config:zb({config:n.config,key:o,value:r})}}}let i=`${n.type}.config.`;if(e.startsWith(i)){let o=e.slice(i.length);return{...n,config:zb({config:n.config,key:o,value:r})}}return n}function eL({authentication:t,credentials:e}){if(Ar(t)?.type!=="oauth2"||!e||typeof e!="object"||Array.isArray(e))return null;let n=Object.keys(e).filter(i=>Ce.OAUTH_CONFIG_CREDENTIAL_KEYS.includes(i));return n.length===0?null:`OAuth configuration keys belong in auth, not credentials: ${n.join(", ")}. Move OAuth client ID to auth.clientId, client secret to auth.clientSecret, auth URL to auth.authUrl, token URL to auth.tokenUrl, scopes to auth.scopes, grant type to auth.grantType, and token request settings to auth fields such as tokenAuthMethod/usePKCE/extraHeaders. Runtime OAuth access and refresh tokens are created by connect OAuth authorization.`}function tL(t){let e=Ar(t);return e?e.type==="oauth2"?La({...e.config||{},grant_type:e.grantType,auth_url:e.authUrl,token_url:e.tokenUrl,scopes:e.scopes?.join(" "),client_id:e.clientId,client_secret:e.clientSecret}):e.type==="connection_string"?e.config||{}:e.config||{}:{}}function lfe(t){return xpe.has(t.trim())}function dfe({credential:t,system:e}){return t?.authentication??e?.authentication??void 0}function Afe({authentication:t,credentials:e}){let r=tL(t);return Ar(t)?.type==="oauth2"?{...e||{},...r}:{...r,...e||{}}}function pfe({input:t,authentication:e,templateOAuth:r}){let n=Ar(e),i=n?.type==="oauth2"?n:void 0,o=i?.config||{},s=t||{},a=(...c)=>c.find(u=>u!=null);return La({grant_type:a(s.grantType,s.grant_type,i?.grantType,r?.grant_type)||"authorization_code",scopes:a(s.scopes,i?.scopes?.join(" "),r?.scopes),client_id:a(s.clientId,s.client_id,i?.clientId),client_secret:a(s.clientSecret,s.client_secret,i?.clientSecret),auth_url:a(s.authUrl,s.auth_url,i?.authUrl,r?.authUrl),token_url:a(s.tokenUrl,s.token_url,i?.tokenUrl,r?.tokenUrl),resource:a(s.resource,o.resource,r?.resource),tokenAuthMethod:a(s.tokenAuthMethod,o.tokenAuthMethod,r?.tokenAuthMethod),tokenContentType:a(s.tokenContentType,o.tokenContentType,r?.tokenContentType),usePKCE:a(s.usePKCE,o.usePKCE,r?.usePKCE),extraHeaders:a(s.extraHeaders,o.extraHeaders,r?.extraHeaders),extraBodyParams:a(s.extraBodyParams,o.extraBodyParams,r?.extraBodyParams)})}function Gb(t){if(t==null)return"";if(typeof t=="string")return t;let e=JSON.stringify(t);return e===void 0?String(t):e}function ffe(t,e={}){let r=new Set((e.hiddenKeys||[]).map(Tt.normalizeCredentialKey));return Object.entries(t).filter(([n])=>!r.has((0,Tt.normalizeCredentialKey)(n))).sort(([n],[i])=>{let o=qx.get((0,Tt.normalizeCredentialKey)(n))??Number.MAX_SAFE_INTEGER,s=qx.get((0,Tt.normalizeCredentialKey)(i))??Number.MAX_SAFE_INTEGER;if(o!==s)return o-s;let a=(0,Tt.isSensitiveCredentialKey)(n),c=(0,Tt.isSensitiveCredentialKey)(i);return a!==c?a?-1:1:n.localeCompare(i)}).map(([n,i])=>({key:n,value:Gb(i),isReservedMasked:e.maskAll||(0,Tt.isSensitiveCredentialKey)(n)}))}function hfe(t){return Object.fromEntries(Object.entries(t).map(([e,r])=>[e,Gb(r)]))}function gfe({hideOAuthFiles:t=!1,configKeys:e=[]}){return[...e,...t?["oauth_cert","oauth_key"]:[]]}function mfe(t){return Et(t.access_token)||Et(t.refresh_token)}function yfe(t){let e=t.expires_at??t.expiry;if(e){let n=(0,Rpe.parseUTCDate)(e);if(n)return`Expires ${n.toLocaleString()}`}let r=t.expires_in;return Et(r)?`Expires in ${r} seconds`:null}function Efe(t){return!!(t&&typeof t=="object"&&!Array.isArray(t)&&Object.values(t).some(e=>Et(e)))}function Ife(t){if(!t||typeof t!="object"||Array.isArray(t))return null;let e=(0,Tt.getInvalidCredentialKeyNames)(Object.keys(t));return e.length===0?null:`${Tt.CREDENTIAL_KEY_VALIDATION_DESCRIPTION} Invalid keys: ${e.join(", ")}`}function Cfe(t){let e=(0,Tt.getInvalidCredentialKeyNames)(t);return e.length===0?null:`${Tt.CREDENTIAL_KEY_VALIDATION_DESCRIPTION} Invalid keys: ${e.join(", ")}`}function bfe(t){let e={"grant_type authorization_code or client_credentials":"grantType authorization_code or client_credentials",client_id:"clientId",token_url:"tokenUrl",auth_url:"authUrl","client_secret or usePKCE":"clientSecret or usePKCE","client_secret or oauth_cert + oauth_key":"clientSecret or oauth_cert + oauth_key"};return t.map(r=>e[r]||r)}function Sfe({authentication:t,credentials:e}){return eL({authentication:t,credentials:e})}});var CL=m(ho=>{"use strict";Object.defineProperty(ho,"__esModule",{value:!0});ho.bundles=void 0;ho.buildBundleAgentLaunch=Ufe;ho.getBundle=Mfe;ho.listBundles=xfe;var wfe="https://sandbox.api.sap.com/s4hanacloud/sap/opu/odata/sap",Bfe="<<(p) => { const value = p['sage_intacct_entity_id']; if (!value) return ''; const escaped = String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;').replaceAll(\"'\", '&apos;'); return `<locationid>${escaped}</locationid>`; }>>",rL="<<() => crypto.randomUUID()>>";function It(t){return`<?xml version="1.0" encoding="UTF-8"?><request><control><senderid><<sage_intacct_sender_id>></senderid><password><<sage_intacct_sender_password>></password><controlid>${rL}</controlid><uniqueid>false</uniqueid><dtdversion>3.0</dtdversion></control><operation><authentication><login><userid><<sage_intacct_user_id>></userid><companyid><<sage_intacct_company_id>></companyid><password><<sage_intacct_user_password>></password>${Bfe}</login></authentication><content><function controlid="${rL}">${t}</function></content></operation></request>`}function vs({stepId:t,objectNameExpression:e,collectionName:r,mapExpression:n,includeTotalCount:i=!1}){let o=i?"Number(data && data.TOTALCOUNT ? data.TOTALCOUNT : rows.length)":"rows.length",s=n?`rows.map(${n})`:"rows";return`(sourceData) => { const response = sourceData.${t} && sourceData.${t}.data ? sourceData.${t}.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? \` Sage support ID: \${supportIds.join(', ')}.\` : ''; throw new Error(\`Sage Intacct request failed\${details.length ? \`: \${details.join('; ')}\` : '.'}\${suffix}\`); } const data = result ? result.DATA : undefined; const objectName = ${e}; const raw = data ? data[objectName] : undefined; const rows = (Array.isArray(raw) ? raw : (raw ? [raw] : [])).slice(0, (sourceData && sourceData.maxResults) ?? ${i?"1000":"200"}); return { total: ${o}, ${r}: ${s} }; }`}var Ds=`const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;');`,nL="const toIntacctDate = (value) => { const match = String(value).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (!match) throw new Error('Dates must be in YYYY-MM-DD format.'); return match[2] + '/' + match[3] + '/' + match[1]; };",iL="const assertBalanced = (lines) => { const balance = lines.reduce((sum, line) => sum + (line.type === 'credit' ? -1 : 1) * Math.abs(Number(line.amount)), 0); if (Math.abs(balance) > 0.005) throw new Error('Journal lines must balance: debits minus credits is ' + balance.toFixed(2) + '.'); };",oL=`const lineXml = (line) => { const amount = Number(line.amount); if (!Number.isFinite(amount) || amount <= 0) throw new Error('Every journal line needs a positive amount.'); const type = line.type === 'credit' ? -1 : line.type === 'debit' ? 1 : null; if (type === null) throw new Error("Every journal line needs type 'debit' or 'credit'."); if (!line.accountNo) throw new Error('Every journal line needs accountNo.'); let xml = '<GLENTRY><ACCOUNTNO>' + esc(line.accountNo) + '</ACCOUNTNO><TR_TYPE>' + type + '</TR_TYPE><TRX_AMOUNT>' + amount + '</TRX_AMOUNT>'; if (line.department) xml += '<DEPARTMENT>' + esc(line.department) + '</DEPARTMENT>'; if (line.location) xml += '<LOCATION>' + esc(line.location) + '</LOCATION>'; if (line.memo) xml += '<DESCRIPTION>' + esc(line.memo) + '</DESCRIPTION>'; return xml + '</GLENTRY>'; };`;function Eu({stepId:t,objectName:e}){return`(sourceData) => { const response = sourceData.${t} && sourceData.${t}.data ? sourceData.${t}.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? \` Sage support ID: \${supportIds.join(', ')}.\` : ''; throw new Error(\`Sage Intacct request failed\${details.length ? \`: \${details.join('; ')}\` : '.'}\${suffix}\`); } const data = result ? result.DATA : undefined; const raw = data ? (data.${e} || data.${e.toLowerCase()}) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }`}var Yd="netsuite",Jb=100,Gd=1e4,Tg=String.raw`<<(p) => { const url = String(p['netsuite_url'] || ''); if (!url || url.includes('{accountId}')) throw new Error('NetSuite is not connected yet: set the account ID so the system URL is https://<account>.suitetalk.api.netsuite.com/services/rest'); return url.replace(/\/+$/, ''); }>>`,Rg={Authorization:"Bearer <<netsuite_access_token>>",Accept:"application/json"},Wb=String.raw`const has = (value) => value !== undefined && value !== null && value !== ''; const nsId = (value, name) => { const text = String(value ?? '').trim(); if (!/^-?\d+$/.test(text)) throw new Error(name + ' must be a NetSuite internal ID.'); return text; }; const nsDate = (value, name) => { const text = String(value ?? '').trim(); if (!/^\d{4}-\d{2}-\d{2}$/.test(text)) throw new Error(name + ' must be a date in YYYY-MM-DD format.'); return text; }; const ref = (value, name) => ({ id: nsId(value, name) });`,_fe=String.raw`const str = (value) => (value === undefined || value === null || value === '' ? null : String(value)); const num = (value) => (value === undefined || value === null || value === '' ? null : Number(value)); const bool = (value) => value === 'T' || value === true; const ids = (value) => (value === undefined || value === null || value === '' ? [] : String(value).split(',').map((part) => part.trim()).filter(Boolean)); const status = (value) => (value ? String(value).replace(/^[^:]*:\s*/, '') : null);`,sL=String.raw`const stripLinks = (value) => { if (Array.isArray(value)) return value.map(stripLinks); if (value && typeof value === 'object') { const result = {}; for (const [key, entry] of Object.entries(value)) { if (key !== 'links') result[key] = stripLinks(entry); } return result; } return value; };`,Qfe={type:"integer",minimum:1,maximum:Gd,description:`Maximum number of records to return (max ${Gd}). Defaults to ${Jb}. The result always reports the full match count in total, so use maxResults 1 to count. Prefer filters over large values: big results can exceed an AI client's tool output limit.`},vfe={type:"boolean",description:"Only return active records. Defaults to false (inactive records are included)."},Dfe={type:"string",description:"Optional subsidiary internal ID to filter by."},Tfe={type:"string",description:"Optional earliest transaction date as YYYY-MM-DD."},Rfe={type:"string",description:"Optional latest transaction date as YYYY-MM-DD."},Nfe={type:"object",description:"Optional extra NetSuite REST field values merged into the record body as-is, e.g. custom fields like { custentity_region: 'EMEA' } or references like { terms: { id: '2' } }. Fields that this tool's own inputs set are rejected; use those inputs instead.",properties:{},additionalProperties:!0},Hd=t=>({input:"activeOnly",kind:"flag",clause:`${t}.isinactive = 'F'`,schema:vfe}),qd=t=>({input:"subsidiaryId",kind:"id",clause:`${t}.subsidiary = $`,schema:Dfe}),Yb=[{input:"fromDate",kind:"date",clause:"t.trandate >= TO_DATE('$', 'YYYY-MM-DD')",schema:Tfe},{input:"toDate",kind:"date",clause:"t.trandate <= TO_DATE('$', 'YYYY-MM-DD')",schema:Rfe}];function kfe(t){let e=`p[${JSON.stringify(t.input)}]`;if(t.kind==="flag")return`if (${e} === true || ${e} === 'true') where.push(${JSON.stringify(t.clause)});`;let[r,n]=t.clause.split("$");if(t.kind==="enum")return`if (has(${e})) { const allowed = ${JSON.stringify(t.values)}; if (!allowed.includes(String(${e}))) throw new Error(${JSON.stringify(`${t.input} must be one of: ${t.values.join(", ")}.`)}); where.push(${JSON.stringify(r)} + String(${e}) + ${JSON.stringify(n)}); }`;if(t.kind==="prefix")return`if (has(${e})) { const text = String(${e}).trim(); if (!/^[A-Za-z0-9._-]{1,40}$/.test(text)) throw new Error(${JSON.stringify(`${t.input} may only contain letters, digits, dots, underscores and hyphens.`)}); where.push(${JSON.stringify(r)} + text + ${JSON.stringify(n)}); }`;let i=t.kind==="id"?"nsId":"nsDate";return`if (has(${e})) where.push(${JSON.stringify(r)} + ${i}(${e}, ${JSON.stringify(t.input)}) + ${JSON.stringify(n)});`}function Ts({id:t,name:e,shortName:r,instruction:n,stepId:i,collection:o,select:s,baseWhere:a=[],orderBy:c,filters:u=[],properties:l={},required:d=[],mapRow:A}){let p=typeof s=="string"?JSON.stringify(s):s.js,h=`<<(p) => { ${Wb} const where = ${JSON.stringify(a)}; ${u.map(kfe).join(" ")} return JSON.stringify({ q: ${p} + (where.length ? ' WHERE ' + where.join(' AND ') : '') + ${JSON.stringify(` ORDER BY ${c}`)} }); }>>`;return{id:t,name:e,shortName:r,instruction:`${n} Rows are ordered by internal ID. If more than ${Gd} rows match, narrow with the filters or page with the SuiteQL query tool (ORDER BY id, WHERE id > last id).`,inputSchema:{type:"object",properties:{...l,maxResults:Qfe,...Object.fromEntries(u.map(g=>[g.input,g.schema]))},...d.length>0?{required:d}:{},additionalProperties:!1},steps:[{id:i,instruction:"Run the SuiteQL query page by page.",config:{type:"request",systemId:Yd,url:`${Tg}/query/v1/suiteql`,method:"POST",headers:{...Rg,"Content-Type":"application/json",Prefer:"transient"},queryParams:{limit:"1000",offset:"<<offset>>"},body:h,pagination:{type:"offsetBased",pageSize:"1000",stopCondition:`(response, pageInfo, sourceData) => { if (sourceData && ["offset", "limit", "page"].some((key) => sourceData[key] !== undefined)) throw new Error("offset, limit and page are not inputs of this tool: use maxResults and the filters."); const page = response && response.data ? response.data : {}; const merged = pageInfo && pageInfo.mergedResult && Array.isArray(pageInfo.mergedResult.items) ? pageInfo.mergedResult.items.length : 0; const max = Math.min(Math.max(Math.floor(Number(sourceData && sourceData.maxResults)) || ${Jb}, 1), ${Gd}); return page.hasMore !== true || merged >= max; }`}}}],outputTransform:`(sourceData) => { ${_fe} const raw = sourceData.${i} ? sourceData.${i}.data : undefined; const pages = Array.isArray(raw) ? raw : (raw ? [raw] : []); const items = pages.flatMap((page) => (page && Array.isArray(page.items) ? page.items : [])); const last = pages.length ? pages[pages.length - 1] : {}; const max = Math.min(Math.max(Math.floor(Number(sourceData.maxResults)) || ${Jb}, 1), ${Gd}); const rows = items.slice(0, max).map(${A}).map((row) => Object.fromEntries(Object.entries(row).filter((entry) => entry[1] !== null))); const total = last && last.totalResults !== undefined ? Number(last.totalResults) : items.length; return { total, returned: rows.length, hasMore: total > rows.length, ${o}: rows }; }`}}function _r({id:t,name:e,shortName:r,instruction:n,stepId:i,recordType:o,mode:s,properties:a,required:c,body:u,replaceSublist:l}){let d=[...new Set(Array.from(u.matchAll(/record\.([A-Za-z0-9_]+)\s*=/g)).map(p=>p[1]))],A=s==="create"?`/record/v1/${o}`:`/record/v1/${o}/<<(p) => { ${Wb} return nsId(p.internalId, 'internalId'); }>>`;return{id:t,name:e,shortName:r,instruction:n,inputSchema:{type:"object",properties:{...s==="update"?{internalId:{type:"string",description:`Internal ID of the ${o} to update.`}}:{},...a,fields:Nfe},required:s==="update"?["internalId",...c]:c,additionalProperties:!1},steps:[{id:i,instruction:`${s==="create"?"Create":"Update"} the ${o} record.`,modify:!0,config:{type:"request",systemId:Yd,url:`${Tg}${A}`,method:s==="create"?"POST":"PATCH",headers:{...Rg,"Content-Type":"application/json","X-NetSuite-idempotency-key":"<<() => crypto.randomUUID()>>"},...l?{queryParams:{replace:`<<(p) => (Array.isArray(p[${JSON.stringify(l.input)}]) && p[${JSON.stringify(l.input)}].length > 0 ? ${JSON.stringify(l.sublist)} : undefined)>>`}}:{},body:`<<(p) => { ${Wb} const record = {}; ${u} if (p.fields && typeof p.fields === 'object' && !Array.isArray(p.fields)) { const managed = ${JSON.stringify(d)}; const reserved = Object.keys(p.fields).filter((key) => managed.includes(key)); if (reserved.length > 0) throw new Error('fields may not set ' + reserved.join(', ') + ': use this tool\\'s own inputs for them.'); Object.assign(record, p.fields); } if (Object.keys(record).length === 0) throw new Error('Provide at least one field to ${s}.'); return JSON.stringify(record); }>>`,captureHttpResponse:!0}}],outputTransform:s==="create"?`(sourceData) => { const step = sourceData.${i} || {}; const location = step.http && step.http.headers ? String(step.http.headers.location || '') : ''; const match = location.match(/\\/record\\/v1\\/[^/]+\\/([^/?#]+)/); if (!match) throw new Error('NetSuite did not return the location of the new ${o}.'); return { id: decodeURIComponent(match[1]), recordType: '${o}' }; }`:`(sourceData) => ({ id: String(sourceData.internalId).trim(), recordType: '${o}', updated: true })`}}var aL=String.raw`const lines = Array.isArray(p.lines) ? p.lines : []; let balance = 0; const items = lines.map((line, index) => { const amount = Number(line && line.amount); if (!Number.isFinite(amount) || amount <= 0) throw new Error('lines[' + index + '].amount must be a positive number.'); if (line.type !== 'debit' && line.type !== 'credit') throw new Error("lines[" + index + "].type must be 'debit' or 'credit'."); balance += line.type === 'debit' ? amount : -amount; const item = { account: ref(line.accountId, 'lines[' + index + '].accountId') }; item[line.type] = amount; if (has(line.memo)) item.memo = String(line.memo); if (has(line.departmentId)) item.department = ref(line.departmentId, 'lines[' + index + '].departmentId'); if (has(line.classId)) item.class = ref(line.classId, 'lines[' + index + '].classId'); if (has(line.locationId)) item.location = ref(line.locationId, 'lines[' + index + '].locationId'); if (has(line.entityId)) item.entity = ref(line.entityId, 'lines[' + index + '].entityId'); return item; }); if (lines.length > 0 && Math.abs(balance) > 0.005) throw new Error('Journal lines must balance: debits minus credits is ' + balance.toFixed(2) + '.'); if (items.length > 0) record.line = { items };`,cL=String.raw`if (has(p.subsidiaryId)) record.subsidiary = ref(p.subsidiaryId, 'subsidiaryId'); if (has(p.date)) record.tranDate = nsDate(p.date, 'date'); if (has(p.memo)) record.memo = String(p.memo); if (has(p.currencyId)) record.currency = ref(p.currencyId, 'currencyId'); if (has(p.externalId)) record.externalId = String(p.externalId);`,uL={type:"object",properties:{accountId:{type:"string",description:"GL account internal ID."},type:{type:"string",enum:["debit","credit"]},amount:{type:"number",description:"Positive amount."},memo:{type:"string",description:"Optional line memo."},departmentId:{type:"string",description:"Optional department internal ID."},classId:{type:"string",description:"Optional class internal ID."},locationId:{type:"string",description:"Optional location internal ID."},entityId:{type:"string",description:"Optional customer, vendor or employee internal ID for the line."}},required:["accountId","type","amount"],additionalProperties:!1},lL=t=>({subsidiaryId:{type:"string",description:t==="create"?"Subsidiary internal ID. Required in OneWorld accounts.":"Optional new subsidiary internal ID."},date:{type:"string",description:t==="create"?"Transaction date as YYYY-MM-DD.":"Optional new transaction date as YYYY-MM-DD."},memo:{type:"string",description:"Journal entry memo."},currencyId:{type:"string",description:"Optional currency internal ID."},externalId:{type:"string",description:"Optional external ID."}}),wg=String.raw`if (p.isPerson === true || p.isPerson === 'true') record.isPerson = true; if (p.isPerson === false || p.isPerson === 'false') record.isPerson = false; if (has(p.entityId)) record.entityId = String(p.entityId); if (has(p.companyName)) record.companyName = String(p.companyName); if (has(p.firstName)) record.firstName = String(p.firstName); if (has(p.lastName)) record.lastName = String(p.lastName); if (has(p.subsidiaryId)) record.subsidiary = ref(p.subsidiaryId, 'subsidiaryId'); if (has(p.email)) record.email = String(p.email); if (has(p.phone)) record.phone = String(p.phone); if (has(p.currencyId)) record.currency = ref(p.currencyId, 'currencyId'); if (has(p.externalId)) record.externalId = String(p.externalId); if (p.isInactive === true || p.isInactive === 'true') record.isInactive = true; if (p.isInactive === false || p.isInactive === 'false') record.isInactive = false;`;function Bg(t){return{companyName:{type:"string",description:`Company name of the ${t}.`},isPerson:{type:"boolean",description:`True when the ${t} is an individual; then set firstName and lastName.`},firstName:{type:"string",description:"First name for an individual."},lastName:{type:"string",description:"Last name for an individual."},entityId:{type:"string",description:`${t==="customer"?"Customer":"Vendor"} ID. Omit when auto-numbering assigns it.`},subsidiaryId:{type:"string",description:"Primary subsidiary internal ID. Required on create in OneWorld accounts."},email:{type:"string",description:"Email address."},phone:{type:"string",description:"Phone number."},currencyId:{type:"string",description:"Primary currency internal ID."},externalId:{type:"string",description:"Optional external ID."}}}var _g={isInactive:{type:"boolean",description:"Set true to inactivate, false to reactivate."}},Qg=String.raw`if (Array.isArray(p.subsidiaryIds) && p.subsidiaryIds.length > 0) record.subsidiary = { items: p.subsidiaryIds.map((value, index) => ref(value, 'subsidiaryIds[' + index + ']')) }; if (p.includeChildren === true || p.includeChildren === 'true') record.includeChildren = true; if (p.includeChildren === false || p.includeChildren === 'false') record.includeChildren = false;`,EL={subsidiaryIds:{type:"array",items:{type:"string"},description:"Subsidiary internal IDs the record is available in. On update the list replaces the current subsidiaries."},includeChildren:{type:"boolean",description:"Also make the record available to child subsidiaries."}},Zb=["AcctPay","AcctRec","Bank","COGS","CredCard","DeferExpense","DeferRevenue","Equity","Expense","FixedAsset","Income","LongTermLiab","NonPosting","OthAsset","OthCurrAsset","OthCurrLiab","OthExpense","OthIncome","Stat","UnbilledRec"],dL=String.raw`if (has(p.acctNumber)) record.acctNumber = String(p.acctNumber); if (has(p.acctName)) record.acctName = String(p.acctName); if (has(p.acctType)) record.acctType = { id: String(p.acctType) }; if (has(p.parentId)) record.parent = ref(p.parentId, 'parentId'); if (has(p.description)) record.description = String(p.description); if (has(p.currencyId)) record.currency = ref(p.currencyId, 'currencyId'); if (has(p.externalId)) record.externalId = String(p.externalId); if (p.isInactive === true || p.isInactive === 'true') record.isInactive = true; if (p.isInactive === false || p.isInactive === 'false') record.isInactive = false;`,AL={acctNumber:{type:"string",description:"Account number."},acctName:{type:"string",description:"Account name."},acctType:{type:"string",enum:Zb,description:"NetSuite account type."},parentId:{type:"string",description:"Optional parent account internal ID."},description:{type:"string",description:"Optional description."},currencyId:{type:"string",description:"Optional currency internal ID (bank and credit card accounts)."},externalId:{type:"string",description:"Optional external ID."},...EL},pL=String.raw`if (has(p.name)) record.name = String(p.name); if (has(p.parentId)) record.parent = ref(p.parentId, 'parentId'); if (has(p.externalId)) record.externalId = String(p.externalId); if (p.isInactive === true || p.isInactive === 'true') record.isInactive = true; if (p.isInactive === false || p.isInactive === 'false') record.isInactive = false;`,fL={name:{type:"string",description:"Department name."},parentId:{type:"string",description:"Optional parent department internal ID."},externalId:{type:"string",description:"Optional external ID."},...EL},vg=t=>String.raw`if (has(p.${t})) record.entity = ref(p.${t}, '${t}'); if (has(p.subsidiaryId)) record.subsidiary = ref(p.subsidiaryId, 'subsidiaryId'); if (has(p.date)) record.tranDate = nsDate(p.date, 'date'); if (has(p.dueDate)) record.dueDate = nsDate(p.dueDate, 'dueDate'); if (has(p.memo)) record.memo = String(p.memo); if (has(p.currencyId)) record.currency = ref(p.currencyId, 'currencyId'); if (has(p.termsId)) record.terms = ref(p.termsId, 'termsId'); if (has(p.departmentId)) record.department = ref(p.departmentId, 'departmentId'); if (has(p.classId)) record.class = ref(p.classId, 'classId'); if (has(p.locationId)) record.location = ref(p.locationId, 'locationId'); if (has(p.externalId)) record.externalId = String(p.externalId);`,Dg=t=>({subsidiaryId:{type:"string",description:t==="create"?"Optional subsidiary internal ID; defaults to the entity's subsidiary.":"Optional new subsidiary internal ID."},date:{type:"string",description:t==="create"?"Transaction date as YYYY-MM-DD.":"Optional new transaction date as YYYY-MM-DD."},dueDate:{type:"string",description:"Optional due date as YYYY-MM-DD."},memo:{type:"string",description:"Optional memo."},currencyId:{type:"string",description:"Optional currency internal ID."},termsId:{type:"string",description:"Optional payment terms internal ID."},departmentId:{type:"string",description:"Optional header department internal ID."},classId:{type:"string",description:"Optional header class internal ID."},locationId:{type:"string",description:"Optional header location internal ID."},externalId:{type:"string",description:"Optional external ID."}}),IL=String.raw`if (has(line.departmentId)) item.department = ref(line.departmentId, 'lines[' + index + '].departmentId'); if (has(line.classId)) item.class = ref(line.classId, 'lines[' + index + '].classId'); if (has(line.locationId)) item.location = ref(line.locationId, 'lines[' + index + '].locationId');`,hL=String.raw`if (Array.isArray(p.lines) && p.lines.length > 0) record.item = { items: p.lines.map((line, index) => { const item = { item: ref(line && line.itemId, 'lines[' + index + '].itemId') }; if (has(line.quantity)) { const quantity = Number(line.quantity); if (!Number.isFinite(quantity)) throw new Error('lines[' + index + '].quantity must be a number.'); item.quantity = quantity; } if (has(line.rate)) { const rate = Number(line.rate); if (!Number.isFinite(rate)) throw new Error('lines[' + index + '].rate must be a number.'); item.rate = rate; } if (has(line.amount)) { const amount = Number(line.amount); if (!Number.isFinite(amount)) throw new Error('lines[' + index + '].amount must be a number.'); item.amount = amount; } if (has(line.description)) item.description = String(line.description); if (has(line.taxCodeId)) item.taxCode = ref(line.taxCodeId, 'lines[' + index + '].taxCodeId'); ${IL} return item; }) };`,gL={type:"object",properties:{itemId:{type:"string",description:"Item internal ID."},quantity:{type:"number",description:"Optional quantity. Defaults to 1."},rate:{type:"number",description:"Optional unit price; defaults to the item price."},amount:{type:"number",description:"Optional line amount."},description:{type:"string",description:"Optional line description."},taxCodeId:{type:"string",description:"Optional tax code internal ID."},departmentId:{type:"string",description:"Optional department internal ID."},classId:{type:"string",description:"Optional class internal ID. Some accounts ignore line classes on invoices; check the saved record."},locationId:{type:"string",description:"Optional location internal ID."}},required:["itemId"],additionalProperties:!1},mL=String.raw`if (Array.isArray(p.lines) && p.lines.length > 0) record.expense = { items: p.lines.map((line, index) => { const amount = Number(line && line.amount); if (!Number.isFinite(amount) || amount <= 0) throw new Error('lines[' + index + '].amount must be a positive number.'); const item = { account: ref(line.accountId, 'lines[' + index + '].accountId'), amount }; if (has(line.memo)) item.memo = String(line.memo); ${IL} return item; }) };`,yL={type:"object",properties:{accountId:{type:"string",description:"Expense account internal ID."},amount:{type:"number",description:"Positive amount."},memo:{type:"string",description:"Optional line memo."},departmentId:{type:"string",description:"Optional department internal ID."},classId:{type:"string",description:"Optional class internal ID."},locationId:{type:"string",description:"Optional location internal ID."}},required:["accountId","amount"],additionalProperties:!1},$a="Re-running this tool creates another record; it is not idempotent.",Ofe=[Ts({id:"netsuite-list-accounts",name:"List NetSuite chart of accounts",shortName:"Chart of accounts",instruction:"Lists general ledger accounts (the chart of accounts) from NetSuite with number, name, type, parent and subsidiaries. Useful for validating an imported chart of accounts.",stepId:"queryAccounts",collection:"accounts",select:"SELECT a.id, a.acctnumber, a.accountsearchdisplaynamecopy AS name, a.fullname, a.accttype, a.parent, a.subsidiary, cur.symbol AS currency, a.description, a.issummary, a.isinactive FROM account a LEFT JOIN currency cur ON cur.id = a.currency",orderBy:"a.id",filters:[Hd("a"),{input:"accountType",kind:"enum",values:Zb,clause:"a.accttype = '$'",schema:{type:"string",enum:Zb,description:"Only accounts of this NetSuite account type, e.g. Bank or Expense."}},{input:"numberPrefix",kind:"prefix",clause:"a.acctnumber LIKE '$%'",schema:{type:"string",description:"Only accounts whose number starts with this value, e.g. 1000 or 60."}}],mapRow:"(row) => ({ id: row.id, number: str(row.acctnumber), name: str(row.name), fullName: str(row.fullname), type: str(row.accttype), parentId: str(row.parent), subsidiaryIds: ids(row.subsidiary), currency: str(row.currency), description: str(row.description), isSummary: bool(row.issummary), isInactive: bool(row.isinactive) })"}),Ts({id:"netsuite-list-customers",name:"List NetSuite customers",shortName:"Customers",instruction:"Lists customer records from NetSuite with subsidiary, currency and open balance. Useful for verifying migrated AR master data.",stepId:"queryCustomers",collection:"customers",select:"SELECT c.id, c.entityid, c.companyname, c.isperson, c.firstname, c.lastname, c.email, c.phone, c.subsidiary, BUILTIN.DF(c.subsidiary) AS subsidiaryname, cur.symbol AS currency, c.balancesearch, c.overduebalancesearch, c.isinactive, TO_CHAR(c.datecreated, 'YYYY-MM-DD') AS datecreated, TO_CHAR(c.lastmodifieddate, 'YYYY-MM-DD') AS lastmodified FROM customer c LEFT JOIN currency cur ON cur.id = c.currency",orderBy:"c.id",filters:[Hd("c"),qd("c")],mapRow:"(row) => ({ id: row.id, entityId: str(row.entityid), companyName: str(row.companyname), isPerson: bool(row.isperson), firstName: str(row.firstname), lastName: str(row.lastname), email: str(row.email), phone: str(row.phone), subsidiaryId: str(row.subsidiary), subsidiary: str(row.subsidiaryname), currency: str(row.currency), balance: num(row.balancesearch), overdueBalance: num(row.overduebalancesearch), isInactive: bool(row.isinactive), createdOn: str(row.datecreated), modifiedOn: str(row.lastmodified) })"}),Ts({id:"netsuite-list-vendors",name:"List NetSuite vendors",shortName:"Vendors",instruction:"Lists vendor records from NetSuite with subsidiary, currency and balance. Useful for verifying migrated AP master data.",stepId:"queryVendors",collection:"vendors",select:"SELECT v.id, v.entityid, v.companyname, v.isperson, v.firstname, v.lastname, v.email, v.phone, v.subsidiary, BUILTIN.DF(v.subsidiary) AS subsidiaryname, cur.symbol AS currency, v.balance, v.isinactive, TO_CHAR(v.datecreated, 'YYYY-MM-DD') AS datecreated, TO_CHAR(v.lastmodifieddate, 'YYYY-MM-DD') AS lastmodified FROM vendor v LEFT JOIN currency cur ON cur.id = v.currency",orderBy:"v.id",filters:[Hd("v"),qd("v")],mapRow:"(row) => ({ id: row.id, entityId: str(row.entityid), companyName: str(row.companyname), isPerson: bool(row.isperson), firstName: str(row.firstname), lastName: str(row.lastname), email: str(row.email), phone: str(row.phone), subsidiaryId: str(row.subsidiary), subsidiary: str(row.subsidiaryname), currency: str(row.currency), balance: num(row.balance), isInactive: bool(row.isinactive), createdOn: str(row.datecreated), modifiedOn: str(row.lastmodified) })"}),Ts({id:"netsuite-list-journal-entries",name:"List NetSuite journal entries",shortName:"Journal entries",instruction:"Lists journal entry lines from NetSuite, one row per GL line and accounting book with journal, date, period, account, debit, credit and dimensions. Useful for verifying opening balances and postings at cutover.",stepId:"queryJournalLines",collection:"journalLines",select:"SELECT t.id AS journalid, t.tranid, TO_CHAR(t.trandate, 'YYYY-MM-DD') AS trandate, BUILTIN.DF(t.postingperiod) AS period, t.subsidiary, BUILTIN.DF(t.status) AS status, t.posting, t.memo AS journalmemo, cur.symbol AS currency, tl.id AS lineid, tal.accountingbook, tal.account, a.acctnumber, a.accountsearchdisplaynamecopy AS accountname, tal.debit, tal.credit, tl.memo, tl.department, tl.class, tl.location, tl.entity FROM transaction t JOIN transactionline tl ON tl.transaction = t.id JOIN transactionaccountingline tal ON tal.transaction = tl.transaction AND tal.transactionline = tl.id JOIN account a ON a.id = tal.account LEFT JOIN currency cur ON cur.id = t.currency",baseWhere:["t.type = 'Journal'"],orderBy:"t.id, tl.id, tal.accountingbook",filters:[...Yb,qd("t")],mapRow:"(row) => ({ journalId: row.journalid, tranId: str(row.tranid), date: str(row.trandate), period: str(row.period), subsidiaryId: str(row.subsidiary), status: status(row.status), posting: bool(row.posting), journalMemo: str(row.journalmemo), currency: str(row.currency), line: num(row.lineid), accountingBookId: str(row.accountingbook), accountId: str(row.account), accountNumber: str(row.acctnumber), accountName: str(row.accountname), debit: num(row.debit), credit: num(row.credit), memo: str(row.memo), departmentId: str(row.department), classId: str(row.class), locationId: str(row.location), entityId: str(row.entity) })"}),Ts({id:"netsuite-list-invoices",name:"List NetSuite invoices",shortName:"Invoices",instruction:"Lists customer invoices from NetSuite with customer, dates, status, total and amount due. Useful for verifying migrated open AR at go-live.",stepId:"queryInvoices",collection:"invoices",select:"SELECT t.id, t.tranid, t.entity, BUILTIN.DF(t.entity) AS customername, TO_CHAR(t.trandate, 'YYYY-MM-DD') AS trandate, TO_CHAR(t.duedate, 'YYYY-MM-DD') AS duedate, BUILTIN.DF(t.status) AS status, cur.symbol AS currency, t.foreigntotal, t.foreignamountunpaid, t.subsidiary, t.memo FROM transaction t LEFT JOIN currency cur ON cur.id = t.currency",baseWhere:["t.type = 'CustInvc'"],orderBy:"t.id",filters:[...Yb,qd("t"),{input:"openOnly",kind:"flag",clause:"t.status = 'A'",schema:{type:"boolean",description:"Only return open (unpaid) invoices."}}],mapRow:"(row) => ({ id: row.id, tranId: str(row.tranid), customerId: str(row.entity), customer: str(row.customername), date: str(row.trandate), dueDate: str(row.duedate), status: status(row.status), currency: str(row.currency), total: num(row.foreigntotal), amountDue: num(row.foreignamountunpaid), subsidiaryId: str(row.subsidiary), memo: str(row.memo) })"}),Ts({id:"netsuite-list-vendor-bills",name:"List NetSuite vendor bills",shortName:"Vendor bills",instruction:"Lists vendor bills from NetSuite with vendor, dates, status, approval status, total and amount due. Useful for verifying migrated open AP at go-live.",stepId:"queryBills",collection:"bills",select:"SELECT t.id, t.tranid, t.entity, BUILTIN.DF(t.entity) AS vendorname, TO_CHAR(t.trandate, 'YYYY-MM-DD') AS trandate, TO_CHAR(t.duedate, 'YYYY-MM-DD') AS duedate, BUILTIN.DF(t.status) AS status, BUILTIN.DF(t.approvalstatus) AS approvalstatus, cur.symbol AS currency, t.foreigntotal, t.foreignamountunpaid, t.subsidiary, t.memo FROM transaction t LEFT JOIN currency cur ON cur.id = t.currency",baseWhere:["t.type = 'VendBill'"],orderBy:"t.id",filters:[...Yb,qd("t"),{input:"openOnly",kind:"flag",clause:"t.status = 'A'",schema:{type:"boolean",description:"Only return open bills (approved and not fully paid)."}}],mapRow:"(row) => ({ id: row.id, referenceNo: str(row.tranid), vendorId: str(row.entity), vendor: str(row.vendorname), date: str(row.trandate), dueDate: str(row.duedate), status: status(row.status), approvalStatus: str(row.approvalstatus), currency: str(row.currency), total: row.foreigntotal === undefined ? null : Math.abs(Number(row.foreigntotal)), amountDue: num(row.foreignamountunpaid), subsidiaryId: str(row.subsidiary), memo: str(row.memo) })"}),Ts({id:"netsuite-list-dimensions",name:"List NetSuite departments, classes or locations",shortName:"Departments, classes, locations",instruction:"Lists department, class or location records from NetSuite with hierarchy and subsidiaries. Useful for validating the dimension setup after an implementation and for finding the internal IDs the write tools need.",stepId:"queryDimensions",collection:"records",properties:{dimension:{type:"string",enum:["department","class","location"],description:"Which dimension to list."}},required:["dimension"],select:{js:String.raw`'SELECT d.id, d.name, d.fullname, d.parent, d.subsidiary, d.includechildren, d.isinactive FROM ' + (() => { const table = { department: 'department', class: 'classification', location: 'location' }[String(p.dimension || '')]; if (!table) throw new Error("dimension must be 'department', 'class' or 'location'."); return table; })() + ' d'`},orderBy:"d.id",filters:[Hd("d")],mapRow:"(row) => ({ id: row.id, name: str(row.name), fullName: str(row.fullname), parentId: str(row.parent), subsidiaryIds: ids(row.subsidiary), includeChildren: bool(row.includechildren), isInactive: bool(row.isinactive) })"}),Ts({id:"netsuite-list-subsidiaries",name:"List NetSuite subsidiaries",shortName:"Subsidiaries",instruction:"Lists subsidiaries from NetSuite with hierarchy, country, base currency and elimination flag. Most create tools need a subsidiary ID from this list in OneWorld accounts.",stepId:"querySubsidiaries",collection:"subsidiaries",select:"SELECT s.id, s.name, s.fullname, s.parent, s.country, cur.symbol AS currency, s.iselimination, s.isinactive FROM subsidiary s LEFT JOIN currency cur ON cur.id = s.currency",orderBy:"s.id",filters:[Hd("s")],mapRow:"(row) => ({ id: row.id, name: str(row.name), fullName: str(row.fullname), parentId: str(row.parent), country: str(row.country), currency: str(row.currency), isElimination: bool(row.iselimination), isInactive: bool(row.isinactive) })"}),{id:"netsuite-suiteql-query",name:"Run a NetSuite SuiteQL query",shortName:"SuiteQL query",instruction:"Runs a read-only SuiteQL SELECT query against NetSuite, for any record type, join or aggregate outside the prebuilt lists (for example items, employees, transaction lines or custom records). The workhorse tool for migration validation. Returns up to 1000 rows in one call with the total row count and hasMore; values are strings as NetSuite returns them.",inputSchema:{type:"object",properties:{query:{type:"string",description:`SuiteQL SELECT statement, e.g. "SELECT id, itemid, displayname FROM item WHERE isinactive = 'F' ORDER BY id". Dates come back in the user's date format; use TO_CHAR(field, 'YYYY-MM-DD') for ISO dates and BUILTIN.DF(field) for display names. For more than 1000 rows, page by key: ORDER BY id and add WHERE id > <last id>. Common columns: account (id, acctnumber, accountsearchdisplaynamecopy as the name, fullname, accttype, isinactive; there is no acctname column), customer (id, entityid, companyname, email, subsidiary, balancesearch, isinactive), vendor (id, entityid, companyname, email, subsidiary, balance, isinactive), transaction (id, tranid, type, trandate, entity, status, foreigntotal, foreignamountunpaid, subsidiary). Alias tables and qualify columns: FROM transaction t ... t.subsidiary works, an unqualified subsidiary fails.`},maxResults:{type:"integer",minimum:1,maximum:1e3,description:"Maximum number of rows to return (max 1000). Defaults to 100."}},required:["query"],additionalProperties:!1},steps:[{id:"runSuiteQl",instruction:"Run the SuiteQL query.",config:{type:"request",systemId:Yd,url:`${Tg}/query/v1/suiteql`,method:"POST",headers:{...Rg,"Content-Type":"application/json",Prefer:"transient"},queryParams:{limit:"<<(p) => Math.min(Math.max(Math.floor(Number(p.maxResults)) || 100, 2), 1000)>>",offset:"0"},body:String.raw`<<(p) => { const query = String(p.query || '').trim(); if (!/^(select|with)\b/i.test(query)) throw new Error('query must be a SuiteQL SELECT statement.'); return JSON.stringify({ q: query }); }>>`}}],outputTransform:`(sourceData) => { ${sL} const data = sourceData.runSuiteQl && sourceData.runSuiteQl.data ? sourceData.runSuiteQl.data : {}; const items = Array.isArray(data.items) ? data.items : []; const max = Math.min(Math.max(Math.floor(Number(sourceData.maxResults)) || 100, 1), 1000); const records = stripLinks(items.slice(0, max)); const total = data.totalResults !== undefined ? Number(data.totalResults) : items.length; return { total, returned: records.length, hasMore: total > records.length, records }; }`},{id:"netsuite-get-record",name:"Get a NetSuite record",shortName:"Get record",instruction:"Fetches one NetSuite record of any type by internal ID or external ID through the REST record API, including its sublists such as transaction lines. Useful for inspecting a record in full before or after a write.",inputSchema:{type:"object",properties:{recordType:{type:"string",description:'REST record type, e.g. "customer", "vendor", "invoice", "vendorbill", "journalentry", "account", "department" or a custom record like "customrecord_x".'},internalId:{type:"string",description:"Internal ID of the record."},externalId:{type:"string",description:"External ID of the record, used when internalId is not set."},expandSubResources:{type:"boolean",description:"Include sublists and subrecords inline. Defaults to true."}},required:["recordType"],additionalProperties:!1},steps:[{id:"getRecord",instruction:"Fetch the record from the REST record API.",config:{type:"request",systemId:Yd,url:`${Tg}/record/v1/<<(p) => { const type = String(p.recordType || '').trim().toLowerCase(); if (!/^[a-z][a-z0-9_]*$/.test(type)) throw new Error('recordType must contain only letters, numbers and underscores.'); return type; }>>/<<(p) => { if (p.internalId !== undefined && p.internalId !== null && p.internalId !== '') { const id = String(p.internalId).trim(); if (!/^-?\\d+$/.test(id)) throw new Error('internalId must be a NetSuite internal ID.'); return id; } if (p.externalId !== undefined && p.externalId !== null && p.externalId !== '') return 'eid:' + encodeURIComponent(String(p.externalId)); throw new Error('Provide internalId or externalId.'); }>>`,method:"GET",headers:Rg,queryParams:{expandSubResources:"<<(p) => (p.expandSubResources === false || p.expandSubResources === 'false' ? 'false' : 'true')>>"}}}],outputTransform:`(sourceData) => { ${sL} const record = sourceData.getRecord ? sourceData.getRecord.data : undefined; if (!record || typeof record !== 'object') throw new Error('NetSuite returned no record.'); return { record: stripLinks(record) }; }`},_r({id:"netsuite-create-journal-entry",name:"Create NetSuite journal entry",shortName:"Create journal entry",instruction:`Creates a journal entry in NetSuite through the REST record API. Debit and credit lines must balance. Returns the new internal ID. ${$a}`,stepId:"createJournalEntry",recordType:"journalentry",mode:"create",properties:{...lL("create"),lines:{type:"array",description:"Journal lines. Debit and credit totals must balance.",items:uL}},required:["date","lines"],body:`${cL} if (!Array.isArray(p.lines) || p.lines.length < 2) throw new Error('lines must contain at least two journal lines.'); ${aL}`}),_r({id:"netsuite-update-journal-entry",name:"Update NetSuite journal entry",shortName:"Update journal entry",instruction:"Updates an existing NetSuite journal entry by internal ID. Only the provided fields change. When lines are provided they replace all existing lines and must balance. Entries in closed periods refuse updates.",stepId:"updateJournalEntry",recordType:"journalentry",mode:"update",properties:{...lL("update"),lines:{type:"array",description:"Optional replacement lines. When set, they replace every existing line and must balance.",items:uL}},required:[],body:`${cL} if (Array.isArray(p.lines) && p.lines.length < 2) throw new Error('lines must contain at least two journal lines; omit lines to keep the current ones.'); ${aL}`,replaceSublist:{input:"lines",sublist:"line"}}),_r({id:"netsuite-create-vendor",name:"Create NetSuite vendor",shortName:"Create vendor",instruction:`Creates a vendor record in NetSuite. OneWorld accounts need a subsidiaryId. Omit entityId when auto-numbering assigns it. ${$a}`,stepId:"createVendor",recordType:"vendor",mode:"create",properties:Bg("vendor"),required:[],body:`if (!has(p.companyName) && !((p.isPerson === true || p.isPerson === 'true') && has(p.lastName))) throw new Error('Provide companyName, or isPerson with lastName.'); ${wg}`}),_r({id:"netsuite-update-vendor",name:"Update NetSuite vendor",shortName:"Update vendor",instruction:"Updates an existing NetSuite vendor by internal ID. Only the provided fields change; set isInactive to inactivate or reactivate it.",stepId:"updateVendor",recordType:"vendor",mode:"update",properties:{...Bg("vendor"),..._g},required:[],body:wg}),_r({id:"netsuite-create-customer",name:"Create NetSuite customer",shortName:"Create customer",instruction:`Creates a customer record in NetSuite. OneWorld accounts need a subsidiaryId. Omit entityId when auto-numbering assigns it. ${$a}`,stepId:"createCustomer",recordType:"customer",mode:"create",properties:Bg("customer"),required:[],body:`if (!has(p.companyName) && !((p.isPerson === true || p.isPerson === 'true') && has(p.lastName))) throw new Error('Provide companyName, or isPerson with lastName.'); ${wg}`}),_r({id:"netsuite-update-customer",name:"Update NetSuite customer",shortName:"Update customer",instruction:"Updates an existing NetSuite customer by internal ID. Only the provided fields change; set isInactive to inactivate or reactivate it.",stepId:"updateCustomer",recordType:"customer",mode:"update",properties:{...Bg("customer"),..._g},required:[],body:wg}),_r({id:"netsuite-create-account",name:"Create NetSuite GL account",shortName:"Create GL account",instruction:`Creates a general ledger account in NetSuite's chart of accounts. ${$a}`,stepId:"createAccount",recordType:"account",mode:"create",properties:AL,required:["acctName","acctType"],body:`if (!has(p.acctName) || !has(p.acctType)) throw new Error('acctName and acctType are required.'); ${dL} ${Qg}`}),_r({id:"netsuite-update-account",name:"Update NetSuite GL account",shortName:"Update GL account",instruction:"Updates an existing NetSuite GL account by internal ID. Only the provided fields change; set isInactive to inactivate or reactivate it. Accounts with transactions may refuse a type change.",stepId:"updateAccount",recordType:"account",mode:"update",properties:{...AL,..._g},required:[],body:`${dL} ${Qg}`}),_r({id:"netsuite-create-invoice",name:"Create NetSuite invoice",shortName:"Create invoice",instruction:`Creates a customer invoice in NetSuite with item lines. Item, tax and posting rules of the account apply. ${$a}`,stepId:"createInvoice",recordType:"invoice",mode:"create",properties:{customerId:{type:"string",description:"Customer internal ID."},...Dg("create"),lines:{type:"array",description:"Item lines.",items:gL}},required:["customerId","lines"],body:`if (!Array.isArray(p.lines) || p.lines.length === 0) throw new Error('lines must contain at least one item line.'); ${vg("customerId")} ${hL}`}),_r({id:"netsuite-update-invoice",name:"Update NetSuite invoice",shortName:"Update invoice",instruction:"Updates an existing NetSuite invoice by internal ID. Only the provided fields change. When lines are provided they replace all existing item lines. Paid invoices and closed periods may refuse updates.",stepId:"updateInvoice",recordType:"invoice",mode:"update",properties:{customerId:{type:"string",description:"Optional new customer internal ID."},...Dg("update"),lines:{type:"array",description:"Optional replacement item lines; they replace every existing item line.",items:gL}},required:[],body:`if (Array.isArray(p.lines) && p.lines.length === 0) throw new Error('lines must contain at least one item line; omit lines to keep the current ones.'); ${vg("customerId")} ${hL}`,replaceSublist:{input:"lines",sublist:"item"}}),_r({id:"netsuite-create-vendor-bill",name:"Create NetSuite vendor bill",shortName:"Create vendor bill",instruction:`Creates a vendor bill in NetSuite with expense lines. Approval routing of the account applies. ${$a}`,stepId:"createVendorBill",recordType:"vendorbill",mode:"create",properties:{vendorId:{type:"string",description:"Vendor internal ID."},referenceNo:{type:"string",description:"Optional vendor invoice reference number."},...Dg("create"),lines:{type:"array",description:"Expense lines.",items:yL}},required:["vendorId","lines"],body:`if (!Array.isArray(p.lines) || p.lines.length === 0) throw new Error('lines must contain at least one expense line.'); ${vg("vendorId")} if (has(p.referenceNo)) record.tranId = String(p.referenceNo); ${mL}`}),_r({id:"netsuite-update-vendor-bill",name:"Update NetSuite vendor bill",shortName:"Update vendor bill",instruction:"Updates an existing NetSuite vendor bill by internal ID. Only the provided fields change. When lines are provided they replace all existing expense lines. Paid bills and closed periods may refuse updates.",stepId:"updateVendorBill",recordType:"vendorbill",mode:"update",properties:{vendorId:{type:"string",description:"Optional new vendor internal ID."},referenceNo:{type:"string",description:"Optional vendor invoice reference number."},...Dg("update"),lines:{type:"array",description:"Optional replacement expense lines; they replace every existing expense line.",items:yL}},required:[],body:`if (Array.isArray(p.lines) && p.lines.length === 0) throw new Error('lines must contain at least one expense line; omit lines to keep the current ones.'); ${vg("vendorId")} if (has(p.referenceNo)) record.tranId = String(p.referenceNo); ${mL}`,replaceSublist:{input:"lines",sublist:"expense"}}),_r({id:"netsuite-create-department",name:"Create NetSuite department",shortName:"Create department",instruction:`Creates a department in NetSuite. Without subsidiaryIds NetSuite assigns the parent subsidiary. ${$a}`,stepId:"createDepartment",recordType:"department",mode:"create",properties:fL,required:["name"],body:`if (!has(p.name)) throw new Error('name is required.'); ${pL} ${Qg}`}),_r({id:"netsuite-update-department",name:"Update NetSuite department",shortName:"Update department",instruction:"Updates an existing NetSuite department by internal ID. Only the provided fields change; set isInactive to inactivate or reactivate it.",stepId:"updateDepartment",recordType:"department",mode:"update",properties:{...fL,..._g},required:[],body:`${pL} ${Qg}`})],Vb={sap_s4hana:{bundleId:"sap_s4hana",templateId:"sap_s4hana",systemId:"sap_s4hana",displayName:"SAP S/4HANA",description:"Read business partners, sales orders, products and purchase orders from SAP.",systemUrl:wfe,credentialHint:"Works instantly with SAP's demo data. Add your own key later for your live system.",requiredCredentialKeys:["api_key"],demoCredentials:{api_key:"K8reTgiKCCaqvAPWC4cOjqqiLdLE8dqz"},mcpServer:{name:"sap",displayName:"SAP S/4HANA",description:"Business partners, sales orders, products and purchase orders from SAP."},installMcpServer:!0,agentLaunch:{userPrompt:"I just installed the SAP S/4HANA bundle. What can I do with it?",nextSteps:"Your first reply must be short: SAP is connected to free demo data and works right now, so offer to run one tool immediately as proof. No credential collection is needed to start. If they want their own data: their own free key comes from https://api.sap.com (SAP Business Accelerator Hub), collected and saved directly with a connect field, never via the Connections page; the system URL can then be switched to their own SAP host. Do not list the installed tools, do not add tips or explain SAP concepts unless asked."},tools:[{id:"sap-list-business-partners",name:"List SAP business partners",shortName:"Business partners",instruction:"Lists business partners (customers, suppliers, contacts) from SAP S/4HANA. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "BusinessPartnerCategory eq '2'" for organizations.`},maxResults:{type:"integer",description:"Maximum number of business partners to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchBusinessPartners",instruction:"Fetch business partners, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_BUSINESS_PARTNER/A_BusinessPartner",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"BusinessPartner,BusinessPartnerFullName,BusinessPartnerCategory,BusinessPartnerGrouping,CreationDate"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchBusinessPartners?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, businessPartners: rows.map((r) => ({ id: r.BusinessPartner, name: r.BusinessPartnerFullName, category: r.BusinessPartnerCategory, grouping: r.BusinessPartnerGrouping, createdOn: d(r.CreationDate) })) }; }"},{id:"sap-list-sales-orders",name:"List SAP sales orders",shortName:"Sales orders",instruction:"Lists sales orders from SAP S/4HANA with their net amount, currency and sold-to party. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "SalesOrderType eq 'OR'" or "TotalNetAmount gt 1000".`},maxResults:{type:"integer",description:"Maximum number of sales orders to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchSalesOrders",instruction:"Fetch sales orders, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_SALES_ORDER_SRV/A_SalesOrder",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"SalesOrder,SalesOrderType,SoldToParty,TotalNetAmount,TransactionCurrency,SalesOrderDate,OverallSDProcessStatus"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchSalesOrders?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, salesOrders: rows.map((r) => ({ id: r.SalesOrder, type: r.SalesOrderType, soldToParty: r.SoldToParty, netAmount: Number(r.TotalNetAmount), currency: r.TransactionCurrency, orderDate: d(r.SalesOrderDate), status: r.OverallSDProcessStatus })) }; }"},{id:"sap-list-products",name:"List SAP products",shortName:"Products",instruction:"Lists products (materials) from SAP S/4HANA with their type, group and base unit. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "ProductType eq 'FERT'" for finished goods.`},maxResults:{type:"integer",description:"Maximum number of products to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchProducts",instruction:"Fetch products, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_PRODUCT_SRV/A_Product",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$expand:"to_Description",$select:"Product,ProductType,ProductGroup,BaseUnit,GrossWeight,WeightUnit,CreationDate,to_Description/Language,to_Description/ProductDescription"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const nameOf = (r) => { const list = r.to_Description?.results ?? []; const hit = list.find((x) => x.Language === 'EN') ?? list[0]; return hit?.ProductDescription; }; const rows = (sourceData.fetchProducts?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, products: rows.map((r) => ({ id: r.Product, name: nameOf(r), type: r.ProductType, group: r.ProductGroup, baseUnit: r.BaseUnit, grossWeight: Number(r.GrossWeight), weightUnit: r.WeightUnit, createdOn: d(r.CreationDate) })) }; }"},{id:"sap-list-purchase-orders",name:"List SAP purchase orders",shortName:"Purchase orders",instruction:"Lists purchase orders from SAP S/4HANA with their supplier, currency and creation date. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "PurchaseOrderType eq 'NB'" for standard orders.`},maxResults:{type:"integer",description:"Maximum number of purchase orders to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchPurchaseOrders",instruction:"Fetch purchase orders, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_PURCHASEORDER_PROCESS_SRV/A_PurchaseOrder",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"PurchaseOrder,PurchaseOrderType,Supplier,PurchaseOrderDate,DocumentCurrency,CreatedByUser"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchPurchaseOrders?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, purchaseOrders: rows.map((r) => ({ id: r.PurchaseOrder, type: r.PurchaseOrderType, supplier: r.Supplier, orderDate: d(r.PurchaseOrderDate), currency: r.DocumentCurrency, createdBy: r.CreatedByUser })) }; }"},{id:"sap-list-gl-accounts",name:"List SAP chart of accounts",shortName:"Chart of accounts",instruction:"Lists general ledger accounts (the chart of accounts) from SAP S/4HANA. Supports an optional OData $filter, e.g. by ChartOfAccounts.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "ChartOfAccounts eq 'YCOA'" or "GLAccountType eq 'X'".`},maxResults:{type:"integer",description:"Maximum number of accounts to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchGLAccounts",instruction:"Fetch GL accounts, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_GLACCOUNTINCHARTOFACCOUNTS_SRV/A_GLAccountInChartOfAccounts",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:`<<(p) => p.filter ? "ChartOfAccounts ne '' and (" + p.filter + ")" : "ChartOfAccounts ne ''">>`,$expand:"to_Text",$select:"GLAccount,ChartOfAccounts,GLAccountType,GLAccountGroup,IsBalanceSheetAccount,AccountIsBlockedForPosting,to_Text/Language,to_Text/GLAccountName"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const nameOf = (r) => { const list = r.to_Text?.results ?? []; const hit = list.find((x) => x.Language === 'EN') ?? list[0]; return hit?.GLAccountName; }; const rows = (sourceData.fetchGLAccounts?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, accounts: rows.map((r) => ({ account: r.GLAccount, name: nameOf(r), chartOfAccounts: r.ChartOfAccounts, type: r.GLAccountType, group: r.GLAccountGroup, isBalanceSheet: r.IsBalanceSheetAccount, blockedForPosting: r.AccountIsBlockedForPosting })) }; }"},{id:"sap-list-billing-documents",name:"List SAP billing documents",shortName:"Billing documents",instruction:"Lists billing documents (invoices, credit memos) from SAP S/4HANA with amount, currency and sold-to party. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "BillingDocumentType eq 'F2'" or "TotalNetAmount gt 1000".`},maxResults:{type:"integer",description:"Maximum number of billing documents to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchBillingDocuments",instruction:"Fetch billing documents, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_BILLING_DOCUMENT_SRV/A_BillingDocument",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"BillingDocument,BillingDocumentType,SoldToParty,TotalNetAmount,TransactionCurrency,BillingDocumentDate"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchBillingDocuments?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, billingDocuments: rows.map((r) => ({ id: r.BillingDocument, type: r.BillingDocumentType, soldToParty: r.SoldToParty, netAmount: Number(r.TotalNetAmount), currency: r.TransactionCurrency, date: d(r.BillingDocumentDate) })) }; }"},{id:"sap-list-journal-entry-items",name:"List SAP journal entry line items",shortName:"Journal entries",instruction:"Lists journal entry line items (accounting document items) from SAP S/4HANA with company code, GL account, amount and posting date. Filter by CompanyCode, FiscalYear or PostingDate to keep results focused. Useful for verifying opening balances at cutover.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "CompanyCode eq '1010' and FiscalYear eq '2026'".`},maxResults:{type:"integer",description:"Maximum number of line items to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"fetchJournalItems",instruction:"Fetch accounting document line items, paging through results with $skip.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/API_OPLACCTGDOCITEMCUBE_SRV/A_OperationalAcctgDocItemCube",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$top:"<<pageSize>>",$skip:"<<offset>>",$filter:"<<filter>>",$select:"AccountingDocument,CompanyCode,FiscalYear,GLAccount,AmountInCompanyCodeCurrency,PostingDate"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const d = (v) => { if (typeof v !== 'string' || !v.startsWith('/Date(')) return v; const n = parseInt(v.slice(6), 10); return Number.isFinite(n) ? new Date(n).toISOString().slice(0, 10) : v; }; const rows = (sourceData.fetchJournalItems?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 200); return { total: rows.length, journalItems: rows.map((r) => ({ document: r.AccountingDocument, companyCode: r.CompanyCode, fiscalYear: r.FiscalYear, account: r.GLAccount, amount: Number(r.AmountInCompanyCodeCurrency), postingDate: d(r.PostingDate) })) }; }"},{id:"sap-query-odata",name:"Query any SAP OData service",shortName:"Query any service",instruction:"Queries any SAP S/4HANA OData service and entity set (for example API_PRODUCT_SRV/A_ProductDescription or API_SALES_ORDER_SRV/A_SalesOrderItem) with optional $select and $filter. The workhorse tool for data checks beyond the prebuilt lists.",inputSchema:{type:"object",properties:{servicePath:{type:"string",description:'Service and entity set in SERVICE/EntitySet form, e.g. "API_SALES_ORDER_SRV/A_SalesOrderItem".'},select:{type:"string",description:"Comma-separated OData $select field list. Omit for all fields."},filter:{type:"string",description:"Optional OData $filter expression."},maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 100."}},required:["servicePath"],additionalProperties:!0},steps:[{id:"queryService",instruction:"Query the requested OData service and entity set.",config:{type:"request",systemId:"sap_s4hana",url:"<<sap_s4hana_url>>/<<servicePath>>",method:"GET",headers:{APIKey:"<<sap_s4hana_api_key>>",Accept:"application/json"},queryParams:{$format:"json",$select:"<<select>>",$filter:"<<filter>>",$top:"<<pageSize>>",$skip:"<<offset>>"},pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const rows = response?.data?.d?.results ?? []; const fetched = pageInfo?.mergedResult?.d?.results?.length ?? 0; const max = sourceData?.maxResults ?? 100; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:"(sourceData) => { const rows = (sourceData.queryService?.data?.d?.results ?? []).slice(0, sourceData.maxResults ?? 100); return { total: rows.length, records: rows.map((r) => { const { __metadata, ...rest } = r; return rest; }) }; }"}]},sage100:{bundleId:"sage100",templateId:"sage100",systemId:"sage100",displayName:"Sage 100",description:"Connect on-premises Sage 100 through the superglue Secure Gateway, with a guided setup playbook and a connection test against the Business Object Interface.",systemUrl:"script://runner/vbs32",credentialHint:"Your assistant first helps you connect a Secure Gateway on your Sage 100 server, then collects your Sage company and user details.",requiredCredentialKeys:["sage_home","sage_company","sage_user","sage_password"],mcpServer:{name:"sage-100",displayName:"Sage 100",description:"Sage 100 Business Object Interface access through the Secure Gateway."},installMcpServer:!1,playbook:{id:"sage100-native-integration",name:"Sage 100 Native Integration (BOI)",whenToRun:"Use when connecting a Sage 100 installation to superglue, testing that connection, or building tools that read or write Sage 100 data through the Business Object Interface.",inputs:"A Sage 100 installation on a Windows machine the user can access; a superglue API key for the gateway; the Sage company code, a Sage user with module access, and the path to the MAS90\\Home directory; the business outcome once connected.",instructions:"First check /org/tunnels for a connected gateway with a runner target. If none is connected, guide the user step by step: download the Windows gateway from https://downloads.superglue.cloud/superglue-gateway-windows.exe onto the machine where Sage 100 and Workstation Setup are installed (the gateway must run there, ProvideX.Script is a local 32-bit COM class), create a config.yaml next to it with a tunnel_id, the server_url ending in /ws/tunnels (wss://api.superglue.cloud/ws/tunnels for hosted superglue), an API key from the API Keys page, and the line enable_script_runner: true, then run the executable. That flag is required: it opts the gateway into running Sage scripts (it is code execution on their machine, so it is off by default), and it is what registers the built-in runner target. No targets section is needed. If a tunnel is connected but has no runner target, the gateway is either missing enable_script_runner: true or is an outdated build; have the user add the flag and restart, or download the current gateway from the same URL. When the tunnel with the runner target appears, attach it to the Sage 100 connection with tools.writeConnection (tunnel with that tunnelId) and keep the URL script://runner/vbs32. Collect sage_home (full path to the MAS90\\Home directory, for example C:\\Sage\\Sage100\\MAS90\\Home, not the MAS90 directory itself), sage_company, sage_user and sage_password through the secure credential form. Then run the Test Sage 100 connection tool once and interpret the result: retVal 0 failures carry the Sage reason in sLastErrorMsg (wrong credentials, missing role access, wrong company code); COM error 0x80040154 means the gateway is not running on a machine with Sage 100 Workstation Setup; a no-license message means all Sage user seats are in use. For new capabilities, build tools whose steps use the script protocol with VBScript in the body: log on with SY_Session, set module context before touching data (nSetDate with YYYYMMDD dates, nSetModule, nLookupTask, nSetProgram), use _svc service objects for reads and _bus business objects for writes, and always release the session with nCleanup and DropObject so the license seat frees up. For reads, set each key segment with nSetKeyValue then nFind for a single record, or browse with nMoveFirst and nMoveNext, and read each field with nGetValue passing a variable that receives the value. To write a document that has lines, such as a sales order, get the header _bus object, set the header fields, get its oLines object, call nAddLine, set the line fields, then call nWrite on the header to commit the header and its lines together. A write fails with a lock error if the record is open in the Sage desktop or held by another session, so report the lock message instead of retrying. Each running script briefly consumes a Sage user seat. Ask for explicit approval before any script that writes to Sage, and warn that records open in the Sage desktop UI cause lock errors.",completionCriteria:"The gateway is connected, the installed Sage 100 system has the tunnel attached and credentials saved, and the connection test returned company data from Sage 100. Any additional requested capability works end to end, with writes explicitly approved before they ran."},agentLaunch:{userPrompt:"I just installed the Sage 100 integration. Help me connect my Sage 100 server.",nextSteps:"Your first reply must be short: one line confirming the Sage 100 integration and setup playbook are installed, then start the connection flow. Check /org/tunnels for a connected gateway with a runner target first. If none exists, walk the user through it one step at a time: download https://downloads.superglue.cloud/superglue-gateway-windows.exe onto the Windows machine where Sage 100 is installed and Workstation Setup has run, create a config.yaml next to it with tunnel_id, server_url (wss://api.superglue.cloud/ws/tunnels for hosted superglue), an API key from the API Keys page, and the line enable_script_runner: true, then run it. That flag is required: it opts the gateway into running scripts on their machine (off by default because it is code execution) and is what registers the runner target. No targets are needed in the config. If a tunnel is connected but has no runner target, the gateway is missing enable_script_runner: true or is an outdated build: have the user add the flag and restart, or download the current one from the same URL. Wait for the user to confirm, then verify the tunnel appears and attach it to the Sage 100 connection with tools.writeConnection tunnel, keeping the URL script://runner/vbs32. Use connect with the connection id and fields to save sage_home (full path to the MAS90\\Home directory, for example C:\\Sage\\Sage100\\MAS90\\Home, not MAS90 itself), sage_company (for example ABC for the demo company), sage_user and sage_password. Never send the user to the Connections page. Then run the Test Sage 100 connection tool once. If it fails, explain the specific cause in plain language before retrying. Mention that each test briefly uses one Sage user license seat. Do not list tools or add tips unless asked."},tools:[{id:"sage100-test-connection",name:"Test Sage 100 connection",shortName:"Connection test",instruction:"Logs on to Sage 100 through the Secure Gateway, opens the configured company, and reads the first customer record to verify the Business Object Interface end to end. Briefly consumes one Sage user license seat.",steps:[{id:"testConnection",instruction:"Run a VBScript through the gateway script runner that logs on via SY_Session, sets A/R module context, and reads the first customer.",config:{type:"request",systemId:"sage100",url:"<<sage100_url>>",method:"POST",body:["Option Explicit","On Error Resume Next","Dim oScript, oSS, oCust, retVal, custNo, custName, today",'Set oScript = CreateObject("ProvideX.Script")','FailOnErr "CREATE", " (Sage 100 Workstation Setup has not registered ProvideX.Script on this machine; the gateway must run on a prepared Sage 100 machine)"','oScript.Init "<<sage100_sage_home>>"','FailOnErr "INIT", " (sage_home must be the full path to the MAS90\\Home directory, not MAS90 itself)"','Set oSS = oScript.NewObject("SY_Session")','FailOnErr "SESSION", ""','retVal = oSS.nSetUser("<<sage100_sage_user>>", "<<sage100_sage_password>>")','FailOnErr "LOGON", ""',"If retVal = 0 Then",' WScript.Echo "LOGON FAILED: " & oSS.sLastErrorMsg'," WScript.Quit 1","End If",'retVal = oSS.nSetCompany("<<sage100_sage_company>>")','FailOnErr "COMPANY", ""',"If retVal = 0 Then",' WScript.Echo "COMPANY FAILED: " & oSS.sLastErrorMsg'," oSS.nCleanup"," oSS.DropObject"," WScript.Quit 1","End If",'today = Year(Date) & Right("0" & Month(Date), 2) & Right("0" & Day(Date), 2)','retVal = oSS.nSetDate("A/R", today)','FailOnErr "DATE", ""','retVal = oSS.nSetModule("A/R")','FailOnErr "MODULE", ""','retVal = oSS.nSetProgram(oSS.nLookupTask("AR_Customer_ui"))','FailOnErr "TASK", ""',"If retVal = 0 Then",' WScript.Echo "TASK FAILED: " & oSS.sLastErrorMsg'," oSS.nCleanup"," oSS.DropObject"," WScript.Quit 1","End If",'Set oCust = oScript.NewObject("AR_Customer_svc", oSS)','FailOnErr "CUSTOMER OBJECT", ""',"retVal = oCust.nMoveFirst()",'FailOnErr "READ", ""',"If retVal = 0 Then",' WScript.Echo "READ FAILED: " & oCust.sLastErrorMsg',"Else",' custNo = "" : custName = ""',' retVal = oCust.nGetValue("CustomerNo$", custNo)',' retVal = oCust.nGetValue("CustomerName$", custName)',' FailOnErr "READ VALUE", " (ByRef value marshalling failed)"',' WScript.Echo "CONNECTED - company <<sage100_sage_company>>, first customer: " & custNo & " / " & custName',"End If","oCust.DropObject","oSS.nCleanup","oSS.DropObject","If retVal = 0 Then WScript.Quit 1","","Sub FailOnErr(stage, hint)"," If Err.Number <> 0 Then",' WScript.Echo stage & " FAILED: [0x" & Hex(Err.Number) & "] " & Err.Description & hint'," WScript.Quit 1"," End If","End Sub"].join(`
113
+ `)}}]}]},sage_intacct:{bundleId:"sage_intacct",templateId:"sage_intacct",systemId:"sage_intacct",displayName:"Sage Intacct",description:"Install a Sage Intacct system, eight read/query tools, fourteen write tools and a native integration playbook.",systemUrl:"https://api.intacct.com/ia/xml/xmlgw.phtml",credentialHint:"Works instantly with a Sage Intacct demo company. Enter your company ID and API user credentials to use your own company. Web Services sender credentials are preconfigured.",requiredCredentialKeys:["sender_id","sender_password","user_id","user_password","company_id"],demoCredentials:{company_id:"IndexCommerceMPP-DEV",user_id:"superglue",user_password:"Linux123___"},mcpServer:{name:"sage-intacct",displayName:"Sage Intacct",description:"Chart of accounts, customers, vendors, journal entries and ad-hoc object queries from Sage Intacct, plus create and update tools for GL accounts, journal entries, invoices, bills, departments, vendors and customers."},installMcpServer:!1,playbook:{id:"sage-intacct-native-integration",name:"Sage Intacct Native Integration",whenToRun:"Use when connecting, validating, querying or extending a Sage Intacct integration through XML Web Services.",inputs:"A configured Sage Intacct system; the object or business process to work with; optional Location/Entity ID for multi-entity companies; validation criteria and desired output.",instructions:"Use the installed read-only tools for chart of accounts, customers, vendors, journal entries, invoices, bills and departments. Use Query any Sage Intacct object for supported objects outside the named library. Use the installed create and update tools for GL accounts, journal entries, invoices, bills, departments, vendors and customers only after the user explicitly confirms the exact records to write; the create tools are not idempotent and re-running them duplicates records. Apply the configured Location/Entity ID when present. Verify every XML Web Services response at control, authentication and function-result level, and preserve Sage support IDs in failures. For other objects or operations, inspect Sage object documentation, create separate least-privilege tools, validate them in a development company and require explicit user confirmation before modifying Sage data.",completionCriteria:"The requested Sage data, write result or validation result is returned; entity scope is correct; Sage XML failures are surfaced as failures with support IDs; no Sage data is modified unless the user explicitly requested and confirmed the write."},agentLaunch:{userPrompt:"I just installed the Sage Intacct integration. What can I do with it?",nextSteps:"Your first reply must be short: one line confirming the Sage Intacct integration and native integration playbook are installed, then collect credentials. The Web Services sender credentials are already configured. Use connect with this system's connection id and fields to save user_id, user_password and company_id, plus optional entity_id when the user wants to target one entity in a multi-entity company. Never send the user to the Connections page. The user id and password are an API user login in the company; company id is the Intacct company id. Once saved, offer one read-only test run. Do not list the installed tools or add tips unless asked. The query tool accepts other supported Intacct object names, and additional read or write tools can be built beyond the default library. The installed create and update tools modify Sage data; run them only after the user confirms the exact records to write."},tools:[{id:"sage-intacct-list-accounts",name:"List Sage Intacct chart of accounts",shortName:"Chart of accounts",instruction:"Lists general ledger accounts (the chart of accounts) from Sage Intacct via the XML Web Services API. Useful for validating an imported chart of accounts after a migration.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryAccounts",instruction:"Query GLACCOUNT records via readByQuery-style paging.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>GLACCOUNT</object><select><field>RECORDNO</field><field>ACCOUNTNO</field><field>TITLE</field><field>ACCOUNTTYPE</field><field>NORMALBALANCE</field><field>STATUS</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.GLACCOUNT : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.GLACCOUNT : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryAccounts",objectNameExpression:"'GLACCOUNT'",collectionName:"accounts",mapExpression:"(record) => ({ recordNo: record.RECORDNO, account: record.ACCOUNTNO, name: record.TITLE, type: record.ACCOUNTTYPE, normalBalance: record.NORMALBALANCE, status: record.STATUS })"})},{id:"sage-intacct-list-customers",name:"List Sage Intacct customers",shortName:"Customers",instruction:"Lists customer master records from Sage Intacct accounts receivable. Useful for verifying migrated AR master data.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryCustomers",instruction:"Query CUSTOMER records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>CUSTOMER</object><select><field>RECORDNO</field><field>CUSTOMERID</field><field>NAME</field><field>STATUS</field><field>WHENCREATED</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.CUSTOMER : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.CUSTOMER : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryCustomers",objectNameExpression:"'CUSTOMER'",collectionName:"customers",mapExpression:"(record) => ({ recordNo: record.RECORDNO, customerId: record.CUSTOMERID, name: record.NAME, status: record.STATUS, createdOn: record.WHENCREATED })"})},{id:"sage-intacct-list-vendors",name:"List Sage Intacct vendors",shortName:"Vendors",instruction:"Lists vendor master records from Sage Intacct accounts payable. Useful for verifying migrated AP master data.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryVendors",instruction:"Query VENDOR records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>VENDOR</object><select><field>RECORDNO</field><field>VENDORID</field><field>NAME</field><field>STATUS</field><field>WHENCREATED</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.VENDOR : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.VENDOR : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryVendors",objectNameExpression:"'VENDOR'",collectionName:"vendors",mapExpression:"(record) => ({ recordNo: record.RECORDNO, vendorId: record.VENDORID, name: record.NAME, status: record.STATUS, createdOn: record.WHENCREATED })"})},{id:"sage-intacct-list-journal-entries",name:"List Sage Intacct journal entries",shortName:"Journal entries",instruction:"Lists general ledger entries from Sage Intacct with account, type and amount. Useful for verifying opening balances and postings at cutover.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryJournalEntries",instruction:"Query GLENTRY records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>GLENTRY</object><select><field>RECORDNO</field><field>BATCHNO</field><field>ACCOUNTNO</field><field>TR_TYPE</field><field>AMOUNT</field><field>ENTRY_DATE</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.GLENTRY : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.GLENTRY : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryJournalEntries",objectNameExpression:"'GLENTRY'",collectionName:"journalEntries",mapExpression:"(record) => ({ recordNo: record.RECORDNO, batch: record.BATCHNO, account: record.ACCOUNTNO, type: record.TR_TYPE, amount: Number(record.AMOUNT), date: record.ENTRY_DATE })"})},{id:"sage-intacct-list-invoices",name:"List Sage Intacct invoices",shortName:"Invoices",instruction:"Lists accounts receivable invoices from Sage Intacct. Useful for verifying migrated open AR at go-live.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryInvoices",instruction:"Query ARINVOICE records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>ARINVOICE</object><select><field>RECORDNO</field><field>RECORDID</field><field>CUSTOMERID</field><field>TOTALDUE</field><field>WHENCREATED</field><field>STATE</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.ARINVOICE : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.ARINVOICE : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryInvoices",objectNameExpression:"'ARINVOICE'",collectionName:"invoices",mapExpression:"(record) => ({ recordNo: record.RECORDNO, invoiceId: record.RECORDID, customerId: record.CUSTOMERID, totalDue: Number(record.TOTALDUE), createdOn: record.WHENCREATED, state: record.STATE })"})},{id:"sage-intacct-list-bills",name:"List Sage Intacct bills",shortName:"Bills",instruction:"Lists accounts payable bills from Sage Intacct. Useful for verifying migrated open AP at go-live.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryBills",instruction:"Query APBILL records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>APBILL</object><select><field>RECORDNO</field><field>RECORDID</field><field>VENDORID</field><field>TOTALDUE</field><field>WHENCREATED</field><field>STATE</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.APBILL : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.APBILL : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryBills",objectNameExpression:"'APBILL'",collectionName:"bills",mapExpression:"(record) => ({ recordNo: record.RECORDNO, billId: record.RECORDID, vendorId: record.VENDORID, totalDue: Number(record.TOTALDUE), createdOn: record.WHENCREATED, state: record.STATE })"})},{id:"sage-intacct-list-departments",name:"List Sage Intacct departments",shortName:"Departments",instruction:"Lists department dimensions from Sage Intacct. Useful for validating the dimension setup after an implementation.",inputSchema:{type:"object",properties:{maxResults:{type:"integer",description:"Maximum number of records to return. Defaults to 200."}},additionalProperties:!0},steps:[{id:"queryDepartments",instruction:"Query DEPARTMENT records.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<query><object>DEPARTMENT</object><select><field>RECORDNO</field><field>DEPARTMENTID</field><field>TITLE</field><field>STATUS</field></select><pagesize><<pageSize>></pagesize><offset><<offset>></offset></query>"),pagination:{type:"offsetBased",pageSize:"100",stopCondition:"(response, pageInfo, sourceData) => { const dig = (o) => o && o.RESPONSE && o.RESPONSE.OPERATION && o.RESPONSE.OPERATION.RESULT ? o.RESPONSE.OPERATION.RESULT.DATA : undefined; const cur = dig(response && response.data); const cr = cur ? cur.DEPARTMENT : undefined; const rows = Array.isArray(cr) ? cr : (cr ? [cr] : []); const mr = dig(pageInfo && pageInfo.mergedResult); const mraw = mr ? mr.DEPARTMENT : undefined; const fetched = Array.isArray(mraw) ? mraw.length : (mraw ? 1 : 0); const max = (sourceData && sourceData.maxResults) ?? 200; return rows.length === 0 || fetched >= max; }"}}}],outputTransform:vs({stepId:"queryDepartments",objectNameExpression:"'DEPARTMENT'",collectionName:"departments",mapExpression:"(record) => ({ recordNo: record.RECORDNO, departmentId: record.DEPARTMENTID, name: record.TITLE, status: record.STATUS })"})},{id:"sage-intacct-query-object",name:"Query any Sage Intacct object",shortName:"Query any object",instruction:"Queries any Sage Intacct object by name (for example GLACCOUNT, PROJECT, GLENTRY, ARINVOICE) using the XML Web Services readByQuery, with an optional Intacct query filter. The workhorse tool for migration validation beyond the prebuilt lists. Returns up to 1000 records in one call.",inputSchema:{type:"object",properties:{object:{type:"string",description:'Intacct object name, e.g. "GLACCOUNT", "PROJECT", "GLENTRY", "ARINVOICE".'},query:{type:"string",description:`Optional Intacct query filter, e.g. "STATUS = 'active'". Leave empty to return all records.`},maxResults:{type:"integer",description:"Maximum number of records to return (max 1000). Defaults to 100."}},required:["object"],additionalProperties:!0},steps:[{id:"queryObject",instruction:"Run readByQuery for the requested object.",config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<readByQuery><object><<(p) => { const value = String(p.object || '').toUpperCase(); if (!/^[A-Z][A-Z0-9_]*$/.test(value)) throw new Error('Sage Intacct object must contain only letters, numbers, and underscores.'); return value; }>></object><fields>*</fields><query><<(p) => String(p.query || '').replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;')>></query><pagesize><<(p) => Math.min(Math.max(Number(p.maxResults) || 100, 1), 1000)>></pagesize></readByQuery>")}}],outputTransform:vs({stepId:"queryObject",objectNameExpression:"(sourceData && sourceData.object ? String(sourceData.object) : '').toUpperCase()",collectionName:"records",includeTotalCount:!0})},{id:"sage-intacct-create-journal-entry",name:"Create Sage Intacct journal entry",shortName:"Create journal entry",instruction:"Creates a journal entry (GLBATCH with GLENTRY lines) in Sage Intacct via the XML Web Services API. Debits and credits must balance. Re-running this tool creates another journal entry; it is not idempotent.",inputSchema:{type:"object",properties:{journal:{type:"string",description:'Journal symbol, e.g. "GJ". Defaults to GJ.'},date:{type:"string",description:"Posting date as YYYY-MM-DD."},title:{type:"string",description:"Journal entry description."},lines:{type:"array",description:"Journal lines. Debit and credit totals must balance.",items:{type:"object",properties:{accountNo:{type:"string",description:"GL account number."},type:{type:"string",enum:["debit","credit"]},amount:{type:"number",description:"Positive amount."},department:{type:"string",description:"Optional department ID."},location:{type:"string",description:"Optional location ID."},memo:{type:"string",description:"Optional line description."}},required:["accountNo","type","amount"],additionalProperties:!0}}},required:["date","title","lines"],additionalProperties:!0},steps:[{id:"createJournalEntry",instruction:"Create the GLBATCH record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><GLBATCH><JOURNAL><<(sourceData) => { ${Ds} return esc(sourceData.journal || 'GJ'); }>></JOURNAL><BATCH_DATE><<(sourceData) => { ${nL} return toIntacctDate(sourceData.date); }>></BATCH_DATE><BATCH_TITLE><<(sourceData) => { ${Ds} return esc(sourceData.title); }>></BATCH_TITLE><ENTRIES><<(sourceData) => { ${Ds} ${oL} ${iL} const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length === 0) throw new Error('lines must contain at least one journal line.'); assertBalanced(lines); return lines.map(lineXml).join(''); }>></ENTRIES></GLBATCH></create>`)}}],outputTransform:Eu({stepId:"createJournalEntry",objectName:"GLBATCH"})},{id:"sage-intacct-update-journal-entry",name:"Update Sage Intacct journal entry",shortName:"Update journal entry",instruction:"Updates an existing journal entry (GLBATCH) in Sage Intacct by record number. Posted or locked entries may refuse updates. When lines are provided they replace all existing lines of the entry.",inputSchema:{type:"object",properties:{recordNo:{type:"integer",description:"RECORDNO of the journal entry to update."},journal:{type:"string",description:"Optional new journal symbol."},date:{type:"string",description:"Optional new posting date as YYYY-MM-DD."},title:{type:"string",description:"Optional new description."},lines:{type:"array",description:"Optional replacement lines. When set, they replace every existing line and must balance.",items:{type:"object",properties:{accountNo:{type:"string",description:"GL account number."},type:{type:"string",enum:["debit","credit"]},amount:{type:"number",description:"Positive amount."},department:{type:"string",description:"Optional department ID."},location:{type:"string",description:"Optional location ID."},memo:{type:"string",description:"Optional line description."}},required:["accountNo","type","amount"],additionalProperties:!0}}},required:["recordNo"],additionalProperties:!0},steps:[{id:"updateJournalEntry",instruction:"Update the GLBATCH record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><GLBATCH><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { ${Ds} ${nL} ${oL} ${iL} let xml = ''; if (sourceData.journal) xml += '<JOURNAL>' + esc(sourceData.journal) + '</JOURNAL>'; if (sourceData.date) xml += '<BATCH_DATE>' + toIntacctDate(sourceData.date) + '</BATCH_DATE>'; if (sourceData.title) xml += '<BATCH_TITLE>' + esc(sourceData.title) + '</BATCH_TITLE>'; if (Array.isArray(sourceData.lines) && sourceData.lines.length > 0) { assertBalanced(sourceData.lines); xml += '<ENTRIES>' + sourceData.lines.map(lineXml).join('') + '</ENTRIES>'; } if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></GLBATCH></update>`)}}],outputTransform:Eu({stepId:"updateJournalEntry",objectName:"GLBATCH"})},{id:"sage-intacct-create-vendor",name:"Create Sage Intacct vendor",shortName:"Create vendor",instruction:"Creates a vendor master record in Sage Intacct via the XML Web Services API. Omit vendorId when the company uses vendor auto-numbering. Re-running this tool creates another vendor; it is not idempotent.",inputSchema:{type:"object",properties:{vendorId:{type:"string",description:"Vendor ID. Omit when auto-numbering assigns it."},name:{type:"string",description:"Vendor name."},taxId:{type:"string",description:"Optional tax ID."}},required:["name"],additionalProperties:!0},steps:[{id:"createVendor",instruction:"Create the VENDOR record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><VENDOR><<(sourceData) => { ${Ds} if (!sourceData.name) throw new Error('name is required.'); let xml = ''; if (sourceData.vendorId) xml += '<VENDORID>' + esc(sourceData.vendorId) + '</VENDORID>'; xml += '<NAME>' + esc(sourceData.name) + '</NAME>'; if (sourceData.taxId) xml += '<TAXID>' + esc(sourceData.taxId) + '</TAXID>'; return xml; }>></VENDOR></create>`)}}],outputTransform:Eu({stepId:"createVendor",objectName:"VENDOR"})},{id:"sage-intacct-update-vendor",name:"Update Sage Intacct vendor",shortName:"Update vendor",instruction:"Updates an existing vendor master record in Sage Intacct by record number. Only the provided fields change.",inputSchema:{type:"object",properties:{recordNo:{type:"integer",description:"RECORDNO of the vendor to update."},name:{type:"string",description:"Optional new vendor name."},status:{type:"string",enum:["active","inactive"]},taxId:{type:"string",description:"Optional new tax ID."}},required:["recordNo"],additionalProperties:!0},steps:[{id:"updateVendor",instruction:"Update the VENDOR record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><VENDOR><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { ${Ds} let xml = ''; if (sourceData.name) xml += '<NAME>' + esc(sourceData.name) + '</NAME>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; if (sourceData.taxId) xml += '<TAXID>' + esc(sourceData.taxId) + '</TAXID>'; if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></VENDOR></update>`)}}],outputTransform:Eu({stepId:"updateVendor",objectName:"VENDOR"})},{id:"sage-intacct-create-customer",name:"Create Sage Intacct customer",shortName:"Create customer",instruction:"Creates a customer master record in Sage Intacct via the XML Web Services API. Omit customerId when the company uses customer auto-numbering. Re-running this tool creates another customer; it is not idempotent.",inputSchema:{type:"object",properties:{customerId:{type:"string",description:"Customer ID. Omit when auto-numbering assigns it."},name:{type:"string",description:"Customer name."},taxId:{type:"string",description:"Optional tax ID."}},required:["name"],additionalProperties:!0},steps:[{id:"createCustomer",instruction:"Create the CUSTOMER record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><CUSTOMER><<(sourceData) => { ${Ds} if (!sourceData.name) throw new Error('name is required.'); let xml = ''; if (sourceData.customerId) xml += '<CUSTOMERID>' + esc(sourceData.customerId) + '</CUSTOMERID>'; xml += '<NAME>' + esc(sourceData.name) + '</NAME>'; if (sourceData.taxId) xml += '<TAXID>' + esc(sourceData.taxId) + '</TAXID>'; return xml; }>></CUSTOMER></create>`)}}],outputTransform:Eu({stepId:"createCustomer",objectName:"CUSTOMER"})},{id:"sage-intacct-update-customer",name:"Update Sage Intacct customer",shortName:"Update customer",instruction:"Updates an existing customer master record in Sage Intacct by record number. Only the provided fields change.",inputSchema:{type:"object",properties:{recordNo:{type:"integer",description:"RECORDNO of the customer to update."},name:{type:"string",description:"Optional new customer name."},status:{type:"string",enum:["active","inactive"]},taxId:{type:"string",description:"Optional new tax ID."}},required:["recordNo"],additionalProperties:!0},steps:[{id:"updateCustomer",instruction:"Update the CUSTOMER record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><CUSTOMER><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { ${Ds} let xml = ''; if (sourceData.name) xml += '<NAME>' + esc(sourceData.name) + '</NAME>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; if (sourceData.taxId) xml += '<TAXID>' + esc(sourceData.taxId) + '</TAXID>'; if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></CUSTOMER></update>`)}}],outputTransform:Eu({stepId:"updateCustomer",objectName:"CUSTOMER"})},{id:"sage-intacct-create-account",name:"Create Sage Intacct GL account",shortName:"Create GL account",instruction:"Creates a general ledger account in Sage Intacct via the XML Web Services API. Re-running this tool creates another account; it is not idempotent.",inputSchema:{type:"object",required:["accountNo","title","normalBalance","accountType"],properties:{title:{type:"string"},accountNo:{type:"string"},accountType:{type:"string",enum:["balancesheet","incomestatement"]},normalBalance:{type:"string",enum:["debit","credit"]},closingType:{type:"string",enum:["non-closing account","closing account"],description:"Period-end closing type. Defaults to non-closing account."},closingAccountNo:{type:"string",description:"Account to close into. Sage requires it when closingType is closing account."}}},steps:[{id:"createAccount",instruction:"Create the GLACCOUNT record via the Sage Intacct XML API.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><GLACCOUNT><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); if (!sourceData.accountNo) throw new Error('accountNo is required.'); if (!sourceData.title) throw new Error('title is required.'); let xml = '<ACCOUNTNO>' + esc(sourceData.accountNo) + '</ACCOUNTNO>'; xml += '<TITLE>' + esc(sourceData.title) + '</TITLE>'; xml += '<NORMALBALANCE>' + esc(sourceData.normalBalance || 'debit') + '</NORMALBALANCE>'; xml += '<ACCOUNTTYPE>' + esc(sourceData.accountType || 'balancesheet') + '</ACCOUNTTYPE>'; xml += '<CLOSINGTYPE>' + esc(sourceData.closingType || 'non-closing account') + '</CLOSINGTYPE>'; if (sourceData.closingAccountNo) xml += '<CLOSINGACCOUNTNO>' + esc(sourceData.closingAccountNo) + '</CLOSINGACCOUNTNO>'; return xml; }>></GLACCOUNT></create>`)}}],outputTransform:"(sourceData) => { const response = sourceData.createAccount && sourceData.createAccount.data ? sourceData.createAccount.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.GLACCOUNT || data.glaccount) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }"},{id:"sage-intacct-update-account",name:"Update Sage Intacct GL account",shortName:"Update GL account",instruction:"Updates an existing general ledger account in Sage Intacct by account number. Only the provided fields change.",inputSchema:{type:"object",required:["accountNo"],properties:{title:{type:"string"},accountNo:{type:"string"},accountType:{type:"string",enum:["balancesheet","incomestatement"]},normalBalance:{type:"string",enum:["debit","credit"]},status:{type:"string",enum:["active","inactive"]}}},steps:[{id:"updateAccount",instruction:"Update the GLACCOUNT record by account number.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><GLACCOUNT><ACCOUNTNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); if (!sourceData.accountNo) throw new Error('accountNo is required.'); return esc(sourceData.accountNo); }>></ACCOUNTNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); let xml = ''; if (sourceData.title) xml += '<TITLE>' + esc(sourceData.title) + '</TITLE>'; if (sourceData.normalBalance) xml += '<NORMALBALANCE>' + esc(sourceData.normalBalance) + '</NORMALBALANCE>'; if (sourceData.accountType) xml += '<ACCOUNTTYPE>' + esc(sourceData.accountType) + '</ACCOUNTTYPE>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></GLACCOUNT></update>`)}}],outputTransform:"(sourceData) => { const response = sourceData.updateAccount && sourceData.updateAccount.data ? sourceData.updateAccount.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.GLACCOUNT || data.glaccount) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { accountNo: sourceData.accountNo, record }; }"},{id:"sage-intacct-create-invoice",name:"Create Sage Intacct AR invoice",shortName:"Create invoice",instruction:"Creates an AR invoice in Sage Intacct via the XML Web Services API. Requires a customer ID, transaction date, and at least one line item with a GL account and amount. Re-running creates another invoice; it is not idempotent.",inputSchema:{type:"object",required:["customerId","dateCreated","dateDue","lines"],properties:{lines:{type:"array",items:{type:"object",required:["glAccountNo","amount"],properties:{memo:{type:"string"},amount:{type:"number"},glAccountNo:{type:"string"},departmentId:{type:"string"},locationId:{type:"string"},vendorId:{type:"string"},customerId:{type:"string"},projectId:{type:"string"}}}},dateDue:{type:"string"},customerId:{type:"string"},dateCreated:{type:"string"},datePosted:{type:"string"},termName:{type:"string"},description:{type:"string"}}},steps:[{id:"createInvoice",instruction:"Create the ARINVOICE record with line items.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<create><ARINVOICE><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;').replaceAll(\"'\", '&apos;'); if (!sourceData.customerId) throw new Error('customerId is required.'); if (!sourceData.dateCreated) throw new Error('dateCreated is required (YYYY-MM-DD).'); const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length === 0) throw new Error('lines must contain at least one invoice line.'); const match = String(sourceData.dateCreated).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); const dateXml = match ? `<WHENCREATED><YEAR>${match[1]}</YEAR><MONTH>${match[2]}</MONTH><DAY>${match[3]}</DAY></WHENCREATED>` : `<WHENCREATED>${esc(sourceData.dateCreated)}</WHENCREATED>`; let xml = '<CUSTOMERID>' + esc(sourceData.customerId) + '</CUSTOMERID>'; xml += dateXml; if (sourceData.datePosted) { const mp = String(sourceData.datePosted).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (mp) xml += `<WHENPOSTED><YEAR>${mp[1]}</YEAR><MONTH>${mp[2]}</MONTH><DAY>${mp[3]}</DAY></WHENPOSTED>`; } if (sourceData.dateDue) { const md = String(sourceData.dateDue).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (md) xml += `<WHENDUE><YEAR>${md[1]}</YEAR><MONTH>${md[2]}</MONTH><DAY>${md[3]}</DAY></WHENDUE>`; } else if (sourceData.termName) { xml += '<TERMNAME>' + esc(sourceData.termName) + '</TERMNAME>'; } if (sourceData.description) xml += '<DESCRIPTION>' + esc(sourceData.description) + '</DESCRIPTION>'; xml += '<ARINVOICEITEMS>'; lines.forEach((line) => { if (!line.glAccountNo) throw new Error('Each line requires glAccountNo.'); if (line.amount == null) throw new Error('Each line requires amount.'); xml += '<ARINVOICEITEM>'; xml += '<ACCOUNTNO>' + esc(line.glAccountNo) + '</ACCOUNTNO>'; xml += '<AMOUNT>' + Number(line.amount) + '</AMOUNT>'; if (line.memo) xml += '<MEMO>' + esc(line.memo) + '</MEMO>'; if (line.departmentId) xml += '<DEPARTMENTID>' + esc(line.departmentId) + '</DEPARTMENTID>'; if (line.locationId) xml += '<LOCATIONID>' + esc(line.locationId) + '</LOCATIONID>'; if (line.vendorId) xml += '<VENDORID>' + esc(line.vendorId) + '</VENDORID>'; if (line.customerId) xml += '<CUSTOMERID>' + esc(line.customerId) + '</CUSTOMERID>'; if (line.projectId) xml += '<PROJECTID>' + esc(line.projectId) + '</PROJECTID>'; xml += '</ARINVOICEITEM>'; }); xml += '</ARINVOICEITEMS>'; return xml; }>></ARINVOICE></create>")}}],outputTransform:"(sourceData) => { const response = sourceData.createInvoice && sourceData.createInvoice.data ? sourceData.createInvoice.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.ARINVOICE || data.arinvoice) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }"},{id:"sage-intacct-update-invoice",name:"Update Sage Intacct AR invoice",shortName:"Update invoice",instruction:"Updates an existing AR invoice in Sage Intacct by record number. Only the provided fields change. Line items can be added or updated by line number.",inputSchema:{type:"object",required:["recordNo"],properties:{recordNo:{type:"integer"},description:{type:"string"},customerId:{type:"string"},dateCreated:{type:"string"},dateDue:{type:"string"},termName:{type:"string"},lines:{type:"array",items:{type:"object",properties:{lineNo:{type:"integer"},memo:{type:"string"},amount:{type:"number"},glAccountNo:{type:"string"},departmentId:{type:"string"},locationId:{type:"string"},vendorId:{type:"string"},customerId:{type:"string"},projectId:{type:"string"}}}}}},steps:[{id:"updateInvoice",instruction:"Update the ARINVOICE record by RECORDNO.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It("<update><ARINVOICE><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('\"', '&quot;').replaceAll(\"'\", '&apos;'); let xml = ''; if (sourceData.customerId) xml += '<CUSTOMERID>' + esc(sourceData.customerId) + '</CUSTOMERID>'; if (sourceData.dateCreated) { const match = String(sourceData.dateCreated).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (match) xml += `<WHENCREATED><YEAR>${match[1]}</YEAR><MONTH>${match[2]}</MONTH><DAY>${match[3]}</DAY></WHENCREATED>`; } if (sourceData.dateDue) { const md = String(sourceData.dateDue).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); if (md) xml += `<WHENDUE><YEAR>${md[1]}</YEAR><MONTH>${md[2]}</MONTH><DAY>${md[3]}</DAY></WHENDUE>`; } if (sourceData.termName) xml += '<TERMNAME>' + esc(sourceData.termName) + '</TERMNAME>'; if (sourceData.description) xml += '<DESCRIPTION>' + esc(sourceData.description) + '</DESCRIPTION>'; const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length > 0) { xml += '<ARINVOICEITEMS>'; lines.forEach((line) => { xml += '<ARINVOICEITEM>'; if (line.lineNo) xml += '<LINE_NO>' + Number(line.lineNo) + '</LINE_NO>'; if (line.glAccountNo) xml += '<ACCOUNTNO>' + esc(line.glAccountNo) + '</ACCOUNTNO>'; if (line.amount != null) xml += '<AMOUNT>' + Number(line.amount) + '</AMOUNT>'; if (line.memo) xml += '<MEMO>' + esc(line.memo) + '</MEMO>'; if (line.departmentId) xml += '<DEPARTMENTID>' + esc(line.departmentId) + '</DEPARTMENTID>'; if (line.locationId) xml += '<LOCATIONID>' + esc(line.locationId) + '</LOCATIONID>'; if (line.vendorId) xml += '<VENDORID>' + esc(line.vendorId) + '</VENDORID>'; if (line.customerId) xml += '<CUSTOMERID>' + esc(line.customerId) + '</CUSTOMERID>'; if (line.projectId) xml += '<PROJECTID>' + esc(line.projectId) + '</PROJECTID>'; xml += '</ARINVOICEITEM>'; }); xml += '</ARINVOICEITEMS>'; } if (!xml && lines.length === 0) throw new Error('Provide at least one field to update.'); return xml; }>></ARINVOICE></update>")}}],outputTransform:"(sourceData) => { const response = sourceData.updateInvoice && sourceData.updateInvoice.data ? sourceData.updateInvoice.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.ARINVOICE || data.arinvoice) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: sourceData.recordNo, record }; }"},{id:"sage-intacct-create-bill",name:"Create Sage Intacct AP bill",shortName:"Create bill",instruction:"Creates an AP bill in Sage Intacct via the XML Web Services API. Requires a vendor ID, transaction date, and at least one line item with a GL account and amount. Re-running creates another bill; it is not idempotent.",inputSchema:{type:"object",required:["lines","dateDue","vendorId","dateCreated"],properties:{lines:{type:"array",items:{type:"object",required:["glAccountNo","amount"],properties:{memo:{type:"string"},amount:{type:"number"},glAccountNo:{type:"string"},departmentId:{type:"string"},locationId:{type:"string"},vendorId:{type:"string"},customerId:{type:"string"},projectId:{type:"string"}}}},dateDue:{type:"string"},vendorId:{type:"string"},dateCreated:{type:"string"},datePosted:{type:"string"},termName:{type:"string"},description:{type:"string"}}},steps:[{id:"createBill",instruction:"Create the APBILL record with line items.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><APBILL><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); if (!sourceData.vendorId) throw new Error('vendorId is required.'); if (!sourceData.dateCreated) throw new Error('dateCreated is required (YYYY-MM-DD).'); const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length === 0) throw new Error('lines must contain at least one bill line.'); const match = String(sourceData.dateCreated).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); const dateStr = match ? match[2] + '/' + match[3] + '/' + match[1] : sourceData.dateCreated; let xml = '<VENDORID>' + esc(sourceData.vendorId) + '</VENDORID>'; xml += '<WHENCREATED>' + esc(dateStr) + '</WHENCREATED>'; if (sourceData.datePosted) { const mp = String(sourceData.datePosted).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); xml += '<WHENPOSTED>' + esc(mp ? mp[2] + '/' + mp[3] + '/' + mp[1] : sourceData.datePosted) + '</WHENPOSTED>'; } if (sourceData.dateDue) { const md = String(sourceData.dateDue).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); xml += '<WHENDUE>' + esc(md ? md[2] + '/' + md[3] + '/' + md[1] : sourceData.dateDue) + '</WHENDUE>'; } else if (sourceData.termName) { xml += '<TERMNAME>' + esc(sourceData.termName) + '</TERMNAME>'; } if (sourceData.description) xml += '<DESCRIPTION>' + esc(sourceData.description) + '</DESCRIPTION>'; xml += '<APBILLITEMS>'; lines.forEach((line) => { if (!line.glAccountNo) throw new Error('Each line requires glAccountNo.'); if (line.amount == null) throw new Error('Each line requires amount.'); xml += '<APBILLITEM>'; xml += '<ACCOUNTNO>' + esc(line.glAccountNo) + '</ACCOUNTNO>'; xml += '<AMOUNT>' + Number(line.amount) + '</AMOUNT>'; if (line.memo) xml += '<MEMO>' + esc(line.memo) + '</MEMO>'; if (line.departmentId) xml += '<DEPARTMENTID>' + esc(line.departmentId) + '</DEPARTMENTID>'; if (line.locationId) xml += '<LOCATIONID>' + esc(line.locationId) + '</LOCATIONID>'; if (line.vendorId) xml += '<VENDORID>' + esc(line.vendorId) + '</VENDORID>'; if (line.customerId) xml += '<CUSTOMERID>' + esc(line.customerId) + '</CUSTOMERID>'; if (line.projectId) xml += '<PROJECTID>' + esc(line.projectId) + '</PROJECTID>'; xml += '</APBILLITEM>'; }); xml += '</APBILLITEMS>'; return xml; }>></APBILL></create>`)}}],outputTransform:"(sourceData) => { const response = sourceData.createBill && sourceData.createBill.data ? sourceData.createBill.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.APBILL || data.apbill) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }"},{id:"sage-intacct-update-bill",name:"Update Sage Intacct AP bill",shortName:"Update bill",instruction:"Updates an existing AP bill in Sage Intacct by record number. Only the provided fields change. Line items can be added or updated by line number.",inputSchema:{type:"object",required:["recordNo"],properties:{recordNo:{type:"integer"},description:{type:"string"},vendorId:{type:"string"},dateCreated:{type:"string"},dateDue:{type:"string"},termName:{type:"string"},lines:{type:"array",items:{type:"object",properties:{lineNo:{type:"integer"},memo:{type:"string"},amount:{type:"number"},glAccountNo:{type:"string"},departmentId:{type:"string"},locationId:{type:"string"},vendorId:{type:"string"},customerId:{type:"string"},projectId:{type:"string"}}}}}},steps:[{id:"updateBill",instruction:"Update the APBILL record by RECORDNO.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><APBILL><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); let xml = ''; if (sourceData.vendorId) xml += '<VENDORID>' + esc(sourceData.vendorId) + '</VENDORID>'; if (sourceData.dateCreated) { const match = String(sourceData.dateCreated).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); xml += '<WHENCREATED>' + esc(match ? match[2] + '/' + match[3] + '/' + match[1] : sourceData.dateCreated) + '</WHENCREATED>'; } if (sourceData.dateDue) { const md = String(sourceData.dateDue).match(/^(\\d{4})-(\\d{2})-(\\d{2})/); xml += '<WHENDUE>' + esc(md ? md[2] + '/' + md[3] + '/' + md[1] : sourceData.dateDue) + '</WHENDUE>'; } if (sourceData.termName) xml += '<TERMNAME>' + esc(sourceData.termName) + '</TERMNAME>'; if (sourceData.description) xml += '<DESCRIPTION>' + esc(sourceData.description) + '</DESCRIPTION>'; const lines = Array.isArray(sourceData.lines) ? sourceData.lines : []; if (lines.length > 0) { xml += '<APBILLITEMS>'; lines.forEach((line) => { xml += '<APBILLITEM>'; if (line.lineNo) xml += '<LINE_NO>' + Number(line.lineNo) + '</LINE_NO>'; if (line.glAccountNo) xml += '<ACCOUNTNO>' + esc(line.glAccountNo) + '</ACCOUNTNO>'; if (line.amount != null) xml += '<AMOUNT>' + Number(line.amount) + '</AMOUNT>'; if (line.memo) xml += '<MEMO>' + esc(line.memo) + '</MEMO>'; if (line.departmentId) xml += '<DEPARTMENTID>' + esc(line.departmentId) + '</DEPARTMENTID>'; if (line.locationId) xml += '<LOCATIONID>' + esc(line.locationId) + '</LOCATIONID>'; if (line.vendorId) xml += '<VENDORID>' + esc(line.vendorId) + '</VENDORID>'; if (line.customerId) xml += '<CUSTOMERID>' + esc(line.customerId) + '</CUSTOMERID>'; if (line.projectId) xml += '<PROJECTID>' + esc(line.projectId) + '</PROJECTID>'; xml += '</APBILLITEM>'; }); xml += '</APBILLITEMS>'; } if (!xml && lines.length === 0) throw new Error('Provide at least one field to update.'); return xml; }>></APBILL></update>`)}}],outputTransform:"(sourceData) => { const response = sourceData.updateBill && sourceData.updateBill.data ? sourceData.updateBill.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.APBILL || data.apbill) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: sourceData.recordNo, record }; }"},{id:"sage-intacct-create-department",name:"Create Sage Intacct department",shortName:"Create department",instruction:"Creates a department in Sage Intacct via the XML Web Services API. Requires a department ID and title. Re-running creates another department; it is not idempotent.",inputSchema:{type:"object",required:["departmentId","title"],properties:{title:{type:"string"},departmentId:{type:"string"}}},steps:[{id:"createDepartment",instruction:"Create the DEPARTMENT record.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<create><DEPARTMENT><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); if (!sourceData.departmentId) throw new Error('departmentId is required.'); if (!sourceData.title) throw new Error('title is required.'); let xml = '<DEPARTMENTID>' + esc(sourceData.departmentId) + '</DEPARTMENTID>'; xml += '<TITLE>' + esc(sourceData.title) + '</TITLE>'; if (sourceData.parentId) xml += '<PARENTID>' + esc(sourceData.parentId) + '</PARENTID>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; return xml; }>></DEPARTMENT></create>`)}}],outputTransform:"(sourceData) => { const response = sourceData.createDepartment && sourceData.createDepartment.data ? sourceData.createDepartment.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.DEPARTMENT || data.department) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: record && record.RECORDNO ? Number(record.RECORDNO) : undefined, record }; }"},{id:"sage-intacct-update-department",name:"Update Sage Intacct department",shortName:"Update department",instruction:"Updates an existing department in Sage Intacct by record number. Only the provided fields change.",inputSchema:{type:"object",required:["recordNo"],properties:{title:{type:"string"},recordNo:{type:"integer"},parentId:{type:"string"},status:{type:"string",enum:["active","inactive"]}}},steps:[{id:"updateDepartment",instruction:"Update the DEPARTMENT record by RECORDNO.",modify:!0,config:{type:"request",systemId:"sage_intacct",url:"<<sage_intacct_url>>",method:"POST",headers:{"Content-Type":"application/xml",Accept:"application/xml"},body:It(`<update><DEPARTMENT><RECORDNO><<(sourceData) => { const recordNo = Number(sourceData.recordNo); if (!Number.isInteger(recordNo) || recordNo <= 0) throw new Error('recordNo must be a positive integer.'); return recordNo; }>></RECORDNO><<(sourceData) => { const esc = (value) => String(value).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&apos;'); let xml = ''; if (sourceData.title) xml += '<TITLE>' + esc(sourceData.title) + '</TITLE>'; if (sourceData.parentId) xml += '<PARENTID>' + esc(sourceData.parentId) + '</PARENTID>'; if (sourceData.status) xml += '<STATUS>' + esc(sourceData.status) + '</STATUS>'; if (!xml) throw new Error('Provide at least one field to update.'); return xml; }>></DEPARTMENT></update>`)}}],outputTransform:"(sourceData) => { const response = sourceData.updateDepartment && sourceData.updateDepartment.data ? sourceData.updateDepartment.data.RESPONSE : undefined; const control = response ? response.CONTROL : undefined; const operation = response ? response.OPERATION : undefined; const authentication = operation ? operation.AUTHENTICATION : undefined; const result = operation ? operation.RESULT : undefined; const statuses = [control && control.STATUS, authentication && authentication.STATUS, result && result.STATUS].filter(Boolean).map((value) => String(value).toLowerCase()); if (statuses.includes('failure')) { const message = (result && result.ERRORMESSAGE) || (authentication && authentication.ERR ? authentication.ERR.ERRORMESSAGE : undefined) || (control && control.ERR ? control.ERR.ERRORMESSAGE : undefined); const rawErrors = message ? message.ERROR : undefined; const errors = Array.isArray(rawErrors) ? rawErrors : (rawErrors ? [rawErrors] : []); const details = errors.map((error) => [error.ERRORNO, error.DESCRIPTION2 || error.DESCRIPTION, error.CORRECTION].filter(Boolean).join(' - ')).filter(Boolean); const supportIds = errors.map((error) => error.SUPPORTID).filter(Boolean); const suffix = supportIds.length ? ` Sage support ID: ${supportIds.join(', ')}.` : ''; throw new Error(`Sage Intacct request failed${details.length ? `: ${details.join('; ')}` : '.'}${suffix}`); } const data = result ? result.DATA : undefined; const raw = data ? (data.DEPARTMENT || data.department) : undefined; const record = Array.isArray(raw) ? raw[0] : raw; return { recordNo: sourceData.recordNo, record }; }"}]},dynamics365_sales:{bundleId:"dynamics365_sales",templateId:"dynamics365_sales",systemId:"dynamics365_sales",displayName:"Dynamics 365 Sales",description:"Read accounts, contacts and the sales pipeline from Dynamics 365 Sales.",systemUrl:"https://<<api_host>>/api/data/v9.2",credentialHint:"Set api_host to your environment host, then connect with Microsoft OAuth. Your assistant walks you through it.",requiredCredentialKeys:["api_host","access_token"],mcpServer:{name:"dynamics-sales",displayName:"Dynamics 365 Sales",description:"Accounts, contacts, opportunity pipeline and ad-hoc Dataverse queries from Dynamics 365 Sales."},installMcpServer:!0,agentLaunch:{userPrompt:"I just installed the Dynamics 365 Sales bundle. What can I do with it?",nextSteps:'Your first reply must be short: one line confirming the Dynamics MCP server is installed, then ask for their environment host in chat (like contoso.crm.dynamics.com \u2014 it is not a secret, so never collect it through a secure form; form values are redacted and you cannot read them back). When they reply, save it with tools.writeConnection passing secrets: { api_host: "<their host>" } directly, without asking for secure inputs. Then start Microsoft OAuth with connect and substitute the same host into the scopes yourself \u2014 set auth.scopes to "https://<host>/user_impersonation offline_access", never the <<api_host>> placeholder, which Microsoft rejects. OAuth fills access_token automatically; never send the user to the Connections page and never suggest the az CLI. Once connected, the MCP server is ready; offer one test run. Do not list the installed tools, do not add tips unless asked. If asked later: OAuth refresh is automatic, the query tool accepts any Dataverse entity set, and record totals above 5000 are reported as capped by Dataverse rather than exact.'},tools:[{id:"dynamics-list-accounts",name:"List Dynamics 365 accounts",shortName:"Accounts",instruction:"Lists account records from Dynamics 365 with name, account number and creation date. Supports an optional OData $filter. Useful for validating migrated accounts.",inputSchema:{type:"object",properties:{filter:{type:"string",description:`Optional OData $filter expression, e.g. "createdon gt 2026-01-01T00:00:00Z" or "contains(name,'GmbH')".`},maxResults:{type:"integer",description:"Maximum number of accounts to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchAccounts",instruction:"Fetch accounts from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/accounts",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"name,accountnumber,telephone1,websiteurl,createdon,modifiedon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchAccounts?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, accounts: rows.map((r) => ({ id: r.accountid, name: r.name, accountNumber: r.accountnumber, phone: r.telephone1, website: r.websiteurl, createdOn: r.createdon, modifiedOn: r.modifiedon })) }; }'},{id:"dynamics-list-contacts",name:"List Dynamics 365 contacts",shortName:"Contacts",instruction:"Lists contact records from Dynamics 365 with name, email and creation date. Supports an optional OData $filter. Useful for validating migrated contacts.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "emailaddress1 eq null" to find contacts missing an email.'},maxResults:{type:"integer",description:"Maximum number of contacts to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchContacts",instruction:"Fetch contacts from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/contacts",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"fullname,emailaddress1,telephone1,jobtitle,createdon,modifiedon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchContacts?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, contacts: rows.map((r) => ({ id: r.contactid, name: r.fullname, email: r.emailaddress1, phone: r.telephone1, jobTitle: r.jobtitle, createdOn: r.createdon, modifiedOn: r.modifiedon })) }; }'},{id:"dynamics-open-opportunities",name:"List Dynamics 365 open opportunities",shortName:"Open opportunities",instruction:"Lists open opportunities from Dynamics 365 with estimated value and close date. Supports an optional additional OData $filter. Useful for pipeline verification during UAT.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional additional OData $filter combined with the open-state filter, e.g. "estimatedvalue gt 10000".'},maxResults:{type:"integer",description:"Maximum number of opportunities to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchOpportunities",instruction:"Fetch open opportunities from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/opportunities",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"name,estimatedvalue,estimatedclosedate,createdon,statecode,_parentaccountid_value",$filter:'<<(p) => p.filter ? "statecode eq 0 and (" + p.filter + ")" : "statecode eq 0">>',$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchOpportunities?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, opportunities: rows.map((r) => ({ id: r.opportunityid, name: r.name, estimatedValue: r.estimatedvalue, estimatedCloseDate: r.estimatedclosedate, accountId: r._parentaccountid_value, createdOn: r.createdon })) }; }'},{id:"dynamics-list-leads",name:"List Dynamics 365 leads",shortName:"Leads",instruction:"Lists lead records from Dynamics 365 with subject, name and company. Supports an optional OData $filter. Useful for validating migrated leads.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "statecode eq 0" for open leads.'},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchLeads",instruction:"Fetch leads from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/leads",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"subject,fullname,companyname,statecode,createdon,modifiedon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchLeads?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows.map((r) => ({ id: r.leadid, subject: r.subject, name: r.fullname, company: r.companyname, state: r.statecode, createdOn: r.createdon, modifiedOn: r.modifiedon })) }; }'},{id:"dynamics-list-cases",name:"List Dynamics 365 cases",shortName:"Cases",instruction:"Lists case (incident) records from Dynamics 365 with title, ticket number and status. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "statecode eq 0" for active cases.'},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchCases",instruction:"Fetch incidents from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/incidents",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"title,ticketnumber,statecode,createdon,_customerid_value",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchCases?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows.map((r) => ({ id: r.incidentid, title: r.title, ticketNumber: r.ticketnumber, state: r.statecode, customerId: r._customerid_value, createdOn: r.createdon })) }; }'},{id:"dynamics-list-users",name:"List Dynamics 365 users",shortName:"Users",instruction:"Lists system users from Dynamics 365 with name, email and disabled state. Useful for owner-mapping checks during migrations.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "isdisabled eq false" for active users.'},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchUsers",instruction:"Fetch systemusers from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/systemusers",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"fullname,internalemailaddress,isdisabled,createdon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchUsers?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows.map((r) => ({ id: r.systemuserid, name: r.fullname, email: r.internalemailaddress, disabled: r.isdisabled, createdOn: r.createdon })) }; }'},{id:"dynamics-list-products",name:"List Dynamics 365 products",shortName:"Products",instruction:"Lists product catalog records from Dynamics 365 with name, number and state. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{filter:{type:"string",description:'Optional OData $filter expression, e.g. "statecode eq 0" for active products.'},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},additionalProperties:!0},steps:[{id:"fetchProducts",instruction:"Fetch products from the Dataverse Web API.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/products",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"name,productnumber,statecode,createdon",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchProducts?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows.map((r) => ({ id: r.productid, name: r.name, number: r.productnumber, state: r.statecode, createdOn: r.createdon })) }; }'},{id:"dynamics-query-dataverse",name:"Query any Dynamics 365 entity",shortName:"Query any entity",instruction:'Queries any Dataverse entity set. Required input: entitySet \u2014 the plural entity set name, e.g. "leads", "systemusers", "incidents". Optional inputs: select (OData $select field list), filter (OData $filter expression), maxResults (record cap, default 100). The workhorse tool for CRM migration validation and data quality checks beyond the prebuilt lists.',inputSchema:{type:"object",properties:{entitySet:{type:"string",description:'Dataverse entity set name (plural), e.g. "leads", "systemusers", "incidents".'},select:{type:"string",description:'Comma-separated OData $select field list, e.g. "subject,createdon". Omit for all fields.'},filter:{type:"string",description:"Optional OData $filter expression."},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},required:["entitySet"],additionalProperties:!0},steps:[{id:"queryEntity",instruction:"Query the requested Dataverse entity set.",config:{type:"request",systemId:"dynamics365_sales",url:"https://<<dynamics365_sales_api_host>>/api/data/v9.2/<<entitySet>>",method:"GET",headers:{Authorization:"Bearer <<dynamics365_sales_access_token>>",Accept:"application/json","OData-MaxVersion":"4.0","OData-Version":"4.0","If-None-Match":"null"},queryParams:{$select:"<<select>>",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.queryEntity?.data ?? {}; const rows = data.value ?? []; const capped = data["@Microsoft.Dynamics.CRM.totalrecordcountlimitexceeded"] === true; return { total: capped ? null : (data["@odata.count"] ?? rows.length), totalCapped: capped, returned: rows.length, records: rows }; }'}]},dynamics365_business_central:{bundleId:"dynamics365_business_central",templateId:"dynamics365_business_central",systemId:"dynamics365_business_central",displayName:"Dynamics 365 Business Central",description:"Read companies, customers, vendors and the chart of accounts from Business Central.",systemUrl:"https://api.businesscentral.dynamics.com/v2.0/<<environment>>/api/v2.0",credentialHint:"Connect your Business Central environment. Your assistant walks you through it.",requiredCredentialKeys:["environment","access_token"],oauthSignIn:!0,mcpServer:{name:"business-central",displayName:"Dynamics 365 Business Central",description:"Companies, customers, vendors, chart of accounts and ad-hoc entity queries from Business Central."},installMcpServer:!0,agentLaunch:{userPrompt:"I just installed the Dynamics 365 Business Central bundle. What can I do with it?",nextSteps:"Your first reply must be short: one line confirming the Business Central MCP server is installed, then collect the credentials. Use connect with this system's connection id and fields to save environment (their BC environment name, usually production or sandbox) and access_token; never send the user to the Connections page. Fastest token: az account get-access-token --resource https://api.businesscentral.dynamics.com. Once saved, the MCP server is ready; run the companies tool as the test, because its result contains the company id every other tool needs. Do not list the installed tools, do not add tips unless asked. If asked later: tokens expire after about an hour, so a 401 means refresh access_token; the query tool accepts any Business Central entity set like items or salesInvoices."},tools:[{id:"business-central-list-companies",name:"List Business Central companies",shortName:"Companies",instruction:"Lists the companies in the Business Central environment. Run this first: every other Business Central tool needs a companyId from this list.",inputSchema:{type:"object",properties:{},additionalProperties:!0},steps:[{id:"fetchCompanies",instruction:"Fetch the companies in this environment.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"}}}],outputTransform:"(sourceData) => { const rows = sourceData.fetchCompanies?.data?.value ?? []; return { total: rows.length, companies: rows.map((r) => ({ companyId: r.id, name: r.name, displayName: r.displayName })) }; }"},{id:"business-central-list-customers",name:"List Business Central customers",shortName:"Customers",instruction:"Lists customer master records from a Business Central company. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:`Optional OData $filter expression, e.g. "blocked ne ''" or "contains(displayName,'GmbH')".`},maxResults:{type:"integer",description:"Maximum number of customers to return in one call. Defaults to 100."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchCustomers",instruction:"Fetch customers for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/customers",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,displayName,email,phoneNumber,blocked,lastModifiedDateTime",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchCustomers?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, customers: rows.map((r) => ({ id: r.id, number: r.number, name: r.displayName, email: r.email, phone: r.phoneNumber, blocked: r.blocked, lastModified: r.lastModifiedDateTime })) }; }'},{id:"business-central-list-vendors",name:"List Business Central vendors",shortName:"Vendors",instruction:"Lists vendor master records from a Business Central company. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:"Optional OData $filter expression."},maxResults:{type:"integer",description:"Maximum number of vendors to return in one call. Defaults to 100."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchVendors",instruction:"Fetch vendors for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/vendors",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,displayName,email,phoneNumber,blocked,lastModifiedDateTime",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchVendors?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, vendors: rows.map((r) => ({ id: r.id, number: r.number, name: r.displayName, email: r.email, phone: r.phoneNumber, blocked: r.blocked, lastModified: r.lastModifiedDateTime })) }; }'},{id:"business-central-list-accounts",name:"List Business Central chart of accounts",shortName:"Chart of accounts",instruction:"Lists general ledger accounts (the chart of accounts) from a Business Central company. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:`Optional OData $filter expression, e.g. "category eq 'Assets'".`},maxResults:{type:"integer",description:"Maximum number of accounts to return in one call. Defaults to 200."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchAccounts",instruction:"Fetch general ledger accounts for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/accounts",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,displayName,category,subCategory,blocked,accountType",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 200>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchAccounts?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, accounts: rows.map((r) => ({ id: r.id, number: r.number, name: r.displayName, category: r.category, subCategory: r.subCategory, type: r.accountType, blocked: r.blocked })) }; }'},{id:"business-central-list-items",name:"List Business Central items",shortName:"Items",instruction:"Lists item (product) master records from a Business Central company. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:`Optional OData $filter expression, e.g. "type eq 'Inventory'".`},maxResults:{type:"integer",description:"Maximum number of items to return in one call. Defaults to 100."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchItems",instruction:"Fetch items for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/items",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,displayName,type,unitPrice,inventory,blocked,lastModifiedDateTime",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchItems?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, items: rows.map((r) => ({ id: r.id, number: r.number, name: r.displayName, type: r.type, unitPrice: r.unitPrice, inventory: r.inventory, blocked: r.blocked })) }; }'},{id:"business-central-list-sales-invoices",name:"List Business Central sales invoices",shortName:"Sales invoices",instruction:"Lists sales invoices from a Business Central company with customer, total and status. Requires a companyId from the companies tool. Supports an optional OData $filter.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:`Optional OData $filter expression, e.g. "status eq 'Open'".`},maxResults:{type:"integer",description:"Maximum number of invoices to return in one call. Defaults to 100."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchSalesInvoices",instruction:"Fetch sales invoices for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/salesInvoices",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,number,customerName,invoiceDate,totalAmountIncludingTax,currencyCode,status",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchSalesInvoices?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, invoices: rows.map((r) => ({ id: r.id, number: r.number, customer: r.customerName, date: r.invoiceDate, total: r.totalAmountIncludingTax, currency: r.currencyCode, status: r.status })) }; }'},{id:"business-central-list-gl-entries",name:"List Business Central general ledger entries",shortName:"GL entries",instruction:"Lists general ledger entries from a Business Central company with account, amounts and posting date. Requires a companyId from the companies tool. Filter by postingDate to verify opening balances at cutover.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},filter:{type:"string",description:'Optional OData $filter expression, e.g. "postingDate ge 2026-01-01".'},maxResults:{type:"integer",description:"Maximum number of entries to return in one call. Defaults to 200."}},required:["companyId"],additionalProperties:!0},steps:[{id:"fetchGLEntries",instruction:"Fetch general ledger entries for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/generalLedgerEntries",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"id,entryNumber,postingDate,documentNumber,accountNumber,description,debitAmount,creditAmount",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 200>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.fetchGLEntries?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, entries: rows.map((r) => ({ entryNumber: r.entryNumber, postingDate: r.postingDate, document: r.documentNumber, account: r.accountNumber, description: r.description, debit: r.debitAmount, credit: r.creditAmount })) }; }'},{id:"business-central-query-entity",name:"Query any Business Central entity",shortName:"Query any entity",instruction:"Queries any Business Central entity set by name (for example items, salesInvoices, generalLedgerEntries) within a company, with optional OData $select and $filter. The workhorse tool for migration validation beyond the prebuilt lists.",inputSchema:{type:"object",properties:{companyId:{type:"string",description:"Company id (GUID) from the companies tool."},entitySet:{type:"string",description:'Business Central entity set name, e.g. "items", "salesInvoices", "generalLedgerEntries".'},select:{type:"string",description:"Comma-separated OData $select field list. Omit for all fields."},filter:{type:"string",description:"Optional OData $filter expression."},maxResults:{type:"integer",description:"Maximum number of records to return in one call. Defaults to 100."}},required:["companyId","entitySet"],additionalProperties:!0},steps:[{id:"queryEntity",instruction:"Query the requested entity set for the given company.",config:{type:"request",systemId:"dynamics365_business_central",url:"https://api.businesscentral.dynamics.com/v2.0/<<dynamics365_business_central_environment>>/api/v2.0/companies(<<companyId>>)/<<entitySet>>",method:"GET",headers:{Authorization:"Bearer <<dynamics365_business_central_access_token>>",Accept:"application/json","Data-Access-Intent":"ReadOnly"},queryParams:{$select:"<<select>>",$filter:"<<filter>>",$top:"<<(p) => p.maxResults ?? 100>>",$count:"true"}}}],outputTransform:'(sourceData) => { const data = sourceData.queryEntity?.data ?? {}; const rows = data.value ?? []; return { total: data["@odata.count"] ?? rows.length, records: rows }; }'}]},netsuite:{bundleId:"netsuite",templateId:"netsuite",systemId:Yd,displayName:"NetSuite",description:"Install a NetSuite system, ten read/query tools, fourteen write tools and a native integration playbook.",systemUrl:"https://{accountId}.suitetalk.api.netsuite.com/services/rest",credentialHint:"Connects through your own NetSuite integration record with OAuth 2.0. Your assistant asks for the account ID and the integration record's client ID and secret, then opens the NetSuite sign-in.",requiredCredentialKeys:["access_token"],oauthSignIn:!0,mcpServer:{name:"netsuite",displayName:"NetSuite",description:"Chart of accounts, customers, vendors, journal entries, invoices, vendor bills, subsidiaries and dimensions from NetSuite, SuiteQL queries and record lookups, plus create and update tools for journal entries, vendors, customers, GL accounts, invoices, vendor bills and departments."},installMcpServer:!1,playbook:{id:"netsuite-native-integration",name:"NetSuite Native Integration",whenToRun:"Use when connecting, validating, querying or extending a NetSuite integration through REST Web Services and SuiteQL.",inputs:"A NetSuite connection with an OAuth sign-in; the record type or business process to work with; subsidiary scope for OneWorld accounts; validation criteria and desired output.",instructions:"Use the installed read-only tools for the chart of accounts, customers, vendors, journal entry lines, invoices, vendor bills, departments, subsidiaries, classes and locations. Use the SuiteQL query tool for any other record type, join or aggregate, and the get-record tool to inspect one record in full. Use the installed create and update tools for journal entries, vendors, customers, GL accounts, invoices, vendor bills and departments only after the user explicitly confirms the exact records to write; the create tools are not idempotent and re-running them duplicates records. Reference other records by internal ID from the list tools, and pass a subsidiary on OneWorld accounts. Surface NetSuite error details (o:errorDetails) as failures. For other record types or operations, inspect the account's metadata catalog, create separate least-privilege tools, validate them in a sandbox account and require explicit user confirmation before modifying NetSuite data.",completionCriteria:"The requested NetSuite data, write result or validation result is returned; subsidiary scope is correct; NetSuite errors are surfaced as failures with their details; no NetSuite data is modified unless the user explicitly requested and confirmed the write."},agentLaunch:{userPrompt:"I just installed the NetSuite integration. What can I do with it?",nextSteps:`Your first reply must be short: one line confirming the NetSuite integration and native integration playbook are installed. If the user already has a NetSuite connection with an OAuth sign-in under this system id, offer one read-only test run and stop. Otherwise connect it in this order. 1) Ask in chat for the NetSuite account ID (Setup > Company > Company Information, like 1234567 or 1234567_SB1 for a sandbox; it is not a secret). 2) Build the host from it in lowercase with "_" replaced by "-" (1234567_SB1 becomes 1234567-sb1). 3) Call connect with this system id, the user's existing NetSuite connection id if one exists, url https://<host>.suitetalk.api.netsuite.com/services/rest, and auth type oauth2 with oauthClientMode custom, authUrl https://<host>.app.netsuite.com/app/login/oauth2/authorize.nl and tokenUrl https://<host>.suitetalk.api.netsuite.com/services/rest/auth/oauth2/v1/token. Confirm no {accountId} remains in url, authUrl, or tokenUrl before calling it. If /org/oauth-apps/ lists an app for this NetSuite account, pass its oauthAppId; otherwise the card collects the client ID and client secret of their NetSuite integration record and then runs the OAuth sign-in. If they have no integration record yet, explain before calling connect: Setup > Integration > Manage Integrations > New, enable Authorization Code Grant with the REST Web Services and RESTlets scopes, set the redirect URI to the superglue OAuth callback URL exactly, and copy the client ID and secret shown once after saving; the NetSuite role needs REST Web Services and Log in using OAuth 2.0 Access Tokens permissions. Once connected, the integration is ready; offer one read-only test run. Do not list the installed tools or add tips unless asked. If asked later: the sign-in lasts seven days and a 401 means signing in again through connect with the connection id; the SuiteQL tool reads any record type; the installed create and update tools modify NetSuite data, so run them only after the user confirms the exact records to write.`},tools:Ofe}};ho.bundles={...Vb,sage_intacct_mcp:{...Vb.sage_intacct,bundleId:"sage_intacct_mcp",description:"Install the Sage Intacct integration and an OAuth-protected MCP server for its read/query and write tools.",installMcpServer:!0},netsuite_mcp:{...Vb.netsuite,bundleId:"netsuite_mcp",description:"Install the NetSuite integration and an OAuth-protected MCP server for its read/query and write tools.",installMcpServer:!0}};function Ufe({bundle:t,install:e}){let r=e.tools.map(s=>` - ${s.id}${s.name?` (${s.name})`:""}`).join(`
114
114
  `),n=e.system.requiredCredentialKeys.join(", "),i=e.mcpServer?[` - MCP server: ${e.mcpServer.name} (id: ${e.mcpServer.id})`,"","Silently load the connections and tool-deployment skills before replying. Do not narrate the skill loads.","","The MCP server card is already visible in this conversation with the server URL, its tools, and the client export options for Claude, Cursor, Langdock and curl. Do not describe or reproduce client setup in prose; point at the card."]:["","Silently load the connections skill before replying. Do not narrate the skill load."],o=[`The user just installed the "${t.displayName}" ${e.mcpServer?"MCP server and integration":"integration"} from the superglue website. Everything below already exists. Do not create, rebuild or duplicate any of it.`,"","Installed:",` - System ID: ${e.system.id} (${e.system.name}) at ${t.systemUrl}`," - Tools:",r,e.playbook?` - Playbook: ${e.playbook.name} (id: ${e.playbook.id})`:void 0,...i,"",e.system.hasUserCredentials?t.demoCredentials?"The connection is preloaded with shared demo secrets, so every tool works right now without any setup.":"The user already has a connection with every required secret.":`The user has no connection with every required secret yet, so no tool will run until the user adds the missing values. Required secret names: ${n}. ${t.credentialHint}`,t.agentLaunch.nextSteps,"","The user already saw this inventory on the install screen. Do not repeat it back to them."];return{userPrompt:t.agentLaunch.userPrompt,hiddenStarterMessage:o.filter(s=>s!==void 0).join(`
115
115
  `)}}function Mfe(t){return typeof t!="string"||!Object.prototype.hasOwnProperty.call(ho.bundles,t)?null:ho.bundles[t]}function xfe(){return Object.values(ho.bundles)}});var BL=m(Ug=>{"use strict";Object.defineProperty(Ug,"__esModule",{value:!0});Ug.chatVisualArtifactTitle=wL;Ug.chatVisualToArtifactHtml=Yfe;var Gr=Wf(),bL=120,Lfe={stats:"Key numbers",chart:"Chart",flow:"Flow",steps:"Steps",table:"Table",mapping:"Field mapping",migration:"Migration status",reconcile:"Reconciliation",timeline:"Timeline",cards:"Overview",diagram:"Diagram",image:"Images",callout:"Note",custom:"Visual",lesson:"Lesson"},Pfe={success:"sg-success",failed:"sg-error",warning:"sg-warning",running:"sg-info"},$fe={info:"",success:"sg-success",warning:"sg-warning",error:"sg-error"},Ffe=["main{max-width:960px;margin:0 auto;padding:32px 24px}","h1{margin:0 0 6px}","h2{margin:28px 0 10px}",".sg-visual-caption{margin:0 0 24px}",".sg-visual-body{overflow-wrap:break-word}",".sg-visual-body pre{white-space:pre-wrap;background:var(--sg-surface);border:1px solid var(--sg-line);border-radius:var(--sg-radius);padding:12px 14px}",".sg-card h3{margin:0 0 4px;font-size:1rem}",".sg-card p{margin:4px 0 0}"].join("");function se(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function Ng(t){return se(t).replace(/`([^`]+)`/g,"<code>$1</code>").replace(/\*\*([^*]+)\*\*/g,"<strong>$1</strong>").replace(/(^|[^*\w])\*([^*\s][^*]*)\*/g,"$1<em>$2</em>").replace(/\[([^\]]+)\]\((https:\/\/[^\s)]+)\)/g,'<a href="$2">$1</a>')}function Og(t){return t.trim().split(/\n\s*\n/).map(e=>{let r=e.split(`
116
116
  `).map(i=>i.trim());if(r.every(i=>/^[-*] /.test(i)))return`<ul>${r.map(i=>`<li>${Ng(i.slice(2))}</li>`).join("")}</ul>`;if(r.every(i=>/^\d+[.)] /.test(i)))return`<ol>${r.map(i=>`<li>${Ng(i.replace(/^\d+[.)] /,""))}</li>`).join("")}</ol>`;let n=/^(#{1,6}) (.*)$/.exec(r[0]);return n&&r.length===1?`<h3>${Ng(n[2])}</h3>`:`<p>${r.map(Ng).join("<br>")}</p>`}).join("")}function jfe(t){return Gr.CHAT_VISUAL_STATUSES.includes(t)}function Fa(t){if(!t)return"";let e=t.charAt(0).toUpperCase()+t.slice(1),r=Pfe[t];return`<span class="sg-badge${r?` ${r}`:""}">${e}</span>`}function Rs(t,e,r=[]){let n=t.map((s,a)=>a===0||e.some(c=>(c[a]??"")!=="")),i=s=>r[s]?' class="sg-num"':"",o=(s,a)=>s.map((c,u)=>n[u]?`<${a}${i(u)}>${c}</${a}>`:"").join("");return['<div class="sg-table-wrap"><table class="sg-table"><thead><tr>',o(t.map(se),"th"),"</tr></thead><tbody>",e.map(s=>`<tr>${o(s,"td")}</tr>`).join(""),"</tbody></table></div>"].join("")}function Yo(t){return t===void 0?"":se(String(t))}function kg(t){return t===void 0?"":(0,Gr.formatChatVisualNumber)(t)}function zfe(t,e){if(t===null)return"";if(typeof t=="boolean")return t?"Yes":"No";if(typeof t=="number")return(0,Gr.formatChatVisualNumber)(t);if(e==="status"&&jfe(t))return Fa(t);if(e==="code")return`<code>${se(t)}</code>`;if(e==="link"){let r=/^\[([^\]]+)\]\((https:\/\/[^\s)]+)\)$/.exec(t);if(r)return`<a href="${se(r[2])}">${se(r[1])}</a>`;if(/^https:\/\//i.test(t))return`<a href="${se(t)}">${se(t)}</a>`}return se(t)}function Hfe(t){let e=a=>a==null?"":se((0,Gr.formatChatVisualNumber)(a,t.unit)),r=Rs(["",...t.series.map(a=>a.name)],t.labels.map((a,c)=>[se(a),...t.series.map(u=>e(u.values[c]))]),[!1,...t.series.map(()=>!0)]);if(t.series.length!==1||t.kind==="line"||t.kind==="area")return r;let n=t.series[0].values,i=Math.max(...n.map(a=>Math.abs(a??0))),o=n.reduce((a,c)=>a+(c??0),0);return`${t.labels.map((a,c)=>{let u=n[c];if(u==null)return"";let l=i>0?Math.round(Math.abs(u)/i*1e3)/10:0,d=t.kind==="donut"&&o>0?` (${Math.round(u/o*1e3)/10}%)`:"";return`<div class="sg-bar"><b>${se(a)}</b><span style="width:${l}%"></span><em>${e(u)}${d}</em></div>`}).join("")}${r}`}function qfe(t){let e=new Map(t.nodes.map(r=>[r.id,r.label]));return(0,Gr.groupFlowNodes)(t.nodes).map(r=>{let n=r.nodes.map(i=>[se(i.label),Yo(i.kind),t.edges.filter(o=>o.from===i.id).map(o=>`${se(e.get(o.to))}${o.label?` <span class="sg-muted">(${se(o.label)})</span>`:""}`).join("<br>"),Fa(i.status),Yo(i.detail)]);return`${r.label?`<h2>${se(r.label)}</h2>`:""}${Rs(["Step","Kind","Leads to","Status","Detail"],n)}`}).join("")}function Gfe(t){return[...t.steps.map((r,n)=>{let i=r.visual===void 0?null:(0,Gr.parseLessonStepVisual)(r.visual),o=r.question?`<p><strong>${se(r.question.prompt)}</strong></p><ol type="A">${r.question.options.map(s=>`<li>${se(s.label)}${s.correct?' <span class="sg-badge sg-success">Answer</span>':""}<span class="sg-hint">${se(s.explanation)}</span></li>`).join("")}</ol>`:"";return[`<h2>${n+1}. ${se(r.title)}</h2>`,r.body?Og(r.body):"",i?SL(i):"",o].join("")}),t.recap?`<h2>Recap</h2>${Og(t.recap)}`:""].join("")}function SL(t){switch(t.type){case"stats":return`<div class="sg-grid">${t.items.map(e=>{let r=(0,Gr.formatChatVisualValue)(e.value,e.unit),n=e.tone==="positive"?" sg-up":e.tone==="negative"?" sg-down":"";return['<div class="sg-kpi">',`<span class="sg-kpi-label">${se(e.label)}</span>`,`<span class="sg-kpi-value">${se(r)}</span>`,e.delta?`<span class="sg-kpi-delta${n}">${se(e.delta)}</span>`:"",e.hint?`<span class="sg-hint">${se(e.hint)}</span>`:"","</div>"].join("")}).join("")}</div>`;case"chart":return Hfe(t);case"flow":return qfe(t);case"steps":return Rs(["#","Step","Status","Detail","Time"],t.items.map((e,r)=>[String(r+1),se(e.title),Fa(e.status),Yo(e.detail),se([e.time,e.duration].filter(Boolean).join(", "))]));case"table":return`${Rs(t.columns.map(e=>e.label),t.rows.map(e=>t.columns.map((r,n)=>zfe(e[n]??null,r.kind))),t.columns.map(e=>e.kind==="number"))}${t.totalRows!==void 0&&t.totalRows>t.rows.length?`<p class="sg-muted">Showing ${t.rows.length} of ${(0,Gr.formatChatVisualNumber)(t.totalRows)} rows.</p>`:""}`;case"mapping":return Rs([t.source.label,t.target.label,"Rule","Example","Note","Status"],t.fields.map(e=>[e.source?`<code>${se(e.source)}</code>`:'<span class="sg-muted">Unmapped</span>',`<code>${se(e.target)}</code>${e.required?' <span class="sg-muted">required</span>':""}`,se([e.rule,e.transform].filter(Boolean).join(": ")),e.sample?se(`${e.sample.from??""} \u2192 ${e.sample.to??""}`):"",Yo(e.note),Fa(e.status)]));case"migration":return`<p class="sg-muted">${se(`${t.source.label} \u2192 ${t.target.label}${t.phase?` \xB7 Current phase: ${t.phase}`:""}`)}</p>${Rs(["#","Object","Load after","Source","Loaded","Failed","Skipped","Status","Issues"],t.objects.map((e,r)=>[String(r+1),`${se(e.name)}${e.layer?`<span class="sg-hint">${se(e.layer)}</span>`:""}`,se(e.needs?.join(", ")??""),kg(e.source),kg(e.loaded),kg(e.failed),kg(e.skipped),Fa(e.status),[...(e.issues??[]).map(n=>se(`${n.label}${n.count!==void 0?` (${(0,Gr.formatChatVisualNumber)(n.count)})`:""}`)),...e.note?[`<span class="sg-muted">${se(e.note)}</span>`]:[]].join("<br>")]),[!1,!1,!1,!0,!0,!0,!0,!1,!1])}`;case"reconcile":{let e=(0,Gr.reconcileGap)(t),r=n=>se(`${n>0?"+":n<0?"\u2212":""}${(0,Gr.formatChatVisualNumber)(Math.abs(n),t.unit)}`);return`${Rs(["",t.object??"Records","Reason"],[[`<strong>${se(t.source.label)}</strong>`,`<strong>${se((0,Gr.formatChatVisualNumber)(t.source.value,t.unit))}</strong>`,""],...t.steps.map(n=>[se(n.label),r(n.value),Yo(n.reason)]),[`<strong>${se(t.target.label)}</strong>`,`<strong>${se((0,Gr.formatChatVisualNumber)(t.target.value,t.unit))}</strong>`,""]],[!1,!0,!1])}<p>${e===0?"Every record is accounted for.":`Unexplained difference: ${r(e)}.`}</p>`}case"timeline":return`${Rs(["Lane","Item",t.scale==="date"?"Start":`Start ${t.scale}`,t.scale==="date"?"End":`End ${t.scale}`,"Status","Depends on"],t.items.map(e=>[Yo(e.lane),`${e.milestone||e.end===void 0?"\u25C6 ":""}${se(e.label)}`,Yo(e.start),Yo(e.end),Fa(e.status),se(e.dependsOn?.join(", ")??"")]))}${t.today!==void 0?`<p class="sg-muted">Today: ${Yo(t.today)}</p>`:""}`;case"cards":return`<div class="sg-grid">${t.items.map(e=>['<div class="sg-card">',`<h3>${e.href?`<a href="${se(e.href)}">${se(e.title)}</a>`:se(e.title)} ${Fa(e.status)}</h3>`,e.subtitle?`<p class="sg-muted">${se(e.subtitle)}</p>`:"",...(e.facts??[]).map(r=>`<p><span class="sg-muted">${se(r.label)}:</span> ${se(String(r.value))}</p>`),"</div>"].join("")).join("")}</div>`;case"diagram":return`<p class="sg-muted">Diagram source (Mermaid)</p><pre><code>${se(t.source)}</code></pre>`;case"image":return`<ul>${t.images.map(e=>`<li><a href="${se(e.src)}">${se(e.alt)}</a>${e.caption?`<span class="sg-hint">${se(e.caption)}</span>`:""}</li>`).join("")}</ul>`;case"callout":{let e=$fe[t.tone];return`<div class="sg-callout${e?` ${e}`:""}">${Og(t.body)}</div>`}case"lesson":return Gfe(t);case"custom":return`${Og(t.summary)}<p class="sg-muted">The interactive version of this visual is in the superglue chat.</p>`}}function wL(t){let r=(t.title??(t.visual.type==="callout"?t.visual.body.split(`
@@ -706,6 +706,7 @@ window.addEventListener("load",schedule);
706
706
  `))!==-1;){let d=i.slice(0,l);if(i=i.slice(l+1),d.endsWith("\r")&&(d=d.slice(0,-1)),d===""){if(a()===!1)return;continue}d.startsWith(":")||(d.startsWith("event:")?o=d.slice(6).trimStart():d.startsWith("data:")&&s.push(d.slice(5).replace(/^ /,"")))}}}finally{try{await r.cancel()}catch{}}}});var sS=m(oS=>{"use strict";Object.defineProperty(oS,"__esModule",{value:!0});oS.injectHeadStyle=qhe;function qhe(t,e,r="end"){if(r==="start"){let o=t.match(/<head(?=[\s>])[^>]*>/i);if(o?.index!==void 0){let s=o.index+o[0].length;return t.slice(0,s)+e+t.slice(s)}}let n=t.search(/<\/head\s*>/i);if(n!==-1)return t.slice(0,n)+e+t.slice(n);let i=t.match(/<body(?=[\s>])[^>]*>/i);if(i?.index!==void 0){let o=i.index+i[0].length;return t.slice(0,o)+e+t.slice(o)}return e+t}});var cS=m(bu=>{"use strict";Object.defineProperty(bu,"__esModule",{value:!0});bu.ARTIFACT_BASE_CSS=void 0;bu.injectArtifactBaseStyle=Vhe;var Ghe=sS(),xg=Vd(),{colors:kn,shades:Cu,chart:ks,radius:aS}=xg.SUPERGLUE_DESIGN;bu.ARTIFACT_BASE_CSS=`
707
707
  :root{--sg-bg:${kn.background};--sg-surface:${kn.surface};--sg-surface-2:${Cu.surface2};--sg-ink:${kn.text};--sg-ink-2:${kn.mutedText};--sg-ink-3:${Cu.ink3};--sg-line:${kn.border};--sg-line-2:${Cu.line2};--sg-input:${Cu.input};--sg-primary:${kn.primary};--sg-primary-hover:${Cu.primaryHover};--sg-ring:${Cu.ring};--sg-link:${kn.link};--sg-destructive:${kn.danger};--sg-success:${kn.success};--sg-warning:${kn.warning};--sg-on-primary:${kn.onPrimary};--sg-accent:${kn.accent};--sg-blue:${ks[0]};--sg-cyan:${ks[1]};--sg-purple:${ks[2]};--sg-pink:${ks[3]};--sg-green:${ks[4]};--sg-chart-1:var(--sg-blue);--sg-chart-2:var(--sg-cyan);--sg-chart-3:var(--sg-purple);--sg-chart-4:var(--sg-pink);--sg-chart-5:var(--sg-green);--sg-chart-6:${ks[5]};--sg-chart-7:${ks[6]};--sg-chart-8:${ks[7]};--sg-radius:${aS}px;--sg-radius-md:${aS*.75}px;--sg-radius-xl:${aS*1.5}px;--sg-shadow-sm:0 1px 2px 0 rgb(0 0 0/.05);--sg-font-sans:${(0,xg.superglueFontStack)("body")};--sg-font-heading:${(0,xg.superglueFontStack)("heading")};--sg-font-mono:${(0,xg.superglueFontStack)("mono")};--sg-header-bg:var(--sg-primary);--sg-header-ink:var(--sg-on-primary)}
708
708
  body{background:var(--sg-bg);color:var(--sg-ink);font-family:var(--sg-font-sans)}
709
+ :where(main){max-width:960px;margin:0 auto;padding:32px 24px}
709
710
  h1{font-size:calc(2em*var(--sg-heading-scale,1))}h2{font-size:calc(1.5em*var(--sg-heading-scale,1))}h3{font-size:calc(1.17em*var(--sg-heading-scale,1))}
710
711
  .sg-header{display:flex;align-items:center;gap:16px;padding:0 0 14px;margin:0 0 24px;border-bottom:1px solid var(--sg-line)}
711
712
  .sg-header img{display:block;height:30px;width:auto;max-width:200px;object-fit:contain}
@@ -760,7 +761,7 @@ label[data-sg-choice]:has(input:focus-visible){box-shadow:0 0 0 1px var(--sg-rin
760
761
  .sg-footnote{color:var(--sg-ink-3);font-size:.75rem;line-height:1.1rem;margin-top:28px;border-top:1px solid var(--sg-line);padding-top:10px}
761
762
  [data-sg-deck]{display:flex;flex-direction:column;align-items:center;gap:24px;padding:24px 0;margin:0;max-width:none}
762
763
  [data-sg-slide]{position:relative!important;box-sizing:border-box!important;display:block;width:1280px!important;height:720px!important;flex:none!important;overflow:hidden!important;zoom:var(--sg-deck-scale,1);background:var(--sg-bg);color:var(--sg-ink);box-shadow:0 1px 3px rgb(0 0 0/.12),0 0 0 1px var(--sg-line);break-after:page}
763
- @media print{[data-sg-deck]{display:block;padding:0}[data-sg-slide]{zoom:1;box-shadow:none}}
764
+ @media print{:where(main){max-width:none;padding:0}[data-sg-deck]{display:block;padding:0}[data-sg-slide]{zoom:1;box-shadow:none}}
764
765
  @media (max-width:640px){.sg-mapping{grid-template-columns:1fr}.sg-mapping>i{display:none}}
765
766
  @media print{.sg-card,.sg-kpi{break-inside:avoid;box-shadow:none}h1,h2,h3,h4,h5,h6{break-after:avoid}}
766
767
  `.trim();var Yhe=`<style data-sg-base>${bu.ARTIFACT_BASE_CSS}</style>`;function Vhe(t){return t.includes("<style data-sg-base>")?t:(0,Ghe.injectHeadStyle)(t,Yhe,"start")}});var LL=m(Jd=>{"use strict";Object.defineProperty(Jd,"__esModule",{value:!0});Jd.DeploymentConfigError=void 0;Jd.buildDeploymentConfig=tge;var Jhe=["pro","team","enterprise"],Lg={pro:"prod_UjB46ulzKsQ1Ef",team:"prod_UiMeaL02tN4BMg",enterprise:"prod_UapuUIQQuluzUV"},Pg=["openai","anthropic","gemini","azure","bedrock","vertex"],Whe=["tavily","model_provider","searxng","disabled"],Zhe=["openai","anthropic","azure"],Khe=["cloud","enterprise"],Xhe=["aws","minio","azure"],ege=/^(?=.{3,63}$)[a-z0-9]+(-[a-z0-9]+)*$/,xL=["email_password","google","github","okta"],uS=class{constructor(e){this.raw=e,this.issues=[]}build(){let e=this.requiredPort("API_PORT",3002,"runtime.apiPort"),r=this.requiredPort("WEB_PORT",3001,"runtime.webPort"),n=this.requiredUrl("PUBLIC_API_URL",`http://localhost:${e}`,"runtime.publicApiUrl"),i=this.url("INTERNAL_API_URL",n,"runtime.internalApiUrl"),o=this.requiredUrl("PUBLIC_APP_URL","https://app.superglue.cloud","runtime.publicAppUrl"),s=this.url("INTERNAL_APP_URL",o,"runtime.internalAppUrl"),a=this.deploymentMode(),c=this.requiredBoolean("BLOCK_LOCAL_REQUESTS",!1,"security.blockLocalRequests"),u=this.llm(this.choice("PRIMARY_LLM_PROVIDER",Pg,"openai","llm.primary.provider"),this.required("PRIMARY_LLM_MODEL","llm.primary.model"),"llm.primary"),l=this.llmFallbacks(),d=this.llm(this.choice("SUMMARIZE_LLM_PROVIDER",Pg,"openai","llm.summarize.provider"),this.required("SUMMARIZE_LLM_MODEL","llm.summarize.model"),"llm.summarize"),A={deployment:{mode:a,orgConcurrencyLimits:a==="enterprise"?"disabled":"tier_config"},runtime:{apiPort:e,webPort:r,publicApiUrl:n,internalApiUrl:i,publicAppUrl:o,internalAppUrl:s,scheduler:this.scheduler()},website:{contactFormToEmail:this.optional("WEBSITE_CONTACT_FORM_TO_EMAIL")??null},security:{jwtSecret:this.required("JWT_AUTH_SECRET","security.jwtSecret"),internalApiToken:this.required("INTERNAL_API_TOKEN","security.internalApiToken"),credentialsEncryptionKey:this.required("MASTER_ENCRYPTION_KEY","security.credentialsEncryptionKey"),blockLocalRequests:c,trustProxyHops:this.nonNegativeInteger("TRUST_PROXY_HOPS",1,"security.trustProxyHops")},storage:{postgres:{host:this.required("POSTGRES_HOST","storage.postgres.host"),port:this.requiredPort("POSTGRES_PORT",5432,"storage.postgres.port"),username:this.required("POSTGRES_USERNAME","storage.postgres.username"),password:this.required("POSTGRES_PASSWORD","storage.postgres.password"),database:this.required("POSTGRES_DB","storage.postgres.database"),ssl:this.requiredBoolean("POSTGRES_SSL",!0,"storage.postgres.ssl")},objectStorage:this.objectStorage()},llm:{primary:u,primaryFallbacks:l,summarize:d},externalProviders:{posthog:this.posthog(),langfuse:this.langfuse(),resend:this.resend(),loops:this.loops(),teamsBot:this.teamsBot(),webSearch:this.webSearch(u.provider,l)},billing:this.billing(a),bundles:this.bundles(),features:{briefings:this.boolean("BRIEFINGS_ENABLED",!1,"features.briefings")},auth:this.auth()};if(this.issues.length>0)throw new $g(this.issues);return A}optional(e){let r=this.raw[e]?.trim();return r||void 0}required(e,r){let n=this.optional(e);return n||(this.issues.push({path:r,message:`${e} is required.`}),"")}requiredOptional(e,r){let n=this.optional(e);return n||this.issues.push({path:r,message:`${e} is required.`}),n}boolean(e,r,n){let i=this.optional(e);return i?i==="true"?!0:i==="false"?!1:(this.issues.push({path:n,message:`${e} must be "true" or "false".`}),r):r}requiredBoolean(e,r,n){let i=this.requiredOptional(e,n);return i?i==="true"?!0:i==="false"?!1:(this.issues.push({path:n,message:`${e} must be "true" or "false".`}),r):r}port(e,r,n){let i=this.optional(e);if(!i)return r;let o=Number(i);return!Number.isInteger(o)||o<1||o>65535?(this.issues.push({path:n,message:`${e} must be a TCP port between 1 and 65535.`}),r):o}nonNegativeInteger(e,r,n){let i=this.optional(e);if(!i)return r;let o=Number(i);return!Number.isInteger(o)||o<0?(this.issues.push({path:n,message:`${e} must be a non-negative integer.`}),r):o}requiredPort(e,r,n){return this.requiredOptional(e,n)?this.port(e,r,n):r}url(e,r,n){return this.validUrl(this.optional(e)||r,e,n)??r}validUrl(e,r,n){try{return new URL(e).toString().replace(/\/$/,"")}catch{this.issues.push({path:n,message:`${r} must be a valid URL.`});return}}requiredUrl(e,r,n){return this.requiredOptional(e,n)?this.url(e,r,n):r}choice(e,r,n,i){let o=this.requiredOptional(e,i)?.toLowerCase();return o?r.includes(o)?o:(this.issues.push({path:i,message:`${e} must be one of: ${r.join(", ")}.`}),n):n}listChoice(e,r,n){let i=this.requiredOptional(e,n);if(!i)return[];let o=[],s=new Set;for(let a of i.split(",")){let c=a.trim().toLowerCase();if(!(!c||s.has(c))){if(s.add(c),r.includes(c)){o.push(c);continue}this.issues.push({path:n,message:`${e} contains unsupported value "${c}". Use one of: ${r.join(", ")}.`})}}return o.length===0&&this.issues.push({path:n,message:`${e} must include at least one provider.`}),o}list(e){return(this.optional(e)??"").split(",").map(r=>r.trim()).filter(Boolean)}deploymentMode(){return this.choice("DEPLOYMENT_MODE",Khe,"cloud","deployment.mode")}scheduler(){return this.requiredBoolean("START_SCHEDULER_SERVER",!1,"runtime.scheduler.mode")?{mode:"in_process"}:{mode:"disabled"}}objectStorage(){let e=this.choice("S3_PROVIDER",Xhe,"aws","storage.objectStorage.provider");if(e==="azure")return this.azureObjectStorage();if(e==="minio")return{provider:"minio",endpoint:this.required("S3_ENDPOINT","storage.objectStorage.endpoint"),publicEndpoint:this.optional("S3_PUBLIC_ENDPOINT")??null,bucketName:this.required("MINIO_BUCKET_NAME","storage.objectStorage.bucketName"),bucketPrefix:this.optional("MINIO_BUCKET_PREFIX")?this.bucketPrefix("MINIO_BUCKET_PREFIX"):this.bucketPrefix("AWS_BUCKET_PREFIX"),accessKeyId:this.required("MINIO_ROOT_USER","storage.objectStorage.accessKeyId"),secretAccessKey:this.required("MINIO_ROOT_PASSWORD","storage.objectStorage.secretAccessKey")};let r=this.optional("AWS_S3_ACCESS_KEY_ID"),n=this.optional("AWS_S3_SECRET_ACCESS_KEY");return(r&&!n||!r&&n)&&this.issues.push({path:"storage.objectStorage.credentials",message:"AWS_S3_ACCESS_KEY_ID and AWS_S3_SECRET_ACCESS_KEY must be set together."}),{provider:"aws",region:this.required("AWS_S3_REGION","storage.objectStorage.region"),bucketName:this.required("AWS_BUCKET_NAME","storage.objectStorage.bucketName"),bucketPrefix:this.bucketPrefix("AWS_BUCKET_PREFIX"),...r&&n?{accessKeyId:r,secretAccessKey:n,...this.optional("AWS_S3_SESSION_TOKEN")&&{sessionToken:this.optional("AWS_S3_SESSION_TOKEN")}}:{}}}azureObjectStorage(){let e=this.required("AZURE_STORAGE_CONTAINER_NAME","storage.objectStorage.containerName");e&&!ege.test(e)&&this.issues.push({path:"storage.objectStorage.containerName",message:"AZURE_STORAGE_CONTAINER_NAME must be 3-63 lowercase letters, numbers and single hyphens."});let r=this.bucketPrefix("AZURE_STORAGE_PREFIX"),n=this.optional("AZURE_STORAGE_MANAGED_IDENTITY_CLIENT_ID"),i=this.optional("AZURE_STORAGE_CONNECTION_STRING");if(i){let a=["AZURE_STORAGE_ACCOUNT_NAME","AZURE_STORAGE_ACCOUNT_KEY","AZURE_STORAGE_BLOB_ENDPOINT","AZURE_STORAGE_MANAGED_IDENTITY_CLIENT_ID"].filter(p=>this.optional(p));a.length>0&&this.issues.push({path:"storage.objectStorage.credential",message:`AZURE_STORAGE_CONNECTION_STRING cannot be combined with ${a.join(", ")}.`});let c=new Map;for(let p of i.split(";")){let h=p.indexOf("=");h>0&&c.set(p.slice(0,h).trim(),p.slice(h+1).trim())}let u=c.get("AccountName")??"",l=c.get("AccountKey")??"";(!u||!l)&&this.issues.push({path:"storage.objectStorage.credential",message:"AZURE_STORAGE_CONNECTION_STRING must contain AccountName and AccountKey."});let d=c.get("DefaultEndpointsProtocol")??"https",A=c.get("EndpointSuffix")??"core.windows.net";return{provider:"azure",accountName:u,blobEndpoint:this.validUrl(c.get("BlobEndpoint")??`${d}://${u}.blob.${A}`,"AZURE_STORAGE_CONNECTION_STRING BlobEndpoint","storage.objectStorage.blobEndpoint")??"",containerName:e,bucketPrefix:r,credential:{type:"shared_key",accountKey:l}}}let o=this.required("AZURE_STORAGE_ACCOUNT_NAME","storage.objectStorage.accountName"),s=this.optional("AZURE_STORAGE_ACCOUNT_KEY");return s&&n&&this.issues.push({path:"storage.objectStorage.credential",message:"AZURE_STORAGE_MANAGED_IDENTITY_CLIENT_ID cannot be combined with AZURE_STORAGE_ACCOUNT_KEY."}),{provider:"azure",accountName:o,blobEndpoint:this.url("AZURE_STORAGE_BLOB_ENDPOINT",`https://${o}.blob.core.windows.net`,"storage.objectStorage.blobEndpoint"),containerName:e,bucketPrefix:r,credential:s?{type:"shared_key",accountKey:s}:{type:"token",...n&&{managedIdentityClientId:n}}}}bucketPrefix(e){let r=this.optional(e)?.replace(/^\/+|\/+$/g,"");if(!r)return"";let n=r.split("/");return r.includes("\\")||n.some(i=>!i||i==="."||i==="..")?(this.issues.push({path:"storage.objectStorage.bucketPrefix",message:`${e} must be a path of non-empty segments without "." or "..".`}),""):`${r}/`}llm(e,r,n){let i=e.toLowerCase();if(!Pg.includes(i))return this.issues.push({path:`${n}.provider`,message:`${n} provider must be one of: ${Pg.join(", ")}.`}),{provider:"openai",apiKey:this.optional("OPENAI_API_KEY")||"",model:r};switch(i){case"openai":return this.openai(r,n);case"anthropic":return this.anthropic(r,n);case"gemini":return this.gemini(r,n);case"azure":return this.azure(r,n);case"bedrock":return this.bedrock(r,n);case"vertex":return this.vertex(r,n)}}openai(e,r){return{provider:"openai",apiKey:this.required("OPENAI_API_KEY",`${r}.apiKey`),model:e,...e==="gpt-6.1-sol"&&{reasoningEffort:"medium"},...this.optional("OPENAI_BASE_URL")&&{baseUrl:this.optional("OPENAI_BASE_URL")}}}anthropic(e,r){return{provider:"anthropic",apiKey:this.required("ANTHROPIC_API_KEY",`${r}.apiKey`),model:e,...this.optional("ANTHROPIC_BASE_URL")&&{baseUrl:this.optional("ANTHROPIC_BASE_URL")}}}gemini(e,r){return{provider:"gemini",apiKey:this.required("GEMINI_API_KEY",`${r}.apiKey`),model:e,...this.optional("GEMINI_BASE_URL")&&{baseUrl:this.optional("GEMINI_BASE_URL")}}}llmFallbacks(){return this.list("PRIMARY_LLM_FALLBACKS").flatMap((e,r)=>{let n=`llm.primaryFallbacks.${r}`,i=e.indexOf(":"),o=e.slice(0,i).trim(),s=e.slice(i+1).trim();return i===-1||!o||!s?(this.issues.push({path:n,message:`PRIMARY_LLM_FALLBACKS entry "${e}" must use the provider:model format.`}),[]):[this.llm(o,s,n)]})}azure(e,r){let n=this.optional("AZURE_RESOURCE_NAME"),i=this.optional("AZURE_BASE_URL");return!n&&!i&&this.issues.push({path:r,message:"AZURE_RESOURCE_NAME or AZURE_BASE_URL is required when using Azure."}),{provider:"azure",apiKey:this.required("AZURE_API_KEY",`${r}.apiKey`),model:e,...n&&{resourceName:n},...i&&{baseUrl:i},...this.optional("AZURE_API_VERSION")&&{apiVersion:this.optional("AZURE_API_VERSION")},useDeploymentBasedUrls:this.boolean("AZURE_USE_DEPLOYMENT_BASED_URLS",!1,`${r}.useDeploymentBasedUrls`)}}bedrock(e,r){let n=this.optional("BEDROCK_AWS_ACCESS_KEY_ID"),i=this.optional("BEDROCK_AWS_SECRET_ACCESS_KEY");return(n&&!i||!n&&i)&&this.issues.push({path:`${r}.credentials`,message:"BEDROCK_AWS_ACCESS_KEY_ID and BEDROCK_AWS_SECRET_ACCESS_KEY must be set together."}),{provider:"bedrock",model:e,region:this.required("AWS_BEDROCK_REGION",`${r}.region`),...this.optional("AWS_BASE_URL")&&{baseUrl:this.optional("AWS_BASE_URL")},...n&&i&&{accessKeyId:n,secretAccessKey:i,...this.optional("BEDROCK_AWS_SESSION_TOKEN")&&{sessionToken:this.optional("BEDROCK_AWS_SESSION_TOKEN")}}}}vertex(e,r){let n=this.optional("VERTEX_API_KEY"),i=this.optional("VERTEX_CLIENT_EMAIL"),o=this.optional("VERTEX_PRIVATE_KEY"),s=this.optional("GOOGLE_APPLICATION_CREDENTIALS"),a=i&&o?{type:"service_account",clientEmail:i,privateKey:o}:s?{type:"credentials_file",path:s}:n?{type:"api_key",apiKey:n}:null;return a||this.issues.push({path:`${r}.auth`,message:"VERTEX_API_KEY, VERTEX_CLIENT_EMAIL plus VERTEX_PRIVATE_KEY, or GOOGLE_APPLICATION_CREDENTIALS is required when using Vertex."}),e.startsWith("claude")&&a?.type==="api_key"&&this.issues.push({path:`${r}.auth`,message:"Vertex Claude models require service account or credentials-file auth."}),{provider:"vertex",model:e,...this.optional("VERTEX_PROJECT")&&{project:this.optional("VERTEX_PROJECT")},...this.optional("VERTEX_LOCATION")&&{location:this.optional("VERTEX_LOCATION")},auth:a||{type:"api_key",apiKey:""}}}webSearch(e,r){let n=this.choice("WEB_SEARCH_PROVIDER",Whe,"disabled","externalProviders.webSearch.provider"),i=this.optional("WEB_SEARCH_API_KEY"),o=Zhe.includes(e)?e:null;return n==="disabled"?{provider:"disabled"}:n==="model_provider"?o?r.some(s=>s.provider!==o)?(this.issues.push({path:"externalProviders.webSearch",message:"WEB_SEARCH_PROVIDER=model_provider requires every PRIMARY_LLM_FALLBACKS entry to use the primary LLM provider."}),{provider:"disabled"}):{provider:"model_provider",llmProvider:o}:(this.issues.push({path:"externalProviders.webSearch",message:"WEB_SEARCH_PROVIDER=model_provider requires OpenAI, Anthropic, or Azure."}),{provider:"disabled"}):n==="tavily"?i?{provider:"tavily",apiKey:i}:(this.issues.push({path:"externalProviders.webSearch.apiKey",message:"WEB_SEARCH_API_KEY is required when WEB_SEARCH_PROVIDER=tavily."}),{provider:"disabled"}):n==="searxng"?this.searxng(i):{provider:"disabled"}}searxng(e){return{provider:"searxng",endpoint:this.required("WEB_SEARCH_ENDPOINT","externalProviders.webSearch.endpoint"),...e&&{apiKey:e}}}posthog(){return this.boolean("POSTHOG_ENABLED",!1,"externalProviders.posthog.enabled")?{enabled:!0,apiKey:this.required("POSTHOG_KEY","externalProviders.posthog.apiKey"),serverHost:this.required("POSTHOG_HOST","externalProviders.posthog.serverHost")}:{enabled:!1}}langfuse(){return this.boolean("LANGFUSE_ENABLED",!1,"externalProviders.langfuse.enabled")?{enabled:!0,publicKey:this.required("LANGFUSE_PUBLIC_KEY","externalProviders.langfuse.publicKey"),secretKey:this.required("LANGFUSE_SECRET_KEY","externalProviders.langfuse.secretKey"),baseUrl:this.required("LANGFUSE_BASE_URL","externalProviders.langfuse.baseUrl"),tracingEnvironment:this.required("LANGFUSE_TRACING_ENVIRONMENT","externalProviders.langfuse.tracingEnvironment")}:{enabled:!1}}resend(){return this.boolean("RESEND_ENABLED",!1,"externalProviders.resend.enabled")?{enabled:!0,apiKey:this.required("RESEND_API_KEY","externalProviders.resend.apiKey"),fromEmail:this.required("RESEND_FROM_EMAIL","externalProviders.resend.fromEmail")}:{enabled:!1}}loops(){return this.boolean("LOOPS_ENABLED",!1,"externalProviders.loops.enabled")?{enabled:!0,apiKey:this.required("LOOPS_API_KEY","externalProviders.loops.apiKey")}:{enabled:!1}}teamsBot(){return this.boolean("TEAMS_BOT_ENABLED",!1,"externalProviders.teamsBot.enabled")?{enabled:!0,appId:this.required("TEAMS_BOT_APP_ID","externalProviders.teamsBot.appId"),appPassword:this.required("TEAMS_BOT_APP_PASSWORD","externalProviders.teamsBot.appPassword"),tenantId:this.optional("TEAMS_BOT_TENANT_ID")??null}:{enabled:!1}}bundles(){let e=this.optional("SAGE_INTACCT_SENDER_ID"),r=this.optional("SAGE_INTACCT_SENDER_PASSWORD");return(e&&!r||!e&&r)&&this.issues.push({path:"bundles.sageIntacctSender",message:"SAGE_INTACCT_SENDER_ID and SAGE_INTACCT_SENDER_PASSWORD must be set together."}),{sageIntacctSender:e&&r?{senderId:e,senderPassword:r}:null}}billing(e){return e==="enterprise"?{provider:"disabled"}:{provider:"stripe",secretKey:this.required("STRIPE_SECRET_KEY","billing.secretKey"),webhookSecret:this.required("STRIPE_WEBHOOK_SECRET","billing.webhookSecret"),productIds:this.stripeProductIds()}}stripeProductIds(){let e=this.optional("STRIPE_PRODUCT_IDS");if(!e)return Lg;try{let r=JSON.parse(e);if(!r||typeof r!="object"||Array.isArray(r))return this.issues.push({path:"billing.productIds",message:"STRIPE_PRODUCT_IDS must be a JSON object."}),Lg;let n={...Lg};for(let i of Jhe){let o=r[i];typeof o=="string"&&o.trim()&&(n[i]=o.trim())}return n}catch{return this.issues.push({path:"billing.productIds",message:"STRIPE_PRODUCT_IDS must be valid JSON."}),Lg}}auth(){let e=this.optional("OKTA_SCIM_TOKEN");e&&e.length<32&&this.issues.push({path:"auth.providers.okta.scimToken",message:"OKTA_SCIM_TOKEN must contain at least 32 characters."});let r=this.listChoice("AUTH_PROVIDERS",xL,"auth.providers"),n=new Map,i=this.configuredOAuthProvider("google","GOOGLE"),o=this.configuredOAuthProvider("github","GITHUB"),s=this.configuredOktaProvider();i&&n.set("google",i),o&&n.set("github",o),s&&n.set("okta",s);for(let d of r)switch(d){case"email_password":n.set(d,{provider:d});break;case"google":n.set(d,this.oauthProvider(d,"GOOGLE","auth.providers.google"));break;case"github":n.set(d,this.oauthProvider(d,"GITHUB","auth.providers.github"));break;case"okta":n.set(d,this.oktaProvider());break}let a=xL.flatMap(d=>{let A=n.get(d);return A?[A]:[]}),c=this.requiredBoolean("AUTH_DISABLE_SIGNUP",!1,"auth.disableSignup"),u=this.requiredBoolean("AUTH_DISABLE_INVITES",!1,"auth.disableInvites"),l=n.has("okta");return c&&u&&!l&&this.issues.push({path:"auth",message:"AUTH_DISABLE_SIGNUP and AUTH_DISABLE_INVITES cannot both be true without an Okta provider \u2014 no account creation path would remain."}),{providers:a,visibleProviders:r,disableSignup:c,disableInvites:u}}configuredOAuthProvider(e,r){let n=this.optional(`${r}_CLIENT_ID`),i=this.optional(`${r}_CLIENT_SECRET`);if(!(!n||!i))return{provider:e,clientId:n,clientSecret:i}}configuredOktaProvider(){let e=this.optional("OKTA_CLIENT_ID"),r=this.optional("OKTA_CLIENT_SECRET"),n=this.optional("OKTA_ISSUER"),i=this.optional("OKTA_ORG_ID"),o=this.optional("OKTA_SCIM_TOKEN");if(!(!e||!r||!n||!i))return{provider:"okta",clientId:e,clientSecret:r,issuer:n.replace(/\/$/,""),organizationId:i,...o?{scimToken:o}:{}}}oauthProvider(e,r,n){return{provider:e,clientId:this.required(`${r}_CLIENT_ID`,`${n}.clientId`),clientSecret:this.required(`${r}_CLIENT_SECRET`,`${n}.clientSecret`)}}oktaProvider(){let e=this.optional("OKTA_SCIM_TOKEN");return{provider:"okta",clientId:this.required("OKTA_CLIENT_ID","auth.providers.okta.clientId"),clientSecret:this.required("OKTA_CLIENT_SECRET","auth.providers.okta.clientSecret"),issuer:this.required("OKTA_ISSUER","auth.providers.okta.issuer").replace(/\/$/,""),organizationId:this.required("OKTA_ORG_ID","auth.providers.okta.organizationId"),...e?{scimToken:e}:{}}}},$g=class extends Error{constructor(e){super(`Invalid deployment environment:
@@ -810,7 +811,7 @@ If the user has no S/4HANA system, offer the free SAP Business Accelerator Hub s
810
811
 
811
812
  If the user has no SuccessFactors instance, offer the free SAP Business Accelerator Hub sandbox: base URL https://sandbox.api.sap.com/successfactors/odata/v2/<EntitySet> with the API key sent in the APIKey header (no OAuth needed). A shared test key can be offered: K8reTgiKCCaqvAPWC4cOjqqiLdLE8dqz (read-only demo data, rate-limited; users can create their own free key at api.sap.com).`},sap_ariba:{name:"sap_ariba",apiUrl:"https://openapi.ariba.com/api",regex:"(^|.*\\b)(ariba|openapi\\.ariba\\.com)(\\b.*|$)",icon:"sap",docsUrl:"https://developer.ariba.com/api/",preferredAuthType:"api_key",keywords:["sap","ariba","procurement","sourcing","suppliers","purchase_orders","invoices","requisitions","contracts","spend","operational_reporting","analytics_reporting"],systemSpecificInstructions:"SAP Ariba Open APIs live under https://openapi.ariba.com/api/<api-name>/<version>/... (regional hosts differ, e.g. eu.openapi.ariba.com for EU realms). Production requests need two credentials on every call: an OAuth 2.0 Bearer token in the Authorization header (client_credentials grant against https://api.ariba.com/v2/oauth/token, with client id and secret sent as Basic auth on the token request), plus the application's apiKey header. Most APIs also require the customer realm name as the realm query parameter. Applications and their API keys are created in the SAP Ariba Developer Portal (developer.ariba.com). Unlike other SAP products, Ariba has no public sandbox on the SAP Business Accelerator Hub \u2014 a real realm and developer portal application are required."},sap_concur:{name:"sap_concur",apiUrl:"https://us.api.concursolutions.com",regex:"(^|.*\\b)(concur|concursolutions\\.com)(\\b.*|$)",icon:"sap",docsUrl:"https://developer.concur.com/api-reference/",preferredAuthType:"api_key",keywords:["sap","concur","travel","expense","expense_reports","receipts","invoices","itineraries","trips","reimbursement","spend"],systemSpecificInstructions:`SAP Concur base URLs are geolocation-specific: https://us.api.concursolutions.com or https://us2.api.concursolutions.com (US), https://emea.api.concursolutions.com (EMEA) \u2014 use the geolocation returned with the OAuth token. Production authentication is OAuth 2.0: exchange credentials at /oauth2/v0/token (form-encoded, with client_id, client_secret, and grant_type such as password, client_credentials, or refresh_token), then send Authorization: Bearer <token>. Popular endpoints: /api/v3.0/expense/reports, /api/v3.0/expense/entries, /api/v3.0/common/lists, /profile/v1/me, /travel/trip/v1.1. v3.0 endpoints return XML by default \u2014 send Accept: application/json for JSON \u2014 and list endpoints paginate with limit and offset.
812
813
 
813
- If the user has no Concur instance, offer the free SAP Business Accelerator Hub sandbox: base URL https://sandbox.api.sap.com/concur/api/v3.0/... with the API key sent in the APIKey header (no OAuth needed). A shared test key can be offered: K8reTgiKCCaqvAPWC4cOjqqiLdLE8dqz (read-only demo data, rate-limited; users can create their own free key at api.sap.com).`},stripe:{name:"stripe",apiUrl:"https://api.stripe.com",regex:"^.*stripe.*$",icon:"stripe",docsUrl:"https://docs.stripe.com/api",openApiUrl:"https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json",preferredAuthType:"api_key",keywords:["customers","charges","payment_intents","products","prices","subscriptions","invoices","balance_transactions","refunds","checkout_sessions","line_items","payment_methods","issuers","plans","setup_intents","payouts","transfers","balance","users","emails"]},shopify:{name:"shopify",apiUrl:"https://admin.shopify.com",regex:"^.*(shopify|myshopify).*$",icon:"shopify",docsUrl:"https://shopify.dev/docs/api",preferredAuthType:"oauth2",oauth:{authUrl:"https://{shop}.myshopify.com/admin/oauth/authorize",tokenUrl:"https://{shop}.myshopify.com/admin/oauth/access_token",scopes:"read_products write_products read_orders write_orders read_all_orders read_customers write_customers read_inventory write_inventory read_fulfillments write_fulfillments read_shipping write_shipping read_draft_orders write_draft_orders read_content write_content read_themes read_locations read_price_rules write_price_rules read_discounts write_discounts read_gift_cards read_reports read_analytics read_checkouts read_metaobject_definitions read_metaobjects write_metaobjects",extraBodyParams:{expiring:"1"}},keywords:["products","variants","collections","customers","orders","fulfillments","inventory_items","inventory_levels","metafields","price_rules","discount_codes","shipping_zones","locations","gift_cards","product_images"],systemSpecificInstructions:`Shopify OAuth URLs contain {shop} placeholders \u2014 ALWAYS substitute with the store's myshopify subdomain (e.g. "my-store" for my-store.myshopify.com) in both auth.authUrl and auth.tokenUrl when calling create_connection. Since Jan 2026 legacy admin custom apps are deprecated; all new apps must be created via the Dev Dashboard (dev.shopify.com/dashboard) or Partner Dashboard: create app \u2192 Versions tab \u2192 set scopes, redirect URL (use the superglue OAuth callback), release version, then install on store. The "App URL" can be set to https://shopify.dev/apps/default-app-home for non-embedded integrations. Client ID and secret are under Settings in the Dev Dashboard (https://dev.shopify.com/dashboard). For maximum Admin API access request all needed scopes during version creation; read_all_orders requires separate approval in Partner Dashboard \u2192 API access \u2192 Access requests (gives order history beyond 60 days). Shopify is migrating to GraphQL Admin API \u2014 REST Admin API is legacy since Oct 2024 and new public apps must use GraphQL exclusively since Apr 2025. API base: https://{shop}.myshopify.com/admin/api/{version}/graphql.json \u2014 IMPORTANT: authenticate with header X-Shopify-Access-Token: <<shopify_access_token>>, NOT Authorization: Bearer. Walk the user through the required Shopify app setup and configuration steps before creating the connection \u2014 Shopify onboarding is non-trivial and users benefit from understanding the Dev Dashboard app creation, scope selection, and redirect URL setup before proceeding.`},hubspot:{name:"hubspot",apiUrl:"https://api.hubapi.com/crm/v3",regex:"^.*(hubapi|hubspot).*$",icon:"hubspot",docsUrl:"https://developers.hubspot.com/docs/api/overview",openApiUrl:"https://api.hubspot.com/public/api/spec/v1/specs",preferredAuthType:"api_key",oauth:{authUrl:"https://app.hubspot.com/oauth/authorize",tokenUrl:"https://api.hubapi.com/oauth/v1/token",scopes:"crm.objects.contacts.read crm.objects.contacts.write crm.objects.companies.read crm.objects.companies.write crm.objects.deals.read crm.objects.deals.write crm.objects.owners.read forms forms-uploaded-files files sales-email-read crm.objects.quotes.read crm.objects.quotes.write"},keywords:["contacts","companies","deals","tickets","line_items","products","associations","memberships"]},zoho_crm:xS("com"),zoho_crm_eu:xS("eu"),zoho_crm_uk:xS("uk"),zoho_projects:LS("com"),zoho_projects_eu:LS("eu"),zoho_projects_uk:LS("uk"),celigo:{name:"celigo",label:"Celigo",apiUrl:"https://api.integrator.io",regex:"^.*(integrator\\.io|celigo).*$",icon:"/logos/celigo.svg",docsUrl:"https://developer.celigo.com/api",preferredAuthType:"api_key",systemSpecificInstructions:`Celigo integrator.io API. Send Authorization: Bearer <<celigo_api_key>>. Only an account owner or administrator can create tokens, under Resources \u2192 API tokens in integrator.io; choose Full access or a Custom scope.
814
+ If the user has no Concur instance, offer the free SAP Business Accelerator Hub sandbox: base URL https://sandbox.api.sap.com/concur/api/v3.0/... with the API key sent in the APIKey header (no OAuth needed). A shared test key can be offered: K8reTgiKCCaqvAPWC4cOjqqiLdLE8dqz (read-only demo data, rate-limited; users can create their own free key at api.sap.com).`},stripe:{name:"stripe",apiUrl:"https://api.stripe.com",regex:"^.*stripe.*$",icon:"stripe",docsUrl:"https://docs.stripe.com/api",openApiUrl:"https://raw.githubusercontent.com/stripe/openapi/master/openapi/spec3.json",preferredAuthType:"api_key",keywords:["customers","charges","payment_intents","products","prices","subscriptions","invoices","balance_transactions","refunds","checkout_sessions","line_items","payment_methods","issuers","plans","setup_intents","payouts","transfers","balance","users","emails"]},shopify:{name:"shopify",apiUrl:"https://admin.shopify.com",regex:"^.*(shopify|myshopify).*$",icon:"shopify",docsUrl:"https://shopify.dev/docs/api",preferredAuthType:"oauth2",oauth:{authUrl:"https://{shop}.myshopify.com/admin/oauth/authorize",tokenUrl:"https://{shop}.myshopify.com/admin/oauth/access_token",scopes:"read_products write_products read_orders write_orders read_all_orders read_customers write_customers read_inventory write_inventory read_fulfillments write_fulfillments read_shipping write_shipping read_draft_orders write_draft_orders read_content write_content read_themes read_locations read_price_rules write_price_rules read_discounts write_discounts read_gift_cards read_reports read_analytics read_checkouts read_metaobject_definitions read_metaobjects write_metaobjects",extraBodyParams:{expiring:"1"}},keywords:["products","variants","collections","customers","orders","fulfillments","inventory_items","inventory_levels","metafields","price_rules","discount_codes","shipping_zones","locations","gift_cards","product_images"],systemSpecificInstructions:`Shopify OAuth URLs contain {shop} placeholders \u2014 ALWAYS substitute with the store's myshopify subdomain (e.g. "my-store" for my-store.myshopify.com) in both auth.authUrl and auth.tokenUrl when calling connect. Since Jan 2026 legacy admin custom apps are deprecated; all new apps must be created via the Dev Dashboard (dev.shopify.com/dashboard) or Partner Dashboard: create app \u2192 Versions tab \u2192 set scopes, redirect URL (use the superglue OAuth callback), release version, then install on store. The "App URL" can be set to https://shopify.dev/apps/default-app-home for non-embedded integrations. Client ID and secret are under Settings in the Dev Dashboard (https://dev.shopify.com/dashboard). For maximum Admin API access request all needed scopes during version creation; read_all_orders requires separate approval in Partner Dashboard \u2192 API access \u2192 Access requests (gives order history beyond 60 days). Shopify is migrating to GraphQL Admin API \u2014 REST Admin API is legacy since Oct 2024 and new public apps must use GraphQL exclusively since Apr 2025. API base: https://{shop}.myshopify.com/admin/api/{version}/graphql.json \u2014 IMPORTANT: authenticate with header X-Shopify-Access-Token: <<shopify_access_token>>, NOT Authorization: Bearer. Walk the user through the required Shopify app setup and configuration steps before creating the connection \u2014 Shopify onboarding is non-trivial and users benefit from understanding the Dev Dashboard app creation, scope selection, and redirect URL setup before proceeding.`},hubspot:{name:"hubspot",apiUrl:"https://api.hubapi.com/crm/v3",regex:"^.*(hubapi|hubspot).*$",icon:"hubspot",docsUrl:"https://developers.hubspot.com/docs/api/overview",openApiUrl:"https://api.hubspot.com/public/api/spec/v1/specs",preferredAuthType:"api_key",oauth:{authUrl:"https://app.hubspot.com/oauth/authorize",tokenUrl:"https://api.hubapi.com/oauth/v1/token",scopes:"crm.objects.contacts.read crm.objects.contacts.write crm.objects.companies.read crm.objects.companies.write crm.objects.deals.read crm.objects.deals.write crm.objects.owners.read forms forms-uploaded-files files sales-email-read crm.objects.quotes.read crm.objects.quotes.write"},keywords:["contacts","companies","deals","tickets","line_items","products","associations","memberships"]},zoho_crm:xS("com"),zoho_crm_eu:xS("eu"),zoho_crm_uk:xS("uk"),zoho_projects:LS("com"),zoho_projects_eu:LS("eu"),zoho_projects_uk:LS("uk"),celigo:{name:"celigo",label:"Celigo",apiUrl:"https://api.integrator.io",regex:"^.*(integrator\\.io|celigo).*$",icon:"/logos/celigo.svg",docsUrl:"https://developer.celigo.com/api",preferredAuthType:"api_key",systemSpecificInstructions:`Celigo integrator.io API. Send Authorization: Bearer <<celigo_api_key>>. Only an account owner or administrator can create tokens, under Resources \u2192 API tokens in integrator.io; choose Full access or a Custom scope.
814
815
  Regions are fully isolated and tokens do not cross them: US https://api.integrator.io (UI integrator.io), EU https://api.eu.integrator.io (UI eu.integrator.io), AU https://api.au.integrator.io, CA https://api.ca.integrator.io. Use the host that matches the user's integrator.io login URL. Non-production environments share the same host but need a separate token.
815
816
  API: resources are under /v1 (integrations, flows, exports, imports, connections, jobs, scripts). List endpoints paginate with a Link header rel="next" that carries an opaque after cursor; follow it until it is absent and never construct the cursor. PUT replaces the whole resource, so GET the current body, change only the needed fields, then PUT it back. Rate limit: a 1,000-request bucket that refills at 300 requests per second; on 429, wait for Retry-After seconds.`,keywords:["integrations","flows","exports","imports","connections","jobs","scripts","errors","lookup caches","ipaas"]},hrworks:{name:"hrworks",apiUrl:"https://api.hrworks.de/v2",regex:"(^|.*\\b)(hr\\s?works|hrworks)(\\b.*|$)",icon:"/logos/hrworks.png",docsUrl:"https://developers.hrworks.de/",preferredAuthType:"api_key",keywords:["hr","employee","absence","vacation","payroll","personnel","time_tracking","human_resources","working_time","attendance","onboarding","applicant_management","travel_expenses","sick_leave"]},gusto:{name:"gusto",apiUrl:"https://api.gusto.com/v1",regex:"(^|.*\\b)(gusto|gusto\\.com|api\\.gusto\\.com)(\\b.*|$)",icon:"gusto",docsUrl:"https://docs.gusto.com/embedded-payroll/reference",preferredAuthType:"oauth2",oauth:{authUrl:"https://api.gusto.com/oauth/authorize",tokenUrl:"https://api.gusto.com/oauth/token"},keywords:["gusto","gusto api","payroll","hr","employees","employee","companies","payrolls","contractors","benefits","time_off","departments","jobs","locations","onboarding","taxes","deductions","pay_schedules","compensation"],systemSpecificInstructions:"Gusto uses OAuth-derived Bearer tokens. Development calls should use https://api.gusto-demo.com/v1; production calls use https://api.gusto.com/v1 after Gusto approval. The URL path stays /v1 while API versioning is controlled by the X-Gusto-API-Version header. Many payroll and benefits endpoints require specific scopes, and benefits containing PHI require stronger scopes."},workday:{name:"workday",apiUrl:"https://{host}/ccx/api/v1/{tenant}",regex:"(^|.*\\b)(workday|workday\\.com|myworkday)(\\b.*|$)",icon:"/logos/workday.svg",docsUrl:"https://community.workday.com/sites/default/files/file-hosting/restapi/index.html",preferredAuthType:"oauth2",oauth:{authUrl:"https://{host}/ccx/oauth2/{tenant}/authorize",tokenUrl:"https://{host}/ccx/oauth2/{tenant}/token"},keywords:["workday","workday api","hr","hcm","payroll","workers","employees","employee","recruiting","benefits","absence","time_tracking","financials","organizations","positions","staffing","reports","raas","business_processes","supervisory_organizations"],systemSpecificInstructions:`{host} is the Workday data-center host, not a tenant subdomain: implementation tenants look like wd2-impl-services1.workday.com and production tenants like wd5-services1.myworkday.com. {tenant} is the tenant name and appears only as a path segment. Read both from the Web Services endpoint URL and the Token Endpoint shown under "View API Clients" in the customer tenant. Workday REST endpoints are tenant, service, and version specific. Do not assume resources live directly under /ccx/api; most REST calls use /ccx/api/{service}/{version}/{tenant}/{resource}. Workday also exposes RaaS/custom report endpoints under /ccx/service/customreport2/{tenant}/... that may use Basic Auth instead of OAuth depending on tenant configuration. Verify the exact REST API endpoint, enabled services, and auth method in the customer's Workday "View API Clients" configuration before creating tools.`},bamboohr:{name:"bamboohr",apiUrl:"https://{companyDomain}.bamboohr.com/api/v1",regex:"(^|.*\\b)(bamboohr|bamboo\\s?hr|bamboohr\\.com)(\\b.*|$)",icon:"/logos/bamboohr.ico",docsUrl:"https://documentation.bamboohr.com/reference",openApiUrl:"https://openapi.bamboohr.io/main/latest/docs/openapi/public-openapi.yaml",preferredAuthType:"basic_auth",keywords:["bamboohr","bamboo hr","bamboohr api","hr","hris","employees","employee","time_off","time_tracking","payroll","reports","fields","applicant_tracking","benefits","company_files","users","webhooks","timesheets","requests"],systemSpecificInstructions:'For API-key auth, use HTTP Basic Auth with the BambooHR API key as the username and any non-empty password such as "x". The companyDomain placeholder is only the subdomain before .bamboohr.com. BambooHR also supports OAuth for many APIs through Developer Portal applications; use OAuth when the customer is building a marketplace or multi-customer app and has client credentials.'},lucca:{name:"lucca",apiUrl:"https://{host}/lucca-api",regex:"(^|.*\\b)(lucca|ilucca|luccasoftware)(\\b.*|$)",icon:"/logos/lucca.svg",docsUrl:"https://developers.luccasoftware.com",openApiUrl:"https://developers.luccasoftware.com/openapi-specs/lucca-api@2024-11-01.json",preferredAuthType:"oauth2",oauth:{tokenUrl:"https://accounts.world.luccasoftware.com/connect/token",grant_type:"client_credentials",tokenAuthMethod:"body",tokenContentType:"form"},keywords:["lucca","hr","hris","employees","employee","employments","departments","legal_entities","business_establishments","job_positions","employee_attributes","working_time_arrangements","leaves","leave_requests","webhooks","files"],systemSpecificInstructions:`{host} is the customer's Lucca account host. Production, test, and demo accounts use {account}.ilucca.net, {account}.ilucca-test.net, and {account}.ilucca-demo.net; Swiss accounts use .ch instead of .net. Sandboxes use {account}-{sandboxName}.sandbox.{server}.luccasoftware.com, where sandboxName is generated at creation and server is eu1, eu2, or ch1. Copy the host from the browser address bar of the account to connect; do not assume production.
816
817
 
@@ -829,7 +830,7 @@ If the user has or creates an OAuth app in their Google Cloud project:
829
830
  1. Create OAuth credentials in Google Cloud Console \u2192 APIs & Services \u2192 Credentials \u2192 Create Credentials \u2192 OAuth client ID
830
831
  2. Set application type to "Web application" and add the superglue callback URL as authorized redirect URI
831
832
  3. Create the connection with OAuth configuration and collect the client secret through the secure oauth_client_secret form
832
- 4. Then run create_connection - the user completes Google sign-in in a popup
833
+ 4. Then run connect - the user completes Google sign-in in a popup
833
834
  5. Superglue auto-refreshes tokens - no manual token management needed
834
835
 
835
836
  OPTION 2: Service Account JWT (Advanced)
@@ -954,7 +955,7 @@ QUERY LIMITS: Chat messages support $orderby lastModifiedDateTime or createdDate
954
955
 
955
956
  RATE LIMITS: 429 with Retry-After. Per app per tenant: 1 request per second on a given chat or channel and 4 per second on a given team. Long backfills of one channel get throttled; keep page size at 50 and retry on Retry-After.`},outlookMail:{name:"outlookMail",label:"Outlook",apiUrl:"https://graph.microsoft.com",regex:"^.*(outlook|graph\\.microsoft\\.com.*(messages|mailFolders|mailboxSettings|calendarView|events)|learn\\.microsoft\\.com.*graph.*(mail|message)).*$",icon:"/logos/outlook.svg",docsUrl:"https://learn.microsoft.com/en-us/graph/api/resources/mail-api-overview",preferredAuthType:"oauth2",oauth:{authUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",scopes:"openid profile email offline_access User.Read Mail.ReadWrite Mail.Send MailboxSettings.Read Contacts.ReadWrite Calendars.ReadWrite",managed:!0},keywords:["outlook","email","mail","mailbox","messages","inbox","drafts","send","attachments","calendar","events","microsoft graph","office 365","oauth"],systemSpecificInstructions:"Outlook uses delegated Microsoft Graph access for work or school accounts. Some permissions require tenant administrator approval. Avoid requesting scopes that need admin consent unless the tool cannot work without them."},powerAutomate:{name:"powerAutomate",skill:"microsoft-dynamics",label:"Power Automate",apiUrl:"https://api.flow.microsoft.com",regex:"^.*(flow\\.microsoft\\.com|powerautomate|power-automate|api\\.powerplatform\\.com.*powerautomate|learn\\.microsoft\\.com.*power-automate).*$",icon:"/logos/power_automate.svg",docsUrl:"https://learn.microsoft.com/en-us/power-automate/manage-flows-with-code",preferredAuthType:"oauth2",oauth:{authUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",scopes:"openid profile email offline_access Activity.Read.All Approvals.Manage.All Approvals.Read.All Flows.Install Flows.Manage.All Flows.Read.All",managed:!0},keywords:["power automate","flow","cloud flow","flow run","run history","activity","approval","approvals","approve","reject","trigger","environment","power platform","oauth"],systemSpecificInstructions:"Power Automate uses the delegated Flow service API with a work or school account."},microsoft:{name:"microsoft",apiUrl:"https://graph.microsoft.com",regex:"^.*(microsoft|graph\\.microsoft|office|outlook|live\\.com|sharepoint).*$",icon:"default",docsUrl:"https://learn.microsoft.com/en-us/graph/api/overview",preferredAuthType:"oauth2",oauth:{authUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",scopes:"openid profile email offline_access User.Read User.ReadBasic.All Mail.ReadWrite Mail.Send MailboxSettings.Read Calendars.ReadWrite Contacts.ReadWrite Files.ReadWrite.All Sites.ReadWrite.All Sites.Manage.All Notes.ReadWrite.All Tasks.ReadWrite Team.ReadBasic.All Team.Create Channel.ReadBasic.All ChannelMessage.Send Chat.ReadWrite",managed:!0},keywords:["users","groups","mail","calendar","contacts","onedrive","sharepoint","teams","planner","tasks","drives","sites","lists","permissions","graph","oauth"],systemSpecificInstructions:"superglue provides a managed multi-tenant Microsoft app (work/school and personal accounts), so no Azure app registration is needed \u2014 authenticate directly via OAuth. The default scopes are user-consentable in most tenants. Add the admin-consent scopes Channel.Create, ChannelMessage.Read.All, Group.ReadWrite.All and TeamMember.ReadWrite.All only when strictly needed. Conditional Access policies can require administrator involvement for other permissions. Always keep offline_access in scopes to receive refresh tokens for long-term access. A custom Entra Web app registration is only needed when an organization requires single-tenant access or its own app governance: register it with the exact OAuth callback URL of the current superglue deployment, use tenant-specific authorization and token URLs instead of /common, and copy the client secret Value, not the Secret ID."},dynamics365_sales:{name:"dynamics365_sales",skill:"microsoft-dynamics",apiUrl:"https://<<api_host>>/api/data/v9.2",regex:"^.*(crm\\d*\\.dynamics\\.com|dynamicscrm).*$",icon:"dynamics365",docsUrl:"https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/query-data-web-api",preferredAuthType:"oauth2",connectionFields:[{key:"api_host",label:"Environment host",placeholder:"contoso.crm.dynamics.com",required:!0}],oauth:{authUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/authorize",tokenUrl:"https://login.microsoftonline.com/common/oauth2/v2.0/token",scopes:"https://<<api_host>>/user_impersonation offline_access",managed:!0,grant_type:"authorization_code"},keywords:["accounts","contacts","leads","opportunities","quotes","salesorders","salesorderdetails","products","incidents","campaigns","invoices","competitors","teams","systemusers","businessunits","odata","dynamics","crm","dynamics 365 sales","dataverse","oauth"],systemSpecificInstructions:`Dynamics 365 Sales \u2014 Dataverse Web API v9.2
956
957
 
957
- CONNECTING: superglue provides a managed multi-tenant Microsoft app, so no Azure app registration is needed \u2014 authenticate directly via OAuth. The Dataverse scope is per-environment: the template scope contains an <<api_host>> placeholder and Microsoft rejects it unresolved \u2014 ALWAYS substitute the environment host (e.g. https://contoso.crm.dynamics.com/user_impersonation offline_access) in scopes when calling create_connection. Ask the user for the host if it is unknown. The user_impersonation scope does not require Entra administrator consent, but the signed-in user needs a Dynamics 365 license and a security role in the target environment. Keep offline_access in scopes to receive refresh tokens.
958
+ CONNECTING: superglue provides a managed multi-tenant Microsoft app, so no Azure app registration is needed \u2014 authenticate directly via OAuth. The Dataverse scope is per-environment: the template scope contains an <<api_host>> placeholder and Microsoft rejects it unresolved \u2014 ALWAYS substitute the environment host (e.g. https://contoso.crm.dynamics.com/user_impersonation offline_access) in scopes when calling connect. Ask the user for the host if it is unknown. The user_impersonation scope does not require Entra administrator consent, but the signed-in user needs a Dynamics 365 license and a security role in the target environment. Keep offline_access in scopes to receive refresh tokens.
958
959
 
959
960
  REQUIRED HEADERS (in addition to Authorization):
960
961
  - OData-MaxVersion: 4.0
@@ -1871,7 +1872,7 @@ ${s}`;return}if(rE(e,i,Jke)){Wke(e,o)&&(r.retry=e.toString("utf8",o));return}if(
1871
1872
  `);t.stack=r?`${r}
1872
1873
  ${o}`:i.stack}K.exports.fetch=function(e,r=void 0){return DOe(e,r).catch(n=>{throw jY?GY(n,jY):n&&typeof n=="object"&&Error.captureStackTrace(n,K.exports.fetch),n})};K.exports.Headers=wc().Headers;K.exports.Response=ep().Response;K.exports.Request=il().Request;K.exports.FormData=Bm().FormData;var{setGlobalOrigin:TOe,getGlobalOrigin:ROe}=Yw();K.exports.setGlobalOrigin=TOe;K.exports.getGlobalOrigin=ROe;var{CacheStorage:NOe}=TG(),{kConstruct:kOe}=Je();K.exports.caches=new NOe(kOe);var{deleteCookie:OOe,getCookies:UOe,getSetCookies:MOe,setCookie:xOe,parseCookie:LOe}=jG();K.exports.deleteCookie=OOe;K.exports.getCookies=UOe;K.exports.getSetCookies=MOe;K.exports.setCookie=xOe;K.exports.parseCookie=LOe;var{parseMIMEType:POe,serializeAMimeType:$Oe}=Un();K.exports.parseMIMEType=POe;K.exports.serializeAMimeType=$Oe;var{CloseEvent:FOe,ErrorEvent:jOe,MessageEvent:zOe}=Hy(),{WebSocket:HOe,ping:qOe}=CY();K.exports.WebSocket=HOe;K.exports.CloseEvent=FOe;K.exports.ErrorEvent=jOe;K.exports.MessageEvent=zOe;K.exports.ping=qOe;K.exports.WebSocketStream=DY().WebSocketStream;K.exports.WebSocketError=Qv().WebSocketError;K.exports.request=Ap(gl.request);K.exports.stream=Ap(gl.stream);K.exports.pipeline=Ap(gl.pipeline);K.exports.connect=Ap(gl.connect);K.exports.upgrade=Ap(gl.upgrade);K.exports.MockClient=mOe;K.exports.MockCallHistory=yOe;K.exports.MockCallHistoryLog=EOe;K.exports.MockPool=COe;K.exports.MockAgent=IOe;K.exports.SnapshotAgent=bOe;K.exports.mockErrors=SOe;var{EventSource:GOe}=FY();K.exports.EventSource=GOe;function YOe(){globalThis.fetch=K.exports.fetch,globalThis.Headers=K.exports.Headers,globalThis.Response=K.exports.Response,globalThis.Request=K.exports.Request,globalThis.FormData=K.exports.FormData,globalThis.WebSocket=K.exports.WebSocket,globalThis.CloseEvent=K.exports.CloseEvent,globalThis.ErrorEvent=K.exports.ErrorEvent,globalThis.MessageEvent=K.exports.MessageEvent,globalThis.EventSource=K.exports.EventSource}K.exports.install=YOe});var JY=m(yl=>{"use strict";Object.defineProperty(yl,"__esModule",{value:!0});yl.SuperglueClient=yl.SuperglueHttpError=void 0;var ml=xr(),Or=tS(),VOe=zS(),JOe=s$(),WOe=Dn(),ds=pu(),ZOe=Ld(),fp=14400*1e3,pp;if(typeof globalThis.process<"u"&&globalThis.process.versions?.node)try{let{Agent:t}=YY();pp=new t({headersTimeout:fp,bodyTimeout:fp})}catch{}function VY(t){if(t?.aborted)throw t.reason??new DOMException("Aborted","AbortError")}var oE=class extends Error{constructor(e,r,n,i){super(e),this.status=r,this.code=n,this.details=i,this.name="SuperglueHttpError"}};yl.SuperglueHttpError=oE;var kv=class{constructor({apiKey:e,apiEndpoint:r,onInfrastructureError:n,refreshToken:i,sseTokenProvider:o,tokenProvider:s}){if(!e&&!s)throw new Error("SuperglueClient requires either apiKey or tokenProvider");this.tokenProvider=s??(async()=>e),this.apiEndpoint=r??"https://api.superglue.cloud",this.sseManager=new VOe.SSELogSubscriptionManager(this.apiEndpoint,o??this.tokenProvider,i),this.onInfrastructureError=n,this.refreshToken=i}async getApiKey(){return this.tokenProvider()}async fetchWithAuthRetry(e,r){let n=await this.getApiKey(),i=await e(n);if(i.status!==401||!this.refreshToken)return i;VY(r);let o=await this.refreshToken();return VY(r),!o||o===n?i:(i.body?.cancel(),e(o))}isInfrastructureError(e){return(0,WOe.isAbortError)(e)?!1:!!(e instanceof TypeError&&e.message.toLowerCase().includes("fetch")||e instanceof Error&&e.name==="TimeoutError")}async restRequest(e,r,n,i,o){let a=await(await this.restResponse({method:e,path:r,body:n,extraHeaders:i,requestInit:o})).text();if(a)return JSON.parse(a)}async restData(...e){return(await this.restRequest(...e)).data}async restResponse({method:e,path:r,body:n,extraHeaders:i,requestInit:o}){let s=`${this.apiEndpoint.replace(/\/$/,"")}${r}`,a=n!=null,c=typeof FormData<"u"&&n instanceof FormData,u=d=>{let A={Authorization:`Bearer ${d}`,...i};return a&&!c&&e!=="GET"&&(A["Content-Type"]="application/json"),fetch(s,{...o,method:e,headers:A,body:a?c?n:JSON.stringify(n):void 0,signal:o?.signal??AbortSignal.timeout(fp),...pp?{dispatcher:pp}:{}})},l;try{l=await this.fetchWithAuthRetry(u,o?.signal)}catch(d){throw this.isInfrastructureError(d)&&this.onInfrastructureError?.(),d}if(!l.ok)throw await this.buildHttpError(l);return l}async uploadFiles(e,r){if(typeof r?.process!="boolean")throw new Error("process must be a boolean");if(e.length===0)return[];let n=e.map(l=>({...l,contentLength:l.contentLength??this.getUploadContentLength(l.content)})),o=(await this.restRequest("POST","/v1/files/uploads",{process:r.process,...r.allowUnprocessed?{allowUnprocessed:!0}:{},files:n.map(({fileName:l,contentType:d,contentLength:A})=>({fileName:l,contentLength:A,...d?{contentType:d}:{}}))})).data.files;if(o.length!==n.length)throw await Promise.all(o.map(l=>this.deleteFileUpload(l.id).catch(()=>{}))),new Error("Upload response did not match the selected files");let s=await Promise.allSettled(o.map(async(l,d)=>{let A=n[d],p=await fetch(l.uploadUrl,{method:"PUT",body:A.content,headers:{...l.uploadHeaders,...A.contentType?{"Content-Type":A.contentType}:{}},signal:AbortSignal.timeout(Math.min(fp,l.expiresIn*1e3))});if(!p.ok)throw new Error(`Upload failed for ${A.fileName}: ${p.status} ${p.statusText}`);return l.id})),a=s.flatMap(l=>l.status==="fulfilled"?[l.value]:[]),c=new Map;if(a.length>0)try{let l=await this.restRequest("POST","/v1/files/uploads/complete",{fileIds:a});c=new Map(l.data.files.map(d=>[d.id,d]))}catch(l){c=new Map(a.map(d=>[d,{id:d,fileName:n[o.findIndex(A=>A.id===d)]?.fileName||d,contentLength:n[o.findIndex(A=>A.id===d)]?.contentLength||0,status:"failed",error:l instanceof Error?l.message:String(l)}]))}let u=o.map((l,d)=>{let A=s[d],p=n[d];return A.status==="rejected"?{id:l.id,fileName:p.fileName,contentLength:p.contentLength,status:"failed",error:A.reason instanceof Error?A.reason.message:String(A.reason)}:c.get(l.id)||{id:l.id,fileName:p.fileName,contentLength:p.contentLength,status:"failed",error:"Upload completion returned no result"}});return await Promise.all(u.filter(l=>l.status==="failed").map(l=>this.deleteFileUpload(l.id).catch(()=>{}))),u}async deleteFileUpload(e){await this.restRequest("DELETE",`/v1/files/uploads/${encodeURIComponent(e)}`)}getUploadContentLength(e){return typeof e=="string"?new TextEncoder().encode(e).byteLength:e instanceof Uint8Array?e.byteLength:e.size}async buildHttpError(e){e.status>=500&&this.onInfrastructureError?.();let r=await e.text(),n=`HTTP ${e.status}: ${r}`,i,o;try{let s=JSON.parse(r);s&&typeof s=="object"&&!Array.isArray(s)&&(o=s),typeof s?.code=="string"&&(i=s.code);let a=s.error;typeof a=="string"?n=a:a&&typeof a=="object"&&(n=a.message||JSON.stringify(a))}catch{}return new oE(n,e.status,i,o)}async streamRequest(e,r,n){let i=e.includes("?")?"&":"?",o=`${this.apiEndpoint.replace(/\/$/,"")}${e}${i}stream=true`,s=u=>fetch(o,{method:"POST",headers:{Authorization:`Bearer ${u}`,Accept:"text/event-stream","Content-Type":"application/json"},body:JSON.stringify(r),signal:n??AbortSignal.timeout(fp),...pp?{dispatcher:pp}:{}}),a;try{a=await this.fetchWithAuthRetry(s,n)}catch(u){throw this.isInfrastructureError(u)&&this.onInfrastructureError?.(),u}if(!a.ok)throw await this.buildHttpError(a);if(!(a.headers.get("content-type")||"").includes("text/event-stream")){let u=await a.text();return u?JSON.parse(u):void 0}try{return await(0,JOe.consumeEventStreamResult)(a)}catch(u){throw this.isInfrastructureError(u)&&this.onInfrastructureError?.(),u}}async subscribeToLogsSSE(e={}){return this.sseManager.subscribeToLogs(e)}async disconnect(){await this.sseManager.disconnect()}async listMemoryNotes(e={}){let r=new URLSearchParams;e.scope&&r.set("scope",e.scope),e.query&&r.set("query",e.query);let n=r.toString();return this.restData("GET",`/v1/memory-notes${n?`?${n}`:""}`)}async createMemoryNote(e){return this.restData("POST","/v1/memory-notes",e)}async updateMemoryNote(e,r){return this.restData("PATCH",`/v1/memory-notes/${encodeURIComponent(e)}`,r)}async deleteMemoryNote(e){await this.restRequest("DELETE",`/v1/memory-notes/${encodeURIComponent(e)}`)}async clearMemoryNotes(e){return(await this.restRequest("DELETE",`/v1/memory-notes?scope=${e}`)).data.deleted}async getMe(){return this.restRequest("GET","/v1/me")}async completeOnboarding(){return this.restRequest("POST","/v1/me/onboarding/complete")}async runTool(e){let r=await this.restRequest("POST",`/v1/tools/${encodeURIComponent(e.toolId)}/run`,{inputs:e.payload,files:e.files,credentials:e.credentials,includeStepResultData:e.includeStepResultData,options:e.options,runId:e.runId,stateFixture:e.stateFixture},void 0,e.signal?{signal:e.signal}:void 0);return{success:r.status==="success",data:r.data,error:r.error,tool:r.tool,stepResults:r.stepResults?.map(n=>({...n}))||[],...r.fileArtifacts&&r.fileArtifacts.length>0?{fileArtifacts:r.fileArtifacts}:{},...r.metadata?.warnings?.length?{warnings:r.metadata.warnings}:{}}}async runToolConfig(e){let r=e.createRun?"/v1/tools/run?createRun=true":"/v1/tools/run",n=await this.restRequest("POST",r,{tool:e.tool,payload:e.payload,files:e.files,credentials:e.credentials,includeStepResultData:e.includeStepResultData,options:e.options,runId:e.runId,stateFixture:e.stateFixture,executionKind:e.executionKind,parentToolId:e.parentToolId,draftId:e.draftId},e.traceId?{"X-Trace-Id":e.traceId}:void 0,e.signal?{signal:e.signal}:void 0);return{success:n.status?n.status==="success":n.success??!1,data:n.data,error:n.error,tool:n.tool||e.tool,stepResults:n.stepResults?.map(o=>({...o}))||[],...n.fileArtifacts&&n.fileArtifacts.length>0?{fileArtifacts:n.fileArtifacts}:{},...n.metadata?.warnings?.length?{warnings:n.metadata.warnings}:{}}}async abortToolExecution(e){return{success:!0,runId:(await this.restRequest("POST",`/v1/runs/${encodeURIComponent(e)}/cancel`)).runId}}async executeStep({step:e,payload:r,files:n,previousResults:i,credentials:o,credentialsList:s,options:a,runId:c,systemIds:u,credentialId:l,systemAuth:d,createRun:A,parentToolId:p,stepIndex:h,stepId:g,signal:w,stream:B}){let _={step:e,payload:r,files:n,previousResults:i,credentials:o,credentialsList:s,options:a,runId:c,systemIds:u,credentialId:l,systemAuth:d,createRun:A,parentToolId:p,stepIndex:h,stepId:g};return B?this.streamRequest("/v1/tools/step/run",_,w):this.restRequest("POST","/v1/tools/step/run",_,void 0,w?{signal:w}:void 0)}async abortStep(e){return this.restRequest("POST","/v1/tools/step/abort",{runId:e})}async executeTransformOnly({outputTransform:e,outputSchema:r,inputSchema:n,payload:i,files:o,stepResults:s,options:a,runId:c,createRun:u,parentToolId:l,stepId:d,signal:A,stream:p}){let h={outputTransform:e,outputSchema:r,inputSchema:n,payload:i,files:o,stepResults:s,options:a,runId:c,createRun:u,parentToolId:l,stepId:d};return p?this.streamRequest("/v1/tools/transform/run",h,A):this.restRequest("POST","/v1/tools/transform/run",h,void 0,A?{signal:A}:void 0)}async createRun({toolId:e,toolConfig:r,toolResult:n,stepResults:i,toolPayload:o,status:s,error:a,startedAt:c,completedAt:u,executionKind:l,parentToolId:d,draftId:A}){return this.restRequest("POST","/v1/runs",{toolId:e,toolConfig:r,toolResult:n,stepResults:i,toolPayload:o,status:s,error:a,startedAt:(0,ds.toUTCISOString)(c,"run.startedAt"),completedAt:(0,ds.toUTCISOString)(u,"run.completedAt"),executionKind:l,parentToolId:d,draftId:A})}async checkRunLimit(){return this.restData("POST","/v1/runs/check-limit")}async extract({file:e,envelope:r}){if(!e)throw new Error("File must be provided for extract.");let n=new FormData;n.append("file",e);let i=r?"/v1/extract?envelope=true":"/v1/extract";return this.restRequest("POST",i,n)}mapOpenAPIRunToRun(e){let r={running:ml.RunStatus.RUNNING,success:ml.RunStatus.SUCCESS,failed:ml.RunStatus.FAILED,aborted:ml.RunStatus.ABORTED};return{runId:e.runId??e.id,toolId:e.toolId,tool:e.tool,systemIds:e.systemIds,status:r[e.status]??ml.RunStatus.FAILED,toolPayload:e.toolPayload,data:e.data,toolResult:e.data,error:e.error,stepResults:e.stepResults,options:e.options,requestSource:e.requestSource,traceId:e.traceId,resultStorageUri:e.resultStorageUri,userId:e.userId,userEmail:e.userEmail,userName:e.userName,metadata:{...e.metadata,executionKind:e.metadata?.executionKind??ml.RunExecutionKind.FULL},fileArtifacts:e.fileArtifacts}}mapOpenAPIScheduleToToolSchedule(e){return{...e,lastRunAt:e.lastRunAt?(0,ds.requireUTCDate)(e.lastRunAt,"schedule.lastRunAt"):void 0,nextRunAt:(0,ds.requireUTCDate)(e.nextRunAt,"schedule.nextRunAt"),createdAt:(0,ds.requireUTCDate)(e.createdAt,"schedule.createdAt"),updatedAt:(0,ds.requireUTCDate)(e.updatedAt,"schedule.updatedAt")}}async listRuns(e={}){let r=(0,Or.createSearchListQueryParams)(e);e.toolId!==void 0&&r.set("toolId",e.toolId),e.searchUserIds?.length&&r.set("searchUserIds",e.searchUserIds.join(",")),e.includeTotal!==void 0&&r.set("includeTotal",String(e.includeTotal)),e.startedAfter!==void 0&&r.set("startedAfter",e.startedAfter instanceof Date?(0,ds.toUTCISOString)(e.startedAfter,"run.startedAfter"):e.startedAfter),e.statuses!==void 0?r.set("status",e.statuses.join(",")):e.status!==void 0&&r.set("status",e.status),e.requestSources!==void 0&&r.set("requestSources",e.requestSources.join(",")),e.executionKinds!==void 0&&r.set("executionKinds",e.executionKinds.join(",")),e.userId!==void 0&&r.set("userId",e.userId),e.systemId!==void 0&&r.set("systemId",e.systemId),e.systemIds!==void 0&&r.set("systemIds",e.systemIds.join(","));let n=r.size>0?`?${r.toString()}`:"",i=await this.restRequest("GET",`/v1/runs${n}`,void 0,void 0,{signal:e.signal});return{data:i.data.map(o=>this.mapOpenAPIRunToRun(o)),total:i.total,page:i.page,limit:i.limit,hasMore:i.hasMore}}async getActivityCounts(e){let r=new URLSearchParams;e?.from&&r.set("from",e.from instanceof Date?(0,ds.toUTCISOString)(e.from,"activity.from"):e.from),e?.to&&r.set("to",e.to instanceof Date?(0,ds.toUTCISOString)(e.to,"activity.to"):e.to);let n=r.toString();return(await this.restRequest("GET",`/v1/activity/counts${n?`?${n}`:""}`,void 0,void 0,{signal:e?.signal})).counts}async getRun(e){try{let r=await this.restRequest("GET",`/v1/runs/${encodeURIComponent(e)}`);return this.mapOpenAPIRunToRun(r)}catch(r){if(r.message?.includes("404")||r.message?.includes("not found"))return null;throw r}}async getTool(e){try{return await this.restRequest("GET",`/v1/tools/${encodeURIComponent(e)}`)}catch(r){if(r.message?.includes("404")||r.message?.includes("not found")||r.message?.includes("403")||r.message?.includes("not allowed"))return null;throw r}}async getToolState(e){return(await this.restRequest("GET",`/v1/tools/${encodeURIComponent(e)}/state`)).state}async setToolState(e,r){await this.restRequest("PUT",`/v1/tools/${encodeURIComponent(e)}/state`,{state:r})}async deleteToolState(e){return(await this.restRequest("DELETE",`/v1/tools/${encodeURIComponent(e)}/state`)).deletedKeys}async archiveTool(e,r=!0){return this.updateTool(e,{archived:r})}async bulkArchiveTools(e,r=!0){return this.restRequest("POST","/v1/tools/bulk/archive",{ids:e,archived:r})}async bulkDeleteTools(e){return this.restRequest("POST","/v1/tools/bulk/delete",{ids:e})}async listTools(e={}){let r=(0,Or.createListQueryParams)(e);e.includeArchived!==void 0&&r.set("includeArchived",String(e.includeArchived));let n=r.size>0?`?${r.toString()}`:"";return this.restRequest("GET",`/v1/tools${n}`)}async listAllTools(e={}){return(0,Or.listAllPages)((r,n)=>this.listTools({...e,page:r,limit:n}))}async createTool(e,r){return this.restRequest("POST","/v1/tools",{...r,id:e})}async updateTool(e,r){return this.restRequest("PUT",`/v1/tools/${encodeURIComponent(e)}`,r)}async deleteTool(e){try{return await this.restRequest("DELETE",`/v1/tools/${encodeURIComponent(e)}`),!0}catch(r){if(r.message?.includes("404"))return!1;throw r}}async renameTool(e,r){return this.restRequest("POST",`/v1/tools/${encodeURIComponent(e)}/rename`,{newId:r})}async getWorkflow(e){return this.getTool(e)}async archiveWorkflow(e,r=!0){return this.upsertWorkflow(e,{archived:r})}async createWorkflow(e,r){return this.createTool(e,r)}async updateWorkflow(e,r){return this.updateTool(e,r)}async upsertWorkflow(e,r){return await this.getTool(e)?this.updateTool(e,r):this.createTool(e,r)}async deleteWorkflow(e){return this.deleteTool(e)}async renameWorkflow(e,r){return this.renameTool(e,r)}async listProjectSummaries(e={}){let r=(0,Or.createSearchListQueryParams)(e);return r.set("includeResources","false"),e.includeArchived!==void 0&&r.set("includeArchived",String(e.includeArchived)),this.restRequest("GET",`/v1/projects?${r.toString()}`)}async listAllProjectSummaries({includeArchived:e}={}){return(0,Or.listAllPages)((r,n)=>this.listProjectSummaries({page:r,limit:n,...e!==void 0?{includeArchived:e}:{}}))}async listAllProjectTasks(e){return(0,Or.listAllPages)((r,n)=>this.restRequest("GET",`/v1/projects/${encodeURIComponent(e)}/tasks?page=${r}&limit=${n}`))}async saveProjectTask({projectId:e,taskId:r,input:n}){let i=`/v1/projects/${encodeURIComponent(e)}/tasks${r?`/${encodeURIComponent(r)}`:""}`;return this.restData(r?"PATCH":"POST",i,n)}async listAllProjectLabels(e){return(0,Or.listAllPages)((r,n)=>this.restRequest("GET",`/v1/projects/${encodeURIComponent(e)}/labels?page=${r}&limit=${n}`))}async saveProjectLabel({projectId:e,labelId:r,input:n}){let i=`/v1/projects/${encodeURIComponent(e)}/labels${r?`/${encodeURIComponent(r)}`:""}`;return this.restData(r?"PATCH":"POST",i,n)}async deleteProjectLabel({projectId:e,labelId:r}){await this.restRequest("DELETE",`/v1/projects/${encodeURIComponent(e)}/labels/${encodeURIComponent(r)}`)}async listSchedules(e={}){let r=(0,Or.createListQueryParams)(e),n=r.size>0?`?${r.toString()}`:"",i=e.toolId?`/v1/tools/${encodeURIComponent(e.toolId)}/schedules${n}`:`/v1/schedules${n}`,o=await this.restRequest("GET",i);return{...o,data:o.data.map(s=>this.mapOpenAPIScheduleToToolSchedule(s))}}async listAllSchedules(e={}){return(0,Or.listAllPages)((r,n)=>this.listSchedules({...e,page:r,limit:n}))}async getToolSchedule(e,r){try{let n=await this.restRequest("GET",`/v1/tools/${encodeURIComponent(e)}/schedules/${encodeURIComponent(r)}`);return this.mapOpenAPIScheduleToToolSchedule(n)}catch(n){if(n.message?.includes("404")||n.message?.includes("not found"))return null;throw n}}async createToolSchedule(e,r){let n=await this.restRequest("POST",`/v1/tools/${encodeURIComponent(e)}/schedules`,{...r,timezone:r.timezone||(0,ZOe.getRuntimeTimezone)()});return this.mapOpenAPIScheduleToToolSchedule(n)}async updateToolSchedule(e,r,n){let i=await this.restRequest("PUT",`/v1/tools/${encodeURIComponent(e)}/schedules/${encodeURIComponent(r)}`,n);return this.mapOpenAPIScheduleToToolSchedule(i)}async deleteToolSchedule(e,r){return await this.restRequest("DELETE",`/v1/tools/${encodeURIComponent(e)}/schedules/${encodeURIComponent(r)}`),!0}async bulkSetSchedulesEnabled(e,r){return this.restRequest("POST","/v1/schedules/bulk/enable",{ids:e,enabled:r})}async bulkDeleteSchedules(e){return this.restRequest("POST","/v1/schedules/bulk/delete",{ids:e})}async listConnections(e={}){let r=(0,Or.createListQueryParams)(e);e.systemId!==void 0&&r.set("systemId",e.systemId);let n=r.size>0?`?${r.toString()}`:"";return this.restRequest("GET",`/v1/connections${n}`)}async listAllConnections(e={}){return(0,Or.listAllPages)((r,n)=>this.listConnections({...e,page:r,limit:n}))}async updateOAuthApp(e,r){return this.restData("PUT",`/v1/oauth-apps/${encodeURIComponent(e)}`,r)}async deleteOAuthApp(e){await this.restRequest("DELETE",`/v1/oauth-apps/${encodeURIComponent(e)}`)}async listOAuthApps({systemId:e}={}){return(0,Or.listAllPages)(async(r,n)=>{let i=new URLSearchParams({page:String(r),limit:String(n),...e?{systemId:e}:{}});return this.restRequest("GET",`/v1/oauth-apps?${i}`)})}async getConnectionSetup(e){return this.restData("GET",`/v1/connections/setup/${encodeURIComponent(e)}`)}async createConnection(e){return this.restData("POST","/v1/connections",e)}async replaceConnection(e,r){return this.restData("PUT",`/v1/connections/${encodeURIComponent(e)}`,{credentials:r})}async updateConnection(e,r){return this.restData("PATCH",`/v1/connections/${encodeURIComponent(e)}`,r)}async deleteConnection(e){await this.restRequest("DELETE",`/v1/connections/${encodeURIComponent(e)}`)}async setDefaultConnection(e){await this.restRequest("POST",`/v1/connections/${encodeURIComponent(e)}/default`)}async listSystems(e={}){let r=(0,Or.createListQueryParams)(e),n=r.size>0?`?${r.toString()}`:"";return this.restRequest("GET",`/v1/systems${n}`)}async listAllSystems(e={}){return(0,Or.listAllPages)((r,n)=>this.listSystems({...e,page:r,limit:n}))}async createOAuthExchange(e){return(await this.restRequest("POST","/v1/oauth/exchanges",e)).data}async completeOAuthExchange(e,r){return(await this.restRequest("POST",`/v1/oauth/exchanges/${encodeURIComponent(e)}/complete`,r)).data}async generateCredentialsLink(e){try{return{success:!0,credentialsUrl:(await this.restRequest("POST","/v1/authenticate",e||{})).data.credentialsUrl}}catch(r){return{success:!1,error:r.message}}}};yl.SuperglueClient=kv});var ZY=m(ft=>{"use strict";Object.defineProperty(ft,"__esModule",{value:!0});ft.UnquotedKeyStrategy=ft.TripleQuoteStrategy=ft.TrailingCommaStrategy=ft.SingleQuoteStrategy=ft.PythonLiteralStrategy=ft.CommentStrategy=ft.ResilientJsonParser=ft.RepairStrategy=void 0;ft.parseJsonResilient=KOe;ft.parseJSON=XOe;ft.isValidJson=eUe;ft.prettyPrintJson=tUe;ft.minifyJson=rUe;var ci=class{validate(e){try{return JSON.parse(e),!0}catch{return!1}}};ft.RepairStrategy=ci;var sE=class extends ci{constructor(){super(...arguments),this.name="TripleQuoteRepair",this.description="Converts triple-quoted strings to proper JSON, parsing nested JSON content"}canApply(e){return/"""/.test(e)}apply(e){return e.replace(/"""([\s\S]*?)"""/g,(r,n)=>{let i=n.trim();if(i.startsWith("{")&&i.endsWith("}")||i.startsWith("[")&&i.endsWith("]"))try{let s=JSON.parse(i);return JSON.stringify(s)}catch{return`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}"`}return`"${n.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t")}"`})}};ft.TripleQuoteStrategy=sE;var aE=class extends ci{constructor(){super(...arguments),this.name="PythonLiteralRepair",this.description="Converts Python literals to JavaScript equivalents"}canApply(e){return/\b(None|True|False)\b/.test(e)}apply(e){return e.replace(/\bNone\b/g,"null").replace(/\bTrue\b/g,"true").replace(/\bFalse\b/g,"false")}};ft.PythonLiteralStrategy=aE;var cE=class extends ci{constructor(){super(...arguments),this.name="TrailingCommaRepair",this.description="Removes trailing commas from objects and arrays"}canApply(e){return/,\s*[}\]]/.test(e)}apply(e){return e.replace(/,(\s*[}\]])/g,"$1")}};ft.TrailingCommaStrategy=cE;var uE=class extends ci{constructor(){super(...arguments),this.name="SingleQuoteRepair",this.description="Converts single quotes to double quotes"}canApply(e){return/[{,]\s*'[^']*'\s*:/.test(e)||/:\s*'[^']*'/.test(e)}apply(e){let r=e.replace(/([{,]\s*)'([^']+)'(\s*:)/g,'$1"$2"$3');return r=r.replace(/(:\s*)'([^']+)'(\s*[,}])/g,'$1"$2"$3'),r}};ft.SingleQuoteStrategy=uE;var lE=class extends ci{constructor(){super(...arguments),this.name="UnquotedKeyRepair",this.description="Adds quotes to unquoted object keys"}canApply(e){return/[{,]\s*[a-zA-Z_$][a-zA-Z0-9_$]*\s*:/.test(e)}apply(e){return e.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)(\s*:)/g,'$1"$2"$3')}};ft.UnquotedKeyStrategy=lE;var dE=class extends ci{constructor(){super(...arguments),this.name="CommentRemoval",this.description="Removes JavaScript-style comments"}canApply(e){return/\/\/.*$|\/\*[\s\S]*?\*\//m.test(e)}apply(e){let r=e.replace(/\/\/.*$/gm,"");return r=r.replace(/\/\*[\s\S]*?\*\//g,""),r}};ft.CommentStrategy=dE;var Ov=class extends ci{constructor(){super(...arguments),this.name="UnescapedControlCharactersRepair",this.description="Escapes unescaped control characters (newlines, tabs, etc.) in JSON strings"}canApply(e){try{return JSON.parse(e),!1}catch(r){let n=r.message||"";return n.includes("control character")||n.includes("Bad control")||n.includes("Unexpected token")&&/[\n\r\t]/.test(e)}}apply(e){let r="",n=!1,i=!1;for(let o=0;o<e.length;o++){let s=e[o],a=o>0?e[o-1]:"";if(i){r+=s,i=!1;continue}if(s==="\\"&&n){r+=s,i=!0;continue}if(s==='"'&&a!=="\\"){n=!n,r+=s;continue}if(n)switch(s){case`
1873
1874
  `:r+="\\n";break;case"\r":r+="\\r";break;case" ":r+="\\t";break;case"\b":r+="\\b";break;case"\f":r+="\\f";break;default:let c=s.charCodeAt(0);c<32?r+="\\u"+("0000"+c.toString(16)).slice(-4):r+=s}else r+=s}return r}},Uv=class extends ci{constructor(){super(...arguments),this.name="TrailingCharactersRepair",this.description="Removes trailing characters after valid JSON structure"}canApply(e){let r=e.trim();if(!r.startsWith("{")&&!r.startsWith("["))return!1;let n=0,i=0,o=!1,s=!1;for(let a=0;a<r.length;a++){let c=r[a];if(o)s?s=!1:c==="\\"?s=!0:c==='"'&&(o=!1);else if(c==='"')o=!0;else if(c==="{")n++;else if(c==="}"){if(n--,n===0&&i===0&&a>0&&a<r.length-1)return!0}else if(c==="[")i++;else if(c==="]"&&(i--,i===0&&n===0&&a>0&&a<r.length-1))return!0}return!1}apply(e){let r=e.trim(),n=0,i=0,o=!1,s=!1,a=-1;for(let c=0;c<r.length;c++){let u=r[c];if(o)s?s=!1:u==="\\"?s=!0:u==='"'&&(o=!1);else if(u==='"')o=!0;else if(u==="{")n++;else if(u==="}"){if(n--,n===0&&i===0&&c>0){a=c;break}}else if(u==="[")i++;else if(u==="]"&&(i--,i===0&&n===0&&c>0)){a=c;break}}return a>0&&a<r.length-1?r.substring(0,a+1):e}},El=class{constructor(e={}){this.strategies=[],this.repairLog=[],this.options={attemptRepair:!0,maxDepth:10,preserveStringsOnFailure:!1,logRepairs:!1,...e},this.initializeDefaultStrategies(),e.customStrategies&&this.strategies.push(...e.customStrategies)}initializeDefaultStrategies(){this.strategies=[new sE,new uE,new Ov,new Uv,new aE,new cE,new lE,new dE]}parse(e){let r=Date.now();this.repairLog=[];let n=e instanceof Buffer?e.toString("utf8"):String(e);try{return{success:!0,data:JSON.parse(n),metadata:{parseTime:Date.now()-r,strategiesApplied:[]}}}catch(s){if(!this.options.attemptRepair)return{success:!1,error:`JSON parse error: ${s}`,metadata:{parseTime:Date.now()-r}}}let i=n,o=[];for(let s of this.strategies)if(s.canApply(i)){let a=i;if(i=s.apply(i),a!==i){o.push(s.name),this.repairLog.push(s.description),this.options.logRepairs&&console.log(`Applied ${s.name}: ${s.description}`);try{return{success:!0,data:JSON.parse(i),repairs:this.repairLog,metadata:{parseTime:Date.now()-r,strategiesApplied:o}}}catch{}}}try{return{success:!0,data:JSON.parse(i),repairs:this.repairLog,metadata:{parseTime:Date.now()-r,strategiesApplied:o}}}catch(s){let a=this.aggressiveFallback(i);return a.success?{...a,repairs:[...this.repairLog,"Applied aggressive fallback"],metadata:{parseTime:Date.now()-r,strategiesApplied:[...o,"AggressiveFallback"]}}:{success:!1,error:`Failed to parse JSON after applying ${o.length} strategies: ${s}`,repairs:this.repairLog,metadata:{parseTime:Date.now()-r,strategiesApplied:o}}}}aggressiveFallback(e){try{let r=e.indexOf("{"),n=e.indexOf("[");if(r===-1&&n===-1)return{success:!1,error:"No JSON-like structure found"};let i=r===-1?n:n===-1?r:Math.min(r,n),o=e.substring(i);for(let a of this.strategies)a.canApply(o)&&(o=a.apply(o));return{success:!0,data:JSON.parse(o)}}catch(r){return{success:!1,error:`Aggressive fallback failed: ${r}`}}}addStrategy(e){this.strategies.push(e)}removeStrategy(e){this.strategies=this.strategies.filter(r=>r.name!==e)}getStrategies(){return this.strategies.map(e=>e.name)}};ft.ResilientJsonParser=El;var WY=new El;function KOe(t,e){return(e?new El(e):WY).parse(t)}function XOe(t){let e=WY.parse(t);if(e.success)return e.repairs&&e.repairs.length>0&&console.log("JSON parsed with repairs:",e.repairs),e.data;throw new Error(`Failed to parse JSON: ${e.error}`)}function eUe(t){try{return JSON.parse(t),!0}catch{return!1}}function tUe(t,e=2){return JSON.stringify(t,null,e)}function rUe(t){let r=new El().parse(t);if(r.success)return JSON.stringify(r.data);throw new Error("Cannot minify invalid JSON")}});var KY=m(yr=>{"use strict";Object.defineProperty(yr,"__esModule",{value:!0});yr.MANAGED_OAUTH_APP_PREFIX=void 0;yr.projectOAuthAppAuthentication=oUe;yr.isDynamicOAuthConfiguration=sUe;yr.isReusableOAuthAppForTemplate=aUe;yr.getManagedOAuthTemplateId=cUe;yr.getOAuthAppSharedConfiguration=uUe;yr.copyOAuthAppConfiguration=lUe;yr.encryptConnectionAuthentication=dUe;yr.decryptConnectionAuthentication=AUe;yr.isManagedOAuthEndpointAllowed=pUe;var nUe=$S(),iUe=Dn();function oUe(t){let{clientSecret:e,config:r,...n}=t,{extraHeaders:i,extraBodyParams:o,...s}=r??{};return{...n,...r?{config:s}:{}}}yr.MANAGED_OAUTH_APP_PREFIX="managed:";function sUe({authentication:t,template:e}){return t.oauthClientMode==="dynamic"||!!e?.oauth?.registrationUrl&&!t.clientSecret}function aUe({app:t,template:e}){return!e?.oauth?.registrationUrl||t.hasClientSecret}function cUe(t){if(t?.type==="oauth2")return t.oauthAppId?.startsWith(yr.MANAGED_OAUTH_APP_PREFIX)?t.oauthAppId.slice(yr.MANAGED_OAUTH_APP_PREFIX.length):void 0}function uUe(t){let{grantType:e,scopes:r,oauthAppId:n,...i}=t;return i}function lUe({appAuthentication:t,authentication:e}){if(e?.type!=="oauth2")return{...t};let r=Object.fromEntries(Object.entries(e).filter(([,n])=>n!==void 0));return{...t,...r,config:{...t.config,...e.config}}}function dUe({authentication:t,encrypt:e}){if(t.type!=="oauth2")return t;let r={...t,config:{...t.config}};t.clientSecret!==void 0&&(r.clientSecret=e({value:t.clientSecret}).value);for(let n of["extraHeaders","extraBodyParams"]){let i=t.config?.[n];i!==void 0&&(r.config[n]=e({value:(0,iUe.safeStringify)(i)}).value)}return r}function AUe({authentication:t,decrypt:e}){if(t.type!=="oauth2")return t;let r={...t,config:{...t.config}};t.clientSecret!==void 0&&(r.clientSecret=e({value:t.clientSecret}).value);for(let n of["extraHeaders","extraBodyParams"]){let i=t.config?.[n];typeof i=="string"&&(r.config[n]=JSON.parse(e({value:i}).value))}return r}function pUe({templateId:t,endpoint:e,url:r}){let n=nUe.systems[t]?.oauth,i=n?.[e];if(!n?.managed||!i)return!1;try{let o=new URL(r),s=new URL(i);return o.protocol!=="https:"||o.port||o.username||o.password||o.hash||o.pathname!==s.pathname?!1:o.hostname===s.hostname||(n.managedEndpointHosts??[]).some(a=>a.startsWith("*.")?o.hostname.endsWith(a.slice(1)):o.hostname===a)}catch{return!1}}});var eV=m(XY=>{"use strict";Object.defineProperty(XY,"__esModule",{value:!0})});var Er=m(W=>{"use strict";var fUe=W&&W.__createBinding||(Object.create?(function(t,e,r,n){n===void 0&&(n=r);var i=Object.getOwnPropertyDescriptor(e,r);(!i||("get"in i?!e.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,n,i)}):(function(t,e,r,n){n===void 0&&(n=r),t[n]=e[r]})),ne=W&&W.__exportStar||function(t,e){for(var r in t)r!=="default"&&!Object.prototype.hasOwnProperty.call(e,r)&&fUe(e,t,r)};Object.defineProperty(W,"__esModule",{value:!0});W.SSELogSubscriptionManager=W.SuperglueHttpError=W.SuperglueClient=void 0;ne(gx(),W);ne(bx(),W);ne(Ox(),W);ne(Mx(),W);ne(Fx(),W);ne(jx(),W);ne(Hx(),W);ne(Sg(),W);ne(CL(),W);ne(Wf(),W);ne(BL(),W);ne(_L(),W);ne(QL(),W);ne(vL(),W);ne(DL(),W);ne(tS(),W);ne(RL(),W);ne(OL(),W);ne(UL(),W);ne(ML(),W);ne(iS(),W);ne(cS(),W);ne(LL(),W);ne(PL(),W);ne(FL(),W);ne(uh(),W);ne(zL(),W);ne(HL(),W);ne(GL(),W);ne(YL(),W);ne(WL(),W);ne(dP(),W);ne(ES(),W);ne(Vd(),W);ne(yS(),W);ne(gP(),W);ne(yP(),W);ne(IP(),W);ne(Eg(),W);ne(DP(),W);ne(RP(),W);ne(Ig(),W);ne(fS(),W);ne(xP(),W);ne(LP(),W);ne($S(),W);ne(JP(),W);ne(WP(),W);ne(ZP(),W);ne(t$(),W);ne(n$(),W);ne(xr(),W);ne(Dn(),W);ne(i$(),W);ne(o$(),W);ne(Fg(),W);ne(pu(),W);ne(Ld(),W);var tV=JY();Object.defineProperty(W,"SuperglueClient",{enumerable:!0,get:function(){return tV.SuperglueClient}});Object.defineProperty(W,"SuperglueHttpError",{enumerable:!0,get:function(){return tV.SuperglueHttpError}});var hUe=zS();Object.defineProperty(W,"SSELogSubscriptionManager",{enumerable:!0,get:function(){return hUe.SSELogSubscriptionManager}});ne(ZY(),W);ne(KY(),W);ne(eV(),W)});var JE=require("commander");var Ur=ye(require("fs")),iV=ye(require("os")),As=ye(require("path")),hp=ye(Er()),rV=new Set(["runner","builder","admin"]),nV={output:{mode:"stdout",directory:".superglue/output"},preset:"admin"};function ps(t){let e=As.join(process.cwd(),".superglue"),r=iV.homedir();if(!r)return e;let n=As.join(r,".superglue");return t===!0?e:t===!1?n:Ur.existsSync(As.join(e,"config.json"))?e:n}function Mv(t){return As.join(ps(t),"config.json")}function AE(t){let e=Mv(t);if(!Ur.existsSync(e))return{};try{return JSON.parse(Ur.readFileSync(e,"utf-8"))}catch{return{}}}function Il(t){let e=AE(),r=t.apiKey||(0,hp.readProcessEnvironmentValue)("SUPERGLUE_API_KEY")||e.apiKey||"",n=t.endpoint||(0,hp.readProcessEnvironmentValue)("SUPERGLUE_API_ENDPOINT")||e.endpoint||"https://api.superglue.cloud",i=(0,hp.readProcessEnvironmentValue)("SUPERGLUE_WEB_ENDPOINT")||e.webEndpoint||n.replace(/:3002\b/,":3001").replace(/api\.superglue/,"app.superglue"),o=(0,hp.readProcessEnvironmentValue)("SUPERGLUE_CLI_PRESET"),s=o&&rV.has(o)?o:e.preset&&rV.has(e.preset)?e.preset:"admin";return{...nV,...e,apiKey:r,endpoint:n,webEndpoint:i,preset:s,output:{...nV.output,...e.output}}}function pE(t,e){let r=ps(e);Ur.existsSync(r)||Ur.mkdirSync(r,{recursive:!0}),Ur.writeFileSync(As.join(r,"config.json"),JSON.stringify(t,null,2)+`
1874
- `,{mode:384})}function fE(t,e){let r=As.join(ps(e),"drafts");if(Ur.existsSync(r)||Ur.mkdirSync(r,{recursive:!0}),t.output.mode==="stdout+file"){let n=As.resolve(t.output.directory);Ur.existsSync(n)||Ur.mkdirSync(n,{recursive:!0})}}var zv=ye(Er());var xv=ye(require("readline"));var aV=require("child_process"),cV=require("util");var oV={name:"@superglue/cli",version:"1.1.212",bin:{sg:"./dist/cli.js"},files:[".claude-plugin/","dist/","skills/","LICENSE"],dependencies:{commander:"15.0.0-0","fast-json-patch":"3.1.1"},devDependencies:{"@superglue/shared":"file:../shared","@types/node":"25.5.0",tsup:"8.5.1",typescript:"5.8.3"},scripts:{build:"tsup && (cp -r skills dist/ 2>/dev/null || true)",dev:"tsup --watch","type-check":"tsc --noEmit",prepublishOnly:"npm run build"},publishConfig:{access:"public"}};var mUe=(0,cV.promisify)(aV.exec),Ir=oV.version;function sV(t){let e=t.match(/^(\d+)(?:-(.+))?$/);return e?{numeric:parseInt(e[1],10),prerelease:e[2]||null}:{numeric:0,prerelease:t}}function gE(t,e){let r=t.split("."),n=e.split("."),i=Math.max(r.length,n.length);for(let o=0;o<i;o++){let s=sV(r[o]||"0"),a=sV(n[o]||"0");if(s.numeric<a.numeric)return-1;if(s.numeric>a.numeric||s.prerelease===null&&a.prerelease!==null)return 1;if(s.prerelease!==null&&a.prerelease===null)return-1;if(s.prerelease!==null&&a.prerelease!==null){if(s.prerelease<a.prerelease)return-1;if(s.prerelease>a.prerelease)return 1}}return 0}async function mE(){try{let t=await fetch("https://registry.npmjs.org/@superglue/cli/latest",{signal:AbortSignal.timeout(5e3)});return t.ok&&(await t.json()).version||null}catch{return null}}var hE=null;function uV(){le()&&(hE=mE())}async function lV(){if(!(!le()||!hE)){try{let t=new Promise(r=>{setTimeout(()=>r(null),2e3).unref()}),e=await Promise.race([hE,t]);e&&gE(Ir,e)<0&&(console.error(""),console.error(`${I.cyan}${I.bold} Update available: ${Ir} \u2192 ${e}${I.reset}`),console.error(`${I.cyan} Run ${I.bold}sg update${I.reset}${I.cyan} to upgrade${I.reset}`),console.error(""))}catch{}hE=null}}async function dV(){let t=await mE();if(!t)return{success:!1,message:"Could not fetch latest version from npm"};if(gE(Ir,t)>=0)return{success:!0,message:`Already on latest version (${Ir})`};try{return await mUe("npm install -g @superglue/cli@latest"),{success:!0,message:`Updated from ${Ir} to ${t}`}}catch(e){return{success:!1,message:`Update failed: ${e.message}. Try manually: npm install -g @superglue/cli@latest`}}}var le=()=>process.argv.includes("--table")&&process.stdout.isTTY,Hn=()=>process.argv.includes("--full"),I={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",italic:"\x1B[3m",underline:"\x1B[4m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",gray:"\x1B[90m",bgRed:"\x1B[41m",bgGreen:"\x1B[42m",bgYellow:"\x1B[43m",bgBlue:"\x1B[44m",bgMagenta:"\x1B[45m",bgCyan:"\x1B[46m"};function AV(t,e){let r=e||t;return`\x1B]8;;${t}\x07${I.underline}${I.cyan}${r}${I.reset}\x1B]8;;\x07`}function pV(){if(!le())return;let t=I.reset,e=I.dim,r="\x1B[47;30m",n=[" #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@- "," =@@@- @@@@ "," @@@ @@% "," -@@ @@@@= @@@ @@@ @@@@@#@ @@@@@@@ @@@@@@@ @@@@@@ @@@ @@@ @@@ @@@@@@* %@@ "," @@ @@@ *@ @@@ @@@ @@@ :@@ @@@ @@@ -@@ @@@ @% @@@ @@@ @@@ @@* @@# "," #@@ @@@# @@@ @@@ @@@ :@@ @@@ @@@ -@@ @@@ @@@ @@@ @@@ @@* @@ "," @@- @@@@= @@@ @@@ @@@@@@@ @@@@@@ @@@@@@@ @@@ @@% @@@ @@@ @@@ @@@@@. @@."," #@% .@@@@ @@@ @@@ @@@ @@@ @@@ -@@ @@@ @@% @@@ @@@ @@@ @@* @@ "," @@ @ @@@ @@@ @@@ @@@ @@@ @@@ -@@ @@@ @@% @@@ @@@ @@@ @@* *@@ "," -@@ @@@@= @@@@@@ @@@ @@@@@@@ @@@ -@@ @@@@@@ @@@@@@% @@@@@@. @@@@@@* #@@ "," :@@* @@@ "," %@@@ =@@@. "," :@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% "];console.log(""),n.forEach(i=>{let o=i.search(/\S/),s=i.length-[...i].reverse().join("").search(/\S/)-1;if(o===-1)return console.log(" "+i);let a=i.slice(0,o),c=i.slice(o,s+1).split("").map(l=>l===" "?" ":"\u2588").join(""),u=i.slice(s+1);console.log(` ${a}${r}${c}${t}${u}`)}),console.log(` ${e} CLI v${Ir}${t}`),console.log("")}function Ot(t){if(!le())return{stop:()=>{},update:()=>{},log:()=>{}};let e=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],r=0,n=t,i=()=>process.stdout.write("\r\x1B[2K"),o=()=>{process.stdout.write(`\r ${I.cyan}${e[r++%e.length]}${I.reset} ${n}`)},s=setInterval(o,80);return{update:a=>{n=a},log:a=>{i(),console.log(` ${I.dim}\u2502${I.reset} ${a}`),o()},stop:a=>{clearInterval(s),i(),a&&console.log(` ${a}`)}}}function te(t){le()?yE(t):console.log(JSON.stringify(t,null,2))}function De(t,e){le()?(console.log(` ${I.green}\u2713${I.reset} ${t}`),e&&yE(e,4)):console.log(JSON.stringify({success:!0,message:t,...e&&typeof e=="object"?e:{data:e}}))}function v(t,e){le()?(console.error(` ${I.red}\u2717${I.reset} ${t}`),e&&yE(e,4)):console.error(JSON.stringify({success:!1,error:t,details:e}))}function un(t){le()&&console.log(` ${I.dim}${t}${I.reset}`)}function kc(t){le()&&(console.log(`
1875
+ `,{mode:384})}function fE(t,e){let r=As.join(ps(e),"drafts");if(Ur.existsSync(r)||Ur.mkdirSync(r,{recursive:!0}),t.output.mode==="stdout+file"){let n=As.resolve(t.output.directory);Ur.existsSync(n)||Ur.mkdirSync(n,{recursive:!0})}}var zv=ye(Er());var xv=ye(require("readline"));var aV=require("child_process"),cV=require("util");var oV={name:"@superglue/cli",version:"1.1.214",bin:{sg:"./dist/cli.js"},files:[".claude-plugin/","dist/","skills/","LICENSE"],dependencies:{commander:"15.0.0-0","fast-json-patch":"3.1.1"},devDependencies:{"@superglue/shared":"file:../shared","@types/node":"25.5.0",tsup:"8.5.1",typescript:"5.8.3"},scripts:{build:"tsup && (cp -r skills dist/ 2>/dev/null || true)",dev:"tsup --watch","type-check":"tsc --noEmit",prepublishOnly:"npm run build"},publishConfig:{access:"public"}};var mUe=(0,cV.promisify)(aV.exec),Ir=oV.version;function sV(t){let e=t.match(/^(\d+)(?:-(.+))?$/);return e?{numeric:parseInt(e[1],10),prerelease:e[2]||null}:{numeric:0,prerelease:t}}function gE(t,e){let r=t.split("."),n=e.split("."),i=Math.max(r.length,n.length);for(let o=0;o<i;o++){let s=sV(r[o]||"0"),a=sV(n[o]||"0");if(s.numeric<a.numeric)return-1;if(s.numeric>a.numeric||s.prerelease===null&&a.prerelease!==null)return 1;if(s.prerelease!==null&&a.prerelease===null)return-1;if(s.prerelease!==null&&a.prerelease!==null){if(s.prerelease<a.prerelease)return-1;if(s.prerelease>a.prerelease)return 1}}return 0}async function mE(){try{let t=await fetch("https://registry.npmjs.org/@superglue/cli/latest",{signal:AbortSignal.timeout(5e3)});return t.ok&&(await t.json()).version||null}catch{return null}}var hE=null;function uV(){le()&&(hE=mE())}async function lV(){if(!(!le()||!hE)){try{let t=new Promise(r=>{setTimeout(()=>r(null),2e3).unref()}),e=await Promise.race([hE,t]);e&&gE(Ir,e)<0&&(console.error(""),console.error(`${I.cyan}${I.bold} Update available: ${Ir} \u2192 ${e}${I.reset}`),console.error(`${I.cyan} Run ${I.bold}sg update${I.reset}${I.cyan} to upgrade${I.reset}`),console.error(""))}catch{}hE=null}}async function dV(){let t=await mE();if(!t)return{success:!1,message:"Could not fetch latest version from npm"};if(gE(Ir,t)>=0)return{success:!0,message:`Already on latest version (${Ir})`};try{return await mUe("npm install -g @superglue/cli@latest"),{success:!0,message:`Updated from ${Ir} to ${t}`}}catch(e){return{success:!1,message:`Update failed: ${e.message}. Try manually: npm install -g @superglue/cli@latest`}}}var le=()=>process.argv.includes("--table")&&process.stdout.isTTY,Hn=()=>process.argv.includes("--full"),I={reset:"\x1B[0m",bold:"\x1B[1m",dim:"\x1B[2m",italic:"\x1B[3m",underline:"\x1B[4m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",gray:"\x1B[90m",bgRed:"\x1B[41m",bgGreen:"\x1B[42m",bgYellow:"\x1B[43m",bgBlue:"\x1B[44m",bgMagenta:"\x1B[45m",bgCyan:"\x1B[46m"};function AV(t,e){let r=e||t;return`\x1B]8;;${t}\x07${I.underline}${I.cyan}${r}${I.reset}\x1B]8;;\x07`}function pV(){if(!le())return;let t=I.reset,e=I.dim,r="\x1B[47;30m",n=[" #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@- "," =@@@- @@@@ "," @@@ @@% "," -@@ @@@@= @@@ @@@ @@@@@#@ @@@@@@@ @@@@@@@ @@@@@@ @@@ @@@ @@@ @@@@@@* %@@ "," @@ @@@ *@ @@@ @@@ @@@ :@@ @@@ @@@ -@@ @@@ @% @@@ @@@ @@@ @@* @@# "," #@@ @@@# @@@ @@@ @@@ :@@ @@@ @@@ -@@ @@@ @@@ @@@ @@@ @@* @@ "," @@- @@@@= @@@ @@@ @@@@@@@ @@@@@@ @@@@@@@ @@@ @@% @@@ @@@ @@@ @@@@@. @@."," #@% .@@@@ @@@ @@@ @@@ @@@ @@@ -@@ @@@ @@% @@@ @@@ @@@ @@* @@ "," @@ @ @@@ @@@ @@@ @@@ @@@ @@@ -@@ @@@ @@% @@@ @@@ @@@ @@* *@@ "," -@@ @@@@= @@@@@@ @@@ @@@@@@@ @@@ -@@ @@@@@@ @@@@@@% @@@@@@. @@@@@@* #@@ "," :@@* @@@ "," %@@@ =@@@. "," :@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@% "];console.log(""),n.forEach(i=>{let o=i.search(/\S/),s=i.length-[...i].reverse().join("").search(/\S/)-1;if(o===-1)return console.log(" "+i);let a=i.slice(0,o),c=i.slice(o,s+1).split("").map(l=>l===" "?" ":"\u2588").join(""),u=i.slice(s+1);console.log(` ${a}${r}${c}${t}${u}`)}),console.log(` ${e} CLI v${Ir}${t}`),console.log("")}function Ot(t){if(!le())return{stop:()=>{},update:()=>{},log:()=>{}};let e=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],r=0,n=t,i=()=>process.stdout.write("\r\x1B[2K"),o=()=>{process.stdout.write(`\r ${I.cyan}${e[r++%e.length]}${I.reset} ${n}`)},s=setInterval(o,80);return{update:a=>{n=a},log:a=>{i(),console.log(` ${I.dim}\u2502${I.reset} ${a}`),o()},stop:a=>{clearInterval(s),i(),a&&console.log(` ${a}`)}}}function te(t){le()?yE(t):console.log(JSON.stringify(t,null,2))}function De(t,e){le()?(console.log(` ${I.green}\u2713${I.reset} ${t}`),e&&yE(e,4)):console.log(JSON.stringify({success:!0,message:t,...e&&typeof e=="object"?e:{data:e}}))}function v(t,e){le()?(console.error(` ${I.red}\u2717${I.reset} ${t}`),e&&yE(e,4)):console.error(JSON.stringify({success:!1,error:t,details:e}))}function un(t){le()&&console.log(` ${I.dim}${t}${I.reset}`)}function kc(t){le()&&(console.log(`
1875
1876
  ${I.bold}${I.cyan}${t}${I.reset}`),console.log(` ${I.dim}${"\u2500".repeat(t.length)}${I.reset}`))}function Pt(t,e,r){if(!le()){console.log(JSON.stringify({success:!0,total:r?.total??t.length,items:t}));return}if(t.length===0){console.log(`
1876
1877
  ${I.dim}0 results${I.reset}
1877
1878
  `);return}let n=e||Object.keys(t[0]),i=Hn()?1/0:60,o=n.map(l=>Math.min(i,Math.max(l.length,...t.map(d=>String(d[l]??"").replace(/[\n\r]+/g," ").trim().length))));console.log("");let s=n.map((l,d)=>`${I.bold}${I.cyan}${l.toUpperCase().padEnd(o[d])}${I.reset}`).join(" ");console.log(` ${s}`);let a=o.map(l=>`${I.dim}${"\u2500".repeat(l)}${I.reset}`).join(`${I.dim}\u2500\u2500${I.reset}`);console.log(` ${a}`);for(let l of t){let d=n.map((A,p)=>{let h=String(l[A]??"").replace(/[\n\r]+/g," ").trim();if(h.length>i){let w=`\u2026 (${h.length})`;h=h.slice(0,Math.max(0,i-w.length))+`${I.dim}${w}${I.reset}`}return A==="status"?`${{success:I.green,running:I.yellow,failed:I.red,aborted:I.red,error:I.red,pending:I.dim}[h.toLowerCase()]||""}${h.padEnd(o[p])}${I.reset}`:h.padEnd(o[p])}).join(" ");console.log(` ${d}`)}let c=r?.total??t.length,u=c===t.length?`${t.length} result${t.length===1?"":"s"}`:`${t.length} of ${c} result${c===1?"":"s"}`;console.log(`