@interactive-inc/claude-funnel 0.60.0 → 0.60.1

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/bin.js CHANGED
@@ -606,7 +606,7 @@ ${Q.comment}`:Q.comment}this.doc.range[2]=Q.offset;break}default:this.errors.pus
606
606
  `)+1;while(Q!==0)this.onNewLine(this.offset+Q),Q=this.source.indexOf(`
607
607
  `,Q)+1}yield*this.pop();break;default:yield*this.pop(),yield*this.step()}}*blockMap($){let Q=$.items[$.items.length-1];switch(this.type){case"newline":if(this.onKeyLine=!1,Q.value){let Y="end"in Q.value?Q.value.end:void 0;if((Array.isArray(Y)?Y[Y.length-1]:void 0)?.type==="comment")Y?.push(this.sourceToken);else $.items.push({start:[this.sourceToken]})}else if(Q.sep)Q.sep.push(this.sourceToken);else Q.start.push(this.sourceToken);return;case"space":case"comment":if(Q.value)$.items.push({start:[this.sourceToken]});else if(Q.sep)Q.sep.push(this.sourceToken);else{if(this.atIndentedComment(Q.start,$.indent)){let X=$.items[$.items.length-2]?.value?.end;if(Array.isArray(X)){EM(X,Q.start),X.push(this.sourceToken),$.items.pop();return}}Q.start.push(this.sourceToken)}return}if(this.indent>=$.indent){let Y=!this.onKeyLine&&this.indent===$.indent,X=Y&&(Q.sep||Q.explicitKey)&&this.type!=="seq-item-ind",z=[];if(X&&Q.sep&&!Q.value){let Z=[];for(let K=0;K<Q.sep.length;++K){let W=Q.sep[K];switch(W.type){case"newline":Z.push(K);break;case"space":break;case"comment":if(W.indent>$.indent)Z.length=0;break;default:Z.length=0}}if(Z.length>=2)z=Q.sep.splice(Z[1])}switch(this.type){case"anchor":case"tag":if(X||Q.value)z.push(this.sourceToken),$.items.push({start:z}),this.onKeyLine=!0;else if(Q.sep)Q.sep.push(this.sourceToken);else Q.start.push(this.sourceToken);return;case"explicit-key-ind":if(!Q.sep&&!Q.explicitKey)Q.start.push(this.sourceToken),Q.explicitKey=!0;else if(X||Q.value)z.push(this.sourceToken),$.items.push({start:z,explicitKey:!0});else this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken],explicitKey:!0}]});this.onKeyLine=!0;return;case"map-value-ind":if(Q.explicitKey)if(!Q.sep)if(bZ(Q.start,"newline"))Object.assign(Q,{key:null,sep:[this.sourceToken]});else{let Z=KH(Q.start);this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:Z,key:null,sep:[this.sourceToken]}]})}else if(Q.value)$.items.push({start:[],key:null,sep:[this.sourceToken]});else if(bZ(Q.sep,"map-value-ind"))this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:z,key:null,sep:[this.sourceToken]}]});else if(V00(Q.key)&&!bZ(Q.sep,"newline")){let Z=KH(Q.start),K=Q.key,W=Q.sep;W.push(this.sourceToken),delete Q.key,delete Q.sep,this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:Z,key:K,sep:W}]})}else if(z.length>0)Q.sep=Q.sep.concat(z,this.sourceToken);else Q.sep.push(this.sourceToken);else if(!Q.sep)Object.assign(Q,{key:null,sep:[this.sourceToken]});else if(Q.value||X)$.items.push({start:z,key:null,sep:[this.sourceToken]});else if(bZ(Q.sep,"map-value-ind"))this.stack.push({type:"block-map",offset:this.offset,indent:this.indent,items:[{start:[],key:null,sep:[this.sourceToken]}]});else Q.sep.push(this.sourceToken);this.onKeyLine=!0;return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{let Z=this.flowScalar(this.type);if(X||Q.value)$.items.push({start:z,key:Z,sep:[]}),this.onKeyLine=!0;else if(Q.sep)this.stack.push(Z);else Object.assign(Q,{key:Z,sep:[]}),this.onKeyLine=!0;return}default:{let Z=this.startBlockValue($);if(Z){if(Z.type==="block-seq"){if(!Q.explicitKey&&Q.sep&&!bZ(Q.sep,"newline")){yield*this.pop({type:"error",offset:this.offset,message:"Unexpected block-seq-ind on same line with key",source:this.source});return}}else if(Y)$.items.push({start:z});this.stack.push(Z);return}}}}yield*this.pop(),yield*this.step()}*blockSequence($){let Q=$.items[$.items.length-1];switch(this.type){case"newline":if(Q.value){let Y="end"in Q.value?Q.value.end:void 0;if((Array.isArray(Y)?Y[Y.length-1]:void 0)?.type==="comment")Y?.push(this.sourceToken);else $.items.push({start:[this.sourceToken]})}else Q.start.push(this.sourceToken);return;case"space":case"comment":if(Q.value)$.items.push({start:[this.sourceToken]});else{if(this.atIndentedComment(Q.start,$.indent)){let X=$.items[$.items.length-2]?.value?.end;if(Array.isArray(X)){EM(X,Q.start),X.push(this.sourceToken),$.items.pop();return}}Q.start.push(this.sourceToken)}return;case"anchor":case"tag":if(Q.value||this.indent<=$.indent)break;Q.start.push(this.sourceToken);return;case"seq-item-ind":if(this.indent!==$.indent)break;if(Q.value||bZ(Q.start,"seq-item-ind"))$.items.push({start:[this.sourceToken]});else Q.start.push(this.sourceToken);return}if(this.indent>$.indent){let Y=this.startBlockValue($);if(Y){this.stack.push(Y);return}}yield*this.pop(),yield*this.step()}*flowCollection($){let Q=$.items[$.items.length-1];if(this.type==="flow-error-end"){let Y;do yield*this.pop(),Y=this.peek(1);while(Y?.type==="flow-collection")}else if($.end.length===0){switch(this.type){case"comma":case"explicit-key-ind":if(!Q||Q.sep)$.items.push({start:[this.sourceToken]});else Q.start.push(this.sourceToken);return;case"map-value-ind":if(!Q||Q.value)$.items.push({start:[],key:null,sep:[this.sourceToken]});else if(Q.sep)Q.sep.push(this.sourceToken);else Object.assign(Q,{key:null,sep:[this.sourceToken]});return;case"space":case"comment":case"newline":case"anchor":case"tag":if(!Q||Q.value)$.items.push({start:[this.sourceToken]});else if(Q.sep)Q.sep.push(this.sourceToken);else Q.start.push(this.sourceToken);return;case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":{let X=this.flowScalar(this.type);if(!Q||Q.value)$.items.push({start:[],key:X,sep:[]});else if(Q.sep)this.stack.push(X);else Object.assign(Q,{key:X,sep:[]});return}case"flow-map-end":case"flow-seq-end":$.end.push(this.sourceToken);return}let Y=this.startBlockValue($);if(Y)this.stack.push(Y);else yield*this.pop(),yield*this.step()}else{let Y=this.peek(2);if(Y.type==="block-map"&&(this.type==="map-value-ind"&&Y.indent===$.indent||this.type==="newline"&&!Y.items[Y.items.length-1].sep))yield*this.pop(),yield*this.step();else if(this.type==="map-value-ind"&&Y.type!=="flow-collection"){let X=SM(Y),z=KH(X);H00($);let Z=$.end.splice(1,$.end.length);Z.push(this.sourceToken);let K={type:"block-map",offset:$.offset,indent:$.indent,items:[{start:z,key:$,sep:Z}]};this.onKeyLine=!0,this.stack[this.stack.length-1]=K}else yield*this.lineEnd($)}}flowScalar($){if(this.onNewLine){let Q=this.source.indexOf(`
608
608
  `)+1;while(Q!==0)this.onNewLine(this.offset+Q),Q=this.source.indexOf(`
609
- `,Q)+1}return{type:$,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue($){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;let Q=SM($),Y=KH(Q);return Y.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:Y,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;let Q=SM($),Y=KH(Q);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:Y,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment($,Q){if(this.type!=="comment")return!1;if(this.indent<=Q)return!1;return $.every((Y)=>Y.type==="newline"||Y.type==="space")}*documentEnd($){if(this.type!=="doc-mode"){if($.end)$.end.push(this.sourceToken);else $.end=[this.sourceToken];if(this.type==="newline")yield*this.pop()}}*lineEnd($){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;case"space":case"comment":default:if($.end)$.end.push(this.sourceToken);else $.end=[this.sourceToken];if(this.type==="newline")yield*this.pop()}}}ub6.Parser=w00});var x00=q((nb6)=>{var G00=vd(),yb6=Xq(),Vq=zq(),gb6=En(),hb6=d0(),mb6=Cd(),U00=ud();function J00($){let Q=$.prettyErrors!==!1;return{lineCounter:$.lineCounter||Q&&new mb6.LineCounter||null,prettyErrors:Q}}function pb6($,Q={}){let{lineCounter:Y,prettyErrors:X}=J00(Q),z=new U00.Parser(Y?.addNewLine),Z=new G00.Composer(Q),K=Array.from(Z.compose(z.parse($)));if(X&&Y)for(let W of K)W.errors.forEach(Vq.prettifyError($,Y)),W.warnings.forEach(Vq.prettifyError($,Y));if(K.length>0)return K;return Object.assign([],{empty:!0},Z.streamInfo())}function q00($,Q={}){let{lineCounter:Y,prettyErrors:X}=J00(Q),z=new U00.Parser(Y?.addNewLine),Z=new G00.Composer(Q),K=null;for(let W of Z.compose(z.parse($),!0,$.length))if(!K)K=W;else if(K.options.logLevel!=="silent"){K.errors.push(new Vq.YAMLParseError(W.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}if(X&&Y)K.errors.forEach(Vq.prettifyError($,Y)),K.warnings.forEach(Vq.prettifyError($,Y));return K}function ib6($,Q,Y){let X=void 0;if(typeof Q==="function")X=Q;else if(Y===void 0&&Q&&typeof Q==="object")Y=Q;let z=q00($,Y);if(!z)return null;if(z.warnings.forEach((Z)=>gb6.warn(z.options.logLevel,Z)),z.errors.length>0)if(z.options.logLevel!=="silent")throw z.errors[0];else z.errors=[];return z.toJS(Object.assign({reviver:X},Y))}function lb6($,Q,Y){let X=null;if(typeof Q==="function"||Array.isArray(Q))X=Q;else if(Y===void 0&&Q)Y=Q;if(typeof Y==="string")Y=Y.length;if(typeof Y==="number"){let z=Math.round(Y);Y=z<1?void 0:z>8?{indent:8}:{indent:z}}if($===void 0){let{keepUndefined:z}=Y??Q??{};if(!z)return}if(hb6.isDocument($)&&!X)return $.toString(Y);return new yb6.Document($,X,Y).toString(Y)}nb6.parse=ib6;nb6.parseAllDocuments=pb6;nb6.parseDocument=q00;nb6.stringify=lb6});import{homedir as Af6}from"os";var Co={name:"@interactive-inc/claude-funnel",version:"0.60.0",description:"Hub CLI that routes external events (Slack / GitHub / Discord) to Claude Code agents through subscription channels over MCP.",keywords:["bun","claude","claude-code","cli","discord","github","mcp","slack"],homepage:"https://github.com/interactive-inc/open-claude-funnel#readme",bugs:{url:"https://github.com/interactive-inc/open-claude-funnel/issues"},license:"MIT",author:"Interactive Inc.",repository:{type:"git",url:"git+https://github.com/interactive-inc/open-claude-funnel.git"},bin:{fnl:"./dist/bin.js",funnel:"./dist/bin.js"},files:["dist/**/*","funnel.schema.json","README.md","LICENSE"],type:"module",main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",default:"./dist/index.js"},"./claude":{types:"./dist/claude.d.ts",import:"./dist/claude.js",default:"./dist/claude.js"},"./gateway":{types:"./dist/gateway.d.ts",import:"./dist/gateway.js",default:"./dist/gateway.js"},"./profiles":{types:"./dist/profiles.d.ts",import:"./dist/profiles.js",default:"./dist/profiles.js"},"./local-config":{types:"./dist/local-config.d.ts",import:"./dist/local-config.js",default:"./dist/local-config.js"},"./diagnostics":{types:"./dist/diagnostics.d.ts",import:"./dist/diagnostics.js",default:"./dist/diagnostics.js"},"./recovery":{types:"./dist/recovery.d.ts",import:"./dist/recovery.js",default:"./dist/recovery.js"},"./doctor":{types:"./dist/doctor.d.ts",import:"./dist/doctor.js",default:"./dist/doctor.js"},"./docs":{types:"./dist/docs.d.ts",import:"./dist/docs.js",default:"./dist/docs.js"},"./connectors/slack":{types:"./dist/connectors/slack.d.ts",import:"./dist/connectors/slack.js",default:"./dist/connectors/slack.js"},"./connectors/discord":{types:"./dist/connectors/discord.d.ts",import:"./dist/connectors/discord.js",default:"./dist/connectors/discord.js"},"./connectors/gh":{types:"./dist/connectors/gh.d.ts",import:"./dist/connectors/gh.js",default:"./dist/connectors/gh.js"},"./connectors/schedule":{types:"./dist/connectors/schedule.d.ts",import:"./dist/connectors/schedule.js",default:"./dist/connectors/schedule.js"},"./logger":{types:"./dist/logger.d.ts",import:"./dist/logger.js",default:"./dist/logger.js"},"./bin":"./dist/bin.js","./package.json":"./package.json"},publishConfig:{access:"public"},scripts:{prepack:"make build"},dependencies:{"@hono/zod-validator":"0.8.0","@modelcontextprotocol/sdk":"^1.29.0","@slack/bolt":"^4.7.2","@slack/web-api":"^7.16.0","discord.js":"^14.26.4",hono:"^4.12.19",yaml:"^2.9.0",zod:"^4.4.3"},devDependencies:{"@types/bun":"^1.3.14","@typescript/native-preview":"^7.0.0-dev.20260516.1","vite-plus":"^0.1.21",vitest:"^4.1.8"},engines:{bun:">=1.3.0"}};var Q0=class extends Error{res;status;constructor($=500,Q){super(Q?.message,{cause:Q?.cause});this.res=Q?.res,this.status=$}getResponse(){if(this.res)return new Response(this.res.body,{status:this.status,headers:this.res.headers});return new Response(this.message,{status:this.status})}};var P={};YQ(P,{xor:()=>xs,xid:()=>cr,void:()=>Vs,uuidv7:()=>Rr,uuidv6:()=>Ar,uuidv4:()=>_r,uuid:()=>br,util:()=>q1,url:()=>Tr,uppercase:()=>Q2,unknown:()=>lZ,union:()=>GB,undefined:()=>Ws,ulid:()=>ur,uint64:()=>Zs,uint32:()=>Ys,tuple:()=>tA,trim:()=>W2,treeifyError:()=>p3,transform:()=>JB,toUpperCase:()=>V2,toLowerCase:()=>H2,toJSONSchema:()=>cx,templateLiteral:()=>As,symbol:()=>Ks,superRefine:()=>vR,success:()=>Os,stringbool:()=>us,stringFormat:()=>or,string:()=>gH,strictObject:()=>Js,startsWith:()=>X2,slugify:()=>w2,size:()=>mZ,setErrorMap:()=>wY0,set:()=>Ns,safeParseAsync:()=>vA,safeParse:()=>OA,safeEncodeAsync:()=>kA,safeEncode:()=>TA,safeDecodeAsync:()=>SA,safeDecode:()=>fA,registry:()=>Vx,regexes:()=>Y7,regex:()=>e4,refine:()=>OR,record:()=>eA,readonly:()=>FR,property:()=>Sx,promise:()=>Rs,prettifyError:()=>i3,preprocess:()=>ys,prefault:()=>GR,positive:()=>Rx,pipe:()=>lx,partialRecord:()=>Ds,parseAsync:()=>MA,parse:()=>IA,overwrite:()=>XQ,optional:()=>mH,object:()=>Us,number:()=>CA,nullish:()=>Ms,nullable:()=>pH,null:()=>hA,normalize:()=>K2,nonpositive:()=>fx,nonoptional:()=>UR,nonnegative:()=>kx,never:()=>wB,negative:()=>Tx,nativeEnum:()=>Ps,nanoid:()=>Sr,nan:()=>vs,multipleOf:()=>eX,minSize:()=>mQ,minLength:()=>uY,mime:()=>Z2,meta:()=>Es,maxSize:()=>$z,maxLength:()=>pZ,map:()=>Fs,mac:()=>hr,lte:()=>X7,lt:()=>gQ,lowercase:()=>$2,looseRecord:()=>Ls,looseObject:()=>qs,locales:()=>CH,literal:()=>js,length:()=>iZ,lazy:()=>jR,ksuid:()=>yr,keyof:()=>Gs,jwt:()=>ar,json:()=>cs,iso:()=>J2,ipv6:()=>mr,ipv4:()=>gr,invertCodec:()=>_s,intersection:()=>rA,int64:()=>zs,int32:()=>Qs,int:()=>ix,instanceof:()=>Cs,includes:()=>Y2,httpUrl:()=>fr,hostname:()=>rr,hex:()=>sr,hash:()=>tr,guid:()=>vr,gte:()=>e$,gt:()=>hQ,globalRegistry:()=>w$,getErrorMap:()=>GY0,function:()=>Ts,fromJSONSchema:()=>hs,formatError:()=>OH,float64:()=>$s,float32:()=>er,flattenError:()=>MH,file:()=>Is,exactOptional:()=>KR,enum:()=>UB,endsWith:()=>z2,encodeAsync:()=>AA,encode:()=>bA,emoji:()=>kr,email:()=>Or,e164:()=>dr,discriminatedUnion:()=>Bs,describe:()=>Ss,decodeAsync:()=>RA,decode:()=>_A,date:()=>ws,custom:()=>ks,cuid2:()=>Cr,cuid:()=>Er,core:()=>cY,config:()=>w8,coerce:()=>_R,codec:()=>bs,clone:()=>s$,cidrv6:()=>ir,cidrv4:()=>pr,check:()=>fs,catch:()=>xR,boolean:()=>uA,bigint:()=>Xs,base64url:()=>nr,base64:()=>lr,array:()=>dH,any:()=>Hs,_function:()=>Ts,_default:()=>VR,_ZodString:()=>nx,ZodXor:()=>dA,ZodXID:()=>ex,ZodVoid:()=>lA,ZodUnknown:()=>pA,ZodUnion:()=>oH,ZodUndefined:()=>yA,ZodUUID:()=>pQ,ZodURL:()=>lH,ZodULID:()=>tx,ZodType:()=>B0,ZodTuple:()=>sA,ZodTransform:()=>zR,ZodTemplateLiteral:()=>NR,ZodSymbol:()=>cA,ZodSuccess:()=>JR,ZodStringFormat:()=>V6,ZodString:()=>B2,ZodSet:()=>QR,ZodRecord:()=>q2,ZodRealError:()=>_9,ZodReadonly:()=>LR,ZodPromise:()=>IR,ZodPreprocess:()=>DR,ZodPrefault:()=>wR,ZodPipe:()=>rH,ZodOptional:()=>qB,ZodObject:()=>aH,ZodNumberFormat:()=>nZ,ZodNumber:()=>L2,ZodNullable:()=>WR,ZodNull:()=>gA,ZodNonOptional:()=>xB,ZodNever:()=>iA,ZodNanoID:()=>ox,ZodNaN:()=>BR,ZodMap:()=>$R,ZodMAC:()=>EA,ZodLiteral:()=>YR,ZodLazy:()=>PR,ZodKSUID:()=>$B,ZodJWT:()=>HB,ZodIssueCode:()=>VY0,ZodIntersection:()=>oA,ZodISOTime:()=>mx,ZodISODuration:()=>px,ZodISODateTime:()=>gx,ZodISODate:()=>hx,ZodIPv6:()=>YB,ZodIPv4:()=>QB,ZodGUID:()=>hH,ZodFunction:()=>MR,ZodFirstPartyTypeKind:()=>bR,ZodFile:()=>XR,ZodExactOptional:()=>ZR,ZodError:()=>WY0,ZodEnum:()=>x2,ZodEmoji:()=>ax,ZodEmail:()=>dx,ZodE164:()=>WB,ZodDiscriminatedUnion:()=>aA,ZodDefault:()=>HR,ZodDate:()=>nH,ZodCustomStringFormat:()=>D2,ZodCustom:()=>tH,ZodCodec:()=>sH,ZodCatch:()=>qR,ZodCUID2:()=>sx,ZodCUID:()=>rx,ZodCIDRv6:()=>zB,ZodCIDRv4:()=>XB,ZodBoolean:()=>F2,ZodBigIntFormat:()=>VB,ZodBigInt:()=>N2,ZodBase64URL:()=>KB,ZodBase64:()=>ZB,ZodArray:()=>nA,ZodAny:()=>mA,TimePrecision:()=>tb,NEVER:()=>T3,$output:()=>nb,$input:()=>db,$brand:()=>f3});var cY={};YQ(cY,{version:()=>gO,util:()=>q1,treeifyError:()=>p3,toJSONSchema:()=>cx,toDotPath:()=>po,safeParseAsync:()=>n3,safeParse:()=>l3,safeEncodeAsync:()=>V70,safeEncode:()=>W70,safeDecodeAsync:()=>w70,safeDecode:()=>H70,registry:()=>Vx,regexes:()=>Y7,process:()=>Z6,prettifyError:()=>i3,parseAsync:()=>hq,parse:()=>gq,meta:()=>f_,locales:()=>CH,isValidJWT:()=>Ur,isValidBase64URL:()=>Gr,isValidBase64:()=>Hv,initializeContext:()=>Qz,globalRegistry:()=>w$,globalConfig:()=>uZ,formatError:()=>OH,flattenError:()=>MH,finalize:()=>Xz,extractDefs:()=>Yz,encodeAsync:()=>Z70,encode:()=>X70,describe:()=>T_,decodeAsync:()=>K70,decode:()=>z70,createToJSONSchemaMethod:()=>S_,createStandardJSONSchemaMethod:()=>U2,config:()=>w8,clone:()=>s$,_xor:()=>uQ0,_xid:()=>Nx,_void:()=>j_,_uuidv7:()=>qx,_uuidv6:()=>Jx,_uuidv4:()=>Ux,_uuid:()=>Gx,_url:()=>cH,_uppercase:()=>Q2,_unknown:()=>N_,_union:()=>CQ0,_undefined:()=>D_,_ulid:()=>Fx,_uint64:()=>x_,_uint32:()=>V_,_tuple:()=>gQ0,_trim:()=>W2,_transform:()=>dQ0,_toUpperCase:()=>V2,_toLowerCase:()=>H2,_templateLiteral:()=>YY0,_symbol:()=>B_,_superRefine:()=>R_,_success:()=>tQ0,_stringbool:()=>k_,_stringFormat:()=>G2,_string:()=>ob,_startsWith:()=>X2,_slugify:()=>w2,_size:()=>mZ,_set:()=>pQ0,_safeParseAsync:()=>r4,_safeParse:()=>o4,_safeEncodeAsync:()=>aq,_safeEncode:()=>nq,_safeDecodeAsync:()=>oq,_safeDecode:()=>dq,_regex:()=>e4,_refine:()=>A_,_record:()=>hQ0,_readonly:()=>QY0,_property:()=>Sx,_promise:()=>zY0,_positive:()=>Rx,_pipe:()=>$Y0,_parseAsync:()=>a4,_parse:()=>d4,_overwrite:()=>XQ,_optional:()=>aQ0,_number:()=>X_,_nullable:()=>oQ0,_null:()=>L_,_normalize:()=>K2,_nonpositive:()=>fx,_nonoptional:()=>sQ0,_nonnegative:()=>kx,_never:()=>P_,_negative:()=>Tx,_nativeEnum:()=>lQ0,_nanoid:()=>Bx,_nan:()=>O_,_multipleOf:()=>eX,_minSize:()=>mQ,_minLength:()=>uY,_min:()=>e$,_mime:()=>Z2,_maxSize:()=>$z,_maxLength:()=>pZ,_max:()=>X7,_map:()=>mQ0,_mac:()=>sb,_lte:()=>X7,_lt:()=>gQ,_lowercase:()=>$2,_literal:()=>nQ0,_length:()=>iZ,_lazy:()=>XY0,_ksuid:()=>Px,_jwt:()=>Ax,_isoTime:()=>Q_,_isoDuration:()=>Y_,_isoDateTime:()=>eb,_isoDate:()=>$_,_ipv6:()=>Ix,_ipv4:()=>jx,_intersection:()=>yQ0,_int64:()=>q_,_int32:()=>H_,_int:()=>Z_,_includes:()=>Y2,_guid:()=>uH,_gte:()=>e$,_gt:()=>hQ,_float64:()=>W_,_float32:()=>K_,_file:()=>b_,_enum:()=>iQ0,_endsWith:()=>z2,_encodeAsync:()=>iq,_encode:()=>mq,_emoji:()=>xx,_email:()=>wx,_e164:()=>_x,_discriminatedUnion:()=>cQ0,_default:()=>rQ0,_decodeAsync:()=>lq,_decode:()=>pq,_date:()=>I_,_custom:()=>__,_cuid2:()=>Lx,_cuid:()=>Dx,_coercedString:()=>rb,_coercedNumber:()=>z_,_coercedDate:()=>M_,_coercedBoolean:()=>G_,_coercedBigint:()=>J_,_cidrv6:()=>Ox,_cidrv4:()=>Mx,_check:()=>Pr,_catch:()=>eQ0,_boolean:()=>w_,_bigint:()=>U_,_base64url:()=>bx,_base64:()=>vx,_array:()=>v_,_any:()=>F_,TimePrecision:()=>tb,NEVER:()=>T3,JSONSchemaGenerator:()=>LA,JSONSchema:()=>jr,Doc:()=>eq,$output:()=>nb,$input:()=>db,$constructor:()=>y,$brand:()=>f3,$ZodXor:()=>vv,$ZodXID:()=>sO,$ZodVoid:()=>jv,$ZodUnknown:()=>Nv,$ZodUnion:()=>RH,$ZodUndefined:()=>Dv,$ZodUUID:()=>pO,$ZodURL:()=>lO,$ZodULID:()=>rO,$ZodType:()=>K0,$ZodTuple:()=>Kx,$ZodTransform:()=>Ev,$ZodTemplateLiteral:()=>nv,$ZodSymbol:()=>Bv,$ZodSuccess:()=>hv,$ZodStringFormat:()=>H6,$ZodString:()=>hZ,$ZodSet:()=>Tv,$ZodRegistry:()=>ab,$ZodRecord:()=>Av,$ZodRealError:()=>b9,$ZodReadonly:()=>lv,$ZodPromise:()=>av,$ZodPreprocess:()=>iv,$ZodPrefault:()=>yv,$ZodPipe:()=>Hx,$ZodOptional:()=>Wx,$ZodObjectJIT:()=>Ov,$ZodObject:()=>xr,$ZodNumberFormat:()=>qv,$ZodNumber:()=>zx,$ZodNullable:()=>uv,$ZodNull:()=>Lv,$ZodNonOptional:()=>gv,$ZodNever:()=>Pv,$ZodNanoID:()=>dO,$ZodNaN:()=>pv,$ZodMap:()=>Rv,$ZodMAC:()=>Zv,$ZodLiteral:()=>kv,$ZodLazy:()=>ov,$ZodKSUID:()=>tO,$ZodJWT:()=>Uv,$ZodIntersection:()=>_v,$ZodISOTime:()=>Qv,$ZodISODuration:()=>Yv,$ZodISODateTime:()=>eO,$ZodISODate:()=>$v,$ZodIPv6:()=>zv,$ZodIPv4:()=>Xv,$ZodGUID:()=>mO,$ZodFunction:()=>dv,$ZodFile:()=>Sv,$ZodExactOptional:()=>Cv,$ZodError:()=>IH,$ZodEnum:()=>fv,$ZodEncodeError:()=>cZ,$ZodEmoji:()=>nO,$ZodEmail:()=>iO,$ZodE164:()=>Gv,$ZodDiscriminatedUnion:()=>bv,$ZodDefault:()=>cv,$ZodDate:()=>Iv,$ZodCustomStringFormat:()=>Jv,$ZodCustom:()=>rv,$ZodCodec:()=>TH,$ZodCheckUpperCase:()=>kO,$ZodCheckStringFormat:()=>s4,$ZodCheckStartsWith:()=>EO,$ZodCheckSizeEquals:()=>bO,$ZodCheckRegex:()=>TO,$ZodCheckProperty:()=>uO,$ZodCheckOverwrite:()=>yO,$ZodCheckNumberFormat:()=>IO,$ZodCheckMultipleOf:()=>jO,$ZodCheckMinSize:()=>vO,$ZodCheckMinLength:()=>AO,$ZodCheckMimeType:()=>cO,$ZodCheckMaxSize:()=>OO,$ZodCheckMaxLength:()=>_O,$ZodCheckLowerCase:()=>fO,$ZodCheckLessThan:()=>sq,$ZodCheckLengthEquals:()=>RO,$ZodCheckIncludes:()=>SO,$ZodCheckGreaterThan:()=>tq,$ZodCheckEndsWith:()=>CO,$ZodCheckBigIntFormat:()=>MO,$ZodCheck:()=>x6,$ZodCatch:()=>mv,$ZodCUID2:()=>oO,$ZodCUID:()=>aO,$ZodCIDRv6:()=>Wv,$ZodCIDRv4:()=>Kv,$ZodBoolean:()=>AH,$ZodBigIntFormat:()=>xv,$ZodBigInt:()=>Zx,$ZodBase64URL:()=>wv,$ZodBase64:()=>Vv,$ZodAsyncError:()=>yQ,$ZodArray:()=>Mv,$ZodAny:()=>Fv});var uo,T3=Object.freeze({status:"aborted"});function y($,Q,Y){function X(W,H){if(!W._zod)Object.defineProperty(W,"_zod",{value:{def:H,constr:K,traits:new Set},enumerable:!1});if(W._zod.traits.has($))return;W._zod.traits.add($),Q(W,H);let V=K.prototype,w=Object.keys(V);for(let G=0;G<w.length;G++){let U=w[G];if(!(U in W))W[U]=V[U].bind(W)}}let z=Y?.Parent??Object;class Z extends z{}Object.defineProperty(Z,"name",{value:$});function K(W){var H;let V=Y?.Parent?new Z:this;X(V,W),(H=V._zod).deferred??(H.deferred=[]);for(let w of V._zod.deferred)w();return V}return Object.defineProperty(K,"init",{value:X}),Object.defineProperty(K,Symbol.hasInstance,{value:(W)=>{if(Y?.Parent&&W instanceof Y.Parent)return!0;return W?._zod?.traits?.has($)}}),Object.defineProperty(K,"name",{value:$}),K}var f3=Symbol("zod_brand");class yQ extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class cZ extends Error{constructor($){super(`Encountered unidirectional transform during encode: ${$}`);this.name="ZodEncodeError"}}(uo=globalThis).__zod_globalConfig??(uo.__zod_globalConfig={});var uZ=globalThis.__zod_globalConfig;function w8($){if($)Object.assign(uZ,$);return uZ}var q1={};YQ(q1,{unwrapMessage:()=>DH,uint8ArrayToHex:()=>Q70,uint8ArrayToBase64url:()=>e90,uint8ArrayToBase64:()=>go,stringifyPrimitive:()=>G1,slugify:()=>E3,shallowClone:()=>u3,safeExtend:()=>d90,required:()=>r90,randomString:()=>g90,propertyKeyTypes:()=>NH,promiseAllObject:()=>y90,primitiveTypes:()=>c3,prefixIssues:()=>v9,pick:()=>i90,partial:()=>o90,parsedType:()=>J1,optionalKeys:()=>y3,omit:()=>l90,objectClone:()=>C90,numKeys:()=>h90,nullish:()=>oX,normalizeParams:()=>B1,mergeDefs:()=>CY,merge:()=>a90,jsonStringifyReplacer:()=>i4,joinValues:()=>i,issue:()=>n4,isPlainObject:()=>sX,isObject:()=>yZ,hexToUint8Array:()=>$70,getSizableOrigin:()=>PH,getParsedType:()=>m90,getLengthableOrigin:()=>jH,getEnumValues:()=>LH,getElementAtPath:()=>c90,floatSafeRemainder:()=>S3,finalizeIssue:()=>t$,extend:()=>n90,explicitlyAborted:()=>m3,escapeRegex:()=>F7,esc:()=>cq,defineLazy:()=>M0,createTransparentProxy:()=>p90,cloneDef:()=>u90,clone:()=>s$,cleanRegex:()=>FH,cleanEnum:()=>s90,captureStackTrace:()=>yq,cached:()=>l4,base64urlToUint8Array:()=>t90,base64ToUint8Array:()=>yo,assignProp:()=>rX,assertNotEqual:()=>f90,assertNever:()=>S90,assertIs:()=>k90,assertEqual:()=>T90,assert:()=>E90,allowsEval:()=>C3,aborted:()=>tX,NUMBER_FORMAT_RANGES:()=>g3,Class:()=>ho,BIGINT_FORMAT_RANGES:()=>h3});function T90($){return $}function f90($){return $}function k90($){}function S90($){throw Error("Unexpected value in exhaustive check")}function E90($){}function LH($){let Q=Object.values($).filter((X)=>typeof X==="number");return Object.entries($).filter(([X,z])=>Q.indexOf(+X)===-1).map(([X,z])=>z)}function i($,Q="|"){return $.map((Y)=>G1(Y)).join(Q)}function i4($,Q){if(typeof Q==="bigint")return Q.toString();return Q}function l4($){return{get value(){{let Y=$();return Object.defineProperty(this,"value",{value:Y}),Y}throw Error("cached value already set")}}}function oX($){return $===null||$===void 0}function FH($){let Q=$.startsWith("^")?1:0,Y=$.endsWith("$")?$.length-1:$.length;return $.slice(Q,Y)}function S3($,Q){let Y=$/Q,X=Math.round(Y),z=Number.EPSILON*Math.max(Math.abs(Y),1);if(Math.abs(Y-X)<z)return 0;return Y-X}var co=Symbol("evaluating");function M0($,Q,Y){let X=void 0;Object.defineProperty($,Q,{get(){if(X===co)return;if(X===void 0)X=co,X=Y();return X},set(z){Object.defineProperty($,Q,{value:z})},configurable:!0})}function C90($){return Object.create(Object.getPrototypeOf($),Object.getOwnPropertyDescriptors($))}function rX($,Q,Y){Object.defineProperty($,Q,{value:Y,writable:!0,enumerable:!0,configurable:!0})}function CY(...$){let Q={};for(let Y of $){let X=Object.getOwnPropertyDescriptors(Y);Object.assign(Q,X)}return Object.defineProperties({},Q)}function u90($){return CY($._zod.def)}function c90($,Q){if(!Q)return $;return Q.reduce((Y,X)=>Y?.[X],$)}function y90($){let Q=Object.keys($),Y=Q.map((X)=>$[X]);return Promise.all(Y).then((X)=>{let z={};for(let Z=0;Z<Q.length;Z++)z[Q[Z]]=X[Z];return z})}function g90($=10){let Y="";for(let X=0;X<$;X++)Y+="abcdefghijklmnopqrstuvwxyz"[Math.floor(Math.random()*26)];return Y}function cq($){return JSON.stringify($)}function E3($){return $.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}var yq="captureStackTrace"in Error?Error.captureStackTrace:(...$)=>{};function yZ($){return typeof $==="object"&&$!==null&&!Array.isArray($)}var C3=l4(()=>{if(uZ.jitless)return!1;if(typeof navigator<"u"&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch($){return!1}});function sX($){if(yZ($)===!1)return!1;let Q=$.constructor;if(Q===void 0)return!0;if(typeof Q!=="function")return!0;let Y=Q.prototype;if(yZ(Y)===!1)return!1;if(Object.prototype.hasOwnProperty.call(Y,"isPrototypeOf")===!1)return!1;return!0}function u3($){if(sX($))return{...$};if(Array.isArray($))return[...$];if($ instanceof Map)return new Map($);if($ instanceof Set)return new Set($);return $}function h90($){let Q=0;for(let Y in $)if(Object.prototype.hasOwnProperty.call($,Y))Q++;return Q}var m90=($)=>{let Q=typeof $;switch(Q){case"undefined":return"undefined";case"string":return"string";case"number":return Number.isNaN($)?"nan":"number";case"boolean":return"boolean";case"function":return"function";case"bigint":return"bigint";case"symbol":return"symbol";case"object":if(Array.isArray($))return"array";if($===null)return"null";if($.then&&typeof $.then==="function"&&$.catch&&typeof $.catch==="function")return"promise";if(typeof Map<"u"&&$ instanceof Map)return"map";if(typeof Set<"u"&&$ instanceof Set)return"set";if(typeof Date<"u"&&$ instanceof Date)return"date";if(typeof File<"u"&&$ instanceof File)return"file";return"object";default:throw Error(`Unknown data type: ${Q}`)}},NH=new Set(["string","number","symbol"]),c3=new Set(["string","number","bigint","boolean","symbol","undefined"]);function F7($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s$($,Q,Y){let X=new $._zod.constr(Q??$._zod.def);if(!Q||Y?.parent)X._zod.parent=$;return X}function B1($){let Q=$;if(!Q)return{};if(typeof Q==="string")return{error:()=>Q};if(Q?.message!==void 0){if(Q?.error!==void 0)throw Error("Cannot specify both `message` and `error` params");Q.error=Q.message}if(delete Q.message,typeof Q.error==="string")return{...Q,error:()=>Q.error};return Q}function p90($){let Q;return new Proxy({},{get(Y,X,z){return Q??(Q=$()),Reflect.get(Q,X,z)},set(Y,X,z,Z){return Q??(Q=$()),Reflect.set(Q,X,z,Z)},has(Y,X){return Q??(Q=$()),Reflect.has(Q,X)},deleteProperty(Y,X){return Q??(Q=$()),Reflect.deleteProperty(Q,X)},ownKeys(Y){return Q??(Q=$()),Reflect.ownKeys(Q)},getOwnPropertyDescriptor(Y,X){return Q??(Q=$()),Reflect.getOwnPropertyDescriptor(Q,X)},defineProperty(Y,X,z){return Q??(Q=$()),Reflect.defineProperty(Q,X,z)}})}function G1($){if(typeof $==="bigint")return $.toString()+"n";if(typeof $==="string")return`"${$}"`;return`${$}`}function y3($){return Object.keys($).filter((Q)=>{return $[Q]._zod.optin==="optional"&&$[Q]._zod.optout==="optional"})}var g3={safeint:[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-340282346638528860000000000000000000000,340282346638528860000000000000000000000],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]},h3={int64:[BigInt("-9223372036854775808"),BigInt("9223372036854775807")],uint64:[BigInt(0),BigInt("18446744073709551615")]};function i90($,Q){let Y=$._zod.def,X=Y.checks;if(X&&X.length>0)throw Error(".pick() cannot be used on object schemas containing refinements");let Z=CY($._zod.def,{get shape(){let K={};for(let W in Q){if(!(W in Y.shape))throw Error(`Unrecognized key: "${W}"`);if(!Q[W])continue;K[W]=Y.shape[W]}return rX(this,"shape",K),K},checks:[]});return s$($,Z)}function l90($,Q){let Y=$._zod.def,X=Y.checks;if(X&&X.length>0)throw Error(".omit() cannot be used on object schemas containing refinements");let Z=CY($._zod.def,{get shape(){let K={...$._zod.def.shape};for(let W in Q){if(!(W in Y.shape))throw Error(`Unrecognized key: "${W}"`);if(!Q[W])continue;delete K[W]}return rX(this,"shape",K),K},checks:[]});return s$($,Z)}function n90($,Q){if(!sX(Q))throw Error("Invalid input to extend: expected a plain object");let Y=$._zod.def.checks;if(Y&&Y.length>0){let Z=$._zod.def.shape;for(let K in Q)if(Object.getOwnPropertyDescriptor(Z,K)!==void 0)throw Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}let z=CY($._zod.def,{get shape(){let Z={...$._zod.def.shape,...Q};return rX(this,"shape",Z),Z}});return s$($,z)}function d90($,Q){if(!sX(Q))throw Error("Invalid input to safeExtend: expected a plain object");let Y=CY($._zod.def,{get shape(){let X={...$._zod.def.shape,...Q};return rX(this,"shape",X),X}});return s$($,Y)}function a90($,Q){if($._zod.def.checks?.length)throw Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");let Y=CY($._zod.def,{get shape(){let X={...$._zod.def.shape,...Q._zod.def.shape};return rX(this,"shape",X),X},get catchall(){return Q._zod.def.catchall},checks:Q._zod.def.checks??[]});return s$($,Y)}function o90($,Q,Y){let z=Q._zod.def.checks;if(z&&z.length>0)throw Error(".partial() cannot be used on object schemas containing refinements");let K=CY(Q._zod.def,{get shape(){let W=Q._zod.def.shape,H={...W};if(Y)for(let V in Y){if(!(V in W))throw Error(`Unrecognized key: "${V}"`);if(!Y[V])continue;H[V]=$?new $({type:"optional",innerType:W[V]}):W[V]}else for(let V in W)H[V]=$?new $({type:"optional",innerType:W[V]}):W[V];return rX(this,"shape",H),H},checks:[]});return s$(Q,K)}function r90($,Q,Y){let X=CY(Q._zod.def,{get shape(){let z=Q._zod.def.shape,Z={...z};if(Y)for(let K in Y){if(!(K in Z))throw Error(`Unrecognized key: "${K}"`);if(!Y[K])continue;Z[K]=new $({type:"nonoptional",innerType:z[K]})}else for(let K in z)Z[K]=new $({type:"nonoptional",innerType:z[K]});return rX(this,"shape",Z),Z}});return s$(Q,X)}function tX($,Q=0){if($.aborted===!0)return!0;for(let Y=Q;Y<$.issues.length;Y++)if($.issues[Y]?.continue!==!0)return!0;return!1}function m3($,Q=0){if($.aborted===!0)return!0;for(let Y=Q;Y<$.issues.length;Y++)if($.issues[Y]?.continue===!1)return!0;return!1}function v9($,Q){return Q.map((Y)=>{var X;return(X=Y).path??(X.path=[]),Y.path.unshift($),Y})}function DH($){return typeof $==="string"?$:$?.message}function t$($,Q,Y){let X=$.message?$.message:DH($.inst?._zod.def?.error?.($))??DH(Q?.error?.($))??DH(Y.customError?.($))??DH(Y.localeError?.($))??"Invalid input",{inst:z,continue:Z,input:K,...W}=$;if(W.path??(W.path=[]),W.message=X,Q?.reportInput)W.input=K;return W}function PH($){if($ instanceof Set)return"set";if($ instanceof Map)return"map";if($ instanceof File)return"file";return"unknown"}function jH($){if(Array.isArray($))return"array";if(typeof $==="string")return"string";return"unknown"}function J1($){let Q=typeof $;switch(Q){case"number":return Number.isNaN($)?"nan":"number";case"object":{if($===null)return"null";if(Array.isArray($))return"array";let Y=$;if(Y&&Object.getPrototypeOf(Y)!==Object.prototype&&"constructor"in Y&&Y.constructor)return Y.constructor.name}}return Q}function n4(...$){let[Q,Y,X]=$;if(typeof Q==="string")return{message:Q,code:"custom",input:Y,inst:X};return{...Q}}function s90($){return Object.entries($).filter(([Q,Y])=>{return Number.isNaN(Number.parseInt(Q,10))}).map((Q)=>Q[1])}function yo($){let Q=atob($),Y=new Uint8Array(Q.length);for(let X=0;X<Q.length;X++)Y[X]=Q.charCodeAt(X);return Y}function go($){let Q="";for(let Y=0;Y<$.length;Y++)Q+=String.fromCharCode($[Y]);return btoa(Q)}function t90($){let Q=$.replace(/-/g,"+").replace(/_/g,"/"),Y="=".repeat((4-Q.length%4)%4);return yo(Q+Y)}function e90($){return go($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function $70($){let Q=$.replace(/^0x/,"");if(Q.length%2!==0)throw Error("Invalid hex string length");let Y=new Uint8Array(Q.length/2);for(let X=0;X<Q.length;X+=2)Y[X/2]=Number.parseInt(Q.slice(X,X+2),16);return Y}function Q70($){return Array.from($).map((Q)=>Q.toString(16).padStart(2,"0")).join("")}class ho{constructor(...$){}}var mo=($,Q)=>{$.name="$ZodError",Object.defineProperty($,"_zod",{value:$._zod,enumerable:!1}),Object.defineProperty($,"issues",{value:Q,enumerable:!1}),$.message=JSON.stringify(Q,i4,2),Object.defineProperty($,"toString",{value:()=>$.message,enumerable:!1})},IH=y("$ZodError",mo),b9=y("$ZodError",mo,{Parent:Error});function MH($,Q=(Y)=>Y.message){let Y={},X=[];for(let z of $.issues)if(z.path.length>0)Y[z.path[0]]=Y[z.path[0]]||[],Y[z.path[0]].push(Q(z));else X.push(Q(z));return{formErrors:X,fieldErrors:Y}}function OH($,Q=(Y)=>Y.message){let Y={_errors:[]},X=(z,Z=[])=>{for(let K of z.issues)if(K.code==="invalid_union"&&K.errors.length)K.errors.map((W)=>X({issues:W},[...Z,...K.path]));else if(K.code==="invalid_key")X({issues:K.issues},[...Z,...K.path]);else if(K.code==="invalid_element")X({issues:K.issues},[...Z,...K.path]);else{let W=[...Z,...K.path];if(W.length===0)Y._errors.push(Q(K));else{let H=Y,V=0;while(V<W.length){let w=W[V];if(V!==W.length-1)H[w]=H[w]||{_errors:[]};else H[w]=H[w]||{_errors:[]},H[w]._errors.push(Q(K));H=H[w],V++}}}};return X($),Y}function p3($,Q=(Y)=>Y.message){let Y={errors:[]},X=(z,Z=[])=>{var K,W;for(let H of z.issues)if(H.code==="invalid_union"&&H.errors.length)H.errors.map((V)=>X({issues:V},[...Z,...H.path]));else if(H.code==="invalid_key")X({issues:H.issues},[...Z,...H.path]);else if(H.code==="invalid_element")X({issues:H.issues},[...Z,...H.path]);else{let V=[...Z,...H.path];if(V.length===0){Y.errors.push(Q(H));continue}let w=Y,G=0;while(G<V.length){let U=V[G],J=G===V.length-1;if(typeof U==="string")w.properties??(w.properties={}),(K=w.properties)[U]??(K[U]={errors:[]}),w=w.properties[U];else w.items??(w.items=[]),(W=w.items)[U]??(W[U]={errors:[]}),w=w.items[U];if(J)w.errors.push(Q(H));G++}}};return X($),Y}function po($){let Q=[],Y=$.map((X)=>typeof X==="object"?X.key:X);for(let X of Y)if(typeof X==="number")Q.push(`[${X}]`);else if(typeof X==="symbol")Q.push(`[${JSON.stringify(String(X))}]`);else if(/[^\w$]/.test(X))Q.push(`[${JSON.stringify(X)}]`);else{if(Q.length)Q.push(".");Q.push(X)}return Q.join("")}function i3($){let Q=[],Y=[...$.issues].sort((X,z)=>(X.path??[]).length-(z.path??[]).length);for(let X of Y)if(Q.push(`\u2716 ${X.message}`),X.path?.length)Q.push(` \u2192 at ${po(X.path)}`);return Q.join(`
609
+ `,Q)+1}return{type:$,offset:this.offset,indent:this.indent,source:this.source}}startBlockValue($){switch(this.type){case"alias":case"scalar":case"single-quoted-scalar":case"double-quoted-scalar":return this.flowScalar(this.type);case"block-scalar-header":return{type:"block-scalar",offset:this.offset,indent:this.indent,props:[this.sourceToken],source:""};case"flow-map-start":case"flow-seq-start":return{type:"flow-collection",offset:this.offset,indent:this.indent,start:this.sourceToken,items:[],end:[]};case"seq-item-ind":return{type:"block-seq",offset:this.offset,indent:this.indent,items:[{start:[this.sourceToken]}]};case"explicit-key-ind":{this.onKeyLine=!0;let Q=SM($),Y=KH(Q);return Y.push(this.sourceToken),{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:Y,explicitKey:!0}]}}case"map-value-ind":{this.onKeyLine=!0;let Q=SM($),Y=KH(Q);return{type:"block-map",offset:this.offset,indent:this.indent,items:[{start:Y,key:null,sep:[this.sourceToken]}]}}}return null}atIndentedComment($,Q){if(this.type!=="comment")return!1;if(this.indent<=Q)return!1;return $.every((Y)=>Y.type==="newline"||Y.type==="space")}*documentEnd($){if(this.type!=="doc-mode"){if($.end)$.end.push(this.sourceToken);else $.end=[this.sourceToken];if(this.type==="newline")yield*this.pop()}}*lineEnd($){switch(this.type){case"comma":case"doc-start":case"doc-end":case"flow-seq-end":case"flow-map-end":case"map-value-ind":yield*this.pop(),yield*this.step();break;case"newline":this.onKeyLine=!1;case"space":case"comment":default:if($.end)$.end.push(this.sourceToken);else $.end=[this.sourceToken];if(this.type==="newline")yield*this.pop()}}}ub6.Parser=w00});var x00=q((nb6)=>{var G00=vd(),yb6=Xq(),Vq=zq(),gb6=En(),hb6=d0(),mb6=Cd(),U00=ud();function J00($){let Q=$.prettyErrors!==!1;return{lineCounter:$.lineCounter||Q&&new mb6.LineCounter||null,prettyErrors:Q}}function pb6($,Q={}){let{lineCounter:Y,prettyErrors:X}=J00(Q),z=new U00.Parser(Y?.addNewLine),Z=new G00.Composer(Q),K=Array.from(Z.compose(z.parse($)));if(X&&Y)for(let W of K)W.errors.forEach(Vq.prettifyError($,Y)),W.warnings.forEach(Vq.prettifyError($,Y));if(K.length>0)return K;return Object.assign([],{empty:!0},Z.streamInfo())}function q00($,Q={}){let{lineCounter:Y,prettyErrors:X}=J00(Q),z=new U00.Parser(Y?.addNewLine),Z=new G00.Composer(Q),K=null;for(let W of Z.compose(z.parse($),!0,$.length))if(!K)K=W;else if(K.options.logLevel!=="silent"){K.errors.push(new Vq.YAMLParseError(W.range.slice(0,2),"MULTIPLE_DOCS","Source contains multiple documents; please use YAML.parseAllDocuments()"));break}if(X&&Y)K.errors.forEach(Vq.prettifyError($,Y)),K.warnings.forEach(Vq.prettifyError($,Y));return K}function ib6($,Q,Y){let X=void 0;if(typeof Q==="function")X=Q;else if(Y===void 0&&Q&&typeof Q==="object")Y=Q;let z=q00($,Y);if(!z)return null;if(z.warnings.forEach((Z)=>gb6.warn(z.options.logLevel,Z)),z.errors.length>0)if(z.options.logLevel!=="silent")throw z.errors[0];else z.errors=[];return z.toJS(Object.assign({reviver:X},Y))}function lb6($,Q,Y){let X=null;if(typeof Q==="function"||Array.isArray(Q))X=Q;else if(Y===void 0&&Q)Y=Q;if(typeof Y==="string")Y=Y.length;if(typeof Y==="number"){let z=Math.round(Y);Y=z<1?void 0:z>8?{indent:8}:{indent:z}}if($===void 0){let{keepUndefined:z}=Y??Q??{};if(!z)return}if(hb6.isDocument($)&&!X)return $.toString(Y);return new yb6.Document($,X,Y).toString(Y)}nb6.parse=ib6;nb6.parseAllDocuments=pb6;nb6.parseDocument=q00;nb6.stringify=lb6});import{homedir as Af6}from"os";var Co={name:"@interactive-inc/claude-funnel",version:"0.60.1",description:"Hub CLI that routes external events (Slack / GitHub / Discord) to Claude Code agents through subscription channels over MCP.",keywords:["bun","claude","claude-code","cli","discord","github","mcp","slack"],homepage:"https://github.com/interactive-inc/open-claude-funnel#readme",bugs:{url:"https://github.com/interactive-inc/open-claude-funnel/issues"},license:"MIT",author:"Interactive Inc.",repository:{type:"git",url:"git+https://github.com/interactive-inc/open-claude-funnel.git"},bin:{fnl:"./dist/bin.js",funnel:"./dist/bin.js"},files:["dist/**/*","funnel.schema.json","README.md","LICENSE"],type:"module",main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",default:"./dist/index.js"},"./claude":{types:"./dist/claude.d.ts",import:"./dist/claude.js",default:"./dist/claude.js"},"./gateway":{types:"./dist/gateway.d.ts",import:"./dist/gateway.js",default:"./dist/gateway.js"},"./profiles":{types:"./dist/profiles.d.ts",import:"./dist/profiles.js",default:"./dist/profiles.js"},"./local-config":{types:"./dist/local-config.d.ts",import:"./dist/local-config.js",default:"./dist/local-config.js"},"./diagnostics":{types:"./dist/diagnostics.d.ts",import:"./dist/diagnostics.js",default:"./dist/diagnostics.js"},"./recovery":{types:"./dist/recovery.d.ts",import:"./dist/recovery.js",default:"./dist/recovery.js"},"./doctor":{types:"./dist/doctor.d.ts",import:"./dist/doctor.js",default:"./dist/doctor.js"},"./docs":{types:"./dist/docs.d.ts",import:"./dist/docs.js",default:"./dist/docs.js"},"./connectors/slack":{types:"./dist/connectors/slack.d.ts",import:"./dist/connectors/slack.js",default:"./dist/connectors/slack.js"},"./connectors/discord":{types:"./dist/connectors/discord.d.ts",import:"./dist/connectors/discord.js",default:"./dist/connectors/discord.js"},"./connectors/gh":{types:"./dist/connectors/gh.d.ts",import:"./dist/connectors/gh.js",default:"./dist/connectors/gh.js"},"./connectors/schedule":{types:"./dist/connectors/schedule.d.ts",import:"./dist/connectors/schedule.js",default:"./dist/connectors/schedule.js"},"./logger":{types:"./dist/logger.d.ts",import:"./dist/logger.js",default:"./dist/logger.js"},"./bin":"./dist/bin.js","./package.json":"./package.json"},publishConfig:{access:"public"},scripts:{prepack:"make build"},dependencies:{"@hono/zod-validator":"0.8.0","@modelcontextprotocol/sdk":"^1.29.0","@slack/bolt":"^4.7.2","@slack/web-api":"^7.16.0","discord.js":"^14.26.4",hono:"^4.12.19",yaml:"^2.9.0",zod:"^4.4.3"},devDependencies:{"@types/bun":"^1.3.14","@typescript/native-preview":"^7.0.0-dev.20260516.1","vite-plus":"^0.1.21",vitest:"^4.1.8"},engines:{bun:">=1.3.0"}};var Q0=class extends Error{res;status;constructor($=500,Q){super(Q?.message,{cause:Q?.cause});this.res=Q?.res,this.status=$}getResponse(){if(this.res)return new Response(this.res.body,{status:this.status,headers:this.res.headers});return new Response(this.message,{status:this.status})}};var P={};YQ(P,{xor:()=>xs,xid:()=>cr,void:()=>Vs,uuidv7:()=>Rr,uuidv6:()=>Ar,uuidv4:()=>_r,uuid:()=>br,util:()=>q1,url:()=>Tr,uppercase:()=>Q2,unknown:()=>lZ,union:()=>GB,undefined:()=>Ws,ulid:()=>ur,uint64:()=>Zs,uint32:()=>Ys,tuple:()=>tA,trim:()=>W2,treeifyError:()=>p3,transform:()=>JB,toUpperCase:()=>V2,toLowerCase:()=>H2,toJSONSchema:()=>cx,templateLiteral:()=>As,symbol:()=>Ks,superRefine:()=>vR,success:()=>Os,stringbool:()=>us,stringFormat:()=>or,string:()=>gH,strictObject:()=>Js,startsWith:()=>X2,slugify:()=>w2,size:()=>mZ,setErrorMap:()=>wY0,set:()=>Ns,safeParseAsync:()=>vA,safeParse:()=>OA,safeEncodeAsync:()=>kA,safeEncode:()=>TA,safeDecodeAsync:()=>SA,safeDecode:()=>fA,registry:()=>Vx,regexes:()=>Y7,regex:()=>e4,refine:()=>OR,record:()=>eA,readonly:()=>FR,property:()=>Sx,promise:()=>Rs,prettifyError:()=>i3,preprocess:()=>ys,prefault:()=>GR,positive:()=>Rx,pipe:()=>lx,partialRecord:()=>Ds,parseAsync:()=>MA,parse:()=>IA,overwrite:()=>XQ,optional:()=>mH,object:()=>Us,number:()=>CA,nullish:()=>Ms,nullable:()=>pH,null:()=>hA,normalize:()=>K2,nonpositive:()=>fx,nonoptional:()=>UR,nonnegative:()=>kx,never:()=>wB,negative:()=>Tx,nativeEnum:()=>Ps,nanoid:()=>Sr,nan:()=>vs,multipleOf:()=>eX,minSize:()=>mQ,minLength:()=>uY,mime:()=>Z2,meta:()=>Es,maxSize:()=>$z,maxLength:()=>pZ,map:()=>Fs,mac:()=>hr,lte:()=>X7,lt:()=>gQ,lowercase:()=>$2,looseRecord:()=>Ls,looseObject:()=>qs,locales:()=>CH,literal:()=>js,length:()=>iZ,lazy:()=>jR,ksuid:()=>yr,keyof:()=>Gs,jwt:()=>ar,json:()=>cs,iso:()=>J2,ipv6:()=>mr,ipv4:()=>gr,invertCodec:()=>_s,intersection:()=>rA,int64:()=>zs,int32:()=>Qs,int:()=>ix,instanceof:()=>Cs,includes:()=>Y2,httpUrl:()=>fr,hostname:()=>rr,hex:()=>sr,hash:()=>tr,guid:()=>vr,gte:()=>e$,gt:()=>hQ,globalRegistry:()=>w$,getErrorMap:()=>GY0,function:()=>Ts,fromJSONSchema:()=>hs,formatError:()=>OH,float64:()=>$s,float32:()=>er,flattenError:()=>MH,file:()=>Is,exactOptional:()=>KR,enum:()=>UB,endsWith:()=>z2,encodeAsync:()=>AA,encode:()=>bA,emoji:()=>kr,email:()=>Or,e164:()=>dr,discriminatedUnion:()=>Bs,describe:()=>Ss,decodeAsync:()=>RA,decode:()=>_A,date:()=>ws,custom:()=>ks,cuid2:()=>Cr,cuid:()=>Er,core:()=>cY,config:()=>w8,coerce:()=>_R,codec:()=>bs,clone:()=>s$,cidrv6:()=>ir,cidrv4:()=>pr,check:()=>fs,catch:()=>xR,boolean:()=>uA,bigint:()=>Xs,base64url:()=>nr,base64:()=>lr,array:()=>dH,any:()=>Hs,_function:()=>Ts,_default:()=>VR,_ZodString:()=>nx,ZodXor:()=>dA,ZodXID:()=>ex,ZodVoid:()=>lA,ZodUnknown:()=>pA,ZodUnion:()=>oH,ZodUndefined:()=>yA,ZodUUID:()=>pQ,ZodURL:()=>lH,ZodULID:()=>tx,ZodType:()=>B0,ZodTuple:()=>sA,ZodTransform:()=>zR,ZodTemplateLiteral:()=>NR,ZodSymbol:()=>cA,ZodSuccess:()=>JR,ZodStringFormat:()=>V6,ZodString:()=>B2,ZodSet:()=>QR,ZodRecord:()=>q2,ZodRealError:()=>_9,ZodReadonly:()=>LR,ZodPromise:()=>IR,ZodPreprocess:()=>DR,ZodPrefault:()=>wR,ZodPipe:()=>rH,ZodOptional:()=>qB,ZodObject:()=>aH,ZodNumberFormat:()=>nZ,ZodNumber:()=>L2,ZodNullable:()=>WR,ZodNull:()=>gA,ZodNonOptional:()=>xB,ZodNever:()=>iA,ZodNanoID:()=>ox,ZodNaN:()=>BR,ZodMap:()=>$R,ZodMAC:()=>EA,ZodLiteral:()=>YR,ZodLazy:()=>PR,ZodKSUID:()=>$B,ZodJWT:()=>HB,ZodIssueCode:()=>VY0,ZodIntersection:()=>oA,ZodISOTime:()=>mx,ZodISODuration:()=>px,ZodISODateTime:()=>gx,ZodISODate:()=>hx,ZodIPv6:()=>YB,ZodIPv4:()=>QB,ZodGUID:()=>hH,ZodFunction:()=>MR,ZodFirstPartyTypeKind:()=>bR,ZodFile:()=>XR,ZodExactOptional:()=>ZR,ZodError:()=>WY0,ZodEnum:()=>x2,ZodEmoji:()=>ax,ZodEmail:()=>dx,ZodE164:()=>WB,ZodDiscriminatedUnion:()=>aA,ZodDefault:()=>HR,ZodDate:()=>nH,ZodCustomStringFormat:()=>D2,ZodCustom:()=>tH,ZodCodec:()=>sH,ZodCatch:()=>qR,ZodCUID2:()=>sx,ZodCUID:()=>rx,ZodCIDRv6:()=>zB,ZodCIDRv4:()=>XB,ZodBoolean:()=>F2,ZodBigIntFormat:()=>VB,ZodBigInt:()=>N2,ZodBase64URL:()=>KB,ZodBase64:()=>ZB,ZodArray:()=>nA,ZodAny:()=>mA,TimePrecision:()=>tb,NEVER:()=>T3,$output:()=>nb,$input:()=>db,$brand:()=>f3});var cY={};YQ(cY,{version:()=>gO,util:()=>q1,treeifyError:()=>p3,toJSONSchema:()=>cx,toDotPath:()=>po,safeParseAsync:()=>n3,safeParse:()=>l3,safeEncodeAsync:()=>V70,safeEncode:()=>W70,safeDecodeAsync:()=>w70,safeDecode:()=>H70,registry:()=>Vx,regexes:()=>Y7,process:()=>Z6,prettifyError:()=>i3,parseAsync:()=>hq,parse:()=>gq,meta:()=>f_,locales:()=>CH,isValidJWT:()=>Ur,isValidBase64URL:()=>Gr,isValidBase64:()=>Hv,initializeContext:()=>Qz,globalRegistry:()=>w$,globalConfig:()=>uZ,formatError:()=>OH,flattenError:()=>MH,finalize:()=>Xz,extractDefs:()=>Yz,encodeAsync:()=>Z70,encode:()=>X70,describe:()=>T_,decodeAsync:()=>K70,decode:()=>z70,createToJSONSchemaMethod:()=>S_,createStandardJSONSchemaMethod:()=>U2,config:()=>w8,clone:()=>s$,_xor:()=>uQ0,_xid:()=>Nx,_void:()=>j_,_uuidv7:()=>qx,_uuidv6:()=>Jx,_uuidv4:()=>Ux,_uuid:()=>Gx,_url:()=>cH,_uppercase:()=>Q2,_unknown:()=>N_,_union:()=>CQ0,_undefined:()=>D_,_ulid:()=>Fx,_uint64:()=>x_,_uint32:()=>V_,_tuple:()=>gQ0,_trim:()=>W2,_transform:()=>dQ0,_toUpperCase:()=>V2,_toLowerCase:()=>H2,_templateLiteral:()=>YY0,_symbol:()=>B_,_superRefine:()=>R_,_success:()=>tQ0,_stringbool:()=>k_,_stringFormat:()=>G2,_string:()=>ob,_startsWith:()=>X2,_slugify:()=>w2,_size:()=>mZ,_set:()=>pQ0,_safeParseAsync:()=>r4,_safeParse:()=>o4,_safeEncodeAsync:()=>aq,_safeEncode:()=>nq,_safeDecodeAsync:()=>oq,_safeDecode:()=>dq,_regex:()=>e4,_refine:()=>A_,_record:()=>hQ0,_readonly:()=>QY0,_property:()=>Sx,_promise:()=>zY0,_positive:()=>Rx,_pipe:()=>$Y0,_parseAsync:()=>a4,_parse:()=>d4,_overwrite:()=>XQ,_optional:()=>aQ0,_number:()=>X_,_nullable:()=>oQ0,_null:()=>L_,_normalize:()=>K2,_nonpositive:()=>fx,_nonoptional:()=>sQ0,_nonnegative:()=>kx,_never:()=>P_,_negative:()=>Tx,_nativeEnum:()=>lQ0,_nanoid:()=>Bx,_nan:()=>O_,_multipleOf:()=>eX,_minSize:()=>mQ,_minLength:()=>uY,_min:()=>e$,_mime:()=>Z2,_maxSize:()=>$z,_maxLength:()=>pZ,_max:()=>X7,_map:()=>mQ0,_mac:()=>sb,_lte:()=>X7,_lt:()=>gQ,_lowercase:()=>$2,_literal:()=>nQ0,_length:()=>iZ,_lazy:()=>XY0,_ksuid:()=>Px,_jwt:()=>Ax,_isoTime:()=>Q_,_isoDuration:()=>Y_,_isoDateTime:()=>eb,_isoDate:()=>$_,_ipv6:()=>Ix,_ipv4:()=>jx,_intersection:()=>yQ0,_int64:()=>q_,_int32:()=>H_,_int:()=>Z_,_includes:()=>Y2,_guid:()=>uH,_gte:()=>e$,_gt:()=>hQ,_float64:()=>W_,_float32:()=>K_,_file:()=>b_,_enum:()=>iQ0,_endsWith:()=>z2,_encodeAsync:()=>iq,_encode:()=>mq,_emoji:()=>xx,_email:()=>wx,_e164:()=>_x,_discriminatedUnion:()=>cQ0,_default:()=>rQ0,_decodeAsync:()=>lq,_decode:()=>pq,_date:()=>I_,_custom:()=>__,_cuid2:()=>Lx,_cuid:()=>Dx,_coercedString:()=>rb,_coercedNumber:()=>z_,_coercedDate:()=>M_,_coercedBoolean:()=>G_,_coercedBigint:()=>J_,_cidrv6:()=>Ox,_cidrv4:()=>Mx,_check:()=>Pr,_catch:()=>eQ0,_boolean:()=>w_,_bigint:()=>U_,_base64url:()=>bx,_base64:()=>vx,_array:()=>v_,_any:()=>F_,TimePrecision:()=>tb,NEVER:()=>T3,JSONSchemaGenerator:()=>LA,JSONSchema:()=>jr,Doc:()=>eq,$output:()=>nb,$input:()=>db,$constructor:()=>y,$brand:()=>f3,$ZodXor:()=>vv,$ZodXID:()=>sO,$ZodVoid:()=>jv,$ZodUnknown:()=>Nv,$ZodUnion:()=>RH,$ZodUndefined:()=>Dv,$ZodUUID:()=>pO,$ZodURL:()=>lO,$ZodULID:()=>rO,$ZodType:()=>K0,$ZodTuple:()=>Kx,$ZodTransform:()=>Ev,$ZodTemplateLiteral:()=>nv,$ZodSymbol:()=>Bv,$ZodSuccess:()=>hv,$ZodStringFormat:()=>H6,$ZodString:()=>hZ,$ZodSet:()=>Tv,$ZodRegistry:()=>ab,$ZodRecord:()=>Av,$ZodRealError:()=>b9,$ZodReadonly:()=>lv,$ZodPromise:()=>av,$ZodPreprocess:()=>iv,$ZodPrefault:()=>yv,$ZodPipe:()=>Hx,$ZodOptional:()=>Wx,$ZodObjectJIT:()=>Ov,$ZodObject:()=>xr,$ZodNumberFormat:()=>qv,$ZodNumber:()=>zx,$ZodNullable:()=>uv,$ZodNull:()=>Lv,$ZodNonOptional:()=>gv,$ZodNever:()=>Pv,$ZodNanoID:()=>dO,$ZodNaN:()=>pv,$ZodMap:()=>Rv,$ZodMAC:()=>Zv,$ZodLiteral:()=>kv,$ZodLazy:()=>ov,$ZodKSUID:()=>tO,$ZodJWT:()=>Uv,$ZodIntersection:()=>_v,$ZodISOTime:()=>Qv,$ZodISODuration:()=>Yv,$ZodISODateTime:()=>eO,$ZodISODate:()=>$v,$ZodIPv6:()=>zv,$ZodIPv4:()=>Xv,$ZodGUID:()=>mO,$ZodFunction:()=>dv,$ZodFile:()=>Sv,$ZodExactOptional:()=>Cv,$ZodError:()=>IH,$ZodEnum:()=>fv,$ZodEncodeError:()=>cZ,$ZodEmoji:()=>nO,$ZodEmail:()=>iO,$ZodE164:()=>Gv,$ZodDiscriminatedUnion:()=>bv,$ZodDefault:()=>cv,$ZodDate:()=>Iv,$ZodCustomStringFormat:()=>Jv,$ZodCustom:()=>rv,$ZodCodec:()=>TH,$ZodCheckUpperCase:()=>kO,$ZodCheckStringFormat:()=>s4,$ZodCheckStartsWith:()=>EO,$ZodCheckSizeEquals:()=>bO,$ZodCheckRegex:()=>TO,$ZodCheckProperty:()=>uO,$ZodCheckOverwrite:()=>yO,$ZodCheckNumberFormat:()=>IO,$ZodCheckMultipleOf:()=>jO,$ZodCheckMinSize:()=>vO,$ZodCheckMinLength:()=>AO,$ZodCheckMimeType:()=>cO,$ZodCheckMaxSize:()=>OO,$ZodCheckMaxLength:()=>_O,$ZodCheckLowerCase:()=>fO,$ZodCheckLessThan:()=>sq,$ZodCheckLengthEquals:()=>RO,$ZodCheckIncludes:()=>SO,$ZodCheckGreaterThan:()=>tq,$ZodCheckEndsWith:()=>CO,$ZodCheckBigIntFormat:()=>MO,$ZodCheck:()=>x6,$ZodCatch:()=>mv,$ZodCUID2:()=>oO,$ZodCUID:()=>aO,$ZodCIDRv6:()=>Wv,$ZodCIDRv4:()=>Kv,$ZodBoolean:()=>AH,$ZodBigIntFormat:()=>xv,$ZodBigInt:()=>Zx,$ZodBase64URL:()=>wv,$ZodBase64:()=>Vv,$ZodAsyncError:()=>yQ,$ZodArray:()=>Mv,$ZodAny:()=>Fv});var uo,T3=Object.freeze({status:"aborted"});function y($,Q,Y){function X(W,H){if(!W._zod)Object.defineProperty(W,"_zod",{value:{def:H,constr:K,traits:new Set},enumerable:!1});if(W._zod.traits.has($))return;W._zod.traits.add($),Q(W,H);let V=K.prototype,w=Object.keys(V);for(let G=0;G<w.length;G++){let U=w[G];if(!(U in W))W[U]=V[U].bind(W)}}let z=Y?.Parent??Object;class Z extends z{}Object.defineProperty(Z,"name",{value:$});function K(W){var H;let V=Y?.Parent?new Z:this;X(V,W),(H=V._zod).deferred??(H.deferred=[]);for(let w of V._zod.deferred)w();return V}return Object.defineProperty(K,"init",{value:X}),Object.defineProperty(K,Symbol.hasInstance,{value:(W)=>{if(Y?.Parent&&W instanceof Y.Parent)return!0;return W?._zod?.traits?.has($)}}),Object.defineProperty(K,"name",{value:$}),K}var f3=Symbol("zod_brand");class yQ extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class cZ extends Error{constructor($){super(`Encountered unidirectional transform during encode: ${$}`);this.name="ZodEncodeError"}}(uo=globalThis).__zod_globalConfig??(uo.__zod_globalConfig={});var uZ=globalThis.__zod_globalConfig;function w8($){if($)Object.assign(uZ,$);return uZ}var q1={};YQ(q1,{unwrapMessage:()=>DH,uint8ArrayToHex:()=>Q70,uint8ArrayToBase64url:()=>e90,uint8ArrayToBase64:()=>go,stringifyPrimitive:()=>G1,slugify:()=>E3,shallowClone:()=>u3,safeExtend:()=>d90,required:()=>r90,randomString:()=>g90,propertyKeyTypes:()=>NH,promiseAllObject:()=>y90,primitiveTypes:()=>c3,prefixIssues:()=>v9,pick:()=>i90,partial:()=>o90,parsedType:()=>J1,optionalKeys:()=>y3,omit:()=>l90,objectClone:()=>C90,numKeys:()=>h90,nullish:()=>oX,normalizeParams:()=>B1,mergeDefs:()=>CY,merge:()=>a90,jsonStringifyReplacer:()=>i4,joinValues:()=>i,issue:()=>n4,isPlainObject:()=>sX,isObject:()=>yZ,hexToUint8Array:()=>$70,getSizableOrigin:()=>PH,getParsedType:()=>m90,getLengthableOrigin:()=>jH,getEnumValues:()=>LH,getElementAtPath:()=>c90,floatSafeRemainder:()=>S3,finalizeIssue:()=>t$,extend:()=>n90,explicitlyAborted:()=>m3,escapeRegex:()=>F7,esc:()=>cq,defineLazy:()=>M0,createTransparentProxy:()=>p90,cloneDef:()=>u90,clone:()=>s$,cleanRegex:()=>FH,cleanEnum:()=>s90,captureStackTrace:()=>yq,cached:()=>l4,base64urlToUint8Array:()=>t90,base64ToUint8Array:()=>yo,assignProp:()=>rX,assertNotEqual:()=>f90,assertNever:()=>S90,assertIs:()=>k90,assertEqual:()=>T90,assert:()=>E90,allowsEval:()=>C3,aborted:()=>tX,NUMBER_FORMAT_RANGES:()=>g3,Class:()=>ho,BIGINT_FORMAT_RANGES:()=>h3});function T90($){return $}function f90($){return $}function k90($){}function S90($){throw Error("Unexpected value in exhaustive check")}function E90($){}function LH($){let Q=Object.values($).filter((X)=>typeof X==="number");return Object.entries($).filter(([X,z])=>Q.indexOf(+X)===-1).map(([X,z])=>z)}function i($,Q="|"){return $.map((Y)=>G1(Y)).join(Q)}function i4($,Q){if(typeof Q==="bigint")return Q.toString();return Q}function l4($){return{get value(){{let Y=$();return Object.defineProperty(this,"value",{value:Y}),Y}throw Error("cached value already set")}}}function oX($){return $===null||$===void 0}function FH($){let Q=$.startsWith("^")?1:0,Y=$.endsWith("$")?$.length-1:$.length;return $.slice(Q,Y)}function S3($,Q){let Y=$/Q,X=Math.round(Y),z=Number.EPSILON*Math.max(Math.abs(Y),1);if(Math.abs(Y-X)<z)return 0;return Y-X}var co=Symbol("evaluating");function M0($,Q,Y){let X=void 0;Object.defineProperty($,Q,{get(){if(X===co)return;if(X===void 0)X=co,X=Y();return X},set(z){Object.defineProperty($,Q,{value:z})},configurable:!0})}function C90($){return Object.create(Object.getPrototypeOf($),Object.getOwnPropertyDescriptors($))}function rX($,Q,Y){Object.defineProperty($,Q,{value:Y,writable:!0,enumerable:!0,configurable:!0})}function CY(...$){let Q={};for(let Y of $){let X=Object.getOwnPropertyDescriptors(Y);Object.assign(Q,X)}return Object.defineProperties({},Q)}function u90($){return CY($._zod.def)}function c90($,Q){if(!Q)return $;return Q.reduce((Y,X)=>Y?.[X],$)}function y90($){let Q=Object.keys($),Y=Q.map((X)=>$[X]);return Promise.all(Y).then((X)=>{let z={};for(let Z=0;Z<Q.length;Z++)z[Q[Z]]=X[Z];return z})}function g90($=10){let Y="";for(let X=0;X<$;X++)Y+="abcdefghijklmnopqrstuvwxyz"[Math.floor(Math.random()*26)];return Y}function cq($){return JSON.stringify($)}function E3($){return $.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}var yq="captureStackTrace"in Error?Error.captureStackTrace:(...$)=>{};function yZ($){return typeof $==="object"&&$!==null&&!Array.isArray($)}var C3=l4(()=>{if(uZ.jitless)return!1;if(typeof navigator<"u"&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{return new Function(""),!0}catch($){return!1}});function sX($){if(yZ($)===!1)return!1;let Q=$.constructor;if(Q===void 0)return!0;if(typeof Q!=="function")return!0;let Y=Q.prototype;if(yZ(Y)===!1)return!1;if(Object.prototype.hasOwnProperty.call(Y,"isPrototypeOf")===!1)return!1;return!0}function u3($){if(sX($))return{...$};if(Array.isArray($))return[...$];if($ instanceof Map)return new Map($);if($ instanceof Set)return new Set($);return $}function h90($){let Q=0;for(let Y in $)if(Object.prototype.hasOwnProperty.call($,Y))Q++;return Q}var m90=($)=>{let Q=typeof $;switch(Q){case"undefined":return"undefined";case"string":return"string";case"number":return Number.isNaN($)?"nan":"number";case"boolean":return"boolean";case"function":return"function";case"bigint":return"bigint";case"symbol":return"symbol";case"object":if(Array.isArray($))return"array";if($===null)return"null";if($.then&&typeof $.then==="function"&&$.catch&&typeof $.catch==="function")return"promise";if(typeof Map<"u"&&$ instanceof Map)return"map";if(typeof Set<"u"&&$ instanceof Set)return"set";if(typeof Date<"u"&&$ instanceof Date)return"date";if(typeof File<"u"&&$ instanceof File)return"file";return"object";default:throw Error(`Unknown data type: ${Q}`)}},NH=new Set(["string","number","symbol"]),c3=new Set(["string","number","bigint","boolean","symbol","undefined"]);function F7($){return $.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function s$($,Q,Y){let X=new $._zod.constr(Q??$._zod.def);if(!Q||Y?.parent)X._zod.parent=$;return X}function B1($){let Q=$;if(!Q)return{};if(typeof Q==="string")return{error:()=>Q};if(Q?.message!==void 0){if(Q?.error!==void 0)throw Error("Cannot specify both `message` and `error` params");Q.error=Q.message}if(delete Q.message,typeof Q.error==="string")return{...Q,error:()=>Q.error};return Q}function p90($){let Q;return new Proxy({},{get(Y,X,z){return Q??(Q=$()),Reflect.get(Q,X,z)},set(Y,X,z,Z){return Q??(Q=$()),Reflect.set(Q,X,z,Z)},has(Y,X){return Q??(Q=$()),Reflect.has(Q,X)},deleteProperty(Y,X){return Q??(Q=$()),Reflect.deleteProperty(Q,X)},ownKeys(Y){return Q??(Q=$()),Reflect.ownKeys(Q)},getOwnPropertyDescriptor(Y,X){return Q??(Q=$()),Reflect.getOwnPropertyDescriptor(Q,X)},defineProperty(Y,X,z){return Q??(Q=$()),Reflect.defineProperty(Q,X,z)}})}function G1($){if(typeof $==="bigint")return $.toString()+"n";if(typeof $==="string")return`"${$}"`;return`${$}`}function y3($){return Object.keys($).filter((Q)=>{return $[Q]._zod.optin==="optional"&&$[Q]._zod.optout==="optional"})}var g3={safeint:[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-340282346638528860000000000000000000000,340282346638528860000000000000000000000],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]},h3={int64:[BigInt("-9223372036854775808"),BigInt("9223372036854775807")],uint64:[BigInt(0),BigInt("18446744073709551615")]};function i90($,Q){let Y=$._zod.def,X=Y.checks;if(X&&X.length>0)throw Error(".pick() cannot be used on object schemas containing refinements");let Z=CY($._zod.def,{get shape(){let K={};for(let W in Q){if(!(W in Y.shape))throw Error(`Unrecognized key: "${W}"`);if(!Q[W])continue;K[W]=Y.shape[W]}return rX(this,"shape",K),K},checks:[]});return s$($,Z)}function l90($,Q){let Y=$._zod.def,X=Y.checks;if(X&&X.length>0)throw Error(".omit() cannot be used on object schemas containing refinements");let Z=CY($._zod.def,{get shape(){let K={...$._zod.def.shape};for(let W in Q){if(!(W in Y.shape))throw Error(`Unrecognized key: "${W}"`);if(!Q[W])continue;delete K[W]}return rX(this,"shape",K),K},checks:[]});return s$($,Z)}function n90($,Q){if(!sX(Q))throw Error("Invalid input to extend: expected a plain object");let Y=$._zod.def.checks;if(Y&&Y.length>0){let Z=$._zod.def.shape;for(let K in Q)if(Object.getOwnPropertyDescriptor(Z,K)!==void 0)throw Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}let z=CY($._zod.def,{get shape(){let Z={...$._zod.def.shape,...Q};return rX(this,"shape",Z),Z}});return s$($,z)}function d90($,Q){if(!sX(Q))throw Error("Invalid input to safeExtend: expected a plain object");let Y=CY($._zod.def,{get shape(){let X={...$._zod.def.shape,...Q};return rX(this,"shape",X),X}});return s$($,Y)}function a90($,Q){if($._zod.def.checks?.length)throw Error(".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.");let Y=CY($._zod.def,{get shape(){let X={...$._zod.def.shape,...Q._zod.def.shape};return rX(this,"shape",X),X},get catchall(){return Q._zod.def.catchall},checks:Q._zod.def.checks??[]});return s$($,Y)}function o90($,Q,Y){let z=Q._zod.def.checks;if(z&&z.length>0)throw Error(".partial() cannot be used on object schemas containing refinements");let K=CY(Q._zod.def,{get shape(){let W=Q._zod.def.shape,H={...W};if(Y)for(let V in Y){if(!(V in W))throw Error(`Unrecognized key: "${V}"`);if(!Y[V])continue;H[V]=$?new $({type:"optional",innerType:W[V]}):W[V]}else for(let V in W)H[V]=$?new $({type:"optional",innerType:W[V]}):W[V];return rX(this,"shape",H),H},checks:[]});return s$(Q,K)}function r90($,Q,Y){let X=CY(Q._zod.def,{get shape(){let z=Q._zod.def.shape,Z={...z};if(Y)for(let K in Y){if(!(K in Z))throw Error(`Unrecognized key: "${K}"`);if(!Y[K])continue;Z[K]=new $({type:"nonoptional",innerType:z[K]})}else for(let K in z)Z[K]=new $({type:"nonoptional",innerType:z[K]});return rX(this,"shape",Z),Z}});return s$(Q,X)}function tX($,Q=0){if($.aborted===!0)return!0;for(let Y=Q;Y<$.issues.length;Y++)if($.issues[Y]?.continue!==!0)return!0;return!1}function m3($,Q=0){if($.aborted===!0)return!0;for(let Y=Q;Y<$.issues.length;Y++)if($.issues[Y]?.continue===!1)return!0;return!1}function v9($,Q){return Q.map((Y)=>{var X;return(X=Y).path??(X.path=[]),Y.path.unshift($),Y})}function DH($){return typeof $==="string"?$:$?.message}function t$($,Q,Y){let X=$.message?$.message:DH($.inst?._zod.def?.error?.($))??DH(Q?.error?.($))??DH(Y.customError?.($))??DH(Y.localeError?.($))??"Invalid input",{inst:z,continue:Z,input:K,...W}=$;if(W.path??(W.path=[]),W.message=X,Q?.reportInput)W.input=K;return W}function PH($){if($ instanceof Set)return"set";if($ instanceof Map)return"map";if($ instanceof File)return"file";return"unknown"}function jH($){if(Array.isArray($))return"array";if(typeof $==="string")return"string";return"unknown"}function J1($){let Q=typeof $;switch(Q){case"number":return Number.isNaN($)?"nan":"number";case"object":{if($===null)return"null";if(Array.isArray($))return"array";let Y=$;if(Y&&Object.getPrototypeOf(Y)!==Object.prototype&&"constructor"in Y&&Y.constructor)return Y.constructor.name}}return Q}function n4(...$){let[Q,Y,X]=$;if(typeof Q==="string")return{message:Q,code:"custom",input:Y,inst:X};return{...Q}}function s90($){return Object.entries($).filter(([Q,Y])=>{return Number.isNaN(Number.parseInt(Q,10))}).map((Q)=>Q[1])}function yo($){let Q=atob($),Y=new Uint8Array(Q.length);for(let X=0;X<Q.length;X++)Y[X]=Q.charCodeAt(X);return Y}function go($){let Q="";for(let Y=0;Y<$.length;Y++)Q+=String.fromCharCode($[Y]);return btoa(Q)}function t90($){let Q=$.replace(/-/g,"+").replace(/_/g,"/"),Y="=".repeat((4-Q.length%4)%4);return yo(Q+Y)}function e90($){return go($).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function $70($){let Q=$.replace(/^0x/,"");if(Q.length%2!==0)throw Error("Invalid hex string length");let Y=new Uint8Array(Q.length/2);for(let X=0;X<Q.length;X+=2)Y[X/2]=Number.parseInt(Q.slice(X,X+2),16);return Y}function Q70($){return Array.from($).map((Q)=>Q.toString(16).padStart(2,"0")).join("")}class ho{constructor(...$){}}var mo=($,Q)=>{$.name="$ZodError",Object.defineProperty($,"_zod",{value:$._zod,enumerable:!1}),Object.defineProperty($,"issues",{value:Q,enumerable:!1}),$.message=JSON.stringify(Q,i4,2),Object.defineProperty($,"toString",{value:()=>$.message,enumerable:!1})},IH=y("$ZodError",mo),b9=y("$ZodError",mo,{Parent:Error});function MH($,Q=(Y)=>Y.message){let Y={},X=[];for(let z of $.issues)if(z.path.length>0)Y[z.path[0]]=Y[z.path[0]]||[],Y[z.path[0]].push(Q(z));else X.push(Q(z));return{formErrors:X,fieldErrors:Y}}function OH($,Q=(Y)=>Y.message){let Y={_errors:[]},X=(z,Z=[])=>{for(let K of z.issues)if(K.code==="invalid_union"&&K.errors.length)K.errors.map((W)=>X({issues:W},[...Z,...K.path]));else if(K.code==="invalid_key")X({issues:K.issues},[...Z,...K.path]);else if(K.code==="invalid_element")X({issues:K.issues},[...Z,...K.path]);else{let W=[...Z,...K.path];if(W.length===0)Y._errors.push(Q(K));else{let H=Y,V=0;while(V<W.length){let w=W[V];if(V!==W.length-1)H[w]=H[w]||{_errors:[]};else H[w]=H[w]||{_errors:[]},H[w]._errors.push(Q(K));H=H[w],V++}}}};return X($),Y}function p3($,Q=(Y)=>Y.message){let Y={errors:[]},X=(z,Z=[])=>{var K,W;for(let H of z.issues)if(H.code==="invalid_union"&&H.errors.length)H.errors.map((V)=>X({issues:V},[...Z,...H.path]));else if(H.code==="invalid_key")X({issues:H.issues},[...Z,...H.path]);else if(H.code==="invalid_element")X({issues:H.issues},[...Z,...H.path]);else{let V=[...Z,...H.path];if(V.length===0){Y.errors.push(Q(H));continue}let w=Y,G=0;while(G<V.length){let U=V[G],J=G===V.length-1;if(typeof U==="string")w.properties??(w.properties={}),(K=w.properties)[U]??(K[U]={errors:[]}),w=w.properties[U];else w.items??(w.items=[]),(W=w.items)[U]??(W[U]={errors:[]}),w=w.items[U];if(J)w.errors.push(Q(H));G++}}};return X($),Y}function po($){let Q=[],Y=$.map((X)=>typeof X==="object"?X.key:X);for(let X of Y)if(typeof X==="number")Q.push(`[${X}]`);else if(typeof X==="symbol")Q.push(`[${JSON.stringify(String(X))}]`);else if(/[^\w$]/.test(X))Q.push(`[${JSON.stringify(X)}]`);else{if(Q.length)Q.push(".");Q.push(X)}return Q.join("")}function i3($){let Q=[],Y=[...$.issues].sort((X,z)=>(X.path??[]).length-(z.path??[]).length);for(let X of Y)if(Q.push(`\u2716 ${X.message}`),X.path?.length)Q.push(` \u2192 at ${po(X.path)}`);return Q.join(`
610
610
  `)}var d4=($)=>(Q,Y,X,z)=>{let Z=X?{...X,async:!1}:{async:!1},K=Q._zod.run({value:Y,issues:[]},Z);if(K instanceof Promise)throw new yQ;if(K.issues.length){let W=new(z?.Err??$)(K.issues.map((H)=>t$(H,Z,w8())));throw yq(W,z?.callee),W}return K.value},gq=d4(b9),a4=($)=>async(Q,Y,X,z)=>{let Z=X?{...X,async:!0}:{async:!0},K=Q._zod.run({value:Y,issues:[]},Z);if(K instanceof Promise)K=await K;if(K.issues.length){let W=new(z?.Err??$)(K.issues.map((H)=>t$(H,Z,w8())));throw yq(W,z?.callee),W}return K.value},hq=a4(b9),o4=($)=>(Q,Y,X)=>{let z=X?{...X,async:!1}:{async:!1},Z=Q._zod.run({value:Y,issues:[]},z);if(Z instanceof Promise)throw new yQ;return Z.issues.length?{success:!1,error:new($??IH)(Z.issues.map((K)=>t$(K,z,w8())))}:{success:!0,data:Z.value}},l3=o4(b9),r4=($)=>async(Q,Y,X)=>{let z=X?{...X,async:!0}:{async:!0},Z=Q._zod.run({value:Y,issues:[]},z);if(Z instanceof Promise)Z=await Z;return Z.issues.length?{success:!1,error:new $(Z.issues.map((K)=>t$(K,z,w8())))}:{success:!0,data:Z.value}},n3=r4(b9),mq=($)=>(Q,Y,X)=>{let z=X?{...X,direction:"backward"}:{direction:"backward"};return d4($)(Q,Y,z)},X70=mq(b9),pq=($)=>(Q,Y,X)=>{return d4($)(Q,Y,X)},z70=pq(b9),iq=($)=>async(Q,Y,X)=>{let z=X?{...X,direction:"backward"}:{direction:"backward"};return a4($)(Q,Y,z)},Z70=iq(b9),lq=($)=>async(Q,Y,X)=>{return a4($)(Q,Y,X)},K70=lq(b9),nq=($)=>(Q,Y,X)=>{let z=X?{...X,direction:"backward"}:{direction:"backward"};return o4($)(Q,Y,z)},W70=nq(b9),dq=($)=>(Q,Y,X)=>{return o4($)(Q,Y,X)},H70=dq(b9),aq=($)=>async(Q,Y,X)=>{let z=X?{...X,direction:"backward"}:{direction:"backward"};return r4($)(Q,Y,z)},V70=aq(b9),oq=($)=>async(Q,Y,X)=>{return r4($)(Q,Y,X)},w70=oq(b9);var Y7={};YQ(Y7,{xid:()=>r3,uuid7:()=>q70,uuid6:()=>J70,uuid4:()=>U70,uuid:()=>gZ,uppercase:()=>PO,unicodeEmail:()=>io,undefined:()=>FO,ulid:()=>o3,time:()=>UO,string:()=>qO,sha512_hex:()=>E70,sha512_base64url:()=>u70,sha512_base64:()=>C70,sha384_hex:()=>f70,sha384_base64url:()=>S70,sha384_base64:()=>k70,sha256_hex:()=>A70,sha256_base64url:()=>T70,sha256_base64:()=>R70,sha1_hex:()=>v70,sha1_base64url:()=>_70,sha1_base64:()=>b70,rfc5322Email:()=>B70,number:()=>vH,null:()=>LO,nanoid:()=>t3,md5_hex:()=>I70,md5_base64url:()=>O70,md5_base64:()=>M70,mac:()=>ZO,lowercase:()=>NO,ksuid:()=>s3,ipv6:()=>zO,ipv4:()=>XO,integer:()=>BO,idnEmail:()=>D70,httpProtocol:()=>VO,html5Email:()=>x70,hostname:()=>N70,hex:()=>j70,guid:()=>$O,extendedDuration:()=>G70,emoji:()=>YO,email:()=>QO,e164:()=>wO,duration:()=>e3,domain:()=>P70,datetime:()=>JO,date:()=>GO,cuid2:()=>a3,cuid:()=>d3,cidrv6:()=>WO,cidrv4:()=>KO,browserEmail:()=>L70,boolean:()=>DO,bigint:()=>xO,base64url:()=>rq,base64:()=>HO});var d3=/^[cC][0-9a-z]{6,}$/,a3=/^[0-9a-z]+$/,o3=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,r3=/^[0-9a-vA-V]{20}$/,s3=/^[A-Za-z0-9]{27}$/,t3=/^[a-zA-Z0-9_-]{21}$/,e3=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,G70=/^[-+]?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)?)??$/,$O=/^([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})$/,gZ=($)=>{if(!$)return/^([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)$/;return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${$}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`)},U70=gZ(4),J70=gZ(6),q70=gZ(7),QO=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/,x70=/^[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])?)*$/,B70=/^(([^<>()\[\]\\.,;:\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,}))$/,io=/^[^\s@"]{1,64}@[^\s@]{1,255}$/u,D70=io,L70=/^[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])?)*$/,F70="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";function YO(){return new RegExp(F70,"u")}var XO=/^(?:(?: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])$/,zO=/^(([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}|:))$/,ZO=($)=>{let Q=F7($??":");return new RegExp(`^(?:[0-9A-F]{2}${Q}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${Q}){5}[0-9a-f]{2}$`)},KO=/^((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])$/,WO=/^(([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])$/,HO=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,rq=/^[A-Za-z0-9_-]*$/,N70=/^(?=.{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])?)*\.?$/,P70=/^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/,VO=/^https?$/,wO=/^\+[1-9]\d{6,14}$/,lo="(?:(?:\\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])))",GO=new RegExp(`^${lo}$`);function no($){return typeof $.precision==="number"?$.precision===-1?"(?:[01]\\d|2[0-3]):[0-5]\\d":$.precision===0?"(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d":`(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{${$.precision}}`:"(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?"}function UO($){return new RegExp(`^${no($)}$`)}function JO($){let Q=no({precision:$.precision}),Y=["Z"];if($.local)Y.push("");if($.offset)Y.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");let X=`${Q}(?:${Y.join("|")})`;return new RegExp(`^${lo}T(?:${X})$`)}var qO=($)=>{let Q=$?`[\\s\\S]{${$?.minimum??0},${$?.maximum??""}}`:"[\\s\\S]*";return new RegExp(`^${Q}$`)},xO=/^-?\d+n?$/,BO=/^-?\d+$/,vH=/^-?\d+(?:\.\d+)?$/,DO=/^(?:true|false)$/i,LO=/^null$/i;var FO=/^undefined$/i;var NO=/^[^A-Z]*$/,PO=/^[^a-z]*$/,j70=/^[0-9a-fA-F]*$/;function bH($,Q){return new RegExp(`^[A-Za-z0-9+/]{${$}}${Q}$`)}function _H($){return new RegExp(`^[A-Za-z0-9_-]{${$}}$`)}var I70=/^[0-9a-fA-F]{32}$/,M70=bH(22,"=="),O70=_H(22),v70=/^[0-9a-fA-F]{40}$/,b70=bH(27,"="),_70=_H(27),A70=/^[0-9a-fA-F]{64}$/,R70=bH(43,"="),T70=_H(43),f70=/^[0-9a-fA-F]{96}$/,k70=bH(64,""),S70=_H(64),E70=/^[0-9a-fA-F]{128}$/,C70=bH(86,"=="),u70=_H(86);var x6=y("$ZodCheck",($,Q)=>{var Y;$._zod??($._zod={}),$._zod.def=Q,(Y=$._zod).onattach??(Y.onattach=[])}),oo={number:"number",bigint:"bigint",object:"date"},sq=y("$ZodCheckLessThan",($,Q)=>{x6.init($,Q);let Y=oo[typeof Q.value];$._zod.onattach.push((X)=>{let z=X._zod.bag,Z=(Q.inclusive?z.maximum:z.exclusiveMaximum)??Number.POSITIVE_INFINITY;if(Q.value<Z)if(Q.inclusive)z.maximum=Q.value;else z.exclusiveMaximum=Q.value}),$._zod.check=(X)=>{if(Q.inclusive?X.value<=Q.value:X.value<Q.value)return;X.issues.push({origin:Y,code:"too_big",maximum:typeof Q.value==="object"?Q.value.getTime():Q.value,input:X.value,inclusive:Q.inclusive,inst:$,continue:!Q.abort})}}),tq=y("$ZodCheckGreaterThan",($,Q)=>{x6.init($,Q);let Y=oo[typeof Q.value];$._zod.onattach.push((X)=>{let z=X._zod.bag,Z=(Q.inclusive?z.minimum:z.exclusiveMinimum)??Number.NEGATIVE_INFINITY;if(Q.value>Z)if(Q.inclusive)z.minimum=Q.value;else z.exclusiveMinimum=Q.value}),$._zod.check=(X)=>{if(Q.inclusive?X.value>=Q.value:X.value>Q.value)return;X.issues.push({origin:Y,code:"too_small",minimum:typeof Q.value==="object"?Q.value.getTime():Q.value,input:X.value,inclusive:Q.inclusive,inst:$,continue:!Q.abort})}}),jO=y("$ZodCheckMultipleOf",($,Q)=>{x6.init($,Q),$._zod.onattach.push((Y)=>{var X;(X=Y._zod.bag).multipleOf??(X.multipleOf=Q.value)}),$._zod.check=(Y)=>{if(typeof Y.value!==typeof Q.value)throw Error("Cannot mix number and bigint in multiple_of check.");if(typeof Y.value==="bigint"?Y.value%Q.value===BigInt(0):S3(Y.value,Q.value)===0)return;Y.issues.push({origin:typeof Y.value,code:"not_multiple_of",divisor:Q.value,input:Y.value,inst:$,continue:!Q.abort})}}),IO=y("$ZodCheckNumberFormat",($,Q)=>{x6.init($,Q),Q.format=Q.format||"float64";let Y=Q.format?.includes("int"),X=Y?"int":"number",[z,Z]=g3[Q.format];$._zod.onattach.push((K)=>{let W=K._zod.bag;if(W.format=Q.format,W.minimum=z,W.maximum=Z,Y)W.pattern=BO}),$._zod.check=(K)=>{let W=K.value;if(Y){if(!Number.isInteger(W)){K.issues.push({expected:X,format:Q.format,code:"invalid_type",continue:!1,input:W,inst:$});return}if(!Number.isSafeInteger(W)){if(W>0)K.issues.push({input:W,code:"too_big",maximum:Number.MAX_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:$,origin:X,inclusive:!0,continue:!Q.abort});else K.issues.push({input:W,code:"too_small",minimum:Number.MIN_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:$,origin:X,inclusive:!0,continue:!Q.abort});return}}if(W<z)K.issues.push({origin:"number",input:W,code:"too_small",minimum:z,inclusive:!0,inst:$,continue:!Q.abort});if(W>Z)K.issues.push({origin:"number",input:W,code:"too_big",maximum:Z,inclusive:!0,inst:$,continue:!Q.abort})}}),MO=y("$ZodCheckBigIntFormat",($,Q)=>{x6.init($,Q);let[Y,X]=h3[Q.format];$._zod.onattach.push((z)=>{let Z=z._zod.bag;Z.format=Q.format,Z.minimum=Y,Z.maximum=X}),$._zod.check=(z)=>{let Z=z.value;if(Z<Y)z.issues.push({origin:"bigint",input:Z,code:"too_small",minimum:Y,inclusive:!0,inst:$,continue:!Q.abort});if(Z>X)z.issues.push({origin:"bigint",input:Z,code:"too_big",maximum:X,inclusive:!0,inst:$,continue:!Q.abort})}}),OO=y("$ZodCheckMaxSize",($,Q)=>{var Y;x6.init($,Q),(Y=$._zod.def).when??(Y.when=(X)=>{let z=X.value;return!oX(z)&&z.size!==void 0}),$._zod.onattach.push((X)=>{let z=X._zod.bag.maximum??Number.POSITIVE_INFINITY;if(Q.maximum<z)X._zod.bag.maximum=Q.maximum}),$._zod.check=(X)=>{let z=X.value;if(z.size<=Q.maximum)return;X.issues.push({origin:PH(z),code:"too_big",maximum:Q.maximum,inclusive:!0,input:z,inst:$,continue:!Q.abort})}}),vO=y("$ZodCheckMinSize",($,Q)=>{var Y;x6.init($,Q),(Y=$._zod.def).when??(Y.when=(X)=>{let z=X.value;return!oX(z)&&z.size!==void 0}),$._zod.onattach.push((X)=>{let z=X._zod.bag.minimum??Number.NEGATIVE_INFINITY;if(Q.minimum>z)X._zod.bag.minimum=Q.minimum}),$._zod.check=(X)=>{let z=X.value;if(z.size>=Q.minimum)return;X.issues.push({origin:PH(z),code:"too_small",minimum:Q.minimum,inclusive:!0,input:z,inst:$,continue:!Q.abort})}}),bO=y("$ZodCheckSizeEquals",($,Q)=>{var Y;x6.init($,Q),(Y=$._zod.def).when??(Y.when=(X)=>{let z=X.value;return!oX(z)&&z.size!==void 0}),$._zod.onattach.push((X)=>{let z=X._zod.bag;z.minimum=Q.size,z.maximum=Q.size,z.size=Q.size}),$._zod.check=(X)=>{let z=X.value,Z=z.size;if(Z===Q.size)return;let K=Z>Q.size;X.issues.push({origin:PH(z),...K?{code:"too_big",maximum:Q.size}:{code:"too_small",minimum:Q.size},inclusive:!0,exact:!0,input:X.value,inst:$,continue:!Q.abort})}}),_O=y("$ZodCheckMaxLength",($,Q)=>{var Y;x6.init($,Q),(Y=$._zod.def).when??(Y.when=(X)=>{let z=X.value;return!oX(z)&&z.length!==void 0}),$._zod.onattach.push((X)=>{let z=X._zod.bag.maximum??Number.POSITIVE_INFINITY;if(Q.maximum<z)X._zod.bag.maximum=Q.maximum}),$._zod.check=(X)=>{let z=X.value;if(z.length<=Q.maximum)return;let K=jH(z);X.issues.push({origin:K,code:"too_big",maximum:Q.maximum,inclusive:!0,input:z,inst:$,continue:!Q.abort})}}),AO=y("$ZodCheckMinLength",($,Q)=>{var Y;x6.init($,Q),(Y=$._zod.def).when??(Y.when=(X)=>{let z=X.value;return!oX(z)&&z.length!==void 0}),$._zod.onattach.push((X)=>{let z=X._zod.bag.minimum??Number.NEGATIVE_INFINITY;if(Q.minimum>z)X._zod.bag.minimum=Q.minimum}),$._zod.check=(X)=>{let z=X.value;if(z.length>=Q.minimum)return;let K=jH(z);X.issues.push({origin:K,code:"too_small",minimum:Q.minimum,inclusive:!0,input:z,inst:$,continue:!Q.abort})}}),RO=y("$ZodCheckLengthEquals",($,Q)=>{var Y;x6.init($,Q),(Y=$._zod.def).when??(Y.when=(X)=>{let z=X.value;return!oX(z)&&z.length!==void 0}),$._zod.onattach.push((X)=>{let z=X._zod.bag;z.minimum=Q.length,z.maximum=Q.length,z.length=Q.length}),$._zod.check=(X)=>{let z=X.value,Z=z.length;if(Z===Q.length)return;let K=jH(z),W=Z>Q.length;X.issues.push({origin:K,...W?{code:"too_big",maximum:Q.length}:{code:"too_small",minimum:Q.length},inclusive:!0,exact:!0,input:X.value,inst:$,continue:!Q.abort})}}),s4=y("$ZodCheckStringFormat",($,Q)=>{var Y,X;if(x6.init($,Q),$._zod.onattach.push((z)=>{let Z=z._zod.bag;if(Z.format=Q.format,Q.pattern)Z.patterns??(Z.patterns=new Set),Z.patterns.add(Q.pattern)}),Q.pattern)(Y=$._zod).check??(Y.check=(z)=>{if(Q.pattern.lastIndex=0,Q.pattern.test(z.value))return;z.issues.push({origin:"string",code:"invalid_format",format:Q.format,input:z.value,...Q.pattern?{pattern:Q.pattern.toString()}:{},inst:$,continue:!Q.abort})});else(X=$._zod).check??(X.check=()=>{})}),TO=y("$ZodCheckRegex",($,Q)=>{s4.init($,Q),$._zod.check=(Y)=>{if(Q.pattern.lastIndex=0,Q.pattern.test(Y.value))return;Y.issues.push({origin:"string",code:"invalid_format",format:"regex",input:Y.value,pattern:Q.pattern.toString(),inst:$,continue:!Q.abort})}}),fO=y("$ZodCheckLowerCase",($,Q)=>{Q.pattern??(Q.pattern=NO),s4.init($,Q)}),kO=y("$ZodCheckUpperCase",($,Q)=>{Q.pattern??(Q.pattern=PO),s4.init($,Q)}),SO=y("$ZodCheckIncludes",($,Q)=>{x6.init($,Q);let Y=F7(Q.includes),X=new RegExp(typeof Q.position==="number"?`^.{${Q.position}}${Y}`:Y);Q.pattern=X,$._zod.onattach.push((z)=>{let Z=z._zod.bag;Z.patterns??(Z.patterns=new Set),Z.patterns.add(X)}),$._zod.check=(z)=>{if(z.value.includes(Q.includes,Q.position))return;z.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:Q.includes,input:z.value,inst:$,continue:!Q.abort})}}),EO=y("$ZodCheckStartsWith",($,Q)=>{x6.init($,Q);let Y=new RegExp(`^${F7(Q.prefix)}.*`);Q.pattern??(Q.pattern=Y),$._zod.onattach.push((X)=>{let z=X._zod.bag;z.patterns??(z.patterns=new Set),z.patterns.add(Y)}),$._zod.check=(X)=>{if(X.value.startsWith(Q.prefix))return;X.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:Q.prefix,input:X.value,inst:$,continue:!Q.abort})}}),CO=y("$ZodCheckEndsWith",($,Q)=>{x6.init($,Q);let Y=new RegExp(`.*${F7(Q.suffix)}$`);Q.pattern??(Q.pattern=Y),$._zod.onattach.push((X)=>{let z=X._zod.bag;z.patterns??(z.patterns=new Set),z.patterns.add(Y)}),$._zod.check=(X)=>{if(X.value.endsWith(Q.suffix))return;X.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:Q.suffix,input:X.value,inst:$,continue:!Q.abort})}});function ao($,Q,Y){if($.issues.length)Q.issues.push(...v9(Y,$.issues))}var uO=y("$ZodCheckProperty",($,Q)=>{x6.init($,Q),$._zod.check=(Y)=>{let X=Q.schema._zod.run({value:Y.value[Q.property],issues:[]},{});if(X instanceof Promise)return X.then((z)=>ao(z,Y,Q.property));ao(X,Y,Q.property);return}}),cO=y("$ZodCheckMimeType",($,Q)=>{x6.init($,Q);let Y=new Set(Q.mime);$._zod.onattach.push((X)=>{X._zod.bag.mime=Q.mime}),$._zod.check=(X)=>{if(Y.has(X.value.type))return;X.issues.push({code:"invalid_value",values:Q.mime,input:X.value.type,inst:$,continue:!Q.abort})}}),yO=y("$ZodCheckOverwrite",($,Q)=>{x6.init($,Q),$._zod.check=(Y)=>{Y.value=Q.tx(Y.value)}});class eq{constructor($=[]){if(this.content=[],this.indent=0,this)this.args=$}indented($){this.indent+=1,$(this),this.indent-=1}write($){if(typeof $==="function"){$(this,{execution:"sync"}),$(this,{execution:"async"});return}let Y=$.split(`
611
611
  `).filter((Z)=>Z),X=Math.min(...Y.map((Z)=>Z.length-Z.trimStart().length)),z=Y.map((Z)=>Z.slice(X)).map((Z)=>" ".repeat(this.indent*2)+Z);for(let Z of z)this.content.push(Z)}compile(){let $=Function,Q=this?.args,X=[...(this?.content??[""]).map((z)=>` ${z}`)];return new $(...Q,X.join(`
612
612
  `))}}var gO={major:4,minor:4,patch:3};var K0=y("$ZodType",($,Q)=>{var Y;$??($={}),$._zod.def=Q,$._zod.bag=$._zod.bag||{},$._zod.version=gO;let X=[...$._zod.def.checks??[]];if($._zod.traits.has("$ZodCheck"))X.unshift($);for(let z of X)for(let Z of z._zod.onattach)Z($);if(X.length===0)(Y=$._zod).deferred??(Y.deferred=[]),$._zod.deferred?.push(()=>{$._zod.run=$._zod.parse});else{let z=(K,W,H)=>{let V=tX(K),w;for(let G of W){if(G._zod.def.when){if(m3(K))continue;if(!G._zod.def.when(K))continue}else if(V)continue;let U=K.issues.length,J=G._zod.check(K);if(J instanceof Promise&&H?.async===!1)throw new yQ;if(w||J instanceof Promise)w=(w??Promise.resolve()).then(async()=>{if(await J,K.issues.length===U)return;if(!V)V=tX(K,U)});else{if(K.issues.length===U)continue;if(!V)V=tX(K,U)}}if(w)return w.then(()=>{return K});return K},Z=(K,W,H)=>{if(tX(K))return K.aborted=!0,K;let V=z(W,X,H);if(V instanceof Promise){if(H.async===!1)throw new yQ;return V.then((w)=>$._zod.parse(w,H))}return $._zod.parse(V,H)};$._zod.run=(K,W)=>{if(W.skipChecks)return $._zod.parse(K,W);if(W.direction==="backward"){let V=$._zod.parse({value:K.value,issues:[]},{...W,skipChecks:!0});if(V instanceof Promise)return V.then((w)=>{return Z(w,K,W)});return Z(V,K,W)}let H=$._zod.parse(K,W);if(H instanceof Promise){if(W.async===!1)throw new yQ;return H.then((V)=>z(V,X,W))}return z(H,X,W)}}M0($,"~standard",()=>({validate:(z)=>{try{let Z=l3($,z);return Z.success?{value:Z.data}:{issues:Z.error?.issues}}catch(Z){return n3($,z).then((K)=>K.success?{value:K.data}:{issues:K.error?.issues})}},vendor:"zod",version:1}))}),hZ=y("$ZodString",($,Q)=>{K0.init($,Q),$._zod.pattern=[...$?._zod.bag?.patterns??[]].pop()??qO($._zod.bag),$._zod.parse=(Y,X)=>{if(Q.coerce)try{Y.value=String(Y.value)}catch(z){}if(typeof Y.value==="string")return Y;return Y.issues.push({expected:"string",code:"invalid_type",input:Y.value,inst:$}),Y}}),H6=y("$ZodStringFormat",($,Q)=>{s4.init($,Q),hZ.init($,Q)}),mO=y("$ZodGUID",($,Q)=>{Q.pattern??(Q.pattern=$O),H6.init($,Q)}),pO=y("$ZodUUID",($,Q)=>{if(Q.version){let X={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[Q.version];if(X===void 0)throw Error(`Invalid UUID version: "${Q.version}"`);Q.pattern??(Q.pattern=gZ(X))}else Q.pattern??(Q.pattern=gZ());H6.init($,Q)}),iO=y("$ZodEmail",($,Q)=>{Q.pattern??(Q.pattern=QO),H6.init($,Q)}),lO=y("$ZodURL",($,Q)=>{H6.init($,Q),$._zod.check=(Y)=>{try{let X=Y.value.trim();if(!Q.normalize&&Q.protocol?.source===VO.source){if(!/^https?:\/\//i.test(X)){Y.issues.push({code:"invalid_format",format:"url",note:"Invalid URL format",input:Y.value,inst:$,continue:!Q.abort});return}}let z=new URL(X);if(Q.hostname){if(Q.hostname.lastIndex=0,!Q.hostname.test(z.hostname))Y.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:Q.hostname.source,input:Y.value,inst:$,continue:!Q.abort})}if(Q.protocol){if(Q.protocol.lastIndex=0,!Q.protocol.test(z.protocol.endsWith(":")?z.protocol.slice(0,-1):z.protocol))Y.issues.push({code:"invalid_format",format:"url",note:"Invalid protocol",pattern:Q.protocol.source,input:Y.value,inst:$,continue:!Q.abort})}if(Q.normalize)Y.value=z.href;else Y.value=X;return}catch(X){Y.issues.push({code:"invalid_format",format:"url",input:Y.value,inst:$,continue:!Q.abort})}}}),nO=y("$ZodEmoji",($,Q)=>{Q.pattern??(Q.pattern=YO()),H6.init($,Q)}),dO=y("$ZodNanoID",($,Q)=>{Q.pattern??(Q.pattern=t3),H6.init($,Q)}),aO=y("$ZodCUID",($,Q)=>{Q.pattern??(Q.pattern=d3),H6.init($,Q)}),oO=y("$ZodCUID2",($,Q)=>{Q.pattern??(Q.pattern=a3),H6.init($,Q)}),rO=y("$ZodULID",($,Q)=>{Q.pattern??(Q.pattern=o3),H6.init($,Q)}),sO=y("$ZodXID",($,Q)=>{Q.pattern??(Q.pattern=r3),H6.init($,Q)}),tO=y("$ZodKSUID",($,Q)=>{Q.pattern??(Q.pattern=s3),H6.init($,Q)}),eO=y("$ZodISODateTime",($,Q)=>{Q.pattern??(Q.pattern=JO(Q)),H6.init($,Q)}),$v=y("$ZodISODate",($,Q)=>{Q.pattern??(Q.pattern=GO),H6.init($,Q)}),Qv=y("$ZodISOTime",($,Q)=>{Q.pattern??(Q.pattern=UO(Q)),H6.init($,Q)}),Yv=y("$ZodISODuration",($,Q)=>{Q.pattern??(Q.pattern=e3),H6.init($,Q)}),Xv=y("$ZodIPv4",($,Q)=>{Q.pattern??(Q.pattern=XO),H6.init($,Q),$._zod.bag.format="ipv4"}),zv=y("$ZodIPv6",($,Q)=>{Q.pattern??(Q.pattern=zO),H6.init($,Q),$._zod.bag.format="ipv6",$._zod.check=(Y)=>{try{new URL(`http://[${Y.value}]`)}catch{Y.issues.push({code:"invalid_format",format:"ipv6",input:Y.value,inst:$,continue:!Q.abort})}}}),Zv=y("$ZodMAC",($,Q)=>{Q.pattern??(Q.pattern=ZO(Q.delimiter)),H6.init($,Q),$._zod.bag.format="mac"}),Kv=y("$ZodCIDRv4",($,Q)=>{Q.pattern??(Q.pattern=KO),H6.init($,Q)}),Wv=y("$ZodCIDRv6",($,Q)=>{Q.pattern??(Q.pattern=WO),H6.init($,Q),$._zod.check=(Y)=>{let X=Y.value.split("/");try{if(X.length!==2)throw Error();let[z,Z]=X;if(!Z)throw Error();let K=Number(Z);if(`${K}`!==Z)throw Error();if(K<0||K>128)throw Error();new URL(`http://[${z}]`)}catch{Y.issues.push({code:"invalid_format",format:"cidrv6",input:Y.value,inst:$,continue:!Q.abort})}}});function Hv($){if($==="")return!0;if(/\s/.test($))return!1;if($.length%4!==0)return!1;try{return atob($),!0}catch{return!1}}var Vv=y("$ZodBase64",($,Q)=>{Q.pattern??(Q.pattern=HO),H6.init($,Q),$._zod.bag.contentEncoding="base64",$._zod.check=(Y)=>{if(Hv(Y.value))return;Y.issues.push({code:"invalid_format",format:"base64",input:Y.value,inst:$,continue:!Q.abort})}});function Gr($){if(!rq.test($))return!1;let Q=$.replace(/[-_]/g,(X)=>X==="-"?"+":"/"),Y=Q.padEnd(Math.ceil(Q.length/4)*4,"=");return Hv(Y)}var wv=y("$ZodBase64URL",($,Q)=>{Q.pattern??(Q.pattern=rq),H6.init($,Q),$._zod.bag.contentEncoding="base64url",$._zod.check=(Y)=>{if(Gr(Y.value))return;Y.issues.push({code:"invalid_format",format:"base64url",input:Y.value,inst:$,continue:!Q.abort})}}),Gv=y("$ZodE164",($,Q)=>{Q.pattern??(Q.pattern=wO),H6.init($,Q)});function Ur($,Q=null){try{let Y=$.split(".");if(Y.length!==3)return!1;let[X]=Y;if(!X)return!1;let z=JSON.parse(atob(X));if("typ"in z&&z?.typ!=="JWT")return!1;if(!z.alg)return!1;if(Q&&(!("alg"in z)||z.alg!==Q))return!1;return!0}catch{return!1}}var Uv=y("$ZodJWT",($,Q)=>{H6.init($,Q),$._zod.check=(Y)=>{if(Ur(Y.value,Q.alg))return;Y.issues.push({code:"invalid_format",format:"jwt",input:Y.value,inst:$,continue:!Q.abort})}}),Jv=y("$ZodCustomStringFormat",($,Q)=>{H6.init($,Q),$._zod.check=(Y)=>{if(Q.fn(Y.value))return;Y.issues.push({code:"invalid_format",format:Q.format,input:Y.value,inst:$,continue:!Q.abort})}}),zx=y("$ZodNumber",($,Q)=>{K0.init($,Q),$._zod.pattern=$._zod.bag.pattern??vH,$._zod.parse=(Y,X)=>{if(Q.coerce)try{Y.value=Number(Y.value)}catch(K){}let z=Y.value;if(typeof z==="number"&&!Number.isNaN(z)&&Number.isFinite(z))return Y;let Z=typeof z==="number"?Number.isNaN(z)?"NaN":!Number.isFinite(z)?"Infinity":void 0:void 0;return Y.issues.push({expected:"number",code:"invalid_type",input:z,inst:$,...Z?{received:Z}:{}}),Y}}),qv=y("$ZodNumberFormat",($,Q)=>{IO.init($,Q),zx.init($,Q)}),AH=y("$ZodBoolean",($,Q)=>{K0.init($,Q),$._zod.pattern=DO,$._zod.parse=(Y,X)=>{if(Q.coerce)try{Y.value=Boolean(Y.value)}catch(Z){}let z=Y.value;if(typeof z==="boolean")return Y;return Y.issues.push({expected:"boolean",code:"invalid_type",input:z,inst:$}),Y}}),Zx=y("$ZodBigInt",($,Q)=>{K0.init($,Q),$._zod.pattern=xO,$._zod.parse=(Y,X)=>{if(Q.coerce)try{Y.value=BigInt(Y.value)}catch(z){}if(typeof Y.value==="bigint")return Y;return Y.issues.push({expected:"bigint",code:"invalid_type",input:Y.value,inst:$}),Y}}),xv=y("$ZodBigIntFormat",($,Q)=>{MO.init($,Q),Zx.init($,Q)}),Bv=y("$ZodSymbol",($,Q)=>{K0.init($,Q),$._zod.parse=(Y,X)=>{let z=Y.value;if(typeof z==="symbol")return Y;return Y.issues.push({expected:"symbol",code:"invalid_type",input:z,inst:$}),Y}}),Dv=y("$ZodUndefined",($,Q)=>{K0.init($,Q),$._zod.pattern=FO,$._zod.values=new Set([void 0]),$._zod.parse=(Y,X)=>{let z=Y.value;if(typeof z>"u")return Y;return Y.issues.push({expected:"undefined",code:"invalid_type",input:z,inst:$}),Y}}),Lv=y("$ZodNull",($,Q)=>{K0.init($,Q),$._zod.pattern=LO,$._zod.values=new Set([null]),$._zod.parse=(Y,X)=>{let z=Y.value;if(z===null)return Y;return Y.issues.push({expected:"null",code:"invalid_type",input:z,inst:$}),Y}}),Fv=y("$ZodAny",($,Q)=>{K0.init($,Q),$._zod.parse=(Y)=>Y}),Nv=y("$ZodUnknown",($,Q)=>{K0.init($,Q),$._zod.parse=(Y)=>Y}),Pv=y("$ZodNever",($,Q)=>{K0.init($,Q),$._zod.parse=(Y,X)=>{return Y.issues.push({expected:"never",code:"invalid_type",input:Y.value,inst:$}),Y}}),jv=y("$ZodVoid",($,Q)=>{K0.init($,Q),$._zod.parse=(Y,X)=>{let z=Y.value;if(typeof z>"u")return Y;return Y.issues.push({expected:"void",code:"invalid_type",input:z,inst:$}),Y}}),Iv=y("$ZodDate",($,Q)=>{K0.init($,Q),$._zod.parse=(Y,X)=>{if(Q.coerce)try{Y.value=new Date(Y.value)}catch(W){}let z=Y.value,Z=z instanceof Date;if(Z&&!Number.isNaN(z.getTime()))return Y;return Y.issues.push({expected:"date",code:"invalid_type",input:z,...Z?{received:"Invalid Date"}:{},inst:$}),Y}});function so($,Q,Y){if($.issues.length)Q.issues.push(...v9(Y,$.issues));Q.value[Y]=$.value}var Mv=y("$ZodArray",($,Q)=>{K0.init($,Q),$._zod.parse=(Y,X)=>{let z=Y.value;if(!Array.isArray(z))return Y.issues.push({expected:"array",code:"invalid_type",input:z,inst:$}),Y;Y.value=Array(z.length);let Z=[];for(let K=0;K<z.length;K++){let W=z[K],H=Q.element._zod.run({value:W,issues:[]},X);if(H instanceof Promise)Z.push(H.then((V)=>so(V,Y,K)));else so(H,Y,K)}if(Z.length)return Promise.all(Z).then(()=>Y);return Y}});function Xx($,Q,Y,X,z,Z){let K=Y in X;if($.issues.length){if(z&&Z&&!K)return;Q.issues.push(...v9(Y,$.issues))}if(!K&&!z){if(!$.issues.length)Q.issues.push({code:"invalid_type",expected:"nonoptional",input:void 0,path:[Y]});return}if($.value===void 0){if(K)Q.value[Y]=void 0}else Q.value[Y]=$.value}function Jr($){let Q=Object.keys($.shape);for(let X of Q)if(!$.shape?.[X]?._zod?.traits?.has("$ZodType"))throw Error(`Invalid element at key "${X}": expected a Zod schema`);let Y=y3($.shape);return{...$,keys:Q,keySet:new Set(Q),numKeys:Q.length,optionalKeys:new Set(Y)}}function qr($,Q,Y,X,z,Z){let K=[],W=z.keySet,H=z.catchall._zod,V=H.def.type,w=H.optin==="optional",G=H.optout==="optional";for(let U in Q){if(U==="__proto__")continue;if(W.has(U))continue;if(V==="never"){K.push(U);continue}let J=H.run({value:Q[U],issues:[]},X);if(J instanceof Promise)$.push(J.then((x)=>Xx(x,Y,U,Q,w,G)));else Xx(J,Y,U,Q,w,G)}if(K.length)Y.issues.push({code:"unrecognized_keys",keys:K,input:Q,inst:Z});if(!$.length)return Y;return Promise.all($).then(()=>{return Y})}var xr=y("$ZodObject",($,Q)=>{if(K0.init($,Q),!Object.getOwnPropertyDescriptor(Q,"shape")?.get){let W=Q.shape;Object.defineProperty(Q,"shape",{get:()=>{let H={...W};return Object.defineProperty(Q,"shape",{value:H}),H}})}let X=l4(()=>Jr(Q));M0($._zod,"propValues",()=>{let W=Q.shape,H={};for(let V in W){let w=W[V]._zod;if(w.values){H[V]??(H[V]=new Set);for(let G of w.values)H[V].add(G)}}return H});let z=yZ,Z=Q.catchall,K;$._zod.parse=(W,H)=>{K??(K=X.value);let V=W.value;if(!z(V))return W.issues.push({expected:"object",code:"invalid_type",input:V,inst:$}),W;W.value={};let w=[],G=K.shape;for(let U of K.keys){let J=G[U],x=J._zod.optin==="optional",D=J._zod.optout==="optional",B=J._zod.run({value:V[U],issues:[]},H);if(B instanceof Promise)w.push(B.then((L)=>Xx(L,W,U,V,x,D)));else Xx(B,W,U,V,x,D)}if(!Z)return w.length?Promise.all(w).then(()=>W):W;return qr(w,V,W,H,X.value,$)}}),Ov=y("$ZodObjectJIT",($,Q)=>{xr.init($,Q);let Y=$._zod.parse,X=l4(()=>Jr(Q)),z=(U)=>{let J=new eq(["shape","payload","ctx"]),x=X.value,D=(F)=>{let I=cq(F);return`shape[${I}]._zod.run({ value: input[${I}], issues: [] }, ctx)`};J.write("const input = payload.value;");let B=Object.create(null),L=0;for(let F of x.keys)B[F]=`key_${L++}`;J.write("const newResult = {};");for(let F of x.keys){let I=B[F],M=cq(F),c=U[F],e=c?._zod?.optin==="optional",p=c?._zod?.optout==="optional";if(J.write(`const ${I} = ${D(F)};`),e&&p)J.write(`
@@ -2016,9 +2016,9 @@ Runs "bun i -g @interactive-inc/claude-funnel".
2016
2016
 
2017
2017
  This command has no programmable equivalent \u2014 package management belongs to
2018
2018
  the host (npm / bun / yarn install in the host's own way).`,Y80="@interactive-inc/claude-funnel",X80=$1.createHandlers(a1(mR6),async($)=>{let Y=await new p8().attach(["bun","i","-g",Y80]);if(Y!==0)throw new Q0(500,{message:`update failed (exit ${Y})`});return $.text(`updated ${Y80}`)});var Za=$1.createApp().onError(($,Q)=>{if($ instanceof Q0)return Q.text($.message,$.status);return Q.text(`error: ${$ instanceof Error?$.message:String($)}`,400)}).get("/claude",...qt).get("/channels",...F60).post("/channels/add",...d00).post("/channels/add/:channel",...a00).post("/channels/remove",...J60).post("/channels/remove/:channel",...q60).post("/channels/rename/:channel/:newName",...sd).post("/channels/:channel/rename/:newName",...sd).post("/channels/rename",...x60).post("/channels/:channel/rename",...B60).post("/channels/:channel/set/delivery/:mode",...D60).post("/channels/publish",...G60).post("/channels/:channel/publish",...U60).get("/channels/:channel/validate",...P60).get("/channels/validate",...N60).get("/channels/:channel",...L60).get("/channels/:channel/connectors",...o00).post("/channels/:channel/connectors/add",...r00).post("/channels/:channel/connectors/add/:connector",...s00).post("/channels/:channel/connectors/remove",...t00).post("/channels/:channel/connectors/remove/:connector",...e00).post("/channels/:channel/connectors/set",...$60).post("/channels/:channel/connectors/set/:connector",...Q60).post("/channels/:channel/connectors/rename/:connector/:newName",...od).post("/channels/:channel/connectors/:connector/rename/:newName",...od).post("/channels/:channel/connectors/rename",...X60).post("/channels/:channel/connectors/:connector/rename",...z60).post("/channels/:channel/connectors/:connector/request",...Z60).get("/channels/:channel/connectors/:connector",...Y60).get("/channels/:channel/connectors/:connector/schedules",...K60).post("/channels/:channel/connectors/:connector/schedules/add",...W60).post("/channels/:channel/connectors/:connector/schedules/add/:id",...H60).post("/channels/:channel/connectors/:connector/schedules/remove",...V60).post("/channels/:channel/connectors/:connector/schedules/remove/:id",...w60).get("/profiles",...s60).post("/profiles/add",...m60).post("/profiles/add/:profile",...p60).post("/profiles/set",...o60).post("/profiles/set/:profile",...r60).post("/profiles/remove",...d60).post("/profiles/remove/:profile",...a60).post("/profiles/rename/:profile/:newName",...Xa).post("/profiles/:profile/rename/:newName",...Xa).post("/profiles/rename",...l60).post("/profiles/:profile/rename",...n60).post("/profiles/:profile/as-default",...i60).get("/profiles/:profile/run",...za).get("/profiles/:profile",...za).get("/gateway",...R60).get("/gateway/status",...g60).get("/gateway/start",...y60).get("/gateway/stop",...h60).get("/gateway/restart",...C60).get("/gateway/run",...u60).get("/gateway/logs",...k60).get("/gateway/sql",...E60).get("/gateway/listeners",...T60).get("/debug",...j60).get("/debug/events",...I60).get("/debug/dropped",...M60).get("/debug/errors",...O60).get("/debug/replay",...v60).get("/docs",...b60).get("/docs/:topic",..._60).get("/doctor",...A60).get("/schema",...e60).get("/status",...Q80).get("/update",...X80);import{join as pR6}from"path";class Lq{fs;constructor($){this.fs=$.fs,Object.freeze(this)}read($){let Q=pR6($,AZ);if(!this.fs.existsSync(Q))return null;let Y=this.fs.readFileSync(Q),X=(()=>{try{return JSON.parse(Y)}catch(Z){let K=Z instanceof Error?Z.message:String(Z);throw Error(`${AZ} is not valid JSON: ${K}`)}})(),z=gM.safeParse(X);if(!z.success)throw Error(`${AZ} is invalid: ${z.error.message}`);return this.assertProfilesValid(z.data),z.data}assertProfilesValid($){let Q=$.profiles??[];if(Q.length===0)return;let Y=new Set($.channels.map((z)=>z.name)),X=new Set;for(let z of Q){if(!Y.has(z.channel))throw Error(`${AZ} is invalid: profile "${z.name}" binds channel "${z.channel}", which is not declared in channels[]`);if(X.has(z.name))throw Error(`${AZ} is invalid: more than one profile is named "${z.name}" \u2014 names must be unique`);X.add(z.name)}}}import{join as iR6}from"path";var lR6=($)=>{return typeof $==="object"&&$!==null&&!Array.isArray($)},nR6=($,Q)=>{let Y={};if($.$schema!==void 0)Y.$schema=$.$schema;Y.id=Q;for(let X of Object.keys($)){if(X==="$schema"||X==="id")continue;Y[X]=$[X]}return Y};class Ka{fs;constructor($){this.fs=$.fs,Object.freeze(this)}ensureId($,Q){let Y=iR6($,AZ);if(!this.fs.existsSync(Y))return;let X=JSON.parse(this.fs.readFileSync(Y));if(!lR6(X))return;if(typeof X.id==="string"&&X.id!=="")return;let z=nR6(X,Q);this.fs.writeFileSync(Y,`${JSON.stringify(z,null,2)}
2019
- `)}}import{join as Of6}from"path";var z80=($,Q)=>{return $=$.replace(/\/+$/,""),$=$+"/",Q=Q.replace(/^\/+/,""),$+Q},mM=($,Q)=>{for(let[Y,X]of Object.entries(Q)){let z=new RegExp("/:"+Y+"(?:{[^/]+})?\\??");$=$.replace(z,X?`/${X}`:"")}return $},Z80=($)=>{let Q=new URLSearchParams;for(let[Y,X]of Object.entries($)){if(X===void 0)continue;if(Array.isArray(X))for(let z of X)Q.append(Y,z);else Q.set(Y,X)}return Q},K80=($,Q)=>{switch(Q){case"ws":return $.replace(/^http/,"ws");case"http":return $.replace(/^ws/,"http")}},Wa=($)=>{if(/^https?:\/\/[^\/]+?\/index(?=\?|$)/.test($))return $.replace(/\/index(?=\?|$)/,"/");return $.replace(/\/index(?=\?|$)/,"")};function hM($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function Ha($,Q){if(!hM($)&&!hM(Q))return Q;let Y={...$};for(let X in Q){let z=Q[X];if(hM(Y[X])&&hM(z))Y[X]=Ha(Y[X],z);else Y[X]=z}return Y}var W80=($,Q)=>{return new Proxy(()=>{},{get(X,z){if(typeof z!=="string"||z==="then")return;return W80($,[...Q,z])},apply(X,z,Z){return $({path:Q,args:Z})}})},aR6=class{url;method;buildSearchParams;queryParams=void 0;pathParams={};rBody;cType=void 0;constructor($,Q,Y){this.url=$,this.method=Q,this.buildSearchParams=Y.buildSearchParams}fetch=async($,Q)=>{if($){if($.query)this.queryParams=this.buildSearchParams($.query);if($.form){let W=new FormData;for(let[H,V]of Object.entries($.form)){if(V===void 0)continue;if(Array.isArray(V))for(let w of V)W.append(H,w);else W.append(H,V)}this.rBody=W}if($.json)this.rBody=JSON.stringify($.json),this.cType="application/json";if($.param)this.pathParams=$.param}let Y=this.method.toUpperCase(),X={...$?.header,...typeof Q?.headers==="function"?await Q.headers():Q?.headers};if($?.cookie){let W=[];for(let[H,V]of Object.entries($.cookie))W.push(cR(H,V,{path:"/"}));X.Cookie=W.join(",")}if(this.cType)X["Content-Type"]=this.cType;let z=new Headers(X??void 0),Z=this.url;if(Z=Wa(Z),Z=mM(Z,this.pathParams),this.queryParams)Z=Z+"?"+this.queryParams.toString();Y=this.method.toUpperCase();let K=!(Y==="GET"||Y==="HEAD");return(Q?.fetch||fetch)(Z,{body:K?this.rBody:void 0,method:Y,headers:z,...Q?.init})}},Va=($,Q)=>W80(function Y(X){let z=Q?.buildSearchParams??Z80,Z=[...X.path],K=Z.slice(-3).reverse();if(K[0]==="toString"){if(K[1]==="name")return K[2]||"";return Y.toString()}if(K[0]==="valueOf"){if(K[1]==="name")return K[2]||"";return Y}let W="";if(/^\$/.test(K[0])){let G=Z.pop();if(G)W=G.replace(/^\$/,"")}let H=Z.join("/"),V=z80($,H);if(W==="url"||W==="path"){let G=V;if(X.args[0]){if(X.args[0].param)G=mM(V,X.args[0].param);if(X.args[0].query)G=G+"?"+z(X.args[0].query).toString()}if(G=Wa(G),W==="url")return new URL(G);return G.slice($.replace(/\/+$/,"").length).replace(/^\/?/,"/")}if(W==="ws"){let G=K80(X.args[0]&&X.args[0].param?mM(V,X.args[0].param):V,"ws"),U=new URL(G),J=X.args[0]?.query;if(J)Object.entries(J).forEach(([D,B])=>{if(Array.isArray(B))B.forEach((L)=>U.searchParams.append(D,L));else U.searchParams.set(D,B)});return((...D)=>{if(Q?.webSocket!==void 0&&typeof Q.webSocket==="function")return Q.webSocket(...D);return new WebSocket(...D)})(U.toString())}let w=new aR6(V,W,{buildSearchParams:z});if(W){Q??={};let G=Ha(Q,{...X.args[1]});return w.fetch(X.args[0],G)}return w},[]);import{join as H80}from"path";var oR6=new N8,rR6=new p8;class wa{descriptors;fs;process;logger;diagnosticLog;dir;constructor($){this.descriptors=new Map($.descriptors.map((Q)=>[Q.type,Q])),this.fs=$.fs??oR6,this.process=$.process??rR6,this.logger=$.logger,this.diagnosticLog=$.diagnosticLog,this.dir=$.dir??SQ,Object.freeze(this)}has($){return this.descriptors.has($)}types(){return[...this.descriptors.keys()]}createListener($,Q){return this.require(Q.type).createListener(Q,this.listenerDeps($))}createAdapter($){let Q=this.require($.type);if(!Q.createAdapter)return null;return Q.createAdapter($,this.adapterDeps())}secretTokens($){return this.require($.type).secretTokens($)}buildConfig($,Q){let Y=typeof $.type==="string"?$.type:"";return this.require(Y).buildConfig($,Q)}applyUpdate($,Q,Y){return this.require($.type).applyUpdate($,Q,Y)}runOperation($,Q,Y,X){let Z=this.require($.type).operations[Q];if(!Z)throw Error(`connector type "${$.type}" has no operation "${Q}"`);return Z({config:$,args:Y,context:X})}connectorDir($,Q){return H80(this.dir,"channels",$,"connectors",Q)}channelDir($){return H80(this.dir,"channels",$)}require($){let Q=this.descriptors.get($);if(!Q)throw Error(`unknown connector type "${$}". Pass its descriptor to new Funnel({ connectors: [...] }).`);return Q}listenerDeps($){return{channelId:$,fs:this.fs,process:this.process,logger:this.logger,diagnosticLog:this.diagnosticLog,connectorDir:(Q,Y)=>this.connectorDir(Q,Y)}}adapterDeps(){return{fs:this.fs,process:this.process,logger:this.logger}}}class Fq{millis(){return this.now().getTime()}iso(){return this.now().toISOString()}}class f4 extends Fq{now(){return new Date}}var sR6=new f4,tR6=new kQ;class Ga{store;registry;profileChecker;clock;idGenerator;constructor($){this.store=$.store,this.registry=$.registry,this.profileChecker=$.profileChecker??null,this.clock=$.clock??sR6,this.idGenerator=$.idGenerator??tR6,Object.freeze(this)}list(){return this.store.read().channels}get($){return this.list().find((Q)=>Q.name===$)??null}getById($){return this.list().find((Q)=>Q.id===$)??null}add($){let Q=this.store.read();if(Q.channels.some((X)=>X.name===$.name))throw Error(`channel "${$.name}" already exists`);let Y={id:this.idGenerator.generate(),name:$.name,delivery:$.delivery??"fanout",connectors:[]};return Q.channels.push(Y),this.store.write(Q),Y}setDelivery($,Q){let Y=this.store.read(),X=this.requireChannel(Y,$);X.delivery=Q,this.store.write(Y)}remove($){let Q=this.store.read(),Y=Q.channels.findIndex((z)=>z.name===$);if(Y<0)throw Error(`channel "${$}" not found`);let X=Q.channels[Y];if(X&&this.profileChecker?.hasChannelRef(X.id))throw Error(`channel "${$}" is referenced by a profile`);Q.channels.splice(Y,1),this.store.write(Q)}rename($,Q){let Y=this.store.read(),X=Y.channels.find((z)=>z.name===$);if(!X)throw Error(`channel "${$}" not found`);if(Y.channels.some((z)=>z.name===Q))throw Error(`channel "${Q}" already exists`);X.name=Q,this.store.write(Y)}listConnectors($){return this.requireChannel(this.store.read(),$).connectors}getConnector($,Q){let Y=this.get($);if(!Y)return null;return Y.connectors.find((X)=>X.name===Q)??null}listAllConnectors(){let $=[];for(let Q of this.list())for(let Y of Q.connectors)$.push({...Y,channelId:Q.id,channelName:Q.name});return $}addConnector($,Q){let Y=this.store.read(),X=this.requireChannel(Y,$);if(X.connectors.some((Z)=>Z.name===Q.name))throw Error(`connector "${Q.name}" already exists in channel "${$}"`);let z=this.registry.buildConfig(Q,{id:this.idGenerator.generate(),now:this.clock.iso()});return this.assertNoTokenCollision(Y,z),X.connectors.push(z),this.store.write(Y),z}removeConnector($,Q){let Y=this.store.read(),X=this.requireChannel(Y,$),z=X.connectors.findIndex((Z)=>Z.name===Q);if(z<0)throw Error(`connector "${Q}" not found in channel "${$}"`);X.connectors.splice(z,1),this.store.write(Y)}renameConnector($,Q,Y){let X=this.store.read(),z=this.requireChannel(X,$),Z=z.connectors.find((K)=>K.name===Q);if(!Z)throw Error(`connector "${Q}" not found in channel "${$}"`);if(z.connectors.some((K)=>K.name===Y))throw Error(`connector "${Y}" already exists in channel "${$}"`);Z.name=Y,Z.updatedAt=this.clock.iso(),this.store.write(X)}updateConnector($,Q,Y){let X=this.store.read(),z=this.requireChannel(X,$),Z=z.connectors.find((W)=>W.name===Q);if(!Z)throw Error(`connector "${Q}" not found in channel "${$}"`);let K=this.registry.applyUpdate(Z,Y,{now:this.clock.iso()});this.assertNoTokenCollision(X,K),this.replaceConnector(z,Z.name,K),this.store.write(X)}updateSlackConnector($,Q,Y){this.updateConnector($,Q,Y)}updateGhConnector($,Q,Y){this.updateConnector($,Q,Y)}updateDiscordConnector($,Q,Y){this.updateConnector($,Q,Y)}connectorOp($,Q,Y,X){let z=this.store.read(),Z=this.requireChannel(z,$),K=Z.connectors.find((H)=>H.name===Q);if(!K)throw Error(`connector "${Q}" not found in channel "${$}"`);let W=this.registry.runOperation(K,Y,X,{generateId:()=>this.idGenerator.generate(),now:this.clock.iso()});if(W.config!==K)this.replaceConnector(Z,K.name,W.config),this.store.write(z);return W.result}async call($,Q,Y){let X=this.getConnector($,Q);if(!X)throw Error(`connector "${Q}" not found in channel "${$}"`);let z=this.registry.createAdapter(X);if(!z)throw Error(`connector type "${X.type}" does not support outbound calls`);return await z.call(Y)}createListener($,Q){let Y=this.get($);if(!Y)return null;let X=Y.connectors.find((z)=>z.name===Q);if(!X)return null;return{config:X,channelId:Y.id,listener:this.registry.createListener(Y.id,X)}}createAllListeners(){let $=[];for(let Q of this.list())for(let Y of Q.connectors)$.push({config:Y,channelId:Q.id,channelName:Q.name,listener:this.registry.createListener(Q.id,Y)});return $}requireChannel($,Q){let Y=$.channels.find((X)=>X.name===Q);if(!Y)throw Error(`channel "${Q}" not found`);return Y}replaceConnector($,Q,Y){let X=$.connectors.findIndex((z)=>z.name===Q);if(X<0)throw Error(`connector "${Q}" not found in channel "${$.name}"`);$.connectors[X]=Y}assertNoTokenCollision($,Q){let Y=this.registry.secretTokens(Q);if(Y.length===0)return;for(let X of $.channels)for(let z of X.connectors){if(z.id===Q.id)continue;for(let Z of this.registry.secretTokens(z))if(Y.includes(Z))throw Error(`token already in use by connector "${z.name}" in channel "${X.name}"`)}}}var eR6=new p8,$T6=new kQ;class Ua{channels;mcp;gateway;sessions;guard;process;idGenerator;logger;constructor($){this.channels=$.channels,this.mcp=$.mcp,this.gateway=$.gateway,this.sessions=$.sessions,this.guard=$.guard,this.process=$.process??eR6,this.idGenerator=$.idGenerator??$T6,this.logger=$.logger,Object.freeze(this)}async launch($){let Q=this.channels.get($.channel)??this.channels.getById($.channel);if(!Q)throw Error(`channel "${$.channel}" not found`);if($.profileId&&this.guard.isRunning($.profileId))throw Error(`profile "${$.profileId}" is already running`);let Y=$.cwd??globalThis.process.cwd();if(($.installMcp??!0)&&!this.mcp.findInstalledName(Y))this.mcp.install(Y),this.logger?.info("added funnel MCP to .mcp.json",{cwd:Y});if(!this.gateway.isRunning()){if(this.logger?.info("starting gateway automatically"),!await this.gateway.start())throw Error(`gateway failed to start on port ${uX()}; another funnel daemon (a different repo/scope) may already hold it. See 'fnl gateway logs' and 'ps -o pid,args= | grep funnel-gateway'.`)}if($.profileId)this.guard.acquire($.profileId);let Z=($.resume??!1)&&$.profileId?this.resolveSession($.profileId,Y,$.userArgs??[],$.env??{}):null,K=this.buildArgs($.options??[],$.userArgs??[],Y,Z),W=this.buildEnv(Q.id,$.env??{});this.logger?.info("claude launch",{channel:$.channel,channelId:Q.id,cwd:Y});try{return await this.process.attach(["claude",...K],{cwd:Y,env:W,onSpawned:$.onSpawned})}finally{if($.profileId)this.guard.release($.profileId)}}buildArgs($,Q,Y,X){let z=[...$,...Q];if(X!==null)if(X.mode==="resume")z.push("--resume",X.id);else z.push("--session-id",X.id);let Z=this.mcp.findInstalledName(Y);if(Z&&!z.includes("--dangerously-load-development-channels")&&!z.includes("--channels"))z.push("--dangerously-load-development-channels",`server:${Z}`);return z}resolveSession($,Q,Y,X){for(let K of Y){if(K==="-c"||K==="--continue")return null;if(K==="--resume"||K.startsWith("--resume="))return null;if(K==="--session-id"||K.startsWith("--session-id="))return null}let z=this.sessions.getSessionId($);if(z!==null&&this.sessions.sessionFileExists(Q,z,X))return{id:z,mode:"resume"};let Z=this.idGenerator.generate();return this.sessions.setSessionId($,Z),{id:Z,mode:"new"}}buildEnv($,Q){let Y={};for(let[X,z]of Object.entries(Q))Y[X]=z;for(let[X,z]of Object.entries(globalThis.process.env))if(typeof z==="string")Y[X]=z;return Y.FUNNEL_CHANNEL_ID=$,Y.FUNNEL_PORT=String(uX()),Y}}import{join as V80}from"path";var QT6=new N8,YT6=new p8;class pM{fs;process;pidDir;constructor($={}){this.fs=$.fs??QT6,this.process=$.process??YT6,this.pidDir=V80($.dir??SQ,"claude"),Object.freeze(this)}isRunning($){let Q=this.readRecord($);if(!Q)return!1;if(!this.process.isAlive(Q.pid))return this.release($),!1;if(Q.startTime!==null){let Y=this.process.getStartTime(Q.pid);if(Y===null)return this.release($),!1;if(Y!==Q.startTime)return this.release($),!1}return!0}acquire($){this.fs.mkdirSync(this.pidDir,{recursive:!0});let Q=globalThis.process.pid,Y=this.process.getStartTime(Q),X={pid:Q,startTime:Y};this.fs.writeFileSync(this.pidPath($),JSON.stringify(X)),globalThis.process.once("exit",()=>this.release($))}release($){let Q=this.pidPath($);if(this.fs.existsSync(Q))this.fs.unlink(Q)}pidPath($){return V80(this.pidDir,`${$}.pid`)}readRecord($){let Q=this.pidPath($);if(!this.fs.existsSync(Q))return null;try{let Y=this.fs.readFileSync(Q).trim();if(!Y)return null;if(Y.startsWith("{")){let z=JSON.parse(Y),Z=typeof z.pid==="number"?z.pid:Number(z.pid);if(!Number.isInteger(Z)||Z<=0)return null;let K=typeof z.startTime==="string"?z.startTime:null;return{pid:Z,startTime:K}}let X=Number(Y);if(!X||X<=0)return null;return{pid:X,startTime:null}}catch{return null}}}import{existsSync as xa}from"fs";import{join as Ba}from"path";var Ja=($)=>typeof $==="string"&&$.length>0?$:null,iM=($)=>typeof $==="number"?$:null,lM=($,Q)=>typeof $==="string"?$:Q,XT6=($)=>$!==null&&typeof $==="object"&&!Array.isArray($),G80=($)=>{if($===null)return null;try{let Q=JSON.parse($);if(XT6(Q))return Q}catch{return null}return null},w80=($,Q)=>$.length<=Q?$:`${$.slice(0,Q)}\u2026`,zT6=($)=>{if(typeof $!=="string"||$.length===0)return null;let Q=G80($);if(Q!==null&&"text"in Q)return w80(String(Q.text),60);return w80($,60)},nM=($)=>{let Q=Ja($.payload);return{seq:iM($.seq),ts:iM($.ts),type:lM($.type,"?"),outcome:lM($.outcome,"?"),eventId:Ja($.event_id),payload:Q,payloadParsed:G80(Q),preview:zT6($.payload)}},qa=($)=>({seq:iM($.seq),ts:iM($.ts),type:lM($.type,"?"),status:lM($.status,"?"),detail:Ja($.detail)}),o7=($,Q,Y)=>{try{return $.query(Q,Y)}finally{$.close()}};var ZT6=($)=>{if($===null||typeof $!=="object")return!1;if(!("clients"in $)||!Array.isArray($.clients))return!1;if(!("listeners"in $)||!Array.isArray($.listeners))return!1;return!0},KT6=($,Q)=>{if(Q===null)return;return $.connectors?.find((Y)=>Y.id===Q)?.name},WT6=($)=>{let Y=($.connectionErrors[$.connectionErrors.length-1]??null)?.detail??null;if(!$.gateway.running)return{status:"error",message:"gateway is not running",nextActions:["fnl gateway start"],rootCause:null};let X=$.channel;if(!($.listeners.length>0))return{status:"warn",message:"no connectors configured on this channel",nextActions:[`fnl channels ${X} connectors add <name> --type=slack ...`],rootCause:null};let Z=$.listeners.every((V)=>!V.alive),K=$.listeners.some((V)=>!V.alive);if(Z)return{status:"error",message:"all listeners are dead",nextActions:["fnl doctor --fix","fnl doctor --fix --aggressive"],rootCause:Y};if(K)return{status:"warn",message:"some listeners are dead",nextActions:["fnl doctor --fix"],rootCause:Y};if($.claudeClients===0)return{status:"warn",message:"no Claude connected to this channel",nextActions:[`fnl claude --channel ${X}`],rootCause:null};if($.listeners.some((V)=>V.errors>0))return{status:"warn",message:"listeners have errors",nextActions:["fnl gateway logs"],rootCause:Y};let H=HT6($);if(H!==null)return H;return{status:"ok",message:"everything looks healthy",nextActions:[],rootCause:null}},HT6=($)=>{if(!$.listeners.some((Z)=>Z.type==="slack")||$.recentEvents.length===0)return null;let Y=$.recentEvents.filter((Z)=>Z.type==="slack").map((Z)=>Z.payloadParsed?.type);if(Y.length===0)return null;let X=Y.includes("app_mention"),z=Y.includes("message");if(!X||z)return null;return{status:"warn",message:"Slack is only delivering app_mention events; unmentioned thread replies may not arrive",nextActions:["Add Slack bot events: message.channels, message.groups, message.im, message.mpim; reinstall the app; then restart the gateway"],rootCause:"Slack Event Subscriptions likely omit message.* events"}};class Da{props;constructor($){this.props=$;Object.freeze(this)}async diagnose($){let Q=this.props.channels.list(),Y=$?Q.find((Z)=>Z.name===$)??null:Q[0]??null;if(!Y)return null;let X=await this.fetchGatewayStatus(),z=this.resolveStore();return this.buildChannelDiagnosis(Y,X,z,5)}async diagnoseAll(){let $=this.props.channels.list(),Q=await this.fetchGatewayStatus(),Y=this.resolveStore(),X=await Promise.all($.map((H)=>this.buildChannelDiagnosis(H,Q,Y,5))),z=X.filter((H)=>H.diagnosis.status==="error").map((H)=>H.channel),Z=X.filter((H)=>H.diagnosis.status==="warn").map((H)=>H.channel),K=X.filter((H)=>H.diagnosis.status==="ok").map((H)=>H.channel),W=[...new Set(X.flatMap((H)=>H.diagnosis.nextActions))];return{summary:{total:X.length,ok:K.length,warn:Z.length,error:z.length,criticalChannels:z,warnChannels:Z,suggestedActions:W},channels:X}}async recentEvents($,Q=20){let Y=this.resolveStore();if(!Y)return[];let X=this.resolveChannelId($);if($&&!X)return[];let z=new s9(Y),Z=X?o7(z,"SELECT seq, ts, type, outcome, payload FROM processed WHERE channel_id = ? ORDER BY seq DESC LIMIT ?",[X,Q]):o7(z,"SELECT seq, ts, type, outcome, payload FROM processed ORDER BY seq DESC LIMIT ?",[Q]);if(Z instanceof Error)return[];return Z.reverse().map(nM)}async droppedEvents($,Q=20){let Y=this.resolveStore();if(!Y)return[];let X=this.resolveChannelId($);if($&&!X)return[];let z=new s9(Y),Z=X?o7(z,"SELECT seq, ts, type, outcome, payload, event_id FROM processed WHERE channel_id = ? AND outcome LIKE 'skip:%' ORDER BY seq DESC LIMIT ?",[X,Q]):o7(z,"SELECT seq, ts, type, outcome, payload, event_id FROM processed WHERE outcome LIKE 'skip:%' ORDER BY seq DESC LIMIT ?",[Q]);if(Z instanceof Error)return[];return Z.reverse().map(nM)}async connectionErrors($,Q=20){let Y=this.resolveStore();if(!Y)return[];let X=this.resolveChannelId($);if($&&!X)return[];let z=new s9(Y),Z=X?o7(z,"SELECT seq, ts, type, status, detail FROM connection WHERE channel_id = ? AND status IN ('auth-failed','error') ORDER BY seq DESC LIMIT ?",[X,Q]):o7(z,"SELECT seq, ts, type, status, detail FROM connection WHERE status IN ('auth-failed','error') ORDER BY seq DESC LIMIT ?",[Q]);if(Z instanceof Error)return[];return Z.reverse().map(qa)}async replay($,Q){let X=this.props.channels.list().find((x)=>x.name===$);if(!X)return{state:"not-found"};let z=this.resolveStore();if(!z)return{state:"error",reason:"no diagnostic store yet"};let Z=new s9(z),K=Q!==void 0?o7(Z,"SELECT seq, event_id, type, payload, connector_id, channel_id FROM processed WHERE channel_id = ? AND seq = ? LIMIT 1",[X.id,Q]):o7(Z,"SELECT seq, event_id, type, payload, connector_id, channel_id FROM processed WHERE channel_id = ? AND outcome LIKE 'emitted%' ORDER BY seq DESC LIMIT 1",[X.id]);if(K instanceof Error)return{state:"error",reason:K.message};let W=K[0];if(!W)return{state:"not-found"};let H=typeof W.seq==="number"?W.seq:null,V=typeof W.event_id==="string"?W.event_id:null,w=typeof W.connector_id==="string"?W.connector_id:null,G=typeof W.payload==="string"?W.payload:null;if((!G||G.length===0)&&V){let x=o7(new s9(z),"SELECT payload FROM raw WHERE event_id = ? LIMIT 1",[V]),D=x instanceof Error?null:x[0];if(D)G=typeof D.payload==="string"?D.payload:null}if(!G)return{state:"error",reason:"event has no payload to replay"};let U=KT6(X,w),J=await this.props.publisher.publish(X.name,{content:G,connector:U});if(J.state==="offline")return{state:"offline"};if(J.state==="error")return{state:"error",reason:J.reason};return{state:"ok",seq:H,offset:J.offset,preview:G.slice(0,60)}}resolveStore(){let $=this.props.tmpDir,Q=Ba($,"connector-raw.db"),Y=Ba($,"connector-processed.db"),X=Ba($,"connector-connection.db");if(!xa(Q)||!xa(Y)||!xa(X))return null;return{rawPath:Q,processedPath:Y,connectionPath:X}}resolveChannelId($){if(!$)return null;return this.props.channels.list().find((Y)=>Y.name===$)?.id??null}async fetchGatewayStatus(){let $=this.props.gateway.getStatus();if(!$.running)return null;let Q=this.props.gatewayToken.read(),Y=Q?{Authorization:`Bearer ${Q}`}:{},X=await fetch(`${_$($.port)}/status`,{headers:Y}).catch(()=>null);if(!X||!X.ok)return null;let z=await X.json();return ZT6(z)?z:null}async buildChannelDiagnosis($,Q,Y,X){let z=this.props.gateway.getStatus(),Z=$.name,K={channel:Z,channelId:$.id,gateway:{running:z.running,pid:z.pid,port:z.running?z.port:null,uptimeMs:Q?.uptimeMs??null},listeners:[],claudeClients:0,recentEvents:[],connectionErrors:[]};if(Q)K.listeners=Q.listeners.filter((W)=>W.channelName===Z).map((W)=>({name:W.name,type:W.type,alive:W.alive,events:W.events,errors:W.errors,lastEventAt:W.lastEventAt})),K.claudeClients=Q.clients.filter((W)=>W.channelName===Z).length;if(Y){let W=o7(new s9(Y),"SELECT seq, ts, type, outcome, payload FROM processed WHERE channel_id = ? ORDER BY seq DESC LIMIT ?",[$.id,X]);if(!(W instanceof Error))K.recentEvents=W.reverse().map(nM);let H=K.listeners.some((w)=>!w.alive),V=K.listeners.some((w)=>w.errors>0);if(H||V){let w=o7(new s9(Y),"SELECT ts, type, status, detail FROM connection WHERE channel_id = ? AND status IN ('auth-failed','error') ORDER BY seq DESC LIMIT 3",[$.id]);if(!(w instanceof Error))K.connectionErrors=w.reverse().map(qa)}}return{...K,diagnosis:WT6(K)}}}class La{props;constructor($){this.props=$;Object.freeze(this)}async run($="off"){if($==="off"){let W=await this.props.diagnostics.diagnoseAll();return this.buildReport({before:null,after:W,appliedActions:[],fixFailed:!1})}let Q=await this.props.diagnostics.diagnoseAll(),Y=[],X=!1;if(Q.channels.some((W)=>W.diagnosis.status==="error"&&!W.gateway.running)){let W=await this.props.recovery.ensureGatewayRunning();if(Y.push(...W.actions),!W.ok)X=!0}if(Q.channels.some((W)=>W.listeners.some((H)=>!H.alive))){let W=await this.props.recovery.restartAllDeadListeners();if(Y.push(...W.actions),!W.ok&&W.actions.length===0)X=!0}if($==="aggressive"){if(Y.length===0||Q.channels.some((H)=>H.diagnosis.status==="error")){let H=await this.props.recovery.restartGateway();if(Y.push(...H.actions),!H.ok)X=!0}}let K=await this.props.diagnostics.diagnoseAll();return this.buildReport({before:Q,after:K,appliedActions:Y,fixFailed:X})}buildReport($){let Q=$.after.channels.filter((z)=>z.diagnosis.status!=="ok").map((z)=>({channel:z.channel,diagnosis:z.diagnosis})),Y=$.fixFailed?"error":Q.length===0?"ok":"warn",X=VT6({mode:$.before===null?"off":"fix",status:Y,appliedCount:$.appliedActions.length,remainingCount:Q.length});return{status:Y,message:X,before:$.before,after:$.after,appliedActions:$.appliedActions,remainingIssues:Q}}}var VT6=($)=>{if($.mode==="off"){if($.remainingCount===0)return"all channels healthy";return`${$.remainingCount} channel(s) need attention \u2014 run \`fnl doctor --fix\` to apply suggested fixes`}if($.status==="error")return"one or more fix steps failed \u2014 check fnl gateway logs";if($.status==="ok")return`applied ${$.appliedCount} fix(es), all channels healthy`;return`applied ${$.appliedCount} fix(es), ${$.remainingCount} channel(s) still need attention`};function Fa($){if($.env!==void 0)return{botTokenEnv:$.env};if($.literal!==void 0)return{botToken:$.literal};return{}}function U80($){if($.env!==void 0)return{appTokenEnv:$.env};if($.literal!==void 0)return{appToken:$.literal};return{}}class Na{channels;prompter;constructor($){this.channels=$.channels,this.prompter=$.prompter,Object.freeze(this)}async ensure($){if(!this.channels.get($.name))this.channels.add({name:$.name});if($.connectors===void 0)return{touched:[],removed:[]};let Y=[],X=new Set;for(let Z of $.connectors){let K=await this.ensureConnector($.name,Z);Y.push({name:K.name,changed:K.changed}),X.add(K.id)}let z=this.removeExtras($.name,X);return{touched:Y,removed:z}}async ensureConnector($,Q){if(Q.type==="slack")return await this.ensureSlack($,Q);if(Q.type==="discord")return await this.ensureDiscord($,Q);if(Q.type==="gh")return this.ensureGh($,Q);return this.ensureSchedule($,Q)}async ensureSlack($,Q){let Y=this.findExistingSlack($,Q.name),X=await this.resolveSlot({label:`${Q.name}.botToken`,existingLiteral:Y?.botToken,existingEnv:Y?.botTokenEnv}),z=await this.resolveSlot({label:`${Q.name}.appToken`,existingLiteral:Y?.appToken,existingEnv:Y?.appTokenEnv}),Z={botToken:X.token,botTokenEnv:X.tokenEnv,appToken:z.token,appTokenEnv:z.tokenEnv};if(Y){if(!(Y.botToken===X.token&&Y.botTokenEnv===X.tokenEnv&&Y.appToken===z.token&&Y.appTokenEnv===z.tokenEnv))return this.channels.updateSlackConnector($,Q.name,Z),{id:Y.id,name:Q.name,changed:!0};return{id:Y.id,name:Q.name,changed:!1}}return{id:this.channels.addConnector($,{type:"slack",name:Q.name,...Fa({literal:X.token,env:X.tokenEnv}),...U80({literal:z.token,env:z.tokenEnv}),...Q.minify!==void 0?{minify:Q.minify}:{}}).id,name:Q.name,changed:!0}}async ensureDiscord($,Q){let Y=this.findExistingDiscord($,Q.name),X=await this.resolveSlot({label:`${Q.name}.botToken`,existingLiteral:Y?.botToken,existingEnv:Y?.botTokenEnv}),z={botToken:X.token,botTokenEnv:X.tokenEnv};if(Y){if(Y.botToken!==X.token||Y.botTokenEnv!==X.tokenEnv)return this.channels.updateDiscordConnector($,Q.name,z),{id:Y.id,name:Q.name,changed:!0};return{id:Y.id,name:Q.name,changed:!1}}return{id:this.channels.addConnector($,{type:"discord",name:Q.name,...Fa({literal:X.token,env:X.tokenEnv})}).id,name:Q.name,changed:!0}}ensureGh($,Q){let Y=this.channels.getConnector($,Q.name);if(Y&&Y.type!=="gh")throw Error(`connector "${Q.name}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "gh"`);if(Y&&Y.type==="gh"){let z=yz.parse(Y);if(Q.pollInterval!==void 0&&z.pollInterval!==Q.pollInterval)return this.channels.updateGhConnector($,Q.name,{pollInterval:Q.pollInterval}),{id:z.id,name:Q.name,changed:!0};return{id:z.id,name:Q.name,changed:!1}}return{id:this.channels.addConnector($,{type:"gh",name:Q.name,...Q.pollInterval!==void 0?{pollInterval:Q.pollInterval}:{}}).id,name:Q.name,changed:!0}}ensureSchedule($,Q){let Y=this.channels.getConnector($,Q.name);if(Y&&Y.type!=="schedule")throw Error(`connector "${Q.name}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "schedule"`);if(Y&&Y.type==="schedule")return{id:Y.id,name:Q.name,changed:!1};return{id:this.channels.addConnector($,{type:"schedule",name:Q.name}).id,name:Q.name,changed:!0}}findExistingSlack($,Q){let Y=this.channels.getConnector($,Q);if(!Y)return null;if(Y.type!=="slack")throw Error(`connector "${Q}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "slack"`);return HX.parse(Y)}findExistingDiscord($,Q){let Y=this.channels.getConnector($,Q);if(!Y)return null;if(Y.type!=="discord")throw Error(`connector "${Q}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "discord"`);return gY.parse(Y)}removeExtras($,Q){let Y=this.channels.get($);if(!Y)return[];let X=Y.connectors.filter((z)=>!Q.has(z.id));for(let z of X)this.channels.removeConnector($,z.name);return X.map((z)=>z.name)}async resolveSlot($){if($.existingEnv!==void 0)return{token:void 0,tokenEnv:$.existingEnv};if($.existingLiteral!==void 0)return{token:$.existingLiteral,tokenEnv:void 0};return{token:await this.prompter.promptSecret($.label),tokenEnv:void 0}}}import{homedir as wT6}from"os";import{join as J80}from"path";var GT6=new N8;class Pa{store;idGenerator;fs;constructor($){this.store=$.store,this.idGenerator=$.idGenerator,this.fs=$.fs??GT6,Object.freeze(this)}list(){return this.store.read().profiles}get($){return this.list().find((Q)=>Q.name===$)??null}getById($){return this.list().find((Q)=>Q.id===$)??null}getDefault(){return this.list()[0]??null}add($){let Q=this.store.read();if(Q.profiles.some((Y)=>Y.name===$.name))throw Error(`profile "${$.name}" already exists`);if(!Q.channels.some((Y)=>Y.id===$.channelId))throw Error(`channel id "${$.channelId}" not found`);Q.profiles.push({id:this.idGenerator.generate(),name:$.name,path:$.path,channelId:$.channelId,options:$.options??[],env:$.env??{},resume:$.resume??!0}),this.store.write(Q)}remove($){let Q=this.store.read(),Y=Q.profiles.findIndex((X)=>X.name===$);if(Y<0)throw Error(`profile "${$}" not found`);Q.profiles.splice(Y,1),this.store.write(Q)}rename($,Q){let Y=this.store.read(),X=Y.profiles.find((z)=>z.name===$);if(!X)throw Error(`profile "${$}" not found`);if(Y.profiles.some((z)=>z.name===Q))throw Error(`profile "${Q}" already exists`);X.name=Q,this.store.write(Y)}asDefault($){let Q=this.store.read(),Y=Q.profiles.findIndex((z)=>z.name===$);if(Y<0)throw Error(`profile "${$}" not found`);if(Y===0)return;let[X]=Q.profiles.splice(Y,1);if(!X)return;Q.profiles.unshift(X),this.store.write(Q)}hasChannelRef($){return this.store.read().profiles.some((Q)=>Q.channelId===$)}getSessionId($){return this.getById($)?.sessionId??null}setSessionId($,Q){let Y=this.store.read(),X=Y.profiles.find((z)=>z.id===$);if(!X)throw Error(`profile id "${$}" not found`);X.sessionId=Q,this.store.write(Y)}sessionFileExists($,Q,Y){let X=Y.CLAUDE_CONFIG_DIR??globalThis.process.env.CLAUDE_CONFIG_DIR??J80(wT6(),".claude"),z=$.replace(/\//g,"-"),Z=J80(X,"projects",z,`${Q}.jsonl`);if(!this.fs.existsSync(Z))return!1;return this.fs.readFileSync(Z).trim().length>0}update($,Q){let Y=this.store.read(),X=Y.profiles.find((z)=>z.name===$);if(!X)throw Error(`profile "${$}" not found`);if(Q.channelId!==void 0){if(!Y.channels.some((z)=>z.id===Q.channelId))throw Error(`channel id "${Q.channelId}" not found`);X.channelId=Q.channelId}if(Q.path!==void 0)X.path=Q.path;if(Q.options!==void 0)X.options=Q.options;if(Q.env!==void 0)X.env=Q.env;if(Q.resume!==void 0)X.resume=Q.resume;this.store.write(Y)}}class ja{props;constructor($){this.props=$;Object.freeze(this)}async ensureGatewayRunning(){if(this.props.gateway.isRunning())return{ok:!0,actions:[{kind:"gateway:already-running"}],message:"gateway is already running"};if(!await this.props.gateway.start())return{ok:!1,actions:[],message:"gateway failed to start \u2014 check `fnl gateway logs`"};return{ok:!0,actions:[{kind:"gateway:started"}],message:"gateway started"}}async restartGateway(){if(!(await this.props.gateway.restart()).ok)return{ok:!1,actions:[],message:"gateway restart failed \u2014 check `fnl gateway logs`"};return{ok:!0,actions:[{kind:"gateway:restarted"}],message:"gateway restarted"}}async restartListener($,Q){let Y=await this.props.listeners.restart($,Q);if(Y.state==="offline")return{ok:!1,actions:[],message:"gateway is not running \u2014 call ensureGatewayRunning() first"};if(Y.state==="not-found")return{ok:!1,actions:[{kind:"listener:skipped",channel:$,connector:Q,reason:"not-found"}],message:`listener not found: ${$}/${Q}`};if(Y.state==="error")return{ok:!1,actions:[{kind:"listener:skipped",channel:$,connector:Q,reason:Y.reason}],message:`listener restart failed: ${Y.reason}`};return{ok:!0,actions:[{kind:"listener:restarted",channel:$,connector:Q}],message:`restarted ${$}/${Q}`}}async restartAllDeadListeners(){let $=await this.props.listeners.list();if($.state==="offline")return{ok:!1,actions:[],message:"gateway is not running \u2014 call ensureGatewayRunning() first"};if($.state==="error")return{ok:!1,actions:[],message:`could not list listeners: ${$.reason}`};let Q=$.listeners.filter((z)=>!z.alive);if(Q.length===0)return{ok:!0,actions:[],message:"no dead listeners found"};let Y=[];for(let z of Q){let Z=await this.props.listeners.restart(z.channelName,z.name);if(Z.state==="ok")Y.push({kind:"listener:restarted",channel:z.channelName,connector:z.name});else{let K=Z.state==="error"?Z.reason:Z.state;Y.push({kind:"listener:skipped",channel:z.channelName,connector:z.name,reason:K})}}let X=Y.filter((z)=>z.kind==="listener:restarted").length;return{ok:X>0,actions:Y,message:`restarted ${X}/${Q.length} dead listener(s)`}}}import{stderr as dM,stdin as vY}from"process";class Ia{}var UT6="*",JT6="\r",q80=`
2019
+ `)}}import{join as Of6}from"path";var z80=($,Q)=>{return $=$.replace(/\/+$/,""),$=$+"/",Q=Q.replace(/^\/+/,""),$+Q},mM=($,Q)=>{for(let[Y,X]of Object.entries(Q)){let z=new RegExp("/:"+Y+"(?:{[^/]+})?\\??");$=$.replace(z,X?`/${X}`:"")}return $},Z80=($)=>{let Q=new URLSearchParams;for(let[Y,X]of Object.entries($)){if(X===void 0)continue;if(Array.isArray(X))for(let z of X)Q.append(Y,z);else Q.set(Y,X)}return Q},K80=($,Q)=>{switch(Q){case"ws":return $.replace(/^http/,"ws");case"http":return $.replace(/^ws/,"http")}},Wa=($)=>{if(/^https?:\/\/[^\/]+?\/index(?=\?|$)/.test($))return $.replace(/\/index(?=\?|$)/,"/");return $.replace(/\/index(?=\?|$)/,"")};function hM($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function Ha($,Q){if(!hM($)&&!hM(Q))return Q;let Y={...$};for(let X in Q){let z=Q[X];if(hM(Y[X])&&hM(z))Y[X]=Ha(Y[X],z);else Y[X]=z}return Y}var W80=($,Q)=>{return new Proxy(()=>{},{get(X,z){if(typeof z!=="string"||z==="then")return;return W80($,[...Q,z])},apply(X,z,Z){return $({path:Q,args:Z})}})},aR6=class{url;method;buildSearchParams;queryParams=void 0;pathParams={};rBody;cType=void 0;constructor($,Q,Y){this.url=$,this.method=Q,this.buildSearchParams=Y.buildSearchParams}fetch=async($,Q)=>{if($){if($.query)this.queryParams=this.buildSearchParams($.query);if($.form){let W=new FormData;for(let[H,V]of Object.entries($.form)){if(V===void 0)continue;if(Array.isArray(V))for(let w of V)W.append(H,w);else W.append(H,V)}this.rBody=W}if($.json)this.rBody=JSON.stringify($.json),this.cType="application/json";if($.param)this.pathParams=$.param}let Y=this.method.toUpperCase(),X={...$?.header,...typeof Q?.headers==="function"?await Q.headers():Q?.headers};if($?.cookie){let W=[];for(let[H,V]of Object.entries($.cookie))W.push(cR(H,V,{path:"/"}));X.Cookie=W.join(",")}if(this.cType)X["Content-Type"]=this.cType;let z=new Headers(X??void 0),Z=this.url;if(Z=Wa(Z),Z=mM(Z,this.pathParams),this.queryParams)Z=Z+"?"+this.queryParams.toString();Y=this.method.toUpperCase();let K=!(Y==="GET"||Y==="HEAD");return(Q?.fetch||fetch)(Z,{body:K?this.rBody:void 0,method:Y,headers:z,...Q?.init})}},Va=($,Q)=>W80(function Y(X){let z=Q?.buildSearchParams??Z80,Z=[...X.path],K=Z.slice(-3).reverse();if(K[0]==="toString"){if(K[1]==="name")return K[2]||"";return Y.toString()}if(K[0]==="valueOf"){if(K[1]==="name")return K[2]||"";return Y}let W="";if(/^\$/.test(K[0])){let G=Z.pop();if(G)W=G.replace(/^\$/,"")}let H=Z.join("/"),V=z80($,H);if(W==="url"||W==="path"){let G=V;if(X.args[0]){if(X.args[0].param)G=mM(V,X.args[0].param);if(X.args[0].query)G=G+"?"+z(X.args[0].query).toString()}if(G=Wa(G),W==="url")return new URL(G);return G.slice($.replace(/\/+$/,"").length).replace(/^\/?/,"/")}if(W==="ws"){let G=K80(X.args[0]&&X.args[0].param?mM(V,X.args[0].param):V,"ws"),U=new URL(G),J=X.args[0]?.query;if(J)Object.entries(J).forEach(([D,B])=>{if(Array.isArray(B))B.forEach((L)=>U.searchParams.append(D,L));else U.searchParams.set(D,B)});return((...D)=>{if(Q?.webSocket!==void 0&&typeof Q.webSocket==="function")return Q.webSocket(...D);return new WebSocket(...D)})(U.toString())}let w=new aR6(V,W,{buildSearchParams:z});if(W){Q??={};let G=Ha(Q,{...X.args[1]});return w.fetch(X.args[0],G)}return w},[]);import{join as H80}from"path";var oR6=new N8,rR6=new p8;class wa{descriptors;fs;process;logger;diagnosticLog;dir;constructor($){this.descriptors=new Map($.descriptors.map((Q)=>[Q.type,Q])),this.fs=$.fs??oR6,this.process=$.process??rR6,this.logger=$.logger,this.diagnosticLog=$.diagnosticLog,this.dir=$.dir??SQ,Object.freeze(this)}has($){return this.descriptors.has($)}types(){return[...this.descriptors.keys()]}createListener($,Q){return this.require(Q.type).createListener(Q,this.listenerDeps($))}createAdapter($){let Q=this.require($.type);if(!Q.createAdapter)return null;return Q.createAdapter($,this.adapterDeps())}secretTokens($){return this.require($.type).secretTokens($)}buildConfig($,Q){let Y=typeof $.type==="string"?$.type:"";return this.require(Y).buildConfig($,Q)}applyUpdate($,Q,Y){return this.require($.type).applyUpdate($,Q,Y)}runOperation($,Q,Y,X){let Z=this.require($.type).operations[Q];if(!Z)throw Error(`connector type "${$.type}" has no operation "${Q}"`);return Z({config:$,args:Y,context:X})}connectorDir($,Q){return H80(this.dir,"channels",$,"connectors",Q)}channelDir($){return H80(this.dir,"channels",$)}require($){let Q=this.descriptors.get($);if(!Q)throw Error(`unknown connector type "${$}". Pass its descriptor to new Funnel({ connectors: [...] }).`);return Q}listenerDeps($){return{channelId:$,fs:this.fs,process:this.process,logger:this.logger,diagnosticLog:this.diagnosticLog,connectorDir:(Q,Y)=>this.connectorDir(Q,Y)}}adapterDeps(){return{fs:this.fs,process:this.process,logger:this.logger}}}class Fq{millis(){return this.now().getTime()}iso(){return this.now().toISOString()}}class f4 extends Fq{now(){return new Date}}var sR6=new f4,tR6=new kQ;class Ga{store;registry;profileChecker;clock;idGenerator;constructor($){this.store=$.store,this.registry=$.registry,this.profileChecker=$.profileChecker??null,this.clock=$.clock??sR6,this.idGenerator=$.idGenerator??tR6,Object.freeze(this)}list(){return this.store.read().channels}get($){return this.list().find((Q)=>Q.name===$)??null}getById($){return this.list().find((Q)=>Q.id===$)??null}add($){let Q=this.store.read();if(Q.channels.some((X)=>X.name===$.name))throw Error(`channel "${$.name}" already exists`);let Y={id:this.idGenerator.generate(),name:$.name,delivery:$.delivery??"fanout",connectors:[]};return Q.channels.push(Y),this.store.write(Q),Y}setDelivery($,Q){let Y=this.store.read(),X=this.requireChannel(Y,$);X.delivery=Q,this.store.write(Y)}remove($){let Q=this.store.read(),Y=Q.channels.findIndex((z)=>z.name===$);if(Y<0)throw Error(`channel "${$}" not found`);let X=Q.channels[Y];if(X&&this.profileChecker?.hasChannelRef(X.id))throw Error(`channel "${$}" is referenced by a profile`);Q.channels.splice(Y,1),this.store.write(Q)}rename($,Q){let Y=this.store.read(),X=Y.channels.find((z)=>z.name===$);if(!X)throw Error(`channel "${$}" not found`);if(Y.channels.some((z)=>z.name===Q))throw Error(`channel "${Q}" already exists`);X.name=Q,this.store.write(Y)}listConnectors($){return this.requireChannel(this.store.read(),$).connectors}getConnector($,Q){let Y=this.get($);if(!Y)return null;return Y.connectors.find((X)=>X.name===Q)??null}listAllConnectors(){let $=[];for(let Q of this.list())for(let Y of Q.connectors)$.push({...Y,channelId:Q.id,channelName:Q.name});return $}addConnector($,Q){let Y=this.store.read(),X=this.requireChannel(Y,$);if(X.connectors.some((Z)=>Z.name===Q.name))throw Error(`connector "${Q.name}" already exists in channel "${$}"`);let z=this.registry.buildConfig(Q,{id:this.idGenerator.generate(),now:this.clock.iso()});return this.assertNoTokenCollision(Y,z),X.connectors.push(z),this.store.write(Y),z}removeConnector($,Q){let Y=this.store.read(),X=this.requireChannel(Y,$),z=X.connectors.findIndex((Z)=>Z.name===Q);if(z<0)throw Error(`connector "${Q}" not found in channel "${$}"`);X.connectors.splice(z,1),this.store.write(Y)}renameConnector($,Q,Y){let X=this.store.read(),z=this.requireChannel(X,$),Z=z.connectors.find((K)=>K.name===Q);if(!Z)throw Error(`connector "${Q}" not found in channel "${$}"`);if(z.connectors.some((K)=>K.name===Y))throw Error(`connector "${Y}" already exists in channel "${$}"`);Z.name=Y,Z.updatedAt=this.clock.iso(),this.store.write(X)}updateConnector($,Q,Y){let X=this.store.read(),z=this.requireChannel(X,$),Z=z.connectors.find((W)=>W.name===Q);if(!Z)throw Error(`connector "${Q}" not found in channel "${$}"`);let K=this.registry.applyUpdate(Z,Y,{now:this.clock.iso()});this.assertNoTokenCollision(X,K),this.replaceConnector(z,Z.name,K),this.store.write(X)}updateSlackConnector($,Q,Y){this.updateConnector($,Q,Y)}updateGhConnector($,Q,Y){this.updateConnector($,Q,Y)}updateDiscordConnector($,Q,Y){this.updateConnector($,Q,Y)}connectorOp($,Q,Y,X){let z=this.store.read(),Z=this.requireChannel(z,$),K=Z.connectors.find((H)=>H.name===Q);if(!K)throw Error(`connector "${Q}" not found in channel "${$}"`);let W=this.registry.runOperation(K,Y,X,{generateId:()=>this.idGenerator.generate(),now:this.clock.iso()});if(W.config!==K)this.replaceConnector(Z,K.name,W.config),this.store.write(z);return W.result}async call($,Q,Y){let X=this.getConnector($,Q);if(!X)throw Error(`connector "${Q}" not found in channel "${$}"`);let z=this.registry.createAdapter(X);if(!z)throw Error(`connector type "${X.type}" does not support outbound calls`);return await z.call(Y)}createListener($,Q){let Y=this.get($);if(!Y)return null;let X=Y.connectors.find((z)=>z.name===Q);if(!X)return null;return{config:X,channelId:Y.id,listener:this.registry.createListener(Y.id,X)}}createAllListeners(){let $=[];for(let Q of this.list())for(let Y of Q.connectors)$.push({config:Y,channelId:Q.id,channelName:Q.name,listener:this.registry.createListener(Q.id,Y)});return $}requireChannel($,Q){let Y=$.channels.find((X)=>X.name===Q);if(!Y)throw Error(`channel "${Q}" not found`);return Y}replaceConnector($,Q,Y){let X=$.connectors.findIndex((z)=>z.name===Q);if(X<0)throw Error(`connector "${Q}" not found in channel "${$.name}"`);$.connectors[X]=Y}assertNoTokenCollision($,Q){let Y=this.registry.secretTokens(Q);if(Y.length===0)return;for(let X of $.channels)for(let z of X.connectors){if(z.id===Q.id)continue;for(let Z of this.registry.secretTokens(z))if(Y.includes(Z))throw Error(`token already in use by connector "${z.name}" in channel "${X.name}"`)}}}var eR6=new p8,$T6=new kQ;class Ua{channels;mcp;gateway;sessions;guard;process;idGenerator;logger;dir;constructor($){this.channels=$.channels,this.mcp=$.mcp,this.gateway=$.gateway,this.sessions=$.sessions,this.guard=$.guard,this.process=$.process??eR6,this.idGenerator=$.idGenerator??$T6,this.logger=$.logger,this.dir=$.dir,Object.freeze(this)}async launch($){let Q=this.channels.get($.channel)??this.channels.getById($.channel);if(!Q)throw Error(`channel "${$.channel}" not found`);if($.profileId&&this.guard.isRunning($.profileId))throw Error(`profile "${$.profileId}" is already running`);let Y=$.cwd??globalThis.process.cwd();if(($.installMcp??!0)&&!this.mcp.findInstalledName(Y))this.mcp.install(Y),this.logger?.info("added funnel MCP to .mcp.json",{cwd:Y});if(!this.gateway.isRunning()){if(this.logger?.info("starting gateway automatically"),!await this.gateway.start())throw Error(`gateway failed to start on port ${uX()}; another funnel daemon (a different repo/scope) may already hold it. See 'fnl gateway logs' and 'ps -o pid,args= | grep funnel-gateway'.`)}if($.profileId)this.guard.acquire($.profileId);let Z=($.resume??!1)&&$.profileId?this.resolveSession($.profileId,Y,$.userArgs??[],$.env??{}):null,K=this.buildArgs($.options??[],$.userArgs??[],Y,Z),W=this.buildEnv(Q.id,$.env??{});this.logger?.info("claude launch",{channel:$.channel,channelId:Q.id,cwd:Y});try{return await this.process.attach(["claude",...K],{cwd:Y,env:W,onSpawned:$.onSpawned})}finally{if($.profileId)this.guard.release($.profileId)}}buildArgs($,Q,Y,X){let z=[...$,...Q];if(X!==null)if(X.mode==="resume")z.push("--resume",X.id);else z.push("--session-id",X.id);let Z=this.mcp.findInstalledName(Y);if(Z&&!z.includes("--dangerously-load-development-channels")&&!z.includes("--channels"))z.push("--dangerously-load-development-channels",`server:${Z}`);return z}resolveSession($,Q,Y,X){for(let K of Y){if(K==="-c"||K==="--continue")return null;if(K==="--resume"||K.startsWith("--resume="))return null;if(K==="--session-id"||K.startsWith("--session-id="))return null}let z=this.sessions.getSessionId($);if(z!==null&&this.sessions.sessionFileExists(Q,z,X))return{id:z,mode:"resume"};let Z=this.idGenerator.generate();return this.sessions.setSessionId($,Z),{id:Z,mode:"new"}}buildEnv($,Q){let Y={};for(let[X,z]of Object.entries(Q))Y[X]=z;for(let[X,z]of Object.entries(globalThis.process.env))if(typeof z==="string")Y[X]=z;if(Y.FUNNEL_CHANNEL_ID=$,Y.FUNNEL_PORT=String(uX()),this.dir!==void 0)Y.FUNNEL_DIR=this.dir;return Y}}import{join as V80}from"path";var QT6=new N8,YT6=new p8;class pM{fs;process;pidDir;constructor($={}){this.fs=$.fs??QT6,this.process=$.process??YT6,this.pidDir=V80($.dir??SQ,"claude"),Object.freeze(this)}isRunning($){let Q=this.readRecord($);if(!Q)return!1;if(!this.process.isAlive(Q.pid))return this.release($),!1;if(Q.startTime!==null){let Y=this.process.getStartTime(Q.pid);if(Y===null)return this.release($),!1;if(Y!==Q.startTime)return this.release($),!1}return!0}acquire($){this.fs.mkdirSync(this.pidDir,{recursive:!0});let Q=globalThis.process.pid,Y=this.process.getStartTime(Q),X={pid:Q,startTime:Y};this.fs.writeFileSync(this.pidPath($),JSON.stringify(X)),globalThis.process.once("exit",()=>this.release($))}release($){let Q=this.pidPath($);if(this.fs.existsSync(Q))this.fs.unlink(Q)}pidPath($){return V80(this.pidDir,`${$}.pid`)}readRecord($){let Q=this.pidPath($);if(!this.fs.existsSync(Q))return null;try{let Y=this.fs.readFileSync(Q).trim();if(!Y)return null;if(Y.startsWith("{")){let z=JSON.parse(Y),Z=typeof z.pid==="number"?z.pid:Number(z.pid);if(!Number.isInteger(Z)||Z<=0)return null;let K=typeof z.startTime==="string"?z.startTime:null;return{pid:Z,startTime:K}}let X=Number(Y);if(!X||X<=0)return null;return{pid:X,startTime:null}}catch{return null}}}import{existsSync as xa}from"fs";import{join as Ba}from"path";var Ja=($)=>typeof $==="string"&&$.length>0?$:null,iM=($)=>typeof $==="number"?$:null,lM=($,Q)=>typeof $==="string"?$:Q,XT6=($)=>$!==null&&typeof $==="object"&&!Array.isArray($),G80=($)=>{if($===null)return null;try{let Q=JSON.parse($);if(XT6(Q))return Q}catch{return null}return null},w80=($,Q)=>$.length<=Q?$:`${$.slice(0,Q)}\u2026`,zT6=($)=>{if(typeof $!=="string"||$.length===0)return null;let Q=G80($);if(Q!==null&&"text"in Q)return w80(String(Q.text),60);return w80($,60)},nM=($)=>{let Q=Ja($.payload);return{seq:iM($.seq),ts:iM($.ts),type:lM($.type,"?"),outcome:lM($.outcome,"?"),eventId:Ja($.event_id),payload:Q,payloadParsed:G80(Q),preview:zT6($.payload)}},qa=($)=>({seq:iM($.seq),ts:iM($.ts),type:lM($.type,"?"),status:lM($.status,"?"),detail:Ja($.detail)}),o7=($,Q,Y)=>{try{return $.query(Q,Y)}finally{$.close()}};var ZT6=($)=>{if($===null||typeof $!=="object")return!1;if(!("clients"in $)||!Array.isArray($.clients))return!1;if(!("listeners"in $)||!Array.isArray($.listeners))return!1;return!0},KT6=($,Q)=>{if(Q===null)return;return $.connectors?.find((Y)=>Y.id===Q)?.name},WT6=($)=>{let Y=($.connectionErrors[$.connectionErrors.length-1]??null)?.detail??null;if(!$.gateway.running)return{status:"error",message:"gateway is not running",nextActions:["fnl gateway start"],rootCause:null};let X=$.channel;if(!($.listeners.length>0))return{status:"warn",message:"no connectors configured on this channel",nextActions:[`fnl channels ${X} connectors add <name> --type=slack ...`],rootCause:null};let Z=$.listeners.every((V)=>!V.alive),K=$.listeners.some((V)=>!V.alive);if(Z)return{status:"error",message:"all listeners are dead",nextActions:["fnl doctor --fix","fnl doctor --fix --aggressive"],rootCause:Y};if(K)return{status:"warn",message:"some listeners are dead",nextActions:["fnl doctor --fix"],rootCause:Y};if($.claudeClients===0)return{status:"warn",message:"no Claude connected to this channel",nextActions:[`fnl claude --channel ${X}`],rootCause:null};if($.listeners.some((V)=>V.errors>0))return{status:"warn",message:"listeners have errors",nextActions:["fnl gateway logs"],rootCause:Y};let H=HT6($);if(H!==null)return H;return{status:"ok",message:"everything looks healthy",nextActions:[],rootCause:null}},HT6=($)=>{if(!$.listeners.some((Z)=>Z.type==="slack")||$.recentEvents.length===0)return null;let Y=$.recentEvents.filter((Z)=>Z.type==="slack").map((Z)=>Z.payloadParsed?.type);if(Y.length===0)return null;let X=Y.includes("app_mention"),z=Y.includes("message");if(!X||z)return null;return{status:"warn",message:"Slack is only delivering app_mention events; unmentioned thread replies may not arrive",nextActions:["Add Slack bot events: message.channels, message.groups, message.im, message.mpim; reinstall the app; then restart the gateway"],rootCause:"Slack Event Subscriptions likely omit message.* events"}};class Da{props;constructor($){this.props=$;Object.freeze(this)}async diagnose($){let Q=this.props.channels.list(),Y=$?Q.find((Z)=>Z.name===$)??null:Q[0]??null;if(!Y)return null;let X=await this.fetchGatewayStatus(),z=this.resolveStore();return this.buildChannelDiagnosis(Y,X,z,5)}async diagnoseAll(){let $=this.props.channels.list(),Q=await this.fetchGatewayStatus(),Y=this.resolveStore(),X=await Promise.all($.map((H)=>this.buildChannelDiagnosis(H,Q,Y,5))),z=X.filter((H)=>H.diagnosis.status==="error").map((H)=>H.channel),Z=X.filter((H)=>H.diagnosis.status==="warn").map((H)=>H.channel),K=X.filter((H)=>H.diagnosis.status==="ok").map((H)=>H.channel),W=[...new Set(X.flatMap((H)=>H.diagnosis.nextActions))];return{summary:{total:X.length,ok:K.length,warn:Z.length,error:z.length,criticalChannels:z,warnChannels:Z,suggestedActions:W},channels:X}}async recentEvents($,Q=20){let Y=this.resolveStore();if(!Y)return[];let X=this.resolveChannelId($);if($&&!X)return[];let z=new s9(Y),Z=X?o7(z,"SELECT seq, ts, type, outcome, payload FROM processed WHERE channel_id = ? ORDER BY seq DESC LIMIT ?",[X,Q]):o7(z,"SELECT seq, ts, type, outcome, payload FROM processed ORDER BY seq DESC LIMIT ?",[Q]);if(Z instanceof Error)return[];return Z.reverse().map(nM)}async droppedEvents($,Q=20){let Y=this.resolveStore();if(!Y)return[];let X=this.resolveChannelId($);if($&&!X)return[];let z=new s9(Y),Z=X?o7(z,"SELECT seq, ts, type, outcome, payload, event_id FROM processed WHERE channel_id = ? AND outcome LIKE 'skip:%' ORDER BY seq DESC LIMIT ?",[X,Q]):o7(z,"SELECT seq, ts, type, outcome, payload, event_id FROM processed WHERE outcome LIKE 'skip:%' ORDER BY seq DESC LIMIT ?",[Q]);if(Z instanceof Error)return[];return Z.reverse().map(nM)}async connectionErrors($,Q=20){let Y=this.resolveStore();if(!Y)return[];let X=this.resolveChannelId($);if($&&!X)return[];let z=new s9(Y),Z=X?o7(z,"SELECT seq, ts, type, status, detail FROM connection WHERE channel_id = ? AND status IN ('auth-failed','error') ORDER BY seq DESC LIMIT ?",[X,Q]):o7(z,"SELECT seq, ts, type, status, detail FROM connection WHERE status IN ('auth-failed','error') ORDER BY seq DESC LIMIT ?",[Q]);if(Z instanceof Error)return[];return Z.reverse().map(qa)}async replay($,Q){let X=this.props.channels.list().find((x)=>x.name===$);if(!X)return{state:"not-found"};let z=this.resolveStore();if(!z)return{state:"error",reason:"no diagnostic store yet"};let Z=new s9(z),K=Q!==void 0?o7(Z,"SELECT seq, event_id, type, payload, connector_id, channel_id FROM processed WHERE channel_id = ? AND seq = ? LIMIT 1",[X.id,Q]):o7(Z,"SELECT seq, event_id, type, payload, connector_id, channel_id FROM processed WHERE channel_id = ? AND outcome LIKE 'emitted%' ORDER BY seq DESC LIMIT 1",[X.id]);if(K instanceof Error)return{state:"error",reason:K.message};let W=K[0];if(!W)return{state:"not-found"};let H=typeof W.seq==="number"?W.seq:null,V=typeof W.event_id==="string"?W.event_id:null,w=typeof W.connector_id==="string"?W.connector_id:null,G=typeof W.payload==="string"?W.payload:null;if((!G||G.length===0)&&V){let x=o7(new s9(z),"SELECT payload FROM raw WHERE event_id = ? LIMIT 1",[V]),D=x instanceof Error?null:x[0];if(D)G=typeof D.payload==="string"?D.payload:null}if(!G)return{state:"error",reason:"event has no payload to replay"};let U=KT6(X,w),J=await this.props.publisher.publish(X.name,{content:G,connector:U});if(J.state==="offline")return{state:"offline"};if(J.state==="error")return{state:"error",reason:J.reason};return{state:"ok",seq:H,offset:J.offset,preview:G.slice(0,60)}}resolveStore(){let $=this.props.tmpDir,Q=Ba($,"connector-raw.db"),Y=Ba($,"connector-processed.db"),X=Ba($,"connector-connection.db");if(!xa(Q)||!xa(Y)||!xa(X))return null;return{rawPath:Q,processedPath:Y,connectionPath:X}}resolveChannelId($){if(!$)return null;return this.props.channels.list().find((Y)=>Y.name===$)?.id??null}async fetchGatewayStatus(){let $=this.props.gateway.getStatus();if(!$.running)return null;let Q=this.props.gatewayToken.read(),Y=Q?{Authorization:`Bearer ${Q}`}:{},X=await fetch(`${_$($.port)}/status`,{headers:Y}).catch(()=>null);if(!X||!X.ok)return null;let z=await X.json();return ZT6(z)?z:null}async buildChannelDiagnosis($,Q,Y,X){let z=this.props.gateway.getStatus(),Z=$.name,K={channel:Z,channelId:$.id,gateway:{running:z.running,pid:z.pid,port:z.running?z.port:null,uptimeMs:Q?.uptimeMs??null},listeners:[],claudeClients:0,recentEvents:[],connectionErrors:[]};if(Q)K.listeners=Q.listeners.filter((W)=>W.channelName===Z).map((W)=>({name:W.name,type:W.type,alive:W.alive,events:W.events,errors:W.errors,lastEventAt:W.lastEventAt})),K.claudeClients=Q.clients.filter((W)=>W.channelName===Z).length;if(Y){let W=o7(new s9(Y),"SELECT seq, ts, type, outcome, payload FROM processed WHERE channel_id = ? ORDER BY seq DESC LIMIT ?",[$.id,X]);if(!(W instanceof Error))K.recentEvents=W.reverse().map(nM);let H=K.listeners.some((w)=>!w.alive),V=K.listeners.some((w)=>w.errors>0);if(H||V){let w=o7(new s9(Y),"SELECT ts, type, status, detail FROM connection WHERE channel_id = ? AND status IN ('auth-failed','error') ORDER BY seq DESC LIMIT 3",[$.id]);if(!(w instanceof Error))K.connectionErrors=w.reverse().map(qa)}}return{...K,diagnosis:WT6(K)}}}class La{props;constructor($){this.props=$;Object.freeze(this)}async run($="off"){if($==="off"){let W=await this.props.diagnostics.diagnoseAll();return this.buildReport({before:null,after:W,appliedActions:[],fixFailed:!1})}let Q=await this.props.diagnostics.diagnoseAll(),Y=[],X=!1;if(Q.channels.some((W)=>W.diagnosis.status==="error"&&!W.gateway.running)){let W=await this.props.recovery.ensureGatewayRunning();if(Y.push(...W.actions),!W.ok)X=!0}if(Q.channels.some((W)=>W.listeners.some((H)=>!H.alive))){let W=await this.props.recovery.restartAllDeadListeners();if(Y.push(...W.actions),!W.ok&&W.actions.length===0)X=!0}if($==="aggressive"){if(Y.length===0||Q.channels.some((H)=>H.diagnosis.status==="error")){let H=await this.props.recovery.restartGateway();if(Y.push(...H.actions),!H.ok)X=!0}}let K=await this.props.diagnostics.diagnoseAll();return this.buildReport({before:Q,after:K,appliedActions:Y,fixFailed:X})}buildReport($){let Q=$.after.channels.filter((z)=>z.diagnosis.status!=="ok").map((z)=>({channel:z.channel,diagnosis:z.diagnosis})),Y=$.fixFailed?"error":Q.length===0?"ok":"warn",X=VT6({mode:$.before===null?"off":"fix",status:Y,appliedCount:$.appliedActions.length,remainingCount:Q.length});return{status:Y,message:X,before:$.before,after:$.after,appliedActions:$.appliedActions,remainingIssues:Q}}}var VT6=($)=>{if($.mode==="off"){if($.remainingCount===0)return"all channels healthy";return`${$.remainingCount} channel(s) need attention \u2014 run \`fnl doctor --fix\` to apply suggested fixes`}if($.status==="error")return"one or more fix steps failed \u2014 check fnl gateway logs";if($.status==="ok")return`applied ${$.appliedCount} fix(es), all channels healthy`;return`applied ${$.appliedCount} fix(es), ${$.remainingCount} channel(s) still need attention`};function Fa($){if($.env!==void 0)return{botTokenEnv:$.env};if($.literal!==void 0)return{botToken:$.literal};return{}}function U80($){if($.env!==void 0)return{appTokenEnv:$.env};if($.literal!==void 0)return{appToken:$.literal};return{}}class Na{channels;prompter;constructor($){this.channels=$.channels,this.prompter=$.prompter,Object.freeze(this)}async ensure($){if(!this.channels.get($.name))this.channels.add({name:$.name});if($.connectors===void 0)return{touched:[],removed:[]};let Y=[],X=new Set;for(let Z of $.connectors){let K=await this.ensureConnector($.name,Z);Y.push({name:K.name,changed:K.changed}),X.add(K.id)}let z=this.removeExtras($.name,X);return{touched:Y,removed:z}}async ensureConnector($,Q){if(Q.type==="slack")return await this.ensureSlack($,Q);if(Q.type==="discord")return await this.ensureDiscord($,Q);if(Q.type==="gh")return this.ensureGh($,Q);return this.ensureSchedule($,Q)}async ensureSlack($,Q){let Y=this.findExistingSlack($,Q.name),X=await this.resolveSlot({label:`${Q.name}.botToken`,existingLiteral:Y?.botToken,existingEnv:Y?.botTokenEnv}),z=await this.resolveSlot({label:`${Q.name}.appToken`,existingLiteral:Y?.appToken,existingEnv:Y?.appTokenEnv}),Z={botToken:X.token,botTokenEnv:X.tokenEnv,appToken:z.token,appTokenEnv:z.tokenEnv};if(Y){if(!(Y.botToken===X.token&&Y.botTokenEnv===X.tokenEnv&&Y.appToken===z.token&&Y.appTokenEnv===z.tokenEnv))return this.channels.updateSlackConnector($,Q.name,Z),{id:Y.id,name:Q.name,changed:!0};return{id:Y.id,name:Q.name,changed:!1}}return{id:this.channels.addConnector($,{type:"slack",name:Q.name,...Fa({literal:X.token,env:X.tokenEnv}),...U80({literal:z.token,env:z.tokenEnv}),...Q.minify!==void 0?{minify:Q.minify}:{}}).id,name:Q.name,changed:!0}}async ensureDiscord($,Q){let Y=this.findExistingDiscord($,Q.name),X=await this.resolveSlot({label:`${Q.name}.botToken`,existingLiteral:Y?.botToken,existingEnv:Y?.botTokenEnv}),z={botToken:X.token,botTokenEnv:X.tokenEnv};if(Y){if(Y.botToken!==X.token||Y.botTokenEnv!==X.tokenEnv)return this.channels.updateDiscordConnector($,Q.name,z),{id:Y.id,name:Q.name,changed:!0};return{id:Y.id,name:Q.name,changed:!1}}return{id:this.channels.addConnector($,{type:"discord",name:Q.name,...Fa({literal:X.token,env:X.tokenEnv})}).id,name:Q.name,changed:!0}}ensureGh($,Q){let Y=this.channels.getConnector($,Q.name);if(Y&&Y.type!=="gh")throw Error(`connector "${Q.name}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "gh"`);if(Y&&Y.type==="gh"){let z=yz.parse(Y);if(Q.pollInterval!==void 0&&z.pollInterval!==Q.pollInterval)return this.channels.updateGhConnector($,Q.name,{pollInterval:Q.pollInterval}),{id:z.id,name:Q.name,changed:!0};return{id:z.id,name:Q.name,changed:!1}}return{id:this.channels.addConnector($,{type:"gh",name:Q.name,...Q.pollInterval!==void 0?{pollInterval:Q.pollInterval}:{}}).id,name:Q.name,changed:!0}}ensureSchedule($,Q){let Y=this.channels.getConnector($,Q.name);if(Y&&Y.type!=="schedule")throw Error(`connector "${Q.name}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "schedule"`);if(Y&&Y.type==="schedule")return{id:Y.id,name:Q.name,changed:!1};return{id:this.channels.addConnector($,{type:"schedule",name:Q.name}).id,name:Q.name,changed:!0}}findExistingSlack($,Q){let Y=this.channels.getConnector($,Q);if(!Y)return null;if(Y.type!=="slack")throw Error(`connector "${Q}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "slack"`);return HX.parse(Y)}findExistingDiscord($,Q){let Y=this.channels.getConnector($,Q);if(!Y)return null;if(Y.type!=="discord")throw Error(`connector "${Q}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "discord"`);return gY.parse(Y)}removeExtras($,Q){let Y=this.channels.get($);if(!Y)return[];let X=Y.connectors.filter((z)=>!Q.has(z.id));for(let z of X)this.channels.removeConnector($,z.name);return X.map((z)=>z.name)}async resolveSlot($){if($.existingEnv!==void 0)return{token:void 0,tokenEnv:$.existingEnv};if($.existingLiteral!==void 0)return{token:$.existingLiteral,tokenEnv:void 0};return{token:await this.prompter.promptSecret($.label),tokenEnv:void 0}}}import{homedir as wT6}from"os";import{join as J80}from"path";var GT6=new N8;class Pa{store;idGenerator;fs;constructor($){this.store=$.store,this.idGenerator=$.idGenerator,this.fs=$.fs??GT6,Object.freeze(this)}list(){return this.store.read().profiles}get($){return this.list().find((Q)=>Q.name===$)??null}getById($){return this.list().find((Q)=>Q.id===$)??null}getDefault(){return this.list()[0]??null}add($){let Q=this.store.read();if(Q.profiles.some((Y)=>Y.name===$.name))throw Error(`profile "${$.name}" already exists`);if(!Q.channels.some((Y)=>Y.id===$.channelId))throw Error(`channel id "${$.channelId}" not found`);Q.profiles.push({id:this.idGenerator.generate(),name:$.name,path:$.path,channelId:$.channelId,options:$.options??[],env:$.env??{},resume:$.resume??!0}),this.store.write(Q)}remove($){let Q=this.store.read(),Y=Q.profiles.findIndex((X)=>X.name===$);if(Y<0)throw Error(`profile "${$}" not found`);Q.profiles.splice(Y,1),this.store.write(Q)}rename($,Q){let Y=this.store.read(),X=Y.profiles.find((z)=>z.name===$);if(!X)throw Error(`profile "${$}" not found`);if(Y.profiles.some((z)=>z.name===Q))throw Error(`profile "${Q}" already exists`);X.name=Q,this.store.write(Y)}asDefault($){let Q=this.store.read(),Y=Q.profiles.findIndex((z)=>z.name===$);if(Y<0)throw Error(`profile "${$}" not found`);if(Y===0)return;let[X]=Q.profiles.splice(Y,1);if(!X)return;Q.profiles.unshift(X),this.store.write(Q)}hasChannelRef($){return this.store.read().profiles.some((Q)=>Q.channelId===$)}getSessionId($){return this.getById($)?.sessionId??null}setSessionId($,Q){let Y=this.store.read(),X=Y.profiles.find((z)=>z.id===$);if(!X)throw Error(`profile id "${$}" not found`);X.sessionId=Q,this.store.write(Y)}sessionFileExists($,Q,Y){let X=Y.CLAUDE_CONFIG_DIR??globalThis.process.env.CLAUDE_CONFIG_DIR??J80(wT6(),".claude"),z=$.replace(/\//g,"-"),Z=J80(X,"projects",z,`${Q}.jsonl`);if(!this.fs.existsSync(Z))return!1;return this.fs.readFileSync(Z).trim().length>0}update($,Q){let Y=this.store.read(),X=Y.profiles.find((z)=>z.name===$);if(!X)throw Error(`profile "${$}" not found`);if(Q.channelId!==void 0){if(!Y.channels.some((z)=>z.id===Q.channelId))throw Error(`channel id "${Q.channelId}" not found`);X.channelId=Q.channelId}if(Q.path!==void 0)X.path=Q.path;if(Q.options!==void 0)X.options=Q.options;if(Q.env!==void 0)X.env=Q.env;if(Q.resume!==void 0)X.resume=Q.resume;this.store.write(Y)}}class ja{props;constructor($){this.props=$;Object.freeze(this)}async ensureGatewayRunning(){if(this.props.gateway.isRunning())return{ok:!0,actions:[{kind:"gateway:already-running"}],message:"gateway is already running"};if(!await this.props.gateway.start())return{ok:!1,actions:[],message:"gateway failed to start \u2014 check `fnl gateway logs`"};return{ok:!0,actions:[{kind:"gateway:started"}],message:"gateway started"}}async restartGateway(){if(!(await this.props.gateway.restart()).ok)return{ok:!1,actions:[],message:"gateway restart failed \u2014 check `fnl gateway logs`"};return{ok:!0,actions:[{kind:"gateway:restarted"}],message:"gateway restarted"}}async restartListener($,Q){let Y=await this.props.listeners.restart($,Q);if(Y.state==="offline")return{ok:!1,actions:[],message:"gateway is not running \u2014 call ensureGatewayRunning() first"};if(Y.state==="not-found")return{ok:!1,actions:[{kind:"listener:skipped",channel:$,connector:Q,reason:"not-found"}],message:`listener not found: ${$}/${Q}`};if(Y.state==="error")return{ok:!1,actions:[{kind:"listener:skipped",channel:$,connector:Q,reason:Y.reason}],message:`listener restart failed: ${Y.reason}`};return{ok:!0,actions:[{kind:"listener:restarted",channel:$,connector:Q}],message:`restarted ${$}/${Q}`}}async restartAllDeadListeners(){let $=await this.props.listeners.list();if($.state==="offline")return{ok:!1,actions:[],message:"gateway is not running \u2014 call ensureGatewayRunning() first"};if($.state==="error")return{ok:!1,actions:[],message:`could not list listeners: ${$.reason}`};let Q=$.listeners.filter((z)=>!z.alive);if(Q.length===0)return{ok:!0,actions:[],message:"no dead listeners found"};let Y=[];for(let z of Q){let Z=await this.props.listeners.restart(z.channelName,z.name);if(Z.state==="ok")Y.push({kind:"listener:restarted",channel:z.channelName,connector:z.name});else{let K=Z.state==="error"?Z.reason:Z.state;Y.push({kind:"listener:skipped",channel:z.channelName,connector:z.name,reason:K})}}let X=Y.filter((z)=>z.kind==="listener:restarted").length;return{ok:X>0,actions:Y,message:`restarted ${X}/${Q.length} dead listener(s)`}}}import{stderr as dM,stdin as vY}from"process";class Ia{}var UT6="*",JT6="\r",q80=`
2020
2020
  `,qT6=String.fromCharCode(8),xT6=String.fromCharCode(127),BT6=String.fromCharCode(3),DT6=String.fromCharCode(4);class Ma extends Ia{async promptSecret($){if(!vY.isTTY)throw Error(`cannot prompt for "${$}": stdin is not a TTY. Set the matching env var or run \`fnl channels <ch> connectors add ...\` first.`);dM.write(`${$}: `);let Q=vY.isRaw;vY.setRawMode(!0),vY.resume();try{return await this.readSecret()}finally{vY.setRawMode(Q),vY.pause(),dM.write(q80)}}readSecret(){return new Promise(($,Q)=>{let Y="",X=(z)=>{for(let Z of z){let K=String.fromCharCode(Z);if(K===q80||K===JT6){vY.off("data",X),$(Y);return}if(K===BT6){vY.off("data",X),Q(Error("prompt cancelled"));return}if(K===DT6){if(vY.off("data",X),Y.length===0)Q(Error("prompt cancelled"));else $(Y);return}if(K===qT6||K===xT6){if(Y.length>0)Y=Y.slice(0,-1),dM.write("\b \b");continue}Y+=K,dM.write(UT6)}};vY.on("data",X)})}}var LT6=384;class Oa extends nw{dirs;files;mtimes;modes;now;constructor($={}){super();this.dirs=new Set($.dirs??[]),this.files=new Map(Object.entries($.files??{})),this.mtimes=new Map(Object.entries($.mtimes??{})),this.modes=new Map(Object.entries($.modes??{})),this.now=$.now??(()=>Date.now())}existsSync($){return this.dirs.has($)||this.files.has($)}readFileSync($){return this.files.get($)??""}writeFileSync($,Q){this.files.set($,Q),this.touch($)}writeSecretFileSync($,Q){this.files.set($,Q),this.modes.set($,LT6),this.touch($)}appendFileSync($,Q){let Y=this.files.get($)??"";this.files.set($,Y+Q),this.touch($)}unlink($){this.files.delete($),this.mtimes.delete($),this.modes.delete($)}mkdirSync($,Q){this.dirs.add($)}readdirSync($){let Q=$.endsWith("/")?$:`${$}/`,Y=[];for(let X of this.files.keys()){if(!X.startsWith(Q))continue;let z=X.slice(Q.length);if(!z.includes("/"))Y.push(z)}return Y}statSync($){let Q=this.mtimes.get($);if(Q===void 0)throw Error(`not found: ${$}`);return{mtimeMs:Q,mode:this.modes.get($)??null}}setMtime($,Q){this.mtimes.set($,Q)}setMode($,Q){this.modes.set($,Q)}touch($){if(!this.mtimes.has($))this.mtimes.set($,this.now());else this.mtimes.set($,this.now())}}class va extends qq{counter=0;prefix;constructor($={}){super();this.prefix=$.prefix??"id"}generate(){return this.counter++,`${this.prefix}-${this.counter}`}}class ba extends Bq{file=null;entries=[];info($,Q){this.entries.push({level:"info",message:$,meta:Q})}warn($,Q){this.entries.push({level:"warn",message:$,meta:Q})}error($,Q){this.entries.push({level:"error",message:$,meta:Q})}clear(){this.entries.length=0}}var x80={exitCode:0,stdout:"",stderr:""};class _a extends iw{calls=[];killed=[];handler=()=>x80;syncHandler=()=>x80;aliveStub=null;listStub=null;startTimeStub=null;on($){return this.handler=$,this}onSync($){return this.syncHandler=$,this}onIsAlive($){return this.aliveStub=$,this}onListProcessesContaining($){return this.listStub=$,this}onGetStartTime($){return this.startTimeStub=$,this}async run($,Q={}){this.calls.push({kind:"run",command:$,options:Q});let Y=await this.handler($);return{exitCode:Y.exitCode??0,stdout:Y.stdout??"",stderr:Y.stderr??""}}runSync($){this.calls.push({kind:"runSync",command:$});let Q=this.syncHandler($);return{exitCode:Q.exitCode??0,stdout:Q.stdout??"",stderr:Q.stderr??""}}async attach($,Q={}){if(this.calls.push({kind:"attach",command:$,options:Q}),Q.onSpawned)Q.onSpawned(1);return(await this.handler($)).exitCode??0}detach($,Q={}){this.calls.push({kind:"detach",command:$,options:Q})}kill($,Q="SIGTERM"){this.calls.push({kind:"kill",command:[String($),Q]}),this.killed.push({pid:$,signal:Q})}isAlive($){if(this.aliveStub)return this.aliveStub($);let Q=this.syncHandler(["ps","-p",String($),"-o","state="]);if((Q.exitCode??0)!==0)return!1;let Y=(Q.stdout??"").trim();if(!Y)return!1;return!Y.startsWith("Z")}listProcessesContaining($){if(this.listStub)return this.listStub($);return[]}getStartTime($){if(this.startTimeStub)return this.startTimeStub($);return null}}var FT6=($={})=>({version:CX,channels:[],profiles:[],...$});class Aa extends xq{state;constructor($){super();this.state=FT6($)}read(){return this.state}write($){this.state=$}}class Ra extends Fq{current;constructor($={}){super();this.current=$.start??new Date(0)}now(){return new Date(this.current.getTime())}set($){this.current=$}advance($){this.current=new Date(this.current.getTime()+$)}}var B80=P.object({content:P.string().min(1),meta:P.record(P.string(),P.string()).optional(),connector:P.string().min(1).optional(),target:P.string().min(1).optional()}),D80=P.object({ok:P.literal(!0),offset:P.number().int().nonnegative()});var NT6={state:"offline"};class Ta{port;isDaemonRunning;getToken;constructor($){this.port=$.port,this.isDaemonRunning=$.isDaemonRunning,this.getToken=$.getToken??(()=>null),Object.freeze(this)}async publish($,Q){if(!this.isDaemonRunning())return NT6;try{let Y=`${_$(this.port)}/channels/${encodeURIComponent($)}/publish`,X=await fetch(Y,{method:"POST",headers:{...this.authHeaders(),"content-type":"application/json"},body:JSON.stringify(Q)});if(!X.ok)return{state:"error",reason:await X.text()||`HTTP ${X.status}`};let z=D80.safeParse(await X.json());if(!z.success)return{state:"error",reason:"malformed daemon response"};return{state:"ok",offset:z.data.offset}}catch(Y){return{state:"error",reason:Y instanceof Error?Y.message:String(Y)}}}authHeaders(){let $=this.getToken();return $?{authorization:`Bearer ${$}`}:{}}}import{join as L80}from"path";import{existsSync as PT6}from"fs";import{dirname as jT6,resolve as fa}from"path";import{fileURLToPath as IT6}from"url";var aM=()=>{let $=jT6(IT6(import.meta.url)),Q=[fa($,"./daemon.ts"),fa($,"./daemon.js"),fa($,"./gateway/daemon.js")];for(let Y of Q)if(PT6(Y))return Y;throw Error(`daemon script not found (looked in ${Q.join(", ")})`)};var MT6=5000,OT6=2000,F80=100,vT6=200,bT6=new p8,_T6=new N8,AT6=new f4,RT6=($)=>new Promise((Q)=>{setTimeout(Q,$)});class ka{process;fs;clock;dir;pidFile;gatewayLog;tmpDir;port;sleep;constructor($={}){this.process=$.process??bT6,this.fs=$.fs??_T6,this.clock=$.clock??AT6,this.dir=$.dir??SQ,this.tmpDir=$.tmpDir??n$(),this.pidFile=L80(this.dir,"gateway.pid"),this.gatewayLog=L80(this.tmpDir,"gateway.log"),this.port=$.port??uX(),this.sleep=$.sleep??RT6,Object.freeze(this)}isRunning(){let $=this.readPid();if(!$)return!1;return this.isProcessAlive($)}getStatus(){let $=this.readPid(),Q=$!==null&&this.isProcessAlive($);return{running:Q,pid:Q?$:null,port:this.port}}async start($={}){if(this.isRunning())return!0;this.fs.mkdirSync(this.tmpDir,{recursive:!0});let Q=aM(),Y=this.buildStartCommand(Q,$);this.process.detach(Y,{env:{FUNNEL_DIR:this.dir},stdoutFile:this.gatewayLog,stderrFile:this.gatewayLog});let X=this.clock.millis()+MT6;while(this.clock.millis()<X){if(this.isRunning())return!0;await this.sleep(F80)}return this.isRunning()}buildStartCommand($,Q={}){let Y=`funnel-gateway[${this.dir}]`;if(Q.caffeinate!==!1&&globalThis.process.platform==="darwin")return["caffeinate","-is","bun",$,Y];return["bun",$,Y]}async stop(){let $=this.readPid();if(!$)return!0;if(!this.isProcessAlive($))return this.removePid(),!0;try{this.process.kill($,"SIGTERM")}catch{return!1}let Q=this.clock.millis()+OT6;while(this.clock.millis()<Q){if(!this.isProcessAlive($))return this.removePid(),!0;await this.sleep(F80)}try{this.process.kill($,"SIGKILL")}catch{}return await this.sleep(vT6),this.removePid(),!this.isProcessAlive($)}async restart($={}){let Q=this.isRunning();if($.onlyIfRunning&&!Q)return{ok:!0,wasRunning:!1,stopped:!1,started:!1};let Y=Q?await this.stop():!0;if(!Y)return{ok:!1,wasRunning:Q,stopped:!1,started:!1};let X=await this.start({caffeinate:$.caffeinate});return{ok:X,wasRunning:Q,stopped:Y,started:X}}getGatewayLog(){return this.gatewayLog}getPort(){return this.port}readPid(){if(!this.fs.existsSync(this.pidFile))return null;try{let $=this.fs.readFileSync(this.pidFile).trim(),Q=Number($);if(!Q||Q<=0)return null;return Q}catch{return null}}removePid(){this.fs.unlink(this.pidFile)}isProcessAlive($){return this.process.isAlive($)}}import{existsSync as Vf6,mkdirSync as wf6}from"fs";import{dirname as Gf6,join as Uf6}from"path";import{timingSafeEqual as TT6}from"crypto";var Nq=($)=>{return async(Q,Y)=>{let Z=(Q.req.header("authorization")??"").match(/^Bearer\s+(.+)$/i)?.[1]??"";if(!oM(Z,$.expected))return Q.text("unauthorized",401);return await Y()}},oM=($,Q)=>{let Y=Buffer.from($,"utf-8"),X=Buffer.from(Q,"utf-8"),z=Math.max(Y.length,X.length,1),Z=Buffer.alloc(z),K=Buffer.alloc(z);return Y.copy(Z),X.copy(K),TT6(Z,K)&&Y.length===X.length};var B8=MB();var N80=($)=>{let Q=Buffer.byteLength($.content,"utf-8");if($.meta)for(let[Y,X]of Object.entries($.meta))Q+=Buffer.byteLength(Y,"utf-8")+Buffer.byteLength(X,"utf-8");return Q},fT6=1048576,kT6=200,ST6=4194304,ET6=()=>{};class Sa{clients=new Map;subscribers=new Set;logger;onError;maxBufferedBytes;now;replayBufferSize;replayBufferMaxBytes;replayBuffer=[];persistentReplay;exclusiveCursor=new Map;replayBufferBytes=0;eventsBroadcast=0;droppedSlowClients=0;lastBroadcastAt=null;latestOffset=0;constructor($={}){this.logger=$.logger,this.onError=$.onError??ET6,this.maxBufferedBytes=$.maxBufferedBytes??fT6,this.now=$.now??(()=>Date.now()),this.replayBufferSize=Math.max(0,$.replayBufferSize??kT6),this.replayBufferMaxBytes=Math.max(0,$.replayBufferMaxBytes??ST6),this.persistentReplay=$.persistentReplay??null}getMetrics(){return{clients:this.clients.size,subscribers:this.subscribers.size,eventsBroadcast:this.eventsBroadcast,droppedSlowClients:this.droppedSlowClients,lastBroadcastAt:this.lastBroadcastAt?new Date(this.lastBroadcastAt).toISOString():null,latestOffset:this.latestOffset,oldestReplayableOffset:this.replayBuffer[0]?.offset??null}}replaySince($,Q){let Y=this.replayBuffer[0]?.offset,X=this.persistentReplay&&(Y===void 0||$<Y-1),z=this.replayBuffer.filter((H)=>H.offset>$&&this.matchesClient(H,Q));if(!X)return z;let Z=this.persistentReplay?this.persistentReplay.loadSince($).filter((H)=>this.matchesClient(H,Q)):[],K=Y??Number.POSITIVE_INFINITY;return[...Z.filter((H)=>H.offset<K),...z]}matchesClient($,Q){let Y=$.meta?.target;if(Y&&Y!==Q.subscriberId)return!1;let X=$.meta?.channelId;if(X&&X!==Q.channel)return!1;let z=$.meta?.connector;if(!z)return!0;return Q.connectors.includes(z)}pickRecipients($){let Q=new Map,Y=[];for(let[X,z]of this.clients){if(!this.matchesClient($,z))continue;if(z.delivery==="exclusive"){let Z=Q.get(z.channel)??[];Z.push(X),Q.set(z.channel,Z);continue}Y.push(X)}for(let[X,z]of Q){if(z.length===0)continue;let Z=this.exclusiveCursor.get(X)??0,K=z[Z%z.length];if(K)Y.push(K);this.exclusiveCursor.set(X,Z+1)}return Y}addClient($,Q){this.clients.set($,Q)}removeClient($){this.clients.delete($)}getClientCount(){return this.clients.size}listChannels(){return[...this.clients.values()].map(($)=>({...$}))}subscribe($){return this.subscribers.add($),()=>{this.subscribers.delete($)}}broadcast($,Q){this.latestOffset+=1;let Y={content:$,meta:Q,offset:this.latestOffset},X=JSON.stringify(Y),z=Q?.connector;if(this.eventsBroadcast+=1,this.lastBroadcastAt=this.now(),this.replayBufferSize>0){let K=N80(Y);this.replayBuffer.push(Y),this.replayBufferBytes+=K;while((this.replayBuffer.length>this.replayBufferSize||this.replayBufferBytes>this.replayBufferMaxBytes)&&this.replayBuffer.length>0){let W=this.replayBuffer.shift();if(W)this.replayBufferBytes-=N80(W)}}let Z=this.pickRecipients(Y);for(let K of Z){let W=K.getBufferedAmount();if(W>this.maxBufferedBytes){let H=this.clients.get(K);this.logger?.warn("dropping slow WS client (backpressure)",{channel:H?.channel,buffered:W,max:this.maxBufferedBytes});try{K.close(1009,"backpressure")}catch{}this.clients.delete(K),this.droppedSlowClients+=1;continue}K.send(X)}for(let K of this.subscribers)try{K(Y)}catch(W){let H=W instanceof Error?W:Error(String(W));this.logger?.error("broadcast subscriber threw",{error:H.message}),this.onError(H,{component:"broadcaster.subscriber",offset:Y.offset,connector:Y.meta?.connector??null,channel:Y.meta?.channel??null})}return Y}seedLatestOffset($){if($>this.latestOffset)this.latestOffset=$}}var yq8=P.object({type:P.string(),content:P.string(),channel_id:P.string().nullable(),connector_id:P.string().nullable(),meta:P.record(P.string(),P.string()).nullable()});class Ea{}import{Database as CT6}from"bun:sqlite";import{existsSync as uT6,mkdirSync as cT6}from"fs";import{dirname as yT6}from"path";var gT6=/^[a-z_][a-z0-9_]*$/,hT6=500,mT6=new Set(["seq","ts","type","event"]),P80=[["CREATE TABLE IF NOT EXISTS logs (seq INTEGER PRIMARY KEY, ts INTEGER NOT NULL, type TEXT, event TEXT NOT NULL)","CREATE INDEX IF NOT EXISTS idx_logs_ts ON logs (ts)","CREATE INDEX IF NOT EXISTS idx_logs_type ON logs (type)"],["DROP TABLE IF EXISTS leuco_log","CREATE TABLE IF NOT EXISTS logs (seq INTEGER PRIMARY KEY, ts INTEGER NOT NULL, type TEXT, event TEXT NOT NULL)","CREATE INDEX IF NOT EXISTS idx_logs_ts ON logs (ts)","CREATE INDEX IF NOT EXISTS idx_logs_type ON logs (type)"]];class Ca{db;maxRows;maxAgeMs;maxBytes;targetBytes;now;indexes;extractIndexes;insertStmt;insertWithSeqStmt;maxSeqStmt;countStmt;trimRowsStmt;trimAgeStmt;trimOldestStmt;insertsSinceByteCheck=0;constructor($){if($.path!==":memory:"){let Z=yT6($.path);if(!uT6(Z))cT6(Z,{recursive:!0})}if(this.db=new CT6($.path),this.db.run("PRAGMA journal_mode = WAL"),this.migrate(),this.maxRows=$.maxRows??null,this.maxAgeMs=$.maxAgeMs??null,this.maxBytes=$.maxBytes??null,this.targetBytes=$.targetBytes??($.maxBytes!==void 0?Math.floor($.maxBytes/4):null),this.now=$.now??(()=>Date.now()),this.indexes=$.indexes??[],this.indexes.length>0)pT6(this.indexes),this.extractIndexes=$.extractIndexes??null,this.syncIndexColumns();else this.extractIndexes=null;let Q=["ts","type","event",...this.indexes],Y=Q.map(()=>"?").join(", ");this.insertStmt=this.db.prepare(`INSERT INTO logs (${Q.join(", ")}) VALUES (${Y})`);let X=["seq",...Q],z=X.map(()=>"?").join(", ");this.insertWithSeqStmt=this.db.prepare(`INSERT INTO logs (${X.join(", ")}) VALUES (${z})`),this.maxSeqStmt=this.db.prepare("SELECT COALESCE(MAX(seq), 0) AS max FROM logs"),this.countStmt=this.db.prepare("SELECT COUNT(*) AS n FROM logs"),this.trimRowsStmt=this.db.prepare("DELETE FROM logs WHERE seq <= (SELECT seq FROM logs ORDER BY seq DESC LIMIT 1 OFFSET ?)"),this.trimAgeStmt=this.db.prepare("DELETE FROM logs WHERE ts < ?"),this.trimOldestStmt=this.db.prepare("DELETE FROM logs WHERE seq IN (SELECT seq FROM logs ORDER BY seq ASC LIMIT ?)")}insert($){try{let Q=this.buildInsertParams($.ts,$.event),Y=this.insertStmt.run(...Q),X=Number(Y.lastInsertRowid);return this.trim(),{seq:X,ts:$.ts,event:$.event}}catch(Q){return Q instanceof Error?Q:Error(String(Q))}}insertMany($){if($.length===0)return[];try{let Q=[];return this.db.transaction((X)=>{for(let z of X){let Z=this.buildInsertParams(z.ts,z.event),K=this.insertStmt.run(...Z);Q.push({seq:Number(K.lastInsertRowid),ts:z.ts,event:z.event})}})($),this.trim(),Q}catch(Q){return Q instanceof Error?Q:Error(String(Q))}}write($){try{let Q=[$.seq,...this.buildInsertParams($.ts,$.event)];this.insertWithSeqStmt.run(...Q),this.trim()}catch(Q){return Q instanceof Error?Q:Error(String(Q))}}getMaxSeq(){let $=this.maxSeqStmt.get();return $?$.max:0}query($={}){let Q=["seq > ?"],Y=[$.sinceSeq??0];if(typeof $.type==="string")Q.push("type = ?"),Y.push($.type);if($.where)this.appendWhereConditions($.where,Q,Y);let X=$.limit??1000;Y.push(X);let z=$.order==="desc"?"DESC":"ASC",Z=`SELECT seq, ts, type, event FROM logs WHERE ${Q.join(" AND ")} ORDER BY seq ${z} LIMIT ?`,W=this.db.prepare(Z).all(...Y);if(z==="DESC")W.reverse();return W.map(lT6)}getSchemaVersion(){return this.db.prepare("PRAGMA user_version").get()?.user_version??0}close(){this.db.close()}buildInsertParams($,Q){let Y=iT6(Q),X=JSON.stringify(Q);if(this.indexes.length===0)return[$,Y,X];let z=this.extractIndexes?this.extractIndexes(Q):null,Z=this.indexes.map((K)=>z?.[K]??null);return[$,Y,X,...Z]}appendWhereConditions($,Q,Y){let X=$;for(let z of this.indexes){let Z=X[z];if(Z===void 0)continue;if(Z===null)Q.push(`${z} IS NULL`);else Q.push(`${z} = ?`),Y.push(Z)}}trim(){if(this.maxRows!==null){let $=this.countStmt.get();if($&&$.n>this.maxRows)this.trimRowsStmt.run(this.maxRows)}if(this.maxAgeMs!==null)this.trimAgeStmt.run(this.now()-this.maxAgeMs);this.maybeTrimBytes()}maybeTrimBytes(){if(this.maxBytes===null||this.targetBytes===null)return;if(this.insertsSinceByteCheck+=1,this.insertsSinceByteCheck<hT6)return;this.insertsSinceByteCheck=0;let $=this.byteSize();if($<=this.maxBytes)return;let Q=this.countStmt.get()?.n??0;if(Q===0)return;let Y=$-this.targetBytes,X=$/Q,z=Math.min(Q,Math.ceil(Y/X));this.trimOldestStmt.run(z),this.db.run("VACUUM")}byteSize(){let $=this.db.prepare("PRAGMA page_count").get()?.n??0,Q=this.db.prepare("PRAGMA page_size").get()?.n??0;return $*Q}clear(){this.db.run("DELETE FROM logs"),this.db.run("VACUUM"),this.insertsSinceByteCheck=0}syncIndexColumns(){let $=new Set(this.db.prepare("PRAGMA table_info(logs)").all().map((Q)=>Q.name));for(let Q of this.indexes){if(!$.has(Q))this.db.run(`ALTER TABLE logs ADD COLUMN ${Q} TEXT`);this.db.run(`CREATE INDEX IF NOT EXISTS idx_logs_${Q} ON logs (${Q})`)}}migrate(){let Q=this.db.prepare("PRAGMA user_version").get()?.user_version??0;if(Q>=P80.length)return;let Y=P80.slice(Q),X=Q;for(let z of Y)X+=1,this.db.transaction(()=>{for(let K of z)this.db.run(K);this.db.run(`PRAGMA user_version = ${X}`)})()}}function pT6($){for(let Q of $){if(!gT6.test(Q))throw Error(`invalid index column name: ${Q}`);if(mT6.has(Q))throw Error(`reserved index column name: ${Q}`)}}function iT6($){if(typeof $!=="object"||$===null)return null;if(!("type"in $))return null;let Q=$.type;return typeof Q==="string"?Q:null}function lT6($){return{seq:$.seq,ts:$.ts,event:JSON.parse($.event)}}var j80=2000;class ua extends Ea{sink;now;logger;constructor($){super();this.now=$.now??(()=>Date.now()),this.logger=$.logger,this.sink=new Ca({path:$.path,indexes:["channel_id","connector_id"],extractIndexes:(Q)=>({channel_id:Q.channel_id,connector_id:Q.connector_id}),now:this.now,...$.maxRows!==void 0?{maxRows:$.maxRows}:{},...$.maxAgeMs!==void 0?{maxAgeMs:$.maxAgeMs}:{},...$.maxBytes!==void 0?{maxBytes:$.maxBytes}:{},...$.targetBytes!==void 0?{targetBytes:$.targetBytes}:{}})}record($){let Q={type:$.meta?.event_type??"unknown",content:nT6($.content),channel_id:$.channelId,connector_id:$.connectorId,meta:$.meta},Y=this.sink.write({seq:$.offset,ts:this.now(),event:Q});if(Y instanceof Error)this.logger?.error("event log write failed",{offset:$.offset,error:Y.message})}loadSince($){let Q=this.sink.query({sinceSeq:$}),Y=[];for(let X of Q)Y.push({content:X.event.content,meta:X.event.meta??void 0,offset:X.seq});return Y}loadForChannel($){let Q={channel_id:$.channelId};if($.connectorId!==void 0)Q.connector_id=$.connectorId;let Y=this.sink.query({where:Q,...$.sinceSeq!==void 0?{sinceSeq:$.sinceSeq}:{},...$.limit!==void 0?{limit:$.limit}:{}}),X=[];for(let z of Y)X.push({content:z.event.content,meta:z.event.meta??void 0,offset:z.seq});return X}findMaxOffset(){return this.sink.getMaxSeq()}clear(){this.sink.clear()}close(){this.sink.close()}}function nT6($){if($.length<=j80)return $;return`${$.slice(0,j80)}...`}var dT6=()=>{},aT6=30000,oT6=60000,rT6=30000,sT6=($)=>new Promise((Q)=>{setTimeout(Q,$)});class RZ{channels;notify;logger;onError;running=new Map;failureCounts=new Map;stats=new Map;healthCheckIntervalMs;maxBackoffMs;startTimeoutMs;sleep;now;healthCheckTimer=null;healthCheckInFlight=!1;pendingRetry=new Map;constructor($){this.channels=$.channels,this.notify=$.notify,this.logger=$.logger,this.onError=$.onError??dT6,this.healthCheckIntervalMs=$.healthCheckIntervalMs??aT6,this.maxBackoffMs=$.maxBackoffMs??oT6,this.startTimeoutMs=$.startTimeoutMs??rT6,this.sleep=$.sleep??sT6,this.now=$.now??(()=>Date.now())}static keyOf($,Q){return`${$}/${Q}`}isRunning($,Q){return this.running.has(RZ.keyOf($,Q))}list(){return[...this.running.entries()].map(([$,Q])=>{let Y=this.stats.get($);return{channelName:Q.channelName,channelId:Q.channelId,name:Q.config.name,type:Q.config.type,alive:Q.listener.isAlive(),events:Y?.events??0,errors:Y?.errors??0,failureCount:this.failureCounts.get($)??0,lastEventAt:Y?.lastEventAt??null}})}async start($,Q){let Y=RZ.keyOf($,Q);if(this.running.has(Y))return{ok:!0,reason:"already running"};let X=this.channels.createListener($,Q);if(!X)return{ok:!1,reason:`connector "${Q}" not found in channel "${$}"`};let z=async(Z,K)=>{try{await this.notify($,Q,Z,K),this.recordEvent(Y)}catch(W){throw this.recordError(Y),W}};try{return await Promise.race([X.listener.start(z),this.sleep(this.startTimeoutMs).then(()=>{throw Error(`listener start timed out after ${this.startTimeoutMs}ms`)})]),this.running.set(Y,{config:X.config,channelName:$,channelId:X.channelId,listener:X.listener}),this.pendingRetry.delete(Y),this.ensureStats(Y),this.logger?.info(`${X.config.type} listener started`,{channel:$,connector:Q}),{ok:!0}}catch(Z){let K=Z instanceof Error?Z:Error(String(Z));return this.logger?.error(`${X.config.type} listener failed to start`,{channel:$,connector:Q,error:K.message}),this.onError(K,{component:"listener-supervisor.start",channel:$,connector:Q,type:X.config.type}),{ok:!1,reason:K.message}}}async stop($,Q){let Y=RZ.keyOf($,Q),X=this.running.get(Y);if(!X)return{ok:!0,reason:"not running"};try{return await X.listener.stop(),this.logger?.info(`${X.config.type} listener stopped`,{channel:$,connector:Q}),{ok:!0}}catch(z){let Z=z instanceof Error?z:Error(String(z));return this.logger?.error(`${X.config.type} listener failed to stop`,{channel:$,connector:Q,error:Z.message}),this.onError(Z,{component:"listener-supervisor.stop",channel:$,connector:Q,type:X.config.type}),{ok:!1,reason:Z.message}}finally{this.running.delete(Y),this.failureCounts.delete(Y)}}async restart($,Q){let Y=await this.stop($,Q);if(!Y.ok)return Y;return await this.start($,Q)}async startAll(){let $=this.channels.listAllConnectors(),Q=await Promise.allSettled($.map((Y)=>this.start(Y.channelName,Y.name)));for(let Y=0;Y<Q.length;Y++){let X=Q[Y],z=$[Y];if(X.status==="rejected"||X.status==="fulfilled"&&!X.value.ok){let Z=RZ.keyOf(z.channelName,z.name);this.pendingRetry.set(Z,{channelName:z.channelName,connectorName:z.name})}}this.startHealthCheck()}async stopAll(){this.stopHealthCheck(),this.pendingRetry.clear();for(let[,$]of[...this.running.entries()])await this.stop($.channelName,$.config.name)}ensureStats($){let Q=this.stats.get($);if(Q)return Q;let Y={events:0,errors:0,failureCount:0,lastEventAt:null};return this.stats.set($,Y),Y}recordEvent($){let Q=this.ensureStats($);Q.events+=1,Q.lastEventAt=new Date(this.now()).toISOString()}recordError($){this.ensureStats($).errors+=1}startHealthCheck(){if(this.healthCheckTimer)return;this.healthCheckTimer=setInterval(()=>{this.runHealthCheck()},this.healthCheckIntervalMs),this.healthCheckTimer.unref()}stopHealthCheck(){if(!this.healthCheckTimer)return;clearInterval(this.healthCheckTimer),this.healthCheckTimer=null}async runHealthCheckForTest(){await this.runHealthCheck()}async runHealthCheck(){if(this.healthCheckInFlight)return;this.healthCheckInFlight=!0;try{for(let[$,Q]of[...this.running.entries()]){if(Q.listener.isAlive()){this.failureCounts.delete($);continue}await this.recoverDead(Q.channelName,Q.config.name,Q.config.type)}for(let[$,Q]of[...this.pendingRetry.entries()]){if(this.running.has($)){this.pendingRetry.delete($);continue}this.logger?.info("retrying failed listener",{channel:Q.channelName,connector:Q.connectorName});let Y=this.failureCounts.get($)??0,X=Math.min(1000*2**Y,this.maxBackoffMs);if(await this.sleep(X),(await this.start(Q.channelName,Q.connectorName)).ok)this.pendingRetry.delete($),this.failureCounts.delete($);else this.failureCounts.set($,Y+1)}}finally{this.healthCheckInFlight=!1}}async recoverDead($,Q,Y){let X=RZ.keyOf($,Q),z=this.failureCounts.get(X)??0,Z=Math.min(1000*2**z,this.maxBackoffMs);if(this.logger?.warn(`${Y} listener unhealthy, restarting`,{channel:$,connector:Q,attempt:z+1,backoffMs:Z}),await this.stop($,Q),await this.sleep(Z),(await this.start($,Q)).ok)this.failureCounts.delete(X),this.logger?.info(`${Y} listener recovered`,{channel:$,connector:Q});else this.failureCounts.set(X,z+1)}}var tT6=new p8,eT6=3000,$f6=100,Qf6=200,Yf6=($)=>new Promise((Q)=>{setTimeout(Q,$)}),Xf6=($)=>`funnel-gateway[${$}]`,zf6=async($)=>{let Q=$.now()+eT6;while($.now()<Q){if($.pids.every((Y)=>!$.runner.isAlive(Y)))return;await $.sleep($f6)}for(let Y of $.pids){if(!$.runner.isAlive(Y))continue;try{$.runner.kill(Y,"SIGKILL")}catch{}}await $.sleep(Qf6)},I80=async($)=>{let Q=$.process??tT6,Y=$.logger,X=Xf6($.dir),z=Q.listProcessesContaining(X),Z=[];for(let K of z){if(K.pid===$.selfPid)continue;Q.kill(K.pid,"SIGTERM"),Z.push(K.pid),Y?.info("killed competing Slack gateway process",{pid:K.pid,args:K.command.slice(0,160)})}if(Z.length===0)return Z;return await zf6({runner:Q,pids:Z,sleep:$.sleep??Yf6,now:$.now??(()=>Date.now())}),Z};var bY=($)=>I2("param",$,(Q,Y)=>{if(Q.success)return;let X=Q.error.issues[0],z=X?`${X.path.join(".")}: ${X.message}`:"invalid request";return Y.json({ok:!1,reason:z},400)});var ca=P.lazy(()=>P.union([P.string(),P.number(),P.boolean(),P.null(),P.array(ca),P.record(P.string(),ca)])),Zf6=P.object({method:P.string().min(1),path:P.string().min(1),body:ca.optional()}),M80=B8.createHandlers(bY(P.object({channel:P.string().min(1),connector:P.string().min(1)})),async($)=>{let Q=$.req.valid("param"),Y=await $.req.json().catch(()=>null),X=Zf6.safeParse(Y);if(!X.success)throw new Q0(400,{message:X.error.issues[0]?.message??"invalid body"});let z=await $.var.deps.channels.call(Q.channel,Q.connector,{method:X.data.method,path:X.data.path,body:X.data.body});return $.json({ok:!0,result:z})});var O80=B8.createHandlers(bY(P.object({channel:P.string().min(1)})),I2("json",B80,($,Q)=>{if($.success)return;let Y=$.error.issues[0],X=Y?`${Y.path.join(".")}: ${Y.message}`:"invalid body";return Q.json({ok:!1,reason:X},400)}),($)=>{let Q=$.req.valid("param"),Y=$.req.valid("json"),X=Y.target?{...Y.meta,target:Y.target}:Y.meta,Z={ok:!0,offset:$.var.deps.emit({channel:Q.channel,connector:Y.connector,content:Y.content,meta:X}).offset};return $.json(Z)});import{existsSync as ya}from"fs";import{join as ga}from"path";var Kf6=($)=>{if(typeof $!=="string"||$.length===0)return null;try{let Q=JSON.parse($);if(Q!==null&&typeof Q==="object"&&"text"in Q){let Y=String(Q.text);return Y.length>80?`${Y.slice(0,80)}\u2026`:Y}}catch{return $.length>80?`${$.slice(0,80)}\u2026`:$}return $.length>80?`${$.slice(0,80)}\u2026`:$},Wf6=($)=>{let Y=($.connectionErrors[$.connectionErrors.length-1]??null)?.detail??null;if($.connectors.length===0)return{status:"warn",message:"no connectors configured on this channel",nextActions:[`fnl channels ${$.name} connectors add <name> --type=slack ...`],rootCause:null};if(!$.listener)return{status:"error",message:"no listener running for this channel",nextActions:["fnl gateway restart"],rootCause:Y};if(!$.listener.alive)return{status:"error",message:"listener is dead",nextActions:["fnl gateway logs","fnl gateway restart"],rootCause:Y};if($.claudeClients===0)return{status:"warn",message:"no Claude connected to this channel",nextActions:[`fnl claude --channel ${$.name}`],rootCause:null};if($.listener.errors>0)return{status:"warn",message:"listener has errors",nextActions:["fnl gateway logs"],rootCause:Y};return{status:"ok",message:"healthy",nextActions:[],rootCause:null}},v80=B8.createHandlers(async($)=>{let Q=$.var.deps,Y=$.req.query("channel")??null,X=Q.channels.list(),z=Y?X.filter((x)=>x.name===Y||x.id===Y):X,Z=Q.supervisor.list(),K=Q.broadcaster.listChannels(),W=Q.broadcaster.getMetrics(),H=n$(),V=ga(H,"connector-raw.db"),w=ga(H,"connector-processed.db"),G=ga(H,"connector-connection.db"),U=ya(V)&&ya(w)&&ya(G),J=z.map((x)=>{let D=Z.find((M)=>M.channelName===x.name)??null,B=D?{alive:D.alive,events:D.events,errors:D.errors,lastEventAt:D.lastEventAt}:null,L=K.filter((M)=>M.channel===x.id||M.channel===x.name).length,j=[],F=[];if(U){let M=new s9({rawPath:V,processedPath:w,connectionPath:G}),c=(()=>{try{return M.query("SELECT seq, ts, type, outcome, payload FROM processed WHERE channel_id = ? ORDER BY seq DESC LIMIT 10",[x.id])}finally{M.close()}})();if(!(c instanceof Error))for(let p of[...c].reverse()){let g=typeof p.payload==="string"?p.payload:null,l=null;if(g)try{let K1=JSON.parse(g);if(K1!==null&&typeof K1==="object"&&!Array.isArray(K1))l=K1}catch{l=null}j.push({seq:typeof p.seq==="number"?p.seq:null,ts:typeof p.ts==="number"?p.ts:null,type:typeof p.type==="string"?p.type:"?",outcome:typeof p.outcome==="string"?p.outcome:"?",payload:g,payloadParsed:l,preview:Kf6(p.payload)})}if(B&&(!B.alive||B.errors>0)||!B){let p=new s9({rawPath:V,processedPath:w,connectionPath:G}),g=(()=>{try{return p.query("SELECT ts, type, status, detail FROM connection WHERE channel_id = ? AND status IN ('auth-failed','error') ORDER BY seq DESC LIMIT 3",[x.id])}finally{p.close()}})();if(!(g instanceof Error))for(let l of[...g].reverse())F.push({ts:typeof l.ts==="number"?l.ts:null,type:typeof l.type==="string"?l.type:"?",status:typeof l.status==="string"?l.status:"?",detail:typeof l.detail==="string"&&l.detail.length>0?l.detail:null})}}let I={id:x.id,name:x.name,connectors:x.connectors.map((M)=>M.name),listener:B,claudeClients:L,recentEvents:j,connectionErrors:F};return{...I,diagnosis:Wf6(I)}});return $.json({pid:Q.selfPid,uptimeMs:Q.uptimeMs(),eventsBroadcast:W.eventsBroadcast,channels:J})});var b80=B8.createHandlers(($)=>{let Q=$.var.deps;return $.json({ok:!0,pid:Q.selfPid,funnelDir:Q.dir,clients:Q.broadcaster.getClientCount(),listeners:Q.supervisor.list()})});var _80=B8.createHandlers(($)=>{return $.json({listeners:$.var.deps.supervisor.list()})});var A80=B8.createHandlers(bY(P.object({channel:P.string().min(1),connector:P.string().min(1)})),async($)=>{let Q=$.req.valid("param"),Y=await $.var.deps.supervisor.restart(Q.channel,Q.connector);return $.json(Y,Y.ok?200:400)});var R80=B8.createHandlers(bY(P.object({channel:P.string().min(1),connector:P.string().min(1)})),async($)=>{let Q=$.req.valid("param"),Y=await $.var.deps.supervisor.start(Q.channel,Q.connector);return $.json(Y,Y.ok?200:400)});var T80=B8.createHandlers(bY(P.object({channel:P.string().min(1),connector:P.string().min(1)})),async($)=>{let Q=$.req.valid("param"),Y=await $.var.deps.supervisor.stop(Q.channel,Q.connector);return $.json(Y,Y.ok?200:400)});var f80=B8.createHandlers(($)=>{let Q=$.var.deps;return $.json({ok:!0,pid:Q.selfPid,funnelDir:Q.dir,uptimeMs:Q.uptimeMs(),clients:Q.broadcaster.listChannels(),listeners:Q.supervisor.list(),broadcaster:Q.broadcaster.getMetrics()})});function Hf6(){return B8.createApp().onError(($,Q)=>{if($ instanceof Q0)return $.getResponse();let Y=$ instanceof Error?$.message:String($);return Q.json({error:Y},500)}).get("/health",...b80).get("/status",...f80).get("/debug",...v80).get("/listeners",..._80).post("/listeners/:channel/:connector/start",...R80).delete("/listeners/:channel/:connector",...T80).post("/listeners/:channel/:connector/restart",...A80).post("/channels/:channel/connectors/:connector/call",...M80).post("/channels/:channel/publish",...O80)}var k80=Hf6();var Jf6="127.0.0.1",qf6=new Set(["127.0.0.1","localhost","::1","::ffff:127.0.0.1"]),xf6=()=>Uf6(n$(),"events.db"),Bf6=()=>{};class ha{channels;configuredPort;configuredHostname;dbPath;process;logger;onError;selfPid;dir;killCompetingSlack;token;allowInsecureHost;broadcaster;eventLog;supervisor;nowMs;extraRoutes;startedAt=null;server=null;constructor($){this.channels=$.channels,this.configuredPort=$.port??uX(),this.configuredHostname=$.hostname??Jf6,this.dbPath=$.dbPath??xf6(),this.process=$.process,this.logger=$.logger,this.onError=$.onError??Bf6,this.selfPid=$.selfPid??globalThis.process.pid,this.dir=$.dir??SQ,this.killCompetingSlack=$.killCompetingSlack??!0,this.token=$.token??"",this.allowInsecureHost=$.allowInsecureHost??!1,this.extraRoutes=$.extraRoutes??null;let Q=$.clock;if(this.nowMs=Q?()=>Q.millis():()=>Date.now(),$.eventLog)this.eventLog=$.eventLog;else{let Y=Gf6(this.dbPath);if(!Vf6(Y))wf6(Y,{recursive:!0});this.eventLog=new ua({path:this.dbPath,now:this.nowMs,logger:this.logger})}this.broadcaster=new Sa({logger:this.logger,onError:this.onError,now:this.nowMs,persistentReplay:this.eventLog}),this.broadcaster.seedLatestOffset(this.eventLog.findMaxOffset()),this.supervisor=new RZ({channels:this.channels,logger:this.logger,onError:this.onError,notify:async(Y,X,z,Z)=>{this.emit({channel:Y,connector:X,content:z,meta:Z})},now:this.nowMs})}get port(){return this.server?.port??this.configuredPort}get hostname(){return this.server?.hostname??this.configuredHostname}async start(){if(this.server)return;if(!this.token&&!qf6.has(this.configuredHostname)&&!this.allowInsecureHost)throw Error(`refusing to start gateway: hostname "${this.configuredHostname}" is reachable off-box but no token is set. Set a token, bind to loopback (127.0.0.1), or pass allowInsecureHost: true.`);let $=this.buildApp();await this.killCompetingSlackIfNeeded(),this.startedAt=this.nowMs(),this.server=Bun.serve({port:this.configuredPort,hostname:this.configuredHostname,development:!1,fetch:(Q,Y)=>this.handleFetch(Q,Y,$),websocket:{open:(Q)=>this.handleWsOpen(Q),close:(Q)=>this.handleWsClose(Q),message(){}}}),this.logServerStarted(),await this.bootListeners()}async stop(){if(await this.supervisor.stopAll(),this.server)this.server.stop(),this.server=null}getStatus(){return{clients:this.broadcaster.getClientCount(),channels:this.broadcaster.listChannels()}}getBroadcaster(){return this.broadcaster}getSupervisor(){return this.supervisor}getEventLog(){return this.eventLog}onEvent($){return this.broadcaster.subscribe($)}handleFetch($,Q,Y){let X=new URL($.url);if(X.pathname==="/ws"&&$.headers.get("upgrade")==="websocket"){if(this.token&&!this.tokenMatchesUpgrade($))return new Response("unauthorized",{status:401});let z=X.searchParams.get("channel")??"",Z=z?this.resolveChannel(z):null;if(z&&!Z)return new Response(`unknown channel "${z}"`,{status:404});let K=Z?.id??z,W=Z?.name??null,H=Z?.connectors??[],V=Z?.delivery??"fanout",w=X.searchParams.get("since"),G=w===null?Number.NaN:Number.parseInt(w,10),U=Number.isFinite(G)&&G>=0?G:void 0,J=X.searchParams.get("id")??void 0;if(Q.upgrade($,{data:{channel:K,channelName:W,connectors:H,delivery:V,subscriberId:J,since:U}}))return;return new Response("WebSocket upgrade failed",{status:400})}return Y.fetch($)}handleWsOpen($){if(typeof $.data.since==="number"){let Q=this.broadcaster.replaySince($.data.since,$.data);for(let Y of Q)$.send(JSON.stringify(Y))}this.broadcaster.addClient($,$.data),this.logger?.info("channel connected",{event_type:"system",action:"channel_connect",channel:$.data.channelName??"",channelId:$.data.channel,connectors:$.data.connectors.join(","),total:String(this.broadcaster.getClientCount())})}handleWsClose($){this.broadcaster.removeClient($),this.logger?.info("channel disconnected",{event_type:"system",action:"channel_disconnect",channel:$.data.channelName??"",channelId:$.data.channel,total:String(this.broadcaster.getClientCount())})}logServerStarted(){this.logger?.info("gateway started",{event_type:"system",action:"gateway_start",port:String(this.port),pid:String(this.selfPid)}),this.logger?.info("funnel gateway listening",{url:`http://localhost:${this.port}`,websocket:`ws://localhost:${this.port}/ws`,health:`http://localhost:${this.port}/health`})}buildApp(){let $=B8.createApp();if($.use((Y,X)=>{return Y.set("deps",{selfPid:this.selfPid,dir:this.dir,broadcaster:this.broadcaster,supervisor:this.supervisor,channels:this.channels,uptimeMs:()=>this.startedAt?this.nowMs()-this.startedAt:0,emit:(z)=>this.emit(z)}),X()}),this.token)$.use("/listeners/*",Nq({expected:this.token})),$.use("/status",Nq({expected:this.token})),$.use("/debug",Nq({expected:this.token})),$.use("/channels/*",Nq({expected:this.token}));return(this.extraRoutes?$.route("/",this.extraRoutes):$).route("/",k80)}tokenMatchesUpgrade($){let Q=($.headers.get("sec-websocket-protocol")??"").split(",").map((z)=>z.trim()).filter((z)=>z.length>0);for(let z of Q)if(z.startsWith("funnel.token.")&&oM(z.slice(13),this.token))return!0;let X=($.headers.get("authorization")??"").match(/^Bearer\s+(.+)$/i);if(X&&oM(X[1]??"",this.token))return!0;return!1}resolveChannel($){let Q=this.channels.get($)??this.channels.getById($);if(!Q)return null;return{id:Q.id,name:Q.name,connectors:Q.connectors.map((Y)=>Y.name),delivery:Q.delivery}}async killCompetingSlackIfNeeded(){if(!this.killCompetingSlack)return;if(!this.channels.listAllConnectors().some((Y)=>Y.type==="slack"))return;let Q=await I80({selfPid:this.selfPid,dir:this.dir,process:this.process,logger:this.logger});if(Q.length>0)this.logger?.info("killed competing Slack gateway processes",{event_type:"system",action:"kill_competing",pids:Q.join(",")})}async bootListeners(){await this.supervisor.startAll();for(let $ of this.supervisor.list())this.logger?.info(`${$.type} listener started: ${$.name}`,{event_type:"system",action:`${$.type}_connect`,channel:$.channelName,connector:$.name});this.logger?.info(`event store: ${this.dbPath}`),this.logger?.info("funnel gateway running")}emit($){let Q=this.lookupChannelId($.channel),Y=Q&&$.connector?this.lookupConnectorId(Q,$.connector):null,X={...$.meta,channel:$.channel};if($.connector)X.connector=$.connector;if(Q)X.channelId=Q;if(Y)X.connectorId=Y;let z=this.broadcaster.broadcast($.content,X);return this.eventLog.record({content:$.content,channelId:Q??null,connectorId:Y??null,meta:X,offset:z.offset}),{offset:z.offset}}lookupChannelId($){return this.channels.get($)?.id??this.channels.getById($)?.id??null}lookupConnectorId($,Q){return this.channels.getById($)?.connectors.find((X)=>X.name===Q)?.id??null}}import{homedir as Df6}from"os";import{dirname as Lf6,join as S80}from"path";var E80="gateway.token",Ff6=32,Nf6=new N8,Pf6=()=>{let $=new Uint8Array(Ff6);return crypto.getRandomValues($),[...$].map((Q)=>Q.toString(16).padStart(2,"0")).join("")};class ma{fs;path;generate;constructor($={}){this.fs=$.fs??Nf6,this.path=S80($.dir??SQ,E80),this.generate=$.generate??Pf6,Object.freeze(this)}read(){if(!this.fs.existsSync(this.path))return null;let $=this.fs.readFileSync(this.path).trim();return $.length>0?$:null}ensure(){let $=this.read();if($)return $;let Q=this.generate();return this.fs.mkdirSync(Lf6(this.path),{recursive:!0}),this.fs.writeSecretFileSync(this.path,`${Q}
2021
- `),Q}getPath(){return this.path}}var HB8=S80(Df6(),".funnel",E80);var jf6=P.object({channelName:P.string(),channelId:P.string(),name:P.string(),type:P.string(),alive:P.boolean()}),If6=P.object({listeners:P.array(jf6)}),Mf6=P.object({reason:P.string().optional()}),pa={state:"offline"};class ia{port;isDaemonRunning;getToken;constructor($){this.port=$.port,this.isDaemonRunning=$.isDaemonRunning,this.getToken=$.getToken??(()=>null),Object.freeze(this)}async list(){if(!this.isDaemonRunning())return{state:"offline"};try{let $=await fetch(`${_$(this.port)}/listeners`,{headers:this.authHeaders()});if(!$.ok)return{state:"error",reason:`HTTP ${$.status}`};let Q=If6.safeParse(await $.json());if(!Q.success)return{state:"error",reason:"malformed daemon response"};return{state:"ok",listeners:Q.data.listeners}}catch($){return{state:"error",reason:$ instanceof Error?$.message:String($)}}}async start($,Q){if(!this.isDaemonRunning())return pa;return await this.call("POST",`/listeners/${this.path($,Q)}/start`)}async stop($,Q){if(!this.isDaemonRunning())return pa;return await this.call("DELETE",`/listeners/${this.path($,Q)}`)}async restart($,Q){if(!this.isDaemonRunning())return pa;return await this.call("POST",`/listeners/${this.path($,Q)}/restart`)}path($,Q){return`${encodeURIComponent($)}/${encodeURIComponent(Q)}`}authHeaders(){let $=this.getToken();return $?{authorization:`Bearer ${$}`}:{}}async call($,Q){try{let Y=await fetch(`${_$(this.port)}${Q}`,{method:$,headers:this.authHeaders()});if(!Y.ok){let X=Mf6.safeParse(await Y.json().catch(()=>null));return{state:"error",reason:(X.success?X.data.reason:void 0)??`HTTP ${Y.status}`}}return{state:"ok"}}catch(Y){return{state:"error",reason:Y instanceof Error?Y.message:String(Y)}}}}var vf6="/sandbox/.funnel",bf6="/sandbox/tmp",_f6=()=>{};class rM{paths;channels;gateway;gatewayToken;publisher;listeners;claude;profiles;localConfig;localConfigSync;diagnostics;recovery;doctor;docs;fs;process;logger;clock;onError;constructor($={}){let Q=$.dir??p00(),Y=$.tmpDir??n$(),X=$.fs??new N8,z=$.process??new p8,Z=$.clock??new f4,K=$.idGenerator??new kQ;this.paths={dir:Q,tmpDir:Y,settings:Of6(Q,"settings.json")},this.fs=X,this.process=z,this.logger=$.logger,this.clock=Z,this.onError=$.onError??_f6;let W=$.store??new ad({path:this.paths.settings,fs:X,idGenerator:K}),H=new wa({descriptors:$.connectors??[],fs:X,process:z,logger:this.logger,diagnosticLog:$.diagnosticLog,dir:Q});this.profiles=new Pa({store:W,idGenerator:K,fs:X}),this.channels=new Ga({store:W,registry:H,clock:Z,idGenerator:K,profileChecker:this.profiles}),this.gateway=new ka({fs:X,process:z,clock:Z,dir:Q,tmpDir:Y,port:$.port}),this.gatewayToken=new ma({fs:X,dir:Q}),this.publisher=new Ta({port:this.gateway.getPort(),isDaemonRunning:()=>this.gateway.isRunning(),getToken:()=>this.gatewayToken.read()}),this.listeners=new ia({port:this.gateway.getPort(),isDaemonRunning:()=>this.gateway.isRunning(),getToken:()=>this.gatewayToken.read()});let V=new nd({fs:X});this.localConfig=new Lq({fs:X}),this.localConfigSync=new Na({channels:this.channels,prompter:$.tokenPrompter??new Ma}),this.claude=new Ua({channels:this.channels,mcp:V,gateway:this.gateway,sessions:this.profiles,guard:new pM({fs:X,process:z,dir:Q}),process:z,logger:this.logger}),this.diagnostics=new Da({gateway:this.gateway,gatewayToken:this.gatewayToken,channels:this.channels,publisher:this.publisher,tmpDir:Y}),this.recovery=new ja({gateway:this.gateway,listeners:this.listeners,channels:this.channels}),this.doctor=new La({diagnostics:this.diagnostics,recovery:this.recovery}),this.docs=new Gq,Object.freeze(this)}static inMemory($={}){return new rM({...$,store:$.store??new Aa,fs:$.fs??new Oa,process:$.process??new _a,logger:$.logger??new ba,clock:$.clock??new Ra,idGenerator:$.idGenerator??new va,dir:$.dir??vf6,tmpDir:$.tmpDir??bf6})}gatewayServer($={}){return new ha({channels:this.channels,port:$.port,hostname:$.hostname,...$.eventLog?{eventLog:$.eventLog}:{dbPath:$.dbPath},process:this.process,clock:this.clock,logger:this.logger,onError:this.onError,dir:this.paths.dir,killCompetingSlack:$.killCompetingSlack,token:$.token??this.gatewayToken.ensure(),allowInsecureHost:$.allowInsecureHost,extraRoutes:$.extraRoutes})}createProcessGuard(){return new pM({fs:this.fs,process:this.process,dir:this.paths.dir})}async runGatewayForeground($={}){let Q=aM(),X=$.caffeinate!==!1&&globalThis.process.platform==="darwin"?["caffeinate","-is","bun",Q]:["bun",Q];return this.process.attach(X)}gatewayClient(){let{port:$}=this.gateway.getStatus();return Va(_$($))}}process.title="funnel";var Rf6=9743;if(!process.env.FUNNEL_PORT)process.env.FUNNEL_PORT=String(Rf6);var C80=new N8,u80=Nt({localConfig:new Lq({fs:C80}),writer:new Ka({fs:C80}),idGenerator:new kQ,home:Af6()},process.cwd());if(u80)process.env.FUNNEL_DIR=u80;var sM=new rM({logger:new Dq,connectors:_j()}),{claude:y80,profiles:g80,localConfig:h80,localConfigSync:m80}=sM,c80={funnel:sM,claude:y80,profiles:g80,localConfig:h80,localConfigSync:m80},la=`funnel / Open Claude Funnel
2021
+ `),Q}getPath(){return this.path}}var HB8=S80(Df6(),".funnel",E80);var jf6=P.object({channelName:P.string(),channelId:P.string(),name:P.string(),type:P.string(),alive:P.boolean()}),If6=P.object({listeners:P.array(jf6)}),Mf6=P.object({reason:P.string().optional()}),pa={state:"offline"};class ia{port;isDaemonRunning;getToken;constructor($){this.port=$.port,this.isDaemonRunning=$.isDaemonRunning,this.getToken=$.getToken??(()=>null),Object.freeze(this)}async list(){if(!this.isDaemonRunning())return{state:"offline"};try{let $=await fetch(`${_$(this.port)}/listeners`,{headers:this.authHeaders()});if(!$.ok)return{state:"error",reason:`HTTP ${$.status}`};let Q=If6.safeParse(await $.json());if(!Q.success)return{state:"error",reason:"malformed daemon response"};return{state:"ok",listeners:Q.data.listeners}}catch($){return{state:"error",reason:$ instanceof Error?$.message:String($)}}}async start($,Q){if(!this.isDaemonRunning())return pa;return await this.call("POST",`/listeners/${this.path($,Q)}/start`)}async stop($,Q){if(!this.isDaemonRunning())return pa;return await this.call("DELETE",`/listeners/${this.path($,Q)}`)}async restart($,Q){if(!this.isDaemonRunning())return pa;return await this.call("POST",`/listeners/${this.path($,Q)}/restart`)}path($,Q){return`${encodeURIComponent($)}/${encodeURIComponent(Q)}`}authHeaders(){let $=this.getToken();return $?{authorization:`Bearer ${$}`}:{}}async call($,Q){try{let Y=await fetch(`${_$(this.port)}${Q}`,{method:$,headers:this.authHeaders()});if(!Y.ok){let X=Mf6.safeParse(await Y.json().catch(()=>null));return{state:"error",reason:(X.success?X.data.reason:void 0)??`HTTP ${Y.status}`}}return{state:"ok"}}catch(Y){return{state:"error",reason:Y instanceof Error?Y.message:String(Y)}}}}var vf6="/sandbox/.funnel",bf6="/sandbox/tmp",_f6=()=>{};class rM{paths;channels;gateway;gatewayToken;publisher;listeners;claude;profiles;localConfig;localConfigSync;diagnostics;recovery;doctor;docs;fs;process;logger;clock;onError;constructor($={}){let Q=$.dir??p00(),Y=$.tmpDir??n$(),X=$.fs??new N8,z=$.process??new p8,Z=$.clock??new f4,K=$.idGenerator??new kQ;this.paths={dir:Q,tmpDir:Y,settings:Of6(Q,"settings.json")},this.fs=X,this.process=z,this.logger=$.logger,this.clock=Z,this.onError=$.onError??_f6;let W=$.store??new ad({path:this.paths.settings,fs:X,idGenerator:K}),H=new wa({descriptors:$.connectors??[],fs:X,process:z,logger:this.logger,diagnosticLog:$.diagnosticLog,dir:Q});this.profiles=new Pa({store:W,idGenerator:K,fs:X}),this.channels=new Ga({store:W,registry:H,clock:Z,idGenerator:K,profileChecker:this.profiles}),this.gateway=new ka({fs:X,process:z,clock:Z,dir:Q,tmpDir:Y,port:$.port}),this.gatewayToken=new ma({fs:X,dir:Q}),this.publisher=new Ta({port:this.gateway.getPort(),isDaemonRunning:()=>this.gateway.isRunning(),getToken:()=>this.gatewayToken.read()}),this.listeners=new ia({port:this.gateway.getPort(),isDaemonRunning:()=>this.gateway.isRunning(),getToken:()=>this.gatewayToken.read()});let V=new nd({fs:X});this.localConfig=new Lq({fs:X}),this.localConfigSync=new Na({channels:this.channels,prompter:$.tokenPrompter??new Ma}),this.claude=new Ua({channels:this.channels,mcp:V,gateway:this.gateway,sessions:this.profiles,guard:new pM({fs:X,process:z,dir:Q}),process:z,logger:this.logger,dir:Q}),this.diagnostics=new Da({gateway:this.gateway,gatewayToken:this.gatewayToken,channels:this.channels,publisher:this.publisher,tmpDir:Y}),this.recovery=new ja({gateway:this.gateway,listeners:this.listeners,channels:this.channels}),this.doctor=new La({diagnostics:this.diagnostics,recovery:this.recovery}),this.docs=new Gq,Object.freeze(this)}static inMemory($={}){return new rM({...$,store:$.store??new Aa,fs:$.fs??new Oa,process:$.process??new _a,logger:$.logger??new ba,clock:$.clock??new Ra,idGenerator:$.idGenerator??new va,dir:$.dir??vf6,tmpDir:$.tmpDir??bf6})}gatewayServer($={}){return new ha({channels:this.channels,port:$.port,hostname:$.hostname,...$.eventLog?{eventLog:$.eventLog}:{dbPath:$.dbPath},process:this.process,clock:this.clock,logger:this.logger,onError:this.onError,dir:this.paths.dir,killCompetingSlack:$.killCompetingSlack,token:$.token??this.gatewayToken.ensure(),allowInsecureHost:$.allowInsecureHost,extraRoutes:$.extraRoutes})}createProcessGuard(){return new pM({fs:this.fs,process:this.process,dir:this.paths.dir})}async runGatewayForeground($={}){let Q=aM(),X=$.caffeinate!==!1&&globalThis.process.platform==="darwin"?["caffeinate","-is","bun",Q]:["bun",Q];return this.process.attach(X)}gatewayClient(){let{port:$}=this.gateway.getStatus();return Va(_$($))}}process.title="funnel";var Rf6=9743;if(!process.env.FUNNEL_PORT)process.env.FUNNEL_PORT=String(Rf6);var C80=new N8,u80=Nt({localConfig:new Lq({fs:C80}),writer:new Ka({fs:C80}),idGenerator:new kQ,home:Af6()},process.cwd());if(u80)process.env.FUNNEL_DIR=u80;var sM=new rM({logger:new Dq,connectors:_j()}),{claude:y80,profiles:g80,localConfig:h80,localConfigSync:m80}=sM,c80={funnel:sM,claude:y80,profiles:g80,localConfig:h80,localConfigSync:m80},la=`funnel / Open Claude Funnel
2022
2022
 
2023
2023
  usage / funnel [command]
2024
2024
 
package/dist/claude.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as ProcessGuard, c as ChannelResolver, i as SessionStore, n as FunnelClaude, o as McpInstaller, r as LaunchOptions, s as GatewayController, t as FileProcessGuard } from "./file-process-guard-DOlCr4GF.js";
1
+ import { a as ProcessGuard, c as ChannelResolver, i as SessionStore, n as FunnelClaude, o as McpInstaller, r as LaunchOptions, s as GatewayController, t as FileProcessGuard } from "./file-process-guard-C_PLxfUX.js";
2
2
  import { r as ConnectorDescriptor } from "./connector-descriptor-6SXJoszo.js";
3
3
  import { n as FunnelFileSystem } from "./file-system-o51IsM0W.js";
4
4
  import { t as FunnelProfiles } from "./profiles-Cy5wXQ0L.js";
package/dist/claude.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { t as gatewayLoopbackUrl } from "./gateway-base-url-Dy4Ykuoh.js";
2
2
  import { d as settingsSchema, o as resolveFunnelPort } from "./settings-store-CUKSeTXC.js";
3
- import { a as FunnelMcp, i as FUNNEL_MCP_NAME, n as FUNNEL_MCP_ARGS, o as FileProcessGuard, r as FUNNEL_MCP_COMMAND, s as FunnelClaude, t as renderYaml } from "./yaml-render-qW34NlYz.js";
3
+ import { a as FunnelMcp, i as FUNNEL_MCP_NAME, n as FUNNEL_MCP_ARGS, o as FileProcessGuard, r as FUNNEL_MCP_COMMAND, s as FunnelClaude, t as renderYaml } from "./yaml-render-93pX7EF7.js";
4
4
  import { t as FunnelDocs } from "./funnel-docs-BxXZ9Ksx.js";
5
5
  import { a as FunnelLocalConfig, c as connectorSpecSchema, i as FunnelTokenPrompter, l as localConfigSchema, n as NodeFunnelTokenPrompter, o as LOCAL_CONFIG_FILENAME, r as FunnelLocalConfigSync, s as channelSpecSchema, t as funnelJsonSchema, u as profileSpecSchema } from "./local-config-json-schema-JyLqOQNX.js";
6
6
  import { t as FunnelProfiles } from "./profiles-DSzTeKQw.js";
@@ -86,6 +86,7 @@ type Deps$1 = {
86
86
  process?: FunnelProcessRunner;
87
87
  idGenerator?: FunnelIdGenerator;
88
88
  logger?: FunnelLogger;
89
+ dir?: string;
89
90
  };
90
91
  /**
91
92
  * Launches Claude Code with funnel pre-wired: ensures the gateway is running,
@@ -102,6 +103,7 @@ declare class FunnelClaude {
102
103
  private readonly process;
103
104
  private readonly idGenerator;
104
105
  private readonly logger;
106
+ private readonly dir;
105
107
  constructor(deps: Deps$1);
106
108
  launch(options: LaunchOptions): Promise<number>;
107
109
  private buildArgs;
@@ -532,7 +532,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
532
532
  `)},Pa0=($)=>{if(!pB($))return $;let x=UE($,Ba0),Y=$.blocks;if(Array.isArray(Y)){let X=Na0(Y),Q=typeof x.text==="string"?x.text:"";x.text=Q?`${Q}
533
533
  ${X}`:X,x._funnel_omitted=["blocks"]}return x},HA1=($)=>{let x=UE($,qa0);if(Array.isArray(x.files))x.files=x.files.map(Fa0);if(Array.isArray(x.attachments))x.attachments=x.attachments.map(Pa0);return x};var Ia0=new Set(["message","app_mention"]),Ma0=new Set([void 0,"thread_broadcast","bot_message","file_share"]),_a0=1e4,V9=($,x)=>{let Y=$[x];return typeof Y==="string"?Y:void 0};class JE{ownBotUserId;ownBotId;minify;now;dedup=new Map;constructor($){this.ownBotUserId=$.ownBotUserId,this.ownBotId=$.ownBotId,this.minify=$.minify??!0,this.now=$.now??(()=>Date.now())}process($){let x=V9($,"type");if(!x||!Ia0.has(x))return{skip:!0,reason:"skip:type"};let Y=V9($,"subtype");if(!Ma0.has(Y))return{skip:!0,reason:"skip:subtype"};let X=V9($,"channel")??"",Q=V9($,"event_ts")??V9($,"ts")??"",z=`${X}:${Q}`,Z=this.now();if(this.dedup.has(z))return{skip:!0,reason:"skip:dedup"};this.dedup.set(z,Z);for(let D of this.dedup.keys())if((this.dedup.get(D)??0)<Z-_a0)this.dedup.delete(D);let K=V9($,"user"),V=V9($,"bot_id");if(K===this.ownBotUserId)return{skip:!0,reason:"skip:self-user"};if(V===this.ownBotId)return{skip:!0,reason:"skip:self-bot"};let W=V9($,"text")??"",w=W.includes(`<@${this.ownBotUserId}>`),H=V9($,"thread_ts")??V9($,"ts")??"",U=V9($,"ts")??"",J=x==="app_mention"?"app_mention":"message",q=this.minify?HA1($):$;return{skip:!1,event:{kind:"message",channel:X,user:K??"",rawText:W,text:Oa0(W,this.ownBotUserId),threadTs:H,ts:U,isThreadRoot:H===U,mentioned:w,source:J},content:JSON.stringify(q),meta:{event_type:"slack",channel_id:X,user_id:K??"",mentioned:String(w),thread_ts:H},shouldReact:w,channel:X,timestamp:U}}}var Oa0=($,x)=>$.replace(new RegExp(`<@${x}>`,"g"),"").trim();var fa0=c.object({event:c.record(c.string(),c.unknown()).optional()});class qE extends c7{config;channelId;env;logger;diagnosticLog;onAppCreated;preprocessEvent;app=null;connected=!1;constructor($){super();this.config=$.config,this.channelId=$.channelId??null,this.env=$.env??process.env,this.logger=$.logger,this.diagnosticLog=$.diagnosticLog,this.onAppCreated=$.onAppCreated??null,this.preprocessEvent=$.preprocessEvent??null}async start($){this.recordConnection("started","");let x=K7({literal:this.config.botToken,envVar:this.config.botTokenEnv,env:this.env,label:`${this.config.name}.botToken`}),Y=K7({literal:this.config.appToken,envVar:this.config.appTokenEnv,env:this.env,label:`${this.config.name}.appToken`}),X=new XX.SocketModeReceiver({appToken:Y,logLevel:XX.LogLevel.ERROR,autoReconnectEnabled:!1});X.client.on("connected",()=>{this.connected=!0}),X.client.on("disconnected",()=>{this.connected=!1});let Q=new XX.App({token:x,receiver:X,logLevel:XX.LogLevel.ERROR}),z;try{z=await Q.client.auth.test({token:x})}catch(V){throw this.recordConnection("auth-failed",Q8(V)),V}let Z=new JE({ownBotUserId:z.user_id??"",ownBotId:z.bot_id??"",minify:this.config.minify}),K=this.preprocessEvent;if(Q.use(async(V)=>{let W=fa0.safeParse(V);if(!W.success||!W.data.event){await V.next();return}let w=W.data.event,H=crypto.randomUUID();this.recordRaw(H,w);let U=K?K(w):w;if(U===null){this.recordProcessed(H,w,"skip:preprocess","");return}let J=Z.process(U);if(J.skip){this.recordProcessed(H,U,J.reason,"");return}try{await $(J.content,J.meta)}catch(q){throw this.recordProcessed(H,U,"emitted:delivery-failed",J.content),q}if(this.recordProcessed(H,U,"emitted",J.content),J.shouldReact)try{await Q.client.reactions.add({token:x,channel:J.channel,timestamp:J.timestamp,name:"eyes"})}catch{}}),Q.error(async(V)=>{let W=Q8(V);this.recordConnection("error",W),this.logger?.error("Slack error",{error:W})}),this.onAppCreated)await this.onAppCreated(Q);try{await Q.start()}catch(V){throw this.recordConnection("error",Q8(V)),V}this.app=Q,this.connected=!0,this.recordConnection("connected","")}async stop(){if(!this.app)return;try{await this.app.stop(),this.recordConnection("disconnected","")}catch($){this.recordConnection("error",Q8($)),this.logger?.error("Slack stop error",{error:Q8($)})}finally{this.app=null,this.connected=!1,this.recordConnection("stopped","")}}isAlive(){return this.app!==null&&this.connected}recordRaw($,x){this.diagnosticLog?.recordRaw({eventId:$,type:"slack",connectorId:this.config.id,channelId:this.channelId,payload:JSON.stringify(x)})}recordProcessed($,x,Y,X){this.diagnosticLog?.recordProcessed({eventId:$,type:"slack",connectorId:this.config.id,channelId:this.channelId,outcome:Y,payload:X||JSON.stringify(x)})}recordConnection($,x){this.diagnosticLog?.recordConnection({type:"slack",connectorId:this.config.id,channelId:this.channelId,status:$,detail:x})}}var UA1=($={})=>({type:"slack",toolExposed:!0,createListener(x,Y){let X=A7.parse(x);return new qE({config:X,channelId:Y.channelId,logger:Y.logger,diagnosticLog:Y.diagnosticLog,onAppCreated:$.onAppCreated,preprocessEvent:$.preprocessEvent})},createAdapter(x){return new Ik({config:A7.parse(x)})},secretTokens(x){let Y=A7.parse(x);return[Y.botToken,Y.appToken].filter((X)=>X!==void 0)},buildConfig(x,Y){return A7.parse({id:Y.id,type:"slack",name:x.name,...typeof x.botToken==="string"?{botToken:x.botToken}:{},...typeof x.appToken==="string"?{appToken:x.appToken}:{},...typeof x.botTokenEnv==="string"?{botTokenEnv:x.botTokenEnv}:{},...typeof x.appTokenEnv==="string"?{appTokenEnv:x.appTokenEnv}:{},minify:typeof x.minify==="boolean"?x.minify:!0,createdAt:Y.now,updatedAt:Y.now})},applyUpdate(x,Y,X){let Q=A7.parse(x);return A7.parse({id:Q.id,name:Q.name,type:"slack",minify:Q.minify,createdAt:Q.createdAt,updatedAt:X.now,...cV("botToken","botTokenEnv",Y,Q),...cV("appToken","appTokenEnv",Y,Q)})},operations:{}});var GA1=()=>[UA1(),Xw1(),xw1(),Vw1()];import{homedir as DA1}from"os";import{dirname as Aa0,join as DE}from"path";class kW{}class s7 extends kW{generate(){return crypto.randomUUID()}}class AW{}var JA1=c.object({id:c.string(),name:c.string(),type:c.string(),createdAt:c.string().datetime().optional(),updatedAt:c.string().datetime().optional()});var ba0=JA1.passthrough(),ca0=c.enum(["fanout","exclusive"]),Ra0=c.object({id:c.string(),name:c.string(),delivery:ca0.default("fanout"),connectors:c.array(ba0).default([])}),ka0=c.object({id:c.string(),name:c.string(),path:c.string(),channelId:c.string(),options:c.array(c.string()).default([]),env:c.record(c.string(),c.string()).default({}),resume:c.boolean().default(!0),sessionId:c.string().optional()}),o7=1,qA1=c.object({version:c.literal(o7).default(o7),channels:c.array(Ra0).default([]),profiles:c.array(ka0).default([])});function iB(){let $=process.env.FUNNEL_DIR;if($&&$.length>0)return $;return DE(DA1(),".funnel")}var Ta0=9742;function r7(){return Number(process.env.FUNNEL_PORT)||Ta0}var W9=DE(DA1(),".funnel"),Sa0=DE(W9,"settings.json"),ua0=new z8,Ea0=new s7;class BE extends AW{path;fs;idGenerator;constructor($={}){super();this.path=$.path??Sa0,this.fs=$.fs??ua0,this.idGenerator=$.idGenerator??Ea0,Object.freeze(this)}read(){if(!this.fs.existsSync(this.path))return{version:o7,channels:[],profiles:[]};let $=this.fs.readFileSync(this.path),x=JSON.parse($);if(this.looksLikeLegacy(x))throw Error(`legacy settings.json detected at ${this.path}. The schema changed (channel.connectors are now nested objects with ids; profile fields renamed). Migration is intentionally not provided. Back up and remove the old file:
534
534
  mv ${this.path} ${this.path}.bak`);if(x&&typeof x==="object"&&"version"in x&&x.version!==o7)throw Error(`unsupported settings.json version (${this.path}): expected ${o7}, got ${String(x.version)}`);let Y=this.backfillProfileIds(x),X=qA1.safeParse(x);if(!X.success)throw Error(`invalid settings.json (${this.path}): ${X.error.issues.map((Q)=>`${Q.path.join(".")}: ${Q.message}`).join(", ")}`);if(Y)this.write(X.data);return X.data}looksLikeLegacy($){if(!$||typeof $!=="object")return!1;let x=$;if(Array.isArray(x.channels))for(let Y of x.channels){if(!Y||typeof Y!=="object")continue;let X=Y;if(Array.isArray(X.connectors)&&X.connectors.some((Q)=>typeof Q==="string"))return!0;if(!("id"in X)&&"name"in X)return!0}if(Array.isArray(x.connectors))return!0;if(Array.isArray(x.repositories))return!0;if(Array.isArray(x.profiles))for(let Y of x.profiles){if(!Y||typeof Y!=="object")continue;let X=Y;if("repository"in X||"envFiles"in X||"channel"in X&&!("channelId"in X))return!0}return!1}backfillProfileIds($){if(!$||typeof $!=="object")return!1;let x=$;if(!Array.isArray(x.profiles))return!1;let Y=!1;for(let X of x.profiles){if(!X||typeof X!=="object")continue;let Q=X;if(typeof Q.id!=="string")Q.id=this.idGenerator.generate(),Y=!0}return Y}write($){this.fs.mkdirSync(Aa0(this.path),{recursive:!0});let x={...$,version:o7};this.fs.writeSecretFileSync(this.path,`${JSON.stringify(x,null,2)}
535
- `)}}import{tmpdir as Ca0}from"os";import{join as ya0}from"path";function Tx(){let $=process.env.FUNNEL_TMP_DIR;if($&&$.length>0)return $;return ya0(Ca0(),"funnel")}import{join as zr0}from"path";var FE=($)=>{let x=$.split("/");if(x[0]==="")x.shift();return x},BA1=($)=>{let{groups:x,path:Y}=ma0($),X=FE(Y);return ha0(X,x)},ma0=($)=>{let x=[];return $=$.replace(/\{[^}]+\}/g,(Y,X)=>{let Q=`@${X}`;return x.push([Q,Y]),Q}),{groups:x,path:$}},ha0=($,x)=>{for(let Y=x.length-1;Y>=0;Y--){let[X]=x[Y];for(let Q=$.length-1;Q>=0;Q--)if($[Q].includes(X)){$[Q]=$[Q].replace(X,x[Y][1]);break}}return $},lB={},vA1=($,x)=>{if($==="*")return"*";let Y=$.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(Y){let X=`${$}#${x}`;if(!lB[X])if(Y[2])lB[X]=x&&x[0]!==":"&&x[0]!=="*"?[X,Y[1],new RegExp(`^${Y[2]}(?=/${x})`)]:[$,Y[1],new RegExp(`^${Y[2]}$`)];else lB[X]=[$,Y[1],!0];return lB[X]}return null},xK=($,x)=>{try{return x($)}catch{return $.replace(/(?:%[0-9A-Fa-f]{2})+/g,(Y)=>{try{return x(Y)}catch{return Y}})}},ga0=($)=>xK($,decodeURI),LE=($)=>{let x=$.url,Y=x.indexOf("/",x.indexOf(":")+4),X=Y;for(;X<x.length;X++){let Q=x.charCodeAt(X);if(Q===37){let z=x.indexOf("?",X),Z=x.indexOf("#",X),K=z===-1?Z===-1?void 0:Z:Z===-1?z:Math.min(z,Z),V=x.slice(Y,K);return ga0(V.includes("%25")?V.replace(/%25/g,"%2525"):V)}else if(Q===63||Q===35)break}return x.slice(Y,X)};var FA1=($)=>{let x=LE($);return x.length>1&&x.at(-1)==="/"?x.slice(0,-1):x},vY=($,x,...Y)=>{if(Y.length)x=vY(x,...Y);return`${$?.[0]==="/"?"":"/"}${$}${x==="/"?"":`${$?.at(-1)==="/"?"":"/"}${x?.[0]==="/"?x.slice(1):x}`}`},nB=($)=>{if($.charCodeAt($.length-1)!==63||!$.includes(":"))return null;let x=$.split("/"),Y=[],X="";return x.forEach((Q)=>{if(Q!==""&&!/\:/.test(Q))X+="/"+Q;else if(/\:/.test(Q))if(/\?/.test(Q)){if(Y.length===0&&X==="")Y.push("/");else Y.push(X);let z=Q.replace("?","");X+="/"+z,Y.push(X)}else X+="/"+Q}),Y.filter((Q,z,Z)=>Z.indexOf(Q)===z)},vE=($)=>{if(!/[%+]/.test($))return $;if($.indexOf("+")!==-1)$=$.replace(/\+/g," ");return $.indexOf("%")!==-1?xK($,TW):$},LA1=($,x,Y)=>{let X;if(!Y&&x&&!/[%+]/.test(x)){let Z=$.indexOf("?",8);if(Z===-1)return;if(!$.startsWith(x,Z+1))Z=$.indexOf(`&${x}`,Z+1);while(Z!==-1){let K=$.charCodeAt(Z+x.length+1);if(K===61){let V=Z+x.length+2,W=$.indexOf("&",V);return vE($.slice(V,W===-1?void 0:W))}else if(K==38||isNaN(K))return"";Z=$.indexOf(`&${x}`,Z+1)}if(X=/[%+]/.test($),!X)return}let Q={};X??=/[%+]/.test($);let z=$.indexOf("?",8);while(z!==-1){let Z=$.indexOf("&",z+1),K=$.indexOf("=",z);if(K>Z&&Z!==-1)K=-1;let V=$.slice(z+1,K===-1?Z===-1?void 0:Z:K);if(X)V=vE(V);if(z=Z,V==="")continue;let W;if(K===-1)W="";else if(W=$.slice(K+1,Z===-1?void 0:Z),X)W=vE(W);if(Y){if(!(Q[V]&&Array.isArray(Q[V])))Q[V]=[];Q[V].push(W)}else Q[V]??=W}return x?Q[x]:Q},jA1=LA1,NA1=($,x)=>{return LA1($,x,!0)},TW=decodeURIComponent;var IA1=/^[\w!#$%&'*.^`|~+-]+$/,pa0=/^[ !#-:<-[\]-~]*$/,PA1=($)=>{let x=0,Y=$.length;while(x<Y){let X=$.charCodeAt(x);if(X!==32&&X!==9)break;x++}while(Y>x){let X=$.charCodeAt(Y-1);if(X!==32&&X!==9)break;Y--}return x===0&&Y===$.length?$:$.slice(x,Y)},jE=($,x)=>{if(x&&$.indexOf(x)===-1)return{};let Y=$.split(";"),X=Object.create(null);for(let Q of Y){let z=Q.indexOf("=");if(z===-1)continue;let Z=PA1(Q.substring(0,z));if(x&&x!==Z||!IA1.test(Z)||Z in X)continue;let K=PA1(Q.substring(z+1));if(K.startsWith('"')&&K.endsWith('"'))K=K.slice(1,-1);if(pa0.test(K)){if(X[Z]=K.indexOf("%")!==-1?xK(K,TW):K,x)break}}return X};var ia0=($,x,Y={})=>{if(!IA1.test($))throw Error("Invalid cookie name");let X=`${$}=${x}`;if($.startsWith("__Secure-")&&!Y.secure)throw Error("__Secure- Cookie must have Secure attributes");if($.startsWith("__Host-")){if(!Y.secure)throw Error("__Host- Cookie must have Secure attributes");if(Y.path!=="/")throw Error('__Host- Cookie must have Path attributes with "/"');if(Y.domain)throw Error("__Host- Cookie must not have Domain attributes")}for(let Q of["domain","path","sameSite","priority"])if(Y[Q]&&/[;\r\n]/.test(Y[Q]))throw Error(`${Q} must not contain ";", "\\r", or "\\n"`);if(Y&&typeof Y.maxAge==="number"&&Y.maxAge>=0){if(Y.maxAge>34560000)throw Error("Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.");X+=`; Max-Age=${Y.maxAge|0}`}if(Y.domain&&Y.prefix!=="host")X+=`; Domain=${Y.domain}`;if(Y.path)X+=`; Path=${Y.path}`;if(Y.expires){if(Y.expires.getTime()-Date.now()>34560000000)throw Error("Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.");X+=`; Expires=${Y.expires.toUTCString()}`}if(Y.httpOnly)X+="; HttpOnly";if(Y.secure)X+="; Secure";if(Y.sameSite)X+=`; SameSite=${Y.sameSite.charAt(0).toUpperCase()+Y.sameSite.slice(1)}`;if(Y.priority)X+=`; Priority=${Y.priority.charAt(0).toUpperCase()+Y.priority.slice(1)}`;if(Y.partitioned){if(!Y.secure)throw Error("Partitioned Cookie must have Secure attributes");X+="; Partitioned"}return X},NE=($,x,Y)=>{return x=encodeURIComponent(x),ia0($,x,Y)};var MA1=($,x)=>{return $=$.replace(/\/+$/,""),$=$+"/",x=x.replace(/^\/+/,""),$+x},aB=($,x)=>{for(let[Y,X]of Object.entries(x)){let Q=new RegExp("/:"+Y+"(?:{[^/]+})?\\??");$=$.replace(Q,X?`/${X}`:"")}return $},_A1=($)=>{let x=new URLSearchParams;for(let[Y,X]of Object.entries($)){if(X===void 0)continue;if(Array.isArray(X))for(let Q of X)x.append(Y,Q);else x.set(Y,X)}return x},OA1=($,x)=>{switch(x){case"ws":return $.replace(/^http/,"ws");case"http":return $.replace(/^ws/,"http")}},PE=($)=>{if(/^https?:\/\/[^\/]+?\/index(?=\?|$)/.test($))return $.replace(/\/index(?=\?|$)/,"/");return $.replace(/\/index(?=\?|$)/,"")};function dB($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function IE($,x){if(!dB($)&&!dB(x))return x;let Y={...$};for(let X in x){let Q=x[X];if(dB(Y[X])&&dB(Q))Y[X]=IE(Y[X],Q);else Y[X]=Q}return Y}var fA1=($,x)=>{return new Proxy(()=>{},{get(X,Q){if(typeof Q!=="string"||Q==="then")return;return fA1($,[...x,Q])},apply(X,Q,z){return $({path:x,args:z})}})},na0=class{url;method;buildSearchParams;queryParams=void 0;pathParams={};rBody;cType=void 0;constructor($,x,Y){this.url=$,this.method=x,this.buildSearchParams=Y.buildSearchParams}fetch=async($,x)=>{if($){if($.query)this.queryParams=this.buildSearchParams($.query);if($.form){let K=new FormData;for(let[V,W]of Object.entries($.form)){if(W===void 0)continue;if(Array.isArray(W))for(let w of W)K.append(V,w);else K.append(V,W)}this.rBody=K}if($.json)this.rBody=JSON.stringify($.json),this.cType="application/json";if($.param)this.pathParams=$.param}let Y=this.method.toUpperCase(),X={...$?.header,...typeof x?.headers==="function"?await x.headers():x?.headers};if($?.cookie){let K=[];for(let[V,W]of Object.entries($.cookie))K.push(NE(V,W,{path:"/"}));X.Cookie=K.join(",")}if(this.cType)X["Content-Type"]=this.cType;let Q=new Headers(X??void 0),z=this.url;if(z=PE(z),z=aB(z,this.pathParams),this.queryParams)z=z+"?"+this.queryParams.toString();Y=this.method.toUpperCase();let Z=!(Y==="GET"||Y==="HEAD");return(x?.fetch||fetch)(z,{body:Z?this.rBody:void 0,method:Y,headers:Q,...x?.init})}},ME=($,x)=>fA1(function Y(X){let Q=x?.buildSearchParams??_A1,z=[...X.path],Z=z.slice(-3).reverse();if(Z[0]==="toString"){if(Z[1]==="name")return Z[2]||"";return Y.toString()}if(Z[0]==="valueOf"){if(Z[1]==="name")return Z[2]||"";return Y}let K="";if(/^\$/.test(Z[0])){let H=z.pop();if(H)K=H.replace(/^\$/,"")}let V=z.join("/"),W=MA1($,V);if(K==="url"||K==="path"){let H=W;if(X.args[0]){if(X.args[0].param)H=aB(W,X.args[0].param);if(X.args[0].query)H=H+"?"+Q(X.args[0].query).toString()}if(H=PE(H),K==="url")return new URL(H);return H.slice($.replace(/\/+$/,"").length).replace(/^\/?/,"/")}if(K==="ws"){let H=OA1(X.args[0]&&X.args[0].param?aB(W,X.args[0].param):W,"ws"),U=new URL(H),J=X.args[0]?.query;if(J)Object.entries(J).forEach(([B,D])=>{if(Array.isArray(D))D.forEach((v)=>U.searchParams.append(B,v));else U.searchParams.set(B,D)});return((...B)=>{if(x?.webSocket!==void 0&&typeof x.webSocket==="function")return x.webSocket(...B);return new WebSocket(...B)})(U.toString())}let w=new na0(W,K,{buildSearchParams:Q});if(K){x??={};let H=IE(x,{...X.args[1]});return w.fetch(X.args[0],H)}return w},[]);function t7($){return`http://127.0.0.1:${$}`}import{join as bA1}from"path";var da0=new z8,aa0=new X8;class _E{descriptors;fs;process;logger;diagnosticLog;dir;constructor($){this.descriptors=new Map($.descriptors.map((x)=>[x.type,x])),this.fs=$.fs??da0,this.process=$.process??aa0,this.logger=$.logger,this.diagnosticLog=$.diagnosticLog,this.dir=$.dir??W9,Object.freeze(this)}has($){return this.descriptors.has($)}types(){return[...this.descriptors.keys()]}createListener($,x){return this.require(x.type).createListener(x,this.listenerDeps($))}createAdapter($){let x=this.require($.type);if(!x.createAdapter)return null;return x.createAdapter($,this.adapterDeps())}secretTokens($){return this.require($.type).secretTokens($)}buildConfig($,x){let Y=typeof $.type==="string"?$.type:"";return this.require(Y).buildConfig($,x)}applyUpdate($,x,Y){return this.require($.type).applyUpdate($,x,Y)}runOperation($,x,Y,X){let z=this.require($.type).operations[x];if(!z)throw Error(`connector type "${$.type}" has no operation "${x}"`);return z({config:$,args:Y,context:X})}connectorDir($,x){return bA1(this.dir,"channels",$,"connectors",x)}channelDir($){return bA1(this.dir,"channels",$)}require($){let x=this.descriptors.get($);if(!x)throw Error(`unknown connector type "${$}". Pass its descriptor to new Funnel({ connectors: [...] }).`);return x}listenerDeps($){return{channelId:$,fs:this.fs,process:this.process,logger:this.logger,diagnosticLog:this.diagnosticLog,connectorDir:(x,Y)=>this.connectorDir(x,Y)}}adapterDeps(){return{fs:this.fs,process:this.process,logger:this.logger}}}class SW{millis(){return this.now().getTime()}iso(){return this.now().toISOString()}}class zX extends SW{now(){return new Date}}var sa0=new zX,oa0=new s7;class OE{store;registry;profileChecker;clock;idGenerator;constructor($){this.store=$.store,this.registry=$.registry,this.profileChecker=$.profileChecker??null,this.clock=$.clock??sa0,this.idGenerator=$.idGenerator??oa0,Object.freeze(this)}list(){return this.store.read().channels}get($){return this.list().find((x)=>x.name===$)??null}getById($){return this.list().find((x)=>x.id===$)??null}add($){let x=this.store.read();if(x.channels.some((X)=>X.name===$.name))throw Error(`channel "${$.name}" already exists`);let Y={id:this.idGenerator.generate(),name:$.name,delivery:$.delivery??"fanout",connectors:[]};return x.channels.push(Y),this.store.write(x),Y}setDelivery($,x){let Y=this.store.read(),X=this.requireChannel(Y,$);X.delivery=x,this.store.write(Y)}remove($){let x=this.store.read(),Y=x.channels.findIndex((Q)=>Q.name===$);if(Y<0)throw Error(`channel "${$}" not found`);let X=x.channels[Y];if(X&&this.profileChecker?.hasChannelRef(X.id))throw Error(`channel "${$}" is referenced by a profile`);x.channels.splice(Y,1),this.store.write(x)}rename($,x){let Y=this.store.read(),X=Y.channels.find((Q)=>Q.name===$);if(!X)throw Error(`channel "${$}" not found`);if(Y.channels.some((Q)=>Q.name===x))throw Error(`channel "${x}" already exists`);X.name=x,this.store.write(Y)}listConnectors($){return this.requireChannel(this.store.read(),$).connectors}getConnector($,x){let Y=this.get($);if(!Y)return null;return Y.connectors.find((X)=>X.name===x)??null}listAllConnectors(){let $=[];for(let x of this.list())for(let Y of x.connectors)$.push({...Y,channelId:x.id,channelName:x.name});return $}addConnector($,x){let Y=this.store.read(),X=this.requireChannel(Y,$);if(X.connectors.some((z)=>z.name===x.name))throw Error(`connector "${x.name}" already exists in channel "${$}"`);let Q=this.registry.buildConfig(x,{id:this.idGenerator.generate(),now:this.clock.iso()});return this.assertNoTokenCollision(Y,Q),X.connectors.push(Q),this.store.write(Y),Q}removeConnector($,x){let Y=this.store.read(),X=this.requireChannel(Y,$),Q=X.connectors.findIndex((z)=>z.name===x);if(Q<0)throw Error(`connector "${x}" not found in channel "${$}"`);X.connectors.splice(Q,1),this.store.write(Y)}renameConnector($,x,Y){let X=this.store.read(),Q=this.requireChannel(X,$),z=Q.connectors.find((Z)=>Z.name===x);if(!z)throw Error(`connector "${x}" not found in channel "${$}"`);if(Q.connectors.some((Z)=>Z.name===Y))throw Error(`connector "${Y}" already exists in channel "${$}"`);z.name=Y,z.updatedAt=this.clock.iso(),this.store.write(X)}updateConnector($,x,Y){let X=this.store.read(),Q=this.requireChannel(X,$),z=Q.connectors.find((K)=>K.name===x);if(!z)throw Error(`connector "${x}" not found in channel "${$}"`);let Z=this.registry.applyUpdate(z,Y,{now:this.clock.iso()});this.assertNoTokenCollision(X,Z),this.replaceConnector(Q,z.name,Z),this.store.write(X)}updateSlackConnector($,x,Y){this.updateConnector($,x,Y)}updateGhConnector($,x,Y){this.updateConnector($,x,Y)}updateDiscordConnector($,x,Y){this.updateConnector($,x,Y)}connectorOp($,x,Y,X){let Q=this.store.read(),z=this.requireChannel(Q,$),Z=z.connectors.find((V)=>V.name===x);if(!Z)throw Error(`connector "${x}" not found in channel "${$}"`);let K=this.registry.runOperation(Z,Y,X,{generateId:()=>this.idGenerator.generate(),now:this.clock.iso()});if(K.config!==Z)this.replaceConnector(z,Z.name,K.config),this.store.write(Q);return K.result}async call($,x,Y){let X=this.getConnector($,x);if(!X)throw Error(`connector "${x}" not found in channel "${$}"`);let Q=this.registry.createAdapter(X);if(!Q)throw Error(`connector type "${X.type}" does not support outbound calls`);return await Q.call(Y)}createListener($,x){let Y=this.get($);if(!Y)return null;let X=Y.connectors.find((Q)=>Q.name===x);if(!X)return null;return{config:X,channelId:Y.id,listener:this.registry.createListener(Y.id,X)}}createAllListeners(){let $=[];for(let x of this.list())for(let Y of x.connectors)$.push({config:Y,channelId:x.id,channelName:x.name,listener:this.registry.createListener(x.id,Y)});return $}requireChannel($,x){let Y=$.channels.find((X)=>X.name===x);if(!Y)throw Error(`channel "${x}" not found`);return Y}replaceConnector($,x,Y){let X=$.connectors.findIndex((Q)=>Q.name===x);if(X<0)throw Error(`connector "${x}" not found in channel "${$.name}"`);$.connectors[X]=Y}assertNoTokenCollision($,x){let Y=this.registry.secretTokens(x);if(Y.length===0)return;for(let X of $.channels)for(let Q of X.connectors){if(Q.id===x.id)continue;for(let z of this.registry.secretTokens(Q))if(Y.includes(z))throw Error(`token already in use by connector "${Q.name}" in channel "${X.name}"`)}}}var ra0=new X8,ta0=new s7;class fE{channels;mcp;gateway;sessions;guard;process;idGenerator;logger;constructor($){this.channels=$.channels,this.mcp=$.mcp,this.gateway=$.gateway,this.sessions=$.sessions,this.guard=$.guard,this.process=$.process??ra0,this.idGenerator=$.idGenerator??ta0,this.logger=$.logger,Object.freeze(this)}async launch($){let x=this.channels.get($.channel)??this.channels.getById($.channel);if(!x)throw Error(`channel "${$.channel}" not found`);if($.profileId&&this.guard.isRunning($.profileId))throw Error(`profile "${$.profileId}" is already running`);let Y=$.cwd??globalThis.process.cwd();if(($.installMcp??!0)&&!this.mcp.findInstalledName(Y))this.mcp.install(Y),this.logger?.info("added funnel MCP to .mcp.json",{cwd:Y});if(!this.gateway.isRunning()){if(this.logger?.info("starting gateway automatically"),!await this.gateway.start())throw Error(`gateway failed to start on port ${r7()}; another funnel daemon (a different repo/scope) may already hold it. See 'fnl gateway logs' and 'ps -o pid,args= | grep funnel-gateway'.`)}if($.profileId)this.guard.acquire($.profileId);let z=($.resume??!1)&&$.profileId?this.resolveSession($.profileId,Y,$.userArgs??[],$.env??{}):null,Z=this.buildArgs($.options??[],$.userArgs??[],Y,z),K=this.buildEnv(x.id,$.env??{});this.logger?.info("claude launch",{channel:$.channel,channelId:x.id,cwd:Y});try{return await this.process.attach(["claude",...Z],{cwd:Y,env:K,onSpawned:$.onSpawned})}finally{if($.profileId)this.guard.release($.profileId)}}buildArgs($,x,Y,X){let Q=[...$,...x];if(X!==null)if(X.mode==="resume")Q.push("--resume",X.id);else Q.push("--session-id",X.id);let z=this.mcp.findInstalledName(Y);if(z&&!Q.includes("--dangerously-load-development-channels")&&!Q.includes("--channels"))Q.push("--dangerously-load-development-channels",`server:${z}`);return Q}resolveSession($,x,Y,X){for(let Z of Y){if(Z==="-c"||Z==="--continue")return null;if(Z==="--resume"||Z.startsWith("--resume="))return null;if(Z==="--session-id"||Z.startsWith("--session-id="))return null}let Q=this.sessions.getSessionId($);if(Q!==null&&this.sessions.sessionFileExists(x,Q,X))return{id:Q,mode:"resume"};let z=this.idGenerator.generate();return this.sessions.setSessionId($,z),{id:z,mode:"new"}}buildEnv($,x){let Y={};for(let[X,Q]of Object.entries(x))Y[X]=Q;for(let[X,Q]of Object.entries(globalThis.process.env))if(typeof Q==="string")Y[X]=Q;return Y.FUNNEL_CHANNEL_ID=$,Y.FUNNEL_PORT=String(r7()),Y}}import{join as cA1}from"path";var ea0=new z8,$s0=new X8;class sB{fs;process;pidDir;constructor($={}){this.fs=$.fs??ea0,this.process=$.process??$s0,this.pidDir=cA1($.dir??W9,"claude"),Object.freeze(this)}isRunning($){let x=this.readRecord($);if(!x)return!1;if(!this.process.isAlive(x.pid))return this.release($),!1;if(x.startTime!==null){let Y=this.process.getStartTime(x.pid);if(Y===null)return this.release($),!1;if(Y!==x.startTime)return this.release($),!1}return!0}acquire($){this.fs.mkdirSync(this.pidDir,{recursive:!0});let x=globalThis.process.pid,Y=this.process.getStartTime(x),X={pid:x,startTime:Y};this.fs.writeFileSync(this.pidPath($),JSON.stringify(X)),globalThis.process.once("exit",()=>this.release($))}release($){let x=this.pidPath($);if(this.fs.existsSync(x))this.fs.unlink(x)}pidPath($){return cA1(this.pidDir,`${$}.pid`)}readRecord($){let x=this.pidPath($);if(!this.fs.existsSync(x))return null;try{let Y=this.fs.readFileSync(x).trim();if(!Y)return null;if(Y.startsWith("{")){let Q=JSON.parse(Y),z=typeof Q.pid==="number"?Q.pid:Number(Q.pid);if(!Number.isInteger(z)||z<=0)return null;let Z=typeof Q.startTime==="string"?Q.startTime:null;return{pid:z,startTime:Z}}let X=Number(Y);if(!X||X<=0)return null;return{pid:X,startTime:null}}catch{return null}}}import{existsSync as RE}from"fs";import{join as kE}from"path";var bE=($)=>typeof $==="string"&&$.length>0?$:null,oB=($)=>typeof $==="number"?$:null,rB=($,x)=>typeof $==="string"?$:x,xs0=($)=>$!==null&&typeof $==="object"&&!Array.isArray($),kA1=($)=>{if($===null)return null;try{let x=JSON.parse($);if(xs0(x))return x}catch{return null}return null},RA1=($,x)=>$.length<=x?$:`${$.slice(0,x)}\u2026`,Ys0=($)=>{if(typeof $!=="string"||$.length===0)return null;let x=kA1($);if(x!==null&&"text"in x)return RA1(String(x.text),60);return RA1($,60)},tB=($)=>{let x=bE($.payload);return{seq:oB($.seq),ts:oB($.ts),type:rB($.type,"?"),outcome:rB($.outcome,"?"),eventId:bE($.event_id),payload:x,payloadParsed:kA1(x),preview:Ys0($.payload)}},cE=($)=>({seq:oB($.seq),ts:oB($.ts),type:rB($.type,"?"),status:rB($.status,"?"),detail:bE($.detail)}),Sx=($,x,Y)=>{try{return $.query(x,Y)}finally{$.close()}};import{Database as Qs0}from"bun:sqlite";class ux{db;constructor($){let x=new Qs0($.rawPath,{readonly:!0});try{x.run("PRAGMA busy_timeout = 500"),x.prepare("ATTACH DATABASE ? AS processeddb").run($.processedPath),x.prepare("ATTACH DATABASE ? AS connectiondb").run($.connectionPath),x.run(Xs0),x.run(zs0),x.run(Zs0)}catch(Y){throw x.close(),Y}this.db=x,Object.freeze(this)}query($,x=[]){let Y=$.trim().replace(/;$/,"").trim();if(!/^select\b/i.test(Y))return Error("only a single SELECT statement is allowed");if(Y.includes(";"))return Error("only a single statement is allowed (remove the ';')");try{return this.db.prepare(Y).all(...x)}catch(X){return X instanceof Error?X:Error(String(X))}}close(){this.db.close()}}var Xs0=`CREATE TEMP VIEW raw AS SELECT
535
+ `)}}import{tmpdir as Ca0}from"os";import{join as ya0}from"path";function Tx(){let $=process.env.FUNNEL_TMP_DIR;if($&&$.length>0)return $;return ya0(Ca0(),"funnel")}import{join as zr0}from"path";var FE=($)=>{let x=$.split("/");if(x[0]==="")x.shift();return x},BA1=($)=>{let{groups:x,path:Y}=ma0($),X=FE(Y);return ha0(X,x)},ma0=($)=>{let x=[];return $=$.replace(/\{[^}]+\}/g,(Y,X)=>{let Q=`@${X}`;return x.push([Q,Y]),Q}),{groups:x,path:$}},ha0=($,x)=>{for(let Y=x.length-1;Y>=0;Y--){let[X]=x[Y];for(let Q=$.length-1;Q>=0;Q--)if($[Q].includes(X)){$[Q]=$[Q].replace(X,x[Y][1]);break}}return $},lB={},vA1=($,x)=>{if($==="*")return"*";let Y=$.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(Y){let X=`${$}#${x}`;if(!lB[X])if(Y[2])lB[X]=x&&x[0]!==":"&&x[0]!=="*"?[X,Y[1],new RegExp(`^${Y[2]}(?=/${x})`)]:[$,Y[1],new RegExp(`^${Y[2]}$`)];else lB[X]=[$,Y[1],!0];return lB[X]}return null},xK=($,x)=>{try{return x($)}catch{return $.replace(/(?:%[0-9A-Fa-f]{2})+/g,(Y)=>{try{return x(Y)}catch{return Y}})}},ga0=($)=>xK($,decodeURI),LE=($)=>{let x=$.url,Y=x.indexOf("/",x.indexOf(":")+4),X=Y;for(;X<x.length;X++){let Q=x.charCodeAt(X);if(Q===37){let z=x.indexOf("?",X),Z=x.indexOf("#",X),K=z===-1?Z===-1?void 0:Z:Z===-1?z:Math.min(z,Z),V=x.slice(Y,K);return ga0(V.includes("%25")?V.replace(/%25/g,"%2525"):V)}else if(Q===63||Q===35)break}return x.slice(Y,X)};var FA1=($)=>{let x=LE($);return x.length>1&&x.at(-1)==="/"?x.slice(0,-1):x},vY=($,x,...Y)=>{if(Y.length)x=vY(x,...Y);return`${$?.[0]==="/"?"":"/"}${$}${x==="/"?"":`${$?.at(-1)==="/"?"":"/"}${x?.[0]==="/"?x.slice(1):x}`}`},nB=($)=>{if($.charCodeAt($.length-1)!==63||!$.includes(":"))return null;let x=$.split("/"),Y=[],X="";return x.forEach((Q)=>{if(Q!==""&&!/\:/.test(Q))X+="/"+Q;else if(/\:/.test(Q))if(/\?/.test(Q)){if(Y.length===0&&X==="")Y.push("/");else Y.push(X);let z=Q.replace("?","");X+="/"+z,Y.push(X)}else X+="/"+Q}),Y.filter((Q,z,Z)=>Z.indexOf(Q)===z)},vE=($)=>{if(!/[%+]/.test($))return $;if($.indexOf("+")!==-1)$=$.replace(/\+/g," ");return $.indexOf("%")!==-1?xK($,TW):$},LA1=($,x,Y)=>{let X;if(!Y&&x&&!/[%+]/.test(x)){let Z=$.indexOf("?",8);if(Z===-1)return;if(!$.startsWith(x,Z+1))Z=$.indexOf(`&${x}`,Z+1);while(Z!==-1){let K=$.charCodeAt(Z+x.length+1);if(K===61){let V=Z+x.length+2,W=$.indexOf("&",V);return vE($.slice(V,W===-1?void 0:W))}else if(K==38||isNaN(K))return"";Z=$.indexOf(`&${x}`,Z+1)}if(X=/[%+]/.test($),!X)return}let Q={};X??=/[%+]/.test($);let z=$.indexOf("?",8);while(z!==-1){let Z=$.indexOf("&",z+1),K=$.indexOf("=",z);if(K>Z&&Z!==-1)K=-1;let V=$.slice(z+1,K===-1?Z===-1?void 0:Z:K);if(X)V=vE(V);if(z=Z,V==="")continue;let W;if(K===-1)W="";else if(W=$.slice(K+1,Z===-1?void 0:Z),X)W=vE(W);if(Y){if(!(Q[V]&&Array.isArray(Q[V])))Q[V]=[];Q[V].push(W)}else Q[V]??=W}return x?Q[x]:Q},jA1=LA1,NA1=($,x)=>{return LA1($,x,!0)},TW=decodeURIComponent;var IA1=/^[\w!#$%&'*.^`|~+-]+$/,pa0=/^[ !#-:<-[\]-~]*$/,PA1=($)=>{let x=0,Y=$.length;while(x<Y){let X=$.charCodeAt(x);if(X!==32&&X!==9)break;x++}while(Y>x){let X=$.charCodeAt(Y-1);if(X!==32&&X!==9)break;Y--}return x===0&&Y===$.length?$:$.slice(x,Y)},jE=($,x)=>{if(x&&$.indexOf(x)===-1)return{};let Y=$.split(";"),X=Object.create(null);for(let Q of Y){let z=Q.indexOf("=");if(z===-1)continue;let Z=PA1(Q.substring(0,z));if(x&&x!==Z||!IA1.test(Z)||Z in X)continue;let K=PA1(Q.substring(z+1));if(K.startsWith('"')&&K.endsWith('"'))K=K.slice(1,-1);if(pa0.test(K)){if(X[Z]=K.indexOf("%")!==-1?xK(K,TW):K,x)break}}return X};var ia0=($,x,Y={})=>{if(!IA1.test($))throw Error("Invalid cookie name");let X=`${$}=${x}`;if($.startsWith("__Secure-")&&!Y.secure)throw Error("__Secure- Cookie must have Secure attributes");if($.startsWith("__Host-")){if(!Y.secure)throw Error("__Host- Cookie must have Secure attributes");if(Y.path!=="/")throw Error('__Host- Cookie must have Path attributes with "/"');if(Y.domain)throw Error("__Host- Cookie must not have Domain attributes")}for(let Q of["domain","path","sameSite","priority"])if(Y[Q]&&/[;\r\n]/.test(Y[Q]))throw Error(`${Q} must not contain ";", "\\r", or "\\n"`);if(Y&&typeof Y.maxAge==="number"&&Y.maxAge>=0){if(Y.maxAge>34560000)throw Error("Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.");X+=`; Max-Age=${Y.maxAge|0}`}if(Y.domain&&Y.prefix!=="host")X+=`; Domain=${Y.domain}`;if(Y.path)X+=`; Path=${Y.path}`;if(Y.expires){if(Y.expires.getTime()-Date.now()>34560000000)throw Error("Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.");X+=`; Expires=${Y.expires.toUTCString()}`}if(Y.httpOnly)X+="; HttpOnly";if(Y.secure)X+="; Secure";if(Y.sameSite)X+=`; SameSite=${Y.sameSite.charAt(0).toUpperCase()+Y.sameSite.slice(1)}`;if(Y.priority)X+=`; Priority=${Y.priority.charAt(0).toUpperCase()+Y.priority.slice(1)}`;if(Y.partitioned){if(!Y.secure)throw Error("Partitioned Cookie must have Secure attributes");X+="; Partitioned"}return X},NE=($,x,Y)=>{return x=encodeURIComponent(x),ia0($,x,Y)};var MA1=($,x)=>{return $=$.replace(/\/+$/,""),$=$+"/",x=x.replace(/^\/+/,""),$+x},aB=($,x)=>{for(let[Y,X]of Object.entries(x)){let Q=new RegExp("/:"+Y+"(?:{[^/]+})?\\??");$=$.replace(Q,X?`/${X}`:"")}return $},_A1=($)=>{let x=new URLSearchParams;for(let[Y,X]of Object.entries($)){if(X===void 0)continue;if(Array.isArray(X))for(let Q of X)x.append(Y,Q);else x.set(Y,X)}return x},OA1=($,x)=>{switch(x){case"ws":return $.replace(/^http/,"ws");case"http":return $.replace(/^ws/,"http")}},PE=($)=>{if(/^https?:\/\/[^\/]+?\/index(?=\?|$)/.test($))return $.replace(/\/index(?=\?|$)/,"/");return $.replace(/\/index(?=\?|$)/,"")};function dB($){return typeof $==="object"&&$!==null&&!Array.isArray($)}function IE($,x){if(!dB($)&&!dB(x))return x;let Y={...$};for(let X in x){let Q=x[X];if(dB(Y[X])&&dB(Q))Y[X]=IE(Y[X],Q);else Y[X]=Q}return Y}var fA1=($,x)=>{return new Proxy(()=>{},{get(X,Q){if(typeof Q!=="string"||Q==="then")return;return fA1($,[...x,Q])},apply(X,Q,z){return $({path:x,args:z})}})},na0=class{url;method;buildSearchParams;queryParams=void 0;pathParams={};rBody;cType=void 0;constructor($,x,Y){this.url=$,this.method=x,this.buildSearchParams=Y.buildSearchParams}fetch=async($,x)=>{if($){if($.query)this.queryParams=this.buildSearchParams($.query);if($.form){let K=new FormData;for(let[V,W]of Object.entries($.form)){if(W===void 0)continue;if(Array.isArray(W))for(let w of W)K.append(V,w);else K.append(V,W)}this.rBody=K}if($.json)this.rBody=JSON.stringify($.json),this.cType="application/json";if($.param)this.pathParams=$.param}let Y=this.method.toUpperCase(),X={...$?.header,...typeof x?.headers==="function"?await x.headers():x?.headers};if($?.cookie){let K=[];for(let[V,W]of Object.entries($.cookie))K.push(NE(V,W,{path:"/"}));X.Cookie=K.join(",")}if(this.cType)X["Content-Type"]=this.cType;let Q=new Headers(X??void 0),z=this.url;if(z=PE(z),z=aB(z,this.pathParams),this.queryParams)z=z+"?"+this.queryParams.toString();Y=this.method.toUpperCase();let Z=!(Y==="GET"||Y==="HEAD");return(x?.fetch||fetch)(z,{body:Z?this.rBody:void 0,method:Y,headers:Q,...x?.init})}},ME=($,x)=>fA1(function Y(X){let Q=x?.buildSearchParams??_A1,z=[...X.path],Z=z.slice(-3).reverse();if(Z[0]==="toString"){if(Z[1]==="name")return Z[2]||"";return Y.toString()}if(Z[0]==="valueOf"){if(Z[1]==="name")return Z[2]||"";return Y}let K="";if(/^\$/.test(Z[0])){let H=z.pop();if(H)K=H.replace(/^\$/,"")}let V=z.join("/"),W=MA1($,V);if(K==="url"||K==="path"){let H=W;if(X.args[0]){if(X.args[0].param)H=aB(W,X.args[0].param);if(X.args[0].query)H=H+"?"+Q(X.args[0].query).toString()}if(H=PE(H),K==="url")return new URL(H);return H.slice($.replace(/\/+$/,"").length).replace(/^\/?/,"/")}if(K==="ws"){let H=OA1(X.args[0]&&X.args[0].param?aB(W,X.args[0].param):W,"ws"),U=new URL(H),J=X.args[0]?.query;if(J)Object.entries(J).forEach(([B,D])=>{if(Array.isArray(D))D.forEach((v)=>U.searchParams.append(B,v));else U.searchParams.set(B,D)});return((...B)=>{if(x?.webSocket!==void 0&&typeof x.webSocket==="function")return x.webSocket(...B);return new WebSocket(...B)})(U.toString())}let w=new na0(W,K,{buildSearchParams:Q});if(K){x??={};let H=IE(x,{...X.args[1]});return w.fetch(X.args[0],H)}return w},[]);function t7($){return`http://127.0.0.1:${$}`}import{join as bA1}from"path";var da0=new z8,aa0=new X8;class _E{descriptors;fs;process;logger;diagnosticLog;dir;constructor($){this.descriptors=new Map($.descriptors.map((x)=>[x.type,x])),this.fs=$.fs??da0,this.process=$.process??aa0,this.logger=$.logger,this.diagnosticLog=$.diagnosticLog,this.dir=$.dir??W9,Object.freeze(this)}has($){return this.descriptors.has($)}types(){return[...this.descriptors.keys()]}createListener($,x){return this.require(x.type).createListener(x,this.listenerDeps($))}createAdapter($){let x=this.require($.type);if(!x.createAdapter)return null;return x.createAdapter($,this.adapterDeps())}secretTokens($){return this.require($.type).secretTokens($)}buildConfig($,x){let Y=typeof $.type==="string"?$.type:"";return this.require(Y).buildConfig($,x)}applyUpdate($,x,Y){return this.require($.type).applyUpdate($,x,Y)}runOperation($,x,Y,X){let z=this.require($.type).operations[x];if(!z)throw Error(`connector type "${$.type}" has no operation "${x}"`);return z({config:$,args:Y,context:X})}connectorDir($,x){return bA1(this.dir,"channels",$,"connectors",x)}channelDir($){return bA1(this.dir,"channels",$)}require($){let x=this.descriptors.get($);if(!x)throw Error(`unknown connector type "${$}". Pass its descriptor to new Funnel({ connectors: [...] }).`);return x}listenerDeps($){return{channelId:$,fs:this.fs,process:this.process,logger:this.logger,diagnosticLog:this.diagnosticLog,connectorDir:(x,Y)=>this.connectorDir(x,Y)}}adapterDeps(){return{fs:this.fs,process:this.process,logger:this.logger}}}class SW{millis(){return this.now().getTime()}iso(){return this.now().toISOString()}}class zX extends SW{now(){return new Date}}var sa0=new zX,oa0=new s7;class OE{store;registry;profileChecker;clock;idGenerator;constructor($){this.store=$.store,this.registry=$.registry,this.profileChecker=$.profileChecker??null,this.clock=$.clock??sa0,this.idGenerator=$.idGenerator??oa0,Object.freeze(this)}list(){return this.store.read().channels}get($){return this.list().find((x)=>x.name===$)??null}getById($){return this.list().find((x)=>x.id===$)??null}add($){let x=this.store.read();if(x.channels.some((X)=>X.name===$.name))throw Error(`channel "${$.name}" already exists`);let Y={id:this.idGenerator.generate(),name:$.name,delivery:$.delivery??"fanout",connectors:[]};return x.channels.push(Y),this.store.write(x),Y}setDelivery($,x){let Y=this.store.read(),X=this.requireChannel(Y,$);X.delivery=x,this.store.write(Y)}remove($){let x=this.store.read(),Y=x.channels.findIndex((Q)=>Q.name===$);if(Y<0)throw Error(`channel "${$}" not found`);let X=x.channels[Y];if(X&&this.profileChecker?.hasChannelRef(X.id))throw Error(`channel "${$}" is referenced by a profile`);x.channels.splice(Y,1),this.store.write(x)}rename($,x){let Y=this.store.read(),X=Y.channels.find((Q)=>Q.name===$);if(!X)throw Error(`channel "${$}" not found`);if(Y.channels.some((Q)=>Q.name===x))throw Error(`channel "${x}" already exists`);X.name=x,this.store.write(Y)}listConnectors($){return this.requireChannel(this.store.read(),$).connectors}getConnector($,x){let Y=this.get($);if(!Y)return null;return Y.connectors.find((X)=>X.name===x)??null}listAllConnectors(){let $=[];for(let x of this.list())for(let Y of x.connectors)$.push({...Y,channelId:x.id,channelName:x.name});return $}addConnector($,x){let Y=this.store.read(),X=this.requireChannel(Y,$);if(X.connectors.some((z)=>z.name===x.name))throw Error(`connector "${x.name}" already exists in channel "${$}"`);let Q=this.registry.buildConfig(x,{id:this.idGenerator.generate(),now:this.clock.iso()});return this.assertNoTokenCollision(Y,Q),X.connectors.push(Q),this.store.write(Y),Q}removeConnector($,x){let Y=this.store.read(),X=this.requireChannel(Y,$),Q=X.connectors.findIndex((z)=>z.name===x);if(Q<0)throw Error(`connector "${x}" not found in channel "${$}"`);X.connectors.splice(Q,1),this.store.write(Y)}renameConnector($,x,Y){let X=this.store.read(),Q=this.requireChannel(X,$),z=Q.connectors.find((Z)=>Z.name===x);if(!z)throw Error(`connector "${x}" not found in channel "${$}"`);if(Q.connectors.some((Z)=>Z.name===Y))throw Error(`connector "${Y}" already exists in channel "${$}"`);z.name=Y,z.updatedAt=this.clock.iso(),this.store.write(X)}updateConnector($,x,Y){let X=this.store.read(),Q=this.requireChannel(X,$),z=Q.connectors.find((K)=>K.name===x);if(!z)throw Error(`connector "${x}" not found in channel "${$}"`);let Z=this.registry.applyUpdate(z,Y,{now:this.clock.iso()});this.assertNoTokenCollision(X,Z),this.replaceConnector(Q,z.name,Z),this.store.write(X)}updateSlackConnector($,x,Y){this.updateConnector($,x,Y)}updateGhConnector($,x,Y){this.updateConnector($,x,Y)}updateDiscordConnector($,x,Y){this.updateConnector($,x,Y)}connectorOp($,x,Y,X){let Q=this.store.read(),z=this.requireChannel(Q,$),Z=z.connectors.find((V)=>V.name===x);if(!Z)throw Error(`connector "${x}" not found in channel "${$}"`);let K=this.registry.runOperation(Z,Y,X,{generateId:()=>this.idGenerator.generate(),now:this.clock.iso()});if(K.config!==Z)this.replaceConnector(z,Z.name,K.config),this.store.write(Q);return K.result}async call($,x,Y){let X=this.getConnector($,x);if(!X)throw Error(`connector "${x}" not found in channel "${$}"`);let Q=this.registry.createAdapter(X);if(!Q)throw Error(`connector type "${X.type}" does not support outbound calls`);return await Q.call(Y)}createListener($,x){let Y=this.get($);if(!Y)return null;let X=Y.connectors.find((Q)=>Q.name===x);if(!X)return null;return{config:X,channelId:Y.id,listener:this.registry.createListener(Y.id,X)}}createAllListeners(){let $=[];for(let x of this.list())for(let Y of x.connectors)$.push({config:Y,channelId:x.id,channelName:x.name,listener:this.registry.createListener(x.id,Y)});return $}requireChannel($,x){let Y=$.channels.find((X)=>X.name===x);if(!Y)throw Error(`channel "${x}" not found`);return Y}replaceConnector($,x,Y){let X=$.connectors.findIndex((Q)=>Q.name===x);if(X<0)throw Error(`connector "${x}" not found in channel "${$.name}"`);$.connectors[X]=Y}assertNoTokenCollision($,x){let Y=this.registry.secretTokens(x);if(Y.length===0)return;for(let X of $.channels)for(let Q of X.connectors){if(Q.id===x.id)continue;for(let z of this.registry.secretTokens(Q))if(Y.includes(z))throw Error(`token already in use by connector "${Q.name}" in channel "${X.name}"`)}}}var ra0=new X8,ta0=new s7;class fE{channels;mcp;gateway;sessions;guard;process;idGenerator;logger;dir;constructor($){this.channels=$.channels,this.mcp=$.mcp,this.gateway=$.gateway,this.sessions=$.sessions,this.guard=$.guard,this.process=$.process??ra0,this.idGenerator=$.idGenerator??ta0,this.logger=$.logger,this.dir=$.dir,Object.freeze(this)}async launch($){let x=this.channels.get($.channel)??this.channels.getById($.channel);if(!x)throw Error(`channel "${$.channel}" not found`);if($.profileId&&this.guard.isRunning($.profileId))throw Error(`profile "${$.profileId}" is already running`);let Y=$.cwd??globalThis.process.cwd();if(($.installMcp??!0)&&!this.mcp.findInstalledName(Y))this.mcp.install(Y),this.logger?.info("added funnel MCP to .mcp.json",{cwd:Y});if(!this.gateway.isRunning()){if(this.logger?.info("starting gateway automatically"),!await this.gateway.start())throw Error(`gateway failed to start on port ${r7()}; another funnel daemon (a different repo/scope) may already hold it. See 'fnl gateway logs' and 'ps -o pid,args= | grep funnel-gateway'.`)}if($.profileId)this.guard.acquire($.profileId);let z=($.resume??!1)&&$.profileId?this.resolveSession($.profileId,Y,$.userArgs??[],$.env??{}):null,Z=this.buildArgs($.options??[],$.userArgs??[],Y,z),K=this.buildEnv(x.id,$.env??{});this.logger?.info("claude launch",{channel:$.channel,channelId:x.id,cwd:Y});try{return await this.process.attach(["claude",...Z],{cwd:Y,env:K,onSpawned:$.onSpawned})}finally{if($.profileId)this.guard.release($.profileId)}}buildArgs($,x,Y,X){let Q=[...$,...x];if(X!==null)if(X.mode==="resume")Q.push("--resume",X.id);else Q.push("--session-id",X.id);let z=this.mcp.findInstalledName(Y);if(z&&!Q.includes("--dangerously-load-development-channels")&&!Q.includes("--channels"))Q.push("--dangerously-load-development-channels",`server:${z}`);return Q}resolveSession($,x,Y,X){for(let Z of Y){if(Z==="-c"||Z==="--continue")return null;if(Z==="--resume"||Z.startsWith("--resume="))return null;if(Z==="--session-id"||Z.startsWith("--session-id="))return null}let Q=this.sessions.getSessionId($);if(Q!==null&&this.sessions.sessionFileExists(x,Q,X))return{id:Q,mode:"resume"};let z=this.idGenerator.generate();return this.sessions.setSessionId($,z),{id:z,mode:"new"}}buildEnv($,x){let Y={};for(let[X,Q]of Object.entries(x))Y[X]=Q;for(let[X,Q]of Object.entries(globalThis.process.env))if(typeof Q==="string")Y[X]=Q;if(Y.FUNNEL_CHANNEL_ID=$,Y.FUNNEL_PORT=String(r7()),this.dir!==void 0)Y.FUNNEL_DIR=this.dir;return Y}}import{join as cA1}from"path";var ea0=new z8,$s0=new X8;class sB{fs;process;pidDir;constructor($={}){this.fs=$.fs??ea0,this.process=$.process??$s0,this.pidDir=cA1($.dir??W9,"claude"),Object.freeze(this)}isRunning($){let x=this.readRecord($);if(!x)return!1;if(!this.process.isAlive(x.pid))return this.release($),!1;if(x.startTime!==null){let Y=this.process.getStartTime(x.pid);if(Y===null)return this.release($),!1;if(Y!==x.startTime)return this.release($),!1}return!0}acquire($){this.fs.mkdirSync(this.pidDir,{recursive:!0});let x=globalThis.process.pid,Y=this.process.getStartTime(x),X={pid:x,startTime:Y};this.fs.writeFileSync(this.pidPath($),JSON.stringify(X)),globalThis.process.once("exit",()=>this.release($))}release($){let x=this.pidPath($);if(this.fs.existsSync(x))this.fs.unlink(x)}pidPath($){return cA1(this.pidDir,`${$}.pid`)}readRecord($){let x=this.pidPath($);if(!this.fs.existsSync(x))return null;try{let Y=this.fs.readFileSync(x).trim();if(!Y)return null;if(Y.startsWith("{")){let Q=JSON.parse(Y),z=typeof Q.pid==="number"?Q.pid:Number(Q.pid);if(!Number.isInteger(z)||z<=0)return null;let Z=typeof Q.startTime==="string"?Q.startTime:null;return{pid:z,startTime:Z}}let X=Number(Y);if(!X||X<=0)return null;return{pid:X,startTime:null}}catch{return null}}}import{existsSync as RE}from"fs";import{join as kE}from"path";var bE=($)=>typeof $==="string"&&$.length>0?$:null,oB=($)=>typeof $==="number"?$:null,rB=($,x)=>typeof $==="string"?$:x,xs0=($)=>$!==null&&typeof $==="object"&&!Array.isArray($),kA1=($)=>{if($===null)return null;try{let x=JSON.parse($);if(xs0(x))return x}catch{return null}return null},RA1=($,x)=>$.length<=x?$:`${$.slice(0,x)}\u2026`,Ys0=($)=>{if(typeof $!=="string"||$.length===0)return null;let x=kA1($);if(x!==null&&"text"in x)return RA1(String(x.text),60);return RA1($,60)},tB=($)=>{let x=bE($.payload);return{seq:oB($.seq),ts:oB($.ts),type:rB($.type,"?"),outcome:rB($.outcome,"?"),eventId:bE($.event_id),payload:x,payloadParsed:kA1(x),preview:Ys0($.payload)}},cE=($)=>({seq:oB($.seq),ts:oB($.ts),type:rB($.type,"?"),status:rB($.status,"?"),detail:bE($.detail)}),Sx=($,x,Y)=>{try{return $.query(x,Y)}finally{$.close()}};import{Database as Qs0}from"bun:sqlite";class ux{db;constructor($){let x=new Qs0($.rawPath,{readonly:!0});try{x.run("PRAGMA busy_timeout = 500"),x.prepare("ATTACH DATABASE ? AS processeddb").run($.processedPath),x.prepare("ATTACH DATABASE ? AS connectiondb").run($.connectionPath),x.run(Xs0),x.run(zs0),x.run(Zs0)}catch(Y){throw x.close(),Y}this.db=x,Object.freeze(this)}query($,x=[]){let Y=$.trim().replace(/;$/,"").trim();if(!/^select\b/i.test(Y))return Error("only a single SELECT statement is allowed");if(Y.includes(";"))return Error("only a single statement is allowed (remove the ';')");try{return this.db.prepare(Y).all(...x)}catch(X){return X instanceof Error?X:Error(String(X))}}close(){this.db.close()}}var Xs0=`CREATE TEMP VIEW raw AS SELECT
536
536
  seq,
537
537
  ts,
538
538
  json_extract(event, '$.event_id') AS event_id,
@@ -1232,5 +1232,5 @@ related: fnl docs architecture, fnl docs debugging, fnl docs mcp`;var iA1=`funne
1232
1232
  related: fnl docs debugging, fnl docs channels, fnl docs profiles`;var SE={architecture:AA1,channels:TA1,claude:SA1,connectors:uA1,debugging:EA1,gateway:CA1,glossary:yA1,"local-config":mA1,mcp:hA1,profiles:gA1,"programmable-api":pA1,recipes:iA1},Us0={architecture:"how Funnel routes events end-to-end",channels:"what a channel is and how delivery modes work",connectors:"external service bindings nested in channels",profiles:"named Claude launch presets",claude:"fnl claude resolution order and argv assembly",mcp:"the MCP server, inbound notifications, outbound tools",gateway:"the WebSocket + HTTP daemon","local-config":"the per-repo funnel.json file",debugging:"ladder for diagnosing event delivery problems","programmable-api":"Funnel as an SDK; build your own CLI/UI on the engine",recipes:"common task playbooks",glossary:"vocabulary reference"};class uE{constructor(){Object.freeze(this)}list(){return Object.keys(SE).sort().map(($)=>({name:$,summary:Us0[$]??""}))}get($){return SE[$]??null}topics(){return Object.keys(SE).sort()}}import{join as Ls0}from"path";var Gs0=c.object({type:c.literal("slack"),name:c.string(),minify:c.boolean().optional()}),Js0=c.object({type:c.literal("discord"),name:c.string()}),qs0=c.object({type:c.literal("gh"),name:c.string(),pollInterval:c.number().int().positive().optional()}),Ds0=c.object({type:c.literal("schedule"),name:c.string()}),Bs0=c.discriminatedUnion("type",[Gs0,Js0,qs0,Ds0]),vs0=c.object({name:c.string(),connectors:c.array(Bs0).optional()}),Fs0=c.object({name:c.string(),channel:c.string(),options:c.array(c.string()).optional(),env:c.record(c.string(),c.string()).optional(),resume:c.boolean().optional()}),lA1=c.object({$schema:c.string().optional(),id:c.string().optional(),channels:c.array(vs0).min(1),profiles:c.array(Fs0).optional()}),YK="funnel.json";class EE{fs;constructor($){this.fs=$.fs,Object.freeze(this)}read($){let x=Ls0($,YK);if(!this.fs.existsSync(x))return null;let Y=this.fs.readFileSync(x),X=(()=>{try{return JSON.parse(Y)}catch(z){let Z=z instanceof Error?z.message:String(z);throw Error(`${YK} is not valid JSON: ${Z}`)}})(),Q=lA1.safeParse(X);if(!Q.success)throw Error(`${YK} is invalid: ${Q.error.message}`);return this.assertProfilesValid(Q.data),Q.data}assertProfilesValid($){let x=$.profiles??[];if(x.length===0)return;let Y=new Set($.channels.map((Q)=>Q.name)),X=new Set;for(let Q of x){if(!Y.has(Q.channel))throw Error(`${YK} is invalid: profile "${Q.name}" binds channel "${Q.channel}", which is not declared in channels[]`);if(X.has(Q.name))throw Error(`${YK} is invalid: more than one profile is named "${Q.name}" \u2014 names must be unique`);X.add(Q.name)}}}function CE($){if($.env!==void 0)return{botTokenEnv:$.env};if($.literal!==void 0)return{botToken:$.literal};return{}}function nA1($){if($.env!==void 0)return{appTokenEnv:$.env};if($.literal!==void 0)return{appToken:$.literal};return{}}class yE{channels;prompter;constructor($){this.channels=$.channels,this.prompter=$.prompter,Object.freeze(this)}async ensure($){if(!this.channels.get($.name))this.channels.add({name:$.name});if($.connectors===void 0)return{touched:[],removed:[]};let Y=[],X=new Set;for(let z of $.connectors){let Z=await this.ensureConnector($.name,z);Y.push({name:Z.name,changed:Z.changed}),X.add(Z.id)}let Q=this.removeExtras($.name,X);return{touched:Y,removed:Q}}async ensureConnector($,x){if(x.type==="slack")return await this.ensureSlack($,x);if(x.type==="discord")return await this.ensureDiscord($,x);if(x.type==="gh")return this.ensureGh($,x);return this.ensureSchedule($,x)}async ensureSlack($,x){let Y=this.findExistingSlack($,x.name),X=await this.resolveSlot({label:`${x.name}.botToken`,existingLiteral:Y?.botToken,existingEnv:Y?.botTokenEnv}),Q=await this.resolveSlot({label:`${x.name}.appToken`,existingLiteral:Y?.appToken,existingEnv:Y?.appTokenEnv}),z={botToken:X.token,botTokenEnv:X.tokenEnv,appToken:Q.token,appTokenEnv:Q.tokenEnv};if(Y){if(!(Y.botToken===X.token&&Y.botTokenEnv===X.tokenEnv&&Y.appToken===Q.token&&Y.appTokenEnv===Q.tokenEnv))return this.channels.updateSlackConnector($,x.name,z),{id:Y.id,name:x.name,changed:!0};return{id:Y.id,name:x.name,changed:!1}}return{id:this.channels.addConnector($,{type:"slack",name:x.name,...CE({literal:X.token,env:X.tokenEnv}),...nA1({literal:Q.token,env:Q.tokenEnv}),...x.minify!==void 0?{minify:x.minify}:{}}).id,name:x.name,changed:!0}}async ensureDiscord($,x){let Y=this.findExistingDiscord($,x.name),X=await this.resolveSlot({label:`${x.name}.botToken`,existingLiteral:Y?.botToken,existingEnv:Y?.botTokenEnv}),Q={botToken:X.token,botTokenEnv:X.tokenEnv};if(Y){if(Y.botToken!==X.token||Y.botTokenEnv!==X.tokenEnv)return this.channels.updateDiscordConnector($,x.name,Q),{id:Y.id,name:x.name,changed:!0};return{id:Y.id,name:x.name,changed:!1}}return{id:this.channels.addConnector($,{type:"discord",name:x.name,...CE({literal:X.token,env:X.tokenEnv})}).id,name:x.name,changed:!0}}ensureGh($,x){let Y=this.channels.getConnector($,x.name);if(Y&&Y.type!=="gh")throw Error(`connector "${x.name}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "gh"`);if(Y&&Y.type==="gh"){let Q=t2.parse(Y);if(x.pollInterval!==void 0&&Q.pollInterval!==x.pollInterval)return this.channels.updateGhConnector($,x.name,{pollInterval:x.pollInterval}),{id:Q.id,name:x.name,changed:!0};return{id:Q.id,name:x.name,changed:!1}}return{id:this.channels.addConnector($,{type:"gh",name:x.name,...x.pollInterval!==void 0?{pollInterval:x.pollInterval}:{}}).id,name:x.name,changed:!0}}ensureSchedule($,x){let Y=this.channels.getConnector($,x.name);if(Y&&Y.type!=="schedule")throw Error(`connector "${x.name}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "schedule"`);if(Y&&Y.type==="schedule")return{id:Y.id,name:x.name,changed:!1};return{id:this.channels.addConnector($,{type:"schedule",name:x.name}).id,name:x.name,changed:!0}}findExistingSlack($,x){let Y=this.channels.getConnector($,x);if(!Y)return null;if(Y.type!=="slack")throw Error(`connector "${x}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "slack"`);return A7.parse(Y)}findExistingDiscord($,x){let Y=this.channels.getConnector($,x);if(!Y)return null;if(Y.type!=="discord")throw Error(`connector "${x}" exists in channel "${$}" with type "${Y.type}", funnel.json declares "discord"`);return H7.parse(Y)}removeExtras($,x){let Y=this.channels.get($);if(!Y)return[];let X=Y.connectors.filter((Q)=>!x.has(Q.id));for(let Q of X)this.channels.removeConnector($,Q.name);return X.map((Q)=>Q.name)}async resolveSlot($){if($.existingEnv!==void 0)return{token:void 0,tokenEnv:$.existingEnv};if($.existingLiteral!==void 0)return{token:$.existingLiteral,tokenEnv:void 0};return{token:await this.prompter.promptSecret($.label),tokenEnv:void 0}}}import{join as dA1}from"path";var js0="bun",Ns0=["funnel","mcp"],Ps0="funnel",Is0=new z8,uW=($)=>{return typeof $==="object"&&$!==null&&!Array.isArray($)};class mE{fs;constructor($={}){this.fs=$.fs??Is0,Object.freeze(this)}install($){if(!this.fs.existsSync($))throw Error(`repository does not exist: ${$}`);let x=this.readConfig($),Y=x.mcpServers,X=uW(Y)?Y:{},z=this.findServerName(X)??Ps0;X[z]={command:js0,args:Ns0},x.mcpServers=X,this.writeConfig($,x)}uninstall($){if(!this.fs.existsSync($))return;let x=this.readConfig($),Y=x.mcpServers;if(!uW(Y))return;let X=this.findServerName(Y);if(!X)return;delete Y[X],this.writeConfig($,x)}findInstalledName($){let Y=this.readConfig($).mcpServers;return uW(Y)?this.findServerName(Y):null}findServerName($){for(let x of Object.entries($))if(this.isFunnelEntry(x[1]))return x[0];return null}isFunnelEntry($){if(!uW($))return!1;let{command:x,args:Y}=$;if(x==="bun"&&Array.isArray(Y)&&Y[0]==="funnel")return!0;if(x==="funnel")return!0;return!1}readConfig($){let x=dA1($,".mcp.json");if(!this.fs.existsSync(x))return{};let Y=this.fs.readFileSync(x).trim();if(!Y)return{};let X;try{X=JSON.parse(Y)}catch(Q){throw Error(`invalid .mcp.json (${x}): ${Q instanceof Error?Q.message:String(Q)}`)}if(!uW(X))throw Error(`invalid .mcp.json (${x}): expected a JSON object`);return X}writeConfig($,x){let Y=dA1($,".mcp.json");this.fs.writeFileSync(Y,`${JSON.stringify(x,null,2)}
1233
1233
  `)}}import{homedir as Ms0}from"os";import{join as aA1}from"path";var _s0=new z8;class hE{store;idGenerator;fs;constructor($){this.store=$.store,this.idGenerator=$.idGenerator,this.fs=$.fs??_s0,Object.freeze(this)}list(){return this.store.read().profiles}get($){return this.list().find((x)=>x.name===$)??null}getById($){return this.list().find((x)=>x.id===$)??null}getDefault(){return this.list()[0]??null}add($){let x=this.store.read();if(x.profiles.some((Y)=>Y.name===$.name))throw Error(`profile "${$.name}" already exists`);if(!x.channels.some((Y)=>Y.id===$.channelId))throw Error(`channel id "${$.channelId}" not found`);x.profiles.push({id:this.idGenerator.generate(),name:$.name,path:$.path,channelId:$.channelId,options:$.options??[],env:$.env??{},resume:$.resume??!0}),this.store.write(x)}remove($){let x=this.store.read(),Y=x.profiles.findIndex((X)=>X.name===$);if(Y<0)throw Error(`profile "${$}" not found`);x.profiles.splice(Y,1),this.store.write(x)}rename($,x){let Y=this.store.read(),X=Y.profiles.find((Q)=>Q.name===$);if(!X)throw Error(`profile "${$}" not found`);if(Y.profiles.some((Q)=>Q.name===x))throw Error(`profile "${x}" already exists`);X.name=x,this.store.write(Y)}asDefault($){let x=this.store.read(),Y=x.profiles.findIndex((Q)=>Q.name===$);if(Y<0)throw Error(`profile "${$}" not found`);if(Y===0)return;let[X]=x.profiles.splice(Y,1);if(!X)return;x.profiles.unshift(X),this.store.write(x)}hasChannelRef($){return this.store.read().profiles.some((x)=>x.channelId===$)}getSessionId($){return this.getById($)?.sessionId??null}setSessionId($,x){let Y=this.store.read(),X=Y.profiles.find((Q)=>Q.id===$);if(!X)throw Error(`profile id "${$}" not found`);X.sessionId=x,this.store.write(Y)}sessionFileExists($,x,Y){let X=Y.CLAUDE_CONFIG_DIR??globalThis.process.env.CLAUDE_CONFIG_DIR??aA1(Ms0(),".claude"),Q=$.replace(/\//g,"-"),z=aA1(X,"projects",Q,`${x}.jsonl`);if(!this.fs.existsSync(z))return!1;return this.fs.readFileSync(z).trim().length>0}update($,x){let Y=this.store.read(),X=Y.profiles.find((Q)=>Q.name===$);if(!X)throw Error(`profile "${$}" not found`);if(x.channelId!==void 0){if(!Y.channels.some((Q)=>Q.id===x.channelId))throw Error(`channel id "${x.channelId}" not found`);X.channelId=x.channelId}if(x.path!==void 0)X.path=x.path;if(x.options!==void 0)X.options=x.options;if(x.env!==void 0)X.env=x.env;if(x.resume!==void 0)X.resume=x.resume;this.store.write(Y)}}class gE{props;constructor($){this.props=$;Object.freeze(this)}async ensureGatewayRunning(){if(this.props.gateway.isRunning())return{ok:!0,actions:[{kind:"gateway:already-running"}],message:"gateway is already running"};if(!await this.props.gateway.start())return{ok:!1,actions:[],message:"gateway failed to start \u2014 check `fnl gateway logs`"};return{ok:!0,actions:[{kind:"gateway:started"}],message:"gateway started"}}async restartGateway(){if(!(await this.props.gateway.restart()).ok)return{ok:!1,actions:[],message:"gateway restart failed \u2014 check `fnl gateway logs`"};return{ok:!0,actions:[{kind:"gateway:restarted"}],message:"gateway restarted"}}async restartListener($,x){let Y=await this.props.listeners.restart($,x);if(Y.state==="offline")return{ok:!1,actions:[],message:"gateway is not running \u2014 call ensureGatewayRunning() first"};if(Y.state==="not-found")return{ok:!1,actions:[{kind:"listener:skipped",channel:$,connector:x,reason:"not-found"}],message:`listener not found: ${$}/${x}`};if(Y.state==="error")return{ok:!1,actions:[{kind:"listener:skipped",channel:$,connector:x,reason:Y.reason}],message:`listener restart failed: ${Y.reason}`};return{ok:!0,actions:[{kind:"listener:restarted",channel:$,connector:x}],message:`restarted ${$}/${x}`}}async restartAllDeadListeners(){let $=await this.props.listeners.list();if($.state==="offline")return{ok:!1,actions:[],message:"gateway is not running \u2014 call ensureGatewayRunning() first"};if($.state==="error")return{ok:!1,actions:[],message:`could not list listeners: ${$.reason}`};let x=$.listeners.filter((Q)=>!Q.alive);if(x.length===0)return{ok:!0,actions:[],message:"no dead listeners found"};let Y=[];for(let Q of x){let z=await this.props.listeners.restart(Q.channelName,Q.name);if(z.state==="ok")Y.push({kind:"listener:restarted",channel:Q.channelName,connector:Q.name});else{let Z=z.state==="error"?z.reason:z.state;Y.push({kind:"listener:skipped",channel:Q.channelName,connector:Q.name,reason:Z})}}let X=Y.filter((Q)=>Q.kind==="listener:restarted").length;return{ok:X>0,actions:Y,message:`restarted ${X}/${x.length} dead listener(s)`}}}import{stderr as eB,stdin as o9}from"process";class pE{}var Os0="*",fs0="\r",sA1=`
1234
1234
  `,bs0=String.fromCharCode(8),cs0=String.fromCharCode(127),Rs0=String.fromCharCode(3),ks0=String.fromCharCode(4);class iE extends pE{async promptSecret($){if(!o9.isTTY)throw Error(`cannot prompt for "${$}": stdin is not a TTY. Set the matching env var or run \`fnl channels <ch> connectors add ...\` first.`);eB.write(`${$}: `);let x=o9.isRaw;o9.setRawMode(!0),o9.resume();try{return await this.readSecret()}finally{o9.setRawMode(x),o9.pause(),eB.write(sA1)}}readSecret(){return new Promise(($,x)=>{let Y="",X=(Q)=>{for(let z of Q){let Z=String.fromCharCode(z);if(Z===sA1||Z===fs0){o9.off("data",X),$(Y);return}if(Z===Rs0){o9.off("data",X),x(Error("prompt cancelled"));return}if(Z===ks0){if(o9.off("data",X),Y.length===0)x(Error("prompt cancelled"));else $(Y);return}if(Z===bs0||Z===cs0){if(Y.length>0)Y=Y.slice(0,-1),eB.write("\b \b");continue}Y+=Z,eB.write(Os0)}};o9.on("data",X)})}}var As0=384;class lE extends AV{dirs;files;mtimes;modes;now;constructor($={}){super();this.dirs=new Set($.dirs??[]),this.files=new Map(Object.entries($.files??{})),this.mtimes=new Map(Object.entries($.mtimes??{})),this.modes=new Map(Object.entries($.modes??{})),this.now=$.now??(()=>Date.now())}existsSync($){return this.dirs.has($)||this.files.has($)}readFileSync($){return this.files.get($)??""}writeFileSync($,x){this.files.set($,x),this.touch($)}writeSecretFileSync($,x){this.files.set($,x),this.modes.set($,As0),this.touch($)}appendFileSync($,x){let Y=this.files.get($)??"";this.files.set($,Y+x),this.touch($)}unlink($){this.files.delete($),this.mtimes.delete($),this.modes.delete($)}mkdirSync($,x){this.dirs.add($)}readdirSync($){let x=$.endsWith("/")?$:`${$}/`,Y=[];for(let X of this.files.keys()){if(!X.startsWith(x))continue;let Q=X.slice(x.length);if(!Q.includes("/"))Y.push(Q)}return Y}statSync($){let x=this.mtimes.get($);if(x===void 0)throw Error(`not found: ${$}`);return{mtimeMs:x,mode:this.modes.get($)??null}}setMtime($,x){this.mtimes.set($,x)}setMode($,x){this.modes.set($,x)}touch($){if(!this.mtimes.has($))this.mtimes.set($,this.now());else this.mtimes.set($,this.now())}}class nE extends kW{counter=0;prefix;constructor($={}){super();this.prefix=$.prefix??"id"}generate(){return this.counter++,`${this.prefix}-${this.counter}`}}class EW{}class dE extends EW{file=null;entries=[];info($,x){this.entries.push({level:"info",message:$,meta:x})}warn($,x){this.entries.push({level:"warn",message:$,meta:x})}error($,x){this.entries.push({level:"error",message:$,meta:x})}clear(){this.entries.length=0}}var oA1={exitCode:0,stdout:"",stderr:""};class aE extends RV{calls=[];killed=[];handler=()=>oA1;syncHandler=()=>oA1;aliveStub=null;listStub=null;startTimeStub=null;on($){return this.handler=$,this}onSync($){return this.syncHandler=$,this}onIsAlive($){return this.aliveStub=$,this}onListProcessesContaining($){return this.listStub=$,this}onGetStartTime($){return this.startTimeStub=$,this}async run($,x={}){this.calls.push({kind:"run",command:$,options:x});let Y=await this.handler($);return{exitCode:Y.exitCode??0,stdout:Y.stdout??"",stderr:Y.stderr??""}}runSync($){this.calls.push({kind:"runSync",command:$});let x=this.syncHandler($);return{exitCode:x.exitCode??0,stdout:x.stdout??"",stderr:x.stderr??""}}async attach($,x={}){if(this.calls.push({kind:"attach",command:$,options:x}),x.onSpawned)x.onSpawned(1);return(await this.handler($)).exitCode??0}detach($,x={}){this.calls.push({kind:"detach",command:$,options:x})}kill($,x="SIGTERM"){this.calls.push({kind:"kill",command:[String($),x]}),this.killed.push({pid:$,signal:x})}isAlive($){if(this.aliveStub)return this.aliveStub($);let x=this.syncHandler(["ps","-p",String($),"-o","state="]);if((x.exitCode??0)!==0)return!1;let Y=(x.stdout??"").trim();if(!Y)return!1;return!Y.startsWith("Z")}listProcessesContaining($){if(this.listStub)return this.listStub($);return[]}getStartTime($){if(this.startTimeStub)return this.startTimeStub($);return null}}var Ts0=($={})=>({version:o7,channels:[],profiles:[],...$});class sE extends AW{state;constructor($){super();this.state=Ts0($)}read(){return this.state}write($){this.state=$}}class oE extends SW{current;constructor($={}){super();this.current=$.start??new Date(0)}now(){return new Date(this.current.getTime())}set($){this.current=$}advance($){this.current=new Date(this.current.getTime()+$)}}var rA1=c.object({content:c.string().min(1),meta:c.record(c.string(),c.string()).optional(),connector:c.string().min(1).optional(),target:c.string().min(1).optional()}),tA1=c.object({ok:c.literal(!0),offset:c.number().int().nonnegative()});var Ss0={state:"offline"};class rE{port;isDaemonRunning;getToken;constructor($){this.port=$.port,this.isDaemonRunning=$.isDaemonRunning,this.getToken=$.getToken??(()=>null),Object.freeze(this)}async publish($,x){if(!this.isDaemonRunning())return Ss0;try{let Y=`${t7(this.port)}/channels/${encodeURIComponent($)}/publish`,X=await fetch(Y,{method:"POST",headers:{...this.authHeaders(),"content-type":"application/json"},body:JSON.stringify(x)});if(!X.ok)return{state:"error",reason:await X.text()||`HTTP ${X.status}`};let Q=tA1.safeParse(await X.json());if(!Q.success)return{state:"error",reason:"malformed daemon response"};return{state:"ok",offset:Q.data.offset}}catch(Y){return{state:"error",reason:Y instanceof Error?Y.message:String(Y)}}}authHeaders(){let $=this.getToken();return $?{authorization:`Bearer ${$}`}:{}}}import{join as eA1}from"path";import{existsSync as us0}from"fs";import{dirname as Es0,resolve as tE}from"path";import{fileURLToPath as Cs0}from"url";var $v=()=>{let $=Es0(Cs0(import.meta.url)),x=[tE($,"./daemon.ts"),tE($,"./daemon.js"),tE($,"./gateway/daemon.js")];for(let Y of x)if(us0(Y))return Y;throw Error(`daemon script not found (looked in ${x.join(", ")})`)};var ys0=5000,ms0=2000,$T1=100,hs0=200,gs0=new X8,ps0=new z8,is0=new zX,ls0=($)=>new Promise((x)=>{setTimeout(x,$)});class eE{process;fs;clock;dir;pidFile;gatewayLog;tmpDir;port;sleep;constructor($={}){this.process=$.process??gs0,this.fs=$.fs??ps0,this.clock=$.clock??is0,this.dir=$.dir??W9,this.tmpDir=$.tmpDir??Tx(),this.pidFile=eA1(this.dir,"gateway.pid"),this.gatewayLog=eA1(this.tmpDir,"gateway.log"),this.port=$.port??r7(),this.sleep=$.sleep??ls0,Object.freeze(this)}isRunning(){let $=this.readPid();if(!$)return!1;return this.isProcessAlive($)}getStatus(){let $=this.readPid(),x=$!==null&&this.isProcessAlive($);return{running:x,pid:x?$:null,port:this.port}}async start($={}){if(this.isRunning())return!0;this.fs.mkdirSync(this.tmpDir,{recursive:!0});let x=$v(),Y=this.buildStartCommand(x,$);this.process.detach(Y,{env:{FUNNEL_DIR:this.dir},stdoutFile:this.gatewayLog,stderrFile:this.gatewayLog});let X=this.clock.millis()+ys0;while(this.clock.millis()<X){if(this.isRunning())return!0;await this.sleep($T1)}return this.isRunning()}buildStartCommand($,x={}){let Y=`funnel-gateway[${this.dir}]`;if(x.caffeinate!==!1&&globalThis.process.platform==="darwin")return["caffeinate","-is","bun",$,Y];return["bun",$,Y]}async stop(){let $=this.readPid();if(!$)return!0;if(!this.isProcessAlive($))return this.removePid(),!0;try{this.process.kill($,"SIGTERM")}catch{return!1}let x=this.clock.millis()+ms0;while(this.clock.millis()<x){if(!this.isProcessAlive($))return this.removePid(),!0;await this.sleep($T1)}try{this.process.kill($,"SIGKILL")}catch{}return await this.sleep(hs0),this.removePid(),!this.isProcessAlive($)}async restart($={}){let x=this.isRunning();if($.onlyIfRunning&&!x)return{ok:!0,wasRunning:!1,stopped:!1,started:!1};let Y=x?await this.stop():!0;if(!Y)return{ok:!1,wasRunning:x,stopped:!1,started:!1};let X=await this.start({caffeinate:$.caffeinate});return{ok:X,wasRunning:x,stopped:Y,started:X}}getGatewayLog(){return this.gatewayLog}getPort(){return this.port}readPid(){if(!this.fs.existsSync(this.pidFile))return null;try{let $=this.fs.readFileSync(this.pidFile).trim(),x=Number($);if(!x||x<=0)return null;return x}catch{return null}}removePid(){this.fs.unlink(this.pidFile)}isProcessAlive($){return this.process.isAlive($)}}import{existsSync as po0,mkdirSync as io0}from"fs";import{dirname as lo0,join as no0}from"path";import{timingSafeEqual as ns0}from"crypto";var e7=($)=>{return async(x,Y)=>{let z=(x.req.header("authorization")??"").match(/^Bearer\s+(.+)$/i)?.[1]??"";if(!xv(z,$.expected))return x.text("unauthorized",401);return await Y()}},xv=($,x)=>{let Y=Buffer.from($,"utf-8"),X=Buffer.from(x,"utf-8"),Q=Math.max(Y.length,X.length,1),z=Buffer.alloc(Q),Z=Buffer.alloc(Q);return Y.copy(z),X.copy(Z),ns0(z,Z)&&Y.length===X.length};var $C=($,x,Y)=>{return(X,Q)=>{let z=-1;return Z(0);async function Z(K){if(K<=z)throw Error("next() called multiple times");z=K;let V,W=!1,w;if($[K])w=$[K][0][0],X.req.routeIndex=K;else w=K===$.length&&Q||void 0;if(w)try{V=await w(X,()=>Z(K+1))}catch(H){if(H instanceof Error&&x)X.error=H,V=await x(H,X),W=!0;else throw H}else if(X.finalized===!1&&Y)V=await Y(X);if(V&&(X.finalized===!1||W))X.res=V;return X}}};var FY=class extends Error{res;status;constructor($=500,x){super(x?.message,{cause:x?.cause});this.res=x?.res,this.status=$}getResponse(){if(this.res)return new Response(this.res.body,{status:this.status,headers:this.res.headers});return new Response(this.message,{status:this.status})}};var xT1=Symbol();var YT1=async($,x=Object.create(null))=>{let{all:Y=!1,dot:X=!1}=x,z=($ instanceof Yv?$.raw.headers:$.headers).get("Content-Type");if(z?.startsWith("multipart/form-data")||z?.startsWith("application/x-www-form-urlencoded"))return ds0($,{all:Y,dot:X});return{}};async function ds0($,x){let Y=await $.formData();if(Y)return as0(Y,x);return{}}function as0($,x){let Y=Object.create(null);if($.forEach((X,Q)=>{if(!(x.all||Q.endsWith("[]")))Y[Q]=X;else ss0(Y,Q,X)}),x.dot)Object.entries(Y).forEach(([X,Q])=>{if(X.includes("."))os0(Y,X,Q),delete Y[X]});return Y}var ss0=($,x,Y)=>{if($[x]!==void 0)if(Array.isArray($[x]))$[x].push(Y);else $[x]=[$[x],Y];else if(!x.endsWith("[]"))$[x]=Y;else $[x]=[Y]},os0=($,x,Y)=>{if(/(?:^|\.)__proto__\./.test(x))return;let X=$,Q=x.split(".");Q.forEach((z,Z)=>{if(Z===Q.length-1)X[z]=Y;else{if(!X[z]||typeof X[z]!=="object"||Array.isArray(X[z])||X[z]instanceof File)X[z]=Object.create(null);X=X[z]}})};var QT1=($)=>xK($,TW),Yv=class{raw;#$;#x;routeIndex=0;path;bodyCache={};constructor($,x="/",Y=[[]]){this.raw=$,this.path=x,this.#x=Y,this.#$={}}param($){return $?this.#Y($):this.#z()}#Y($){let x=this.#x[0][this.routeIndex][1][$],Y=this.#X(x);return Y&&/\%/.test(Y)?QT1(Y):Y}#z(){let $={},x=Object.keys(this.#x[0][this.routeIndex][1]);for(let Y of x){let X=this.#X(this.#x[0][this.routeIndex][1][Y]);if(X!==void 0)$[Y]=/\%/.test(X)?QT1(X):X}return $}#X($){return this.#x[1]?this.#x[1][$]:$}query($){return jA1(this.url,$)}queries($){return NA1(this.url,$)}header($){if($)return this.raw.headers.get($)??void 0;let x={};return this.raw.headers.forEach((Y,X)=>{x[X]=Y}),x}async parseBody($){return YT1(this,$)}#Q=($)=>{let{bodyCache:x,raw:Y}=this,X=x[$];if(X)return X;let Q=Object.keys(x)[0];if(Q)return x[Q].then((z)=>{if(Q==="json")z=JSON.stringify(z);return new Response(z)[$]()});return x[$]=Y[$]()};json(){return this.#Q("text").then(($)=>JSON.parse($))}text(){return this.#Q("text")}arrayBuffer(){return this.#Q("arrayBuffer")}bytes(){return this.#Q("arrayBuffer").then(($)=>new Uint8Array($))}blob(){return this.#Q("blob")}formData(){return this.#Q("formData")}addValidatedData($,x){this.#$[$]=x}valid($){return this.#$[$]}get url(){return this.raw.url}get method(){return this.raw.method}get[xT1](){return this.#x}get matchedRoutes(){return this.#x[0].map(([[,$]])=>$)}get routePath(){return this.#x[0].map(([[,$]])=>$)[this.routeIndex].path}};var XT1={Stringify:1,BeforeStream:2,Stream:3},rs0=($,x)=>{let Y=new String($);return Y.isEscaped=!0,Y.callbacks=x,Y};var xC=async($,x,Y,X,Q)=>{if(typeof $==="object"&&!($ instanceof String)){if(!($ instanceof Promise))$=$.toString();if($ instanceof Promise)$=await $}let z=$.callbacks;if(!z?.length)return Promise.resolve($);if(Q)Q[0]+=$;else Q=[$];let Z=Promise.all(z.map((K)=>K({phase:x,buffer:Q,context:X}))).then((K)=>Promise.all(K.filter(Boolean).map((V)=>xC(V,x,!1,X,Q))).then(()=>Q[0]));if(Y)return rs0(await Z,z);else return Z};var ts0="text/plain; charset=UTF-8",YC=($,x)=>{return{"Content-Type":$,...x}},CW=($,x)=>new Response($,x),QC=class{#$;#x;env={};#Y;finalized=!1;error;#z;#X;#Q;#w;#V;#W;#K;#H;#U;constructor($,x){if(this.#$=$,x)this.#X=x.executionCtx,this.env=x.env,this.#W=x.notFoundHandler,this.#U=x.path,this.#H=x.matchResult}get req(){return this.#x??=new Yv(this.#$,this.#U,this.#H),this.#x}get event(){if(this.#X&&"respondWith"in this.#X)return this.#X;else throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#X)return this.#X;else throw Error("This context has no ExecutionContext")}get res(){return this.#Q||=CW(null,{headers:this.#K??=new Headers})}set res($){if(this.#Q&&$){$=CW($.body,$);for(let[x,Y]of this.#Q.headers.entries()){if(x==="content-type")continue;if(x==="set-cookie"){let X=this.#Q.headers.getSetCookie();$.headers.delete("set-cookie");for(let Q of X)$.headers.append("set-cookie",Q)}else $.headers.set(x,Y)}}this.#Q=$,this.finalized=!0}render=(...$)=>{return this.#V??=(x)=>this.html(x),this.#V(...$)};setLayout=($)=>this.#w=$;getLayout=()=>this.#w;setRenderer=($)=>{this.#V=$};header=($,x,Y)=>{if(this.finalized)this.#Q=CW(this.#Q.body,this.#Q);let X=this.#Q?this.#Q.headers:this.#K??=new Headers;if(x===void 0)X.delete($);else if(Y?.append)X.append($,x);else X.set($,x)};status=($)=>{this.#z=$};set=($,x)=>{this.#Y??=new Map,this.#Y.set($,x)};get=($)=>{return this.#Y?this.#Y.get($):void 0};get var(){if(!this.#Y)return{};return Object.fromEntries(this.#Y)}#Z($,x,Y){let X=this.#Q?new Headers(this.#Q.headers):this.#K??new Headers;if(typeof x==="object"&&"headers"in x){let z=x.headers instanceof Headers?x.headers:new Headers(x.headers);for(let[Z,K]of z)if(Z.toLowerCase()==="set-cookie")X.append(Z,K);else X.set(Z,K)}if(Y)for(let[z,Z]of Object.entries(Y))if(typeof Z==="string")X.set(z,Z);else{X.delete(z);for(let K of Z)X.append(z,K)}let Q=typeof x==="number"?x:x?.status??this.#z;return CW($,{status:Q,headers:X})}newResponse=(...$)=>this.#Z(...$);body=($,x,Y)=>this.#Z($,x,Y);text=($,x,Y)=>{return!this.#K&&!this.#z&&!x&&!Y&&!this.finalized?new Response($):this.#Z($,x,YC(ts0,Y))};json=($,x,Y)=>{return this.#Z(JSON.stringify($),x,YC("application/json",Y))};html=($,x,Y)=>{let X=(Q)=>this.#Z(Q,x,YC("text/html; charset=UTF-8",Y));return typeof $==="object"?xC($,XT1.Stringify,!1,{}).then(X):X($)};redirect=($,x)=>{let Y=String($);return this.header("Location",!/[^\x00-\xFF]/.test(Y)?Y:encodeURI(Y)),this.newResponse(null,x??302)};notFound=()=>{return this.#W??=()=>CW(),this.#W(this)}};var a0="ALL",zT1="all",ZT1=["get","post","put","delete","options","patch"],Qv="Can not add a route since the matcher is already built.",Xv=class extends Error{};var KT1="__COMPOSED_HANDLER";var es0=($)=>{return $.text("404 Not Found",404)},VT1=($,x)=>{if("getResponse"in $){let Y=$.getResponse();return x.newResponse(Y.body,Y)}return console.error($),x.text("Internal Server Error",500)},WT1=class ${get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#$="/";routes=[];constructor(x={}){[...ZT1,zT1].forEach((z)=>{this[z]=(Z,...K)=>{if(typeof Z==="string")this.#$=Z;else this.#z(z,this.#$,Z);return K.forEach((V)=>{this.#z(z,this.#$,V)}),this}}),this.on=(z,Z,...K)=>{for(let V of[Z].flat()){this.#$=V;for(let W of[z].flat())K.map((w)=>{this.#z(W.toUpperCase(),this.#$,w)})}return this},this.use=(z,...Z)=>{if(typeof z==="string")this.#$=z;else this.#$="*",Z.unshift(z);return Z.forEach((K)=>{this.#z(a0,this.#$,K)}),this};let{strict:X,...Q}=x;Object.assign(this,Q),this.getPath=X??!0?x.getPath??LE:FA1}#x(){let x=new $({router:this.router,getPath:this.getPath});return x.errorHandler=this.errorHandler,x.#Y=this.#Y,x.routes=this.routes,x}#Y=es0;errorHandler=VT1;route(x,Y){let X=this.basePath(x);return Y.routes.map((Q)=>{let z;if(Y.errorHandler===VT1)z=Q.handler;else z=async(Z,K)=>(await $C([],Y.errorHandler)(Z,()=>Q.handler(Z,K))).res,z[KT1]=Q.handler;X.#z(Q.method,Q.path,z,Q.basePath)}),this}basePath(x){let Y=this.#x();return Y._basePath=vY(this._basePath,x),Y}onError=(x)=>{return this.errorHandler=x,this};notFound=(x)=>{return this.#Y=x,this};mount(x,Y,X){let Q,z;if(X)if(typeof X==="function")z=X;else if(z=X.optionHandler,X.replaceRequest===!1)Q=(V)=>V;else Q=X.replaceRequest;let Z=z?(V)=>{let W=z(V);return Array.isArray(W)?W:[W]}:(V)=>{let W=void 0;try{W=V.executionCtx}catch{}return[V.env,W]};Q||=(()=>{let V=vY(this._basePath,x),W=V==="/"?0:V.length;return(w)=>{let H=new URL(w.url);return H.pathname=this.getPath(w).slice(W)||"/",new Request(H,w)}})();let K=async(V,W)=>{let w=await Y(Q(V.req.raw),...Z(V));if(w)return w;await W()};return this.#z(a0,vY(x,"*"),K),this}#z(x,Y,X,Q){x=x.toUpperCase(),Y=vY(this._basePath,Y);let z={basePath:Q!==void 0?vY(this._basePath,Q):this._basePath,path:Y,method:x,handler:X};this.router.add(x,Y,[X,z]),this.routes.push(z)}#X(x,Y){if(x instanceof Error)return this.errorHandler(x,Y);throw x}#Q(x,Y,X,Q){if(Q==="HEAD")return(async()=>new Response(null,await this.#Q(x,Y,X,"GET")))();let z=this.getPath(x,{env:X}),Z=this.router.match(Q,z),K=new QC(x,{path:z,matchResult:Z,env:X,executionCtx:Y,notFoundHandler:this.#Y});if(Z[0].length===1){let W;try{W=Z[0][0][0][0](K,async()=>{K.res=await this.#Y(K)})}catch(w){return this.#X(w,K)}return W instanceof Promise?W.then((w)=>w||(K.finalized?K.res:this.#Y(K))).catch((w)=>this.#X(w,K)):W??this.#Y(K)}let V=$C(Z[0],this.errorHandler,this.#Y);return(async()=>{try{let W=await V(K);if(!W.finalized)throw Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return W.res}catch(W){return this.#X(W,K)}})()}fetch=(x,...Y)=>{return this.#Q(x,Y[1],Y[0],x.method)};request=(x,Y,X,Q)=>{if(x instanceof Request)return this.fetch(Y?new Request(x,Y):x,X,Q);return x=x.toString(),this.fetch(new Request(/^https?:\/\//.test(x)?x:`http://localhost${vY("/",x)}`,Y),X,Q)};fire=()=>{addEventListener("fetch",(x)=>{x.respondWith(this.#Q(x.request,x,void 0,x.request.method))})}};var yW=[];function zv($,x){let Y=this.buildAllMatchers(),X=(Q,z)=>{let Z=Y[Q]||Y[a0],K=Z[2][z];if(K)return K;let V=z.match(Z[0]);if(!V)return[[],yW];let W=V.indexOf("",1);return[Z[1][W],V]};return this.match=X,X($,x)}var Zv="[^/]+",mW=".*",hW="(?:|/.*)",ZX=Symbol(),$o0=new Set(".\\+*[^]$()");function xo0($,x){if($.length===1)return x.length===1?$<x?-1:1:-1;if(x.length===1)return 1;if($===mW||$===hW)return 1;else if(x===mW||x===hW)return-1;if($===Zv)return 1;else if(x===Zv)return-1;return $.length===x.length?$<x?-1:1:x.length-$.length}var wT1=class ${#$;#x;#Y=Object.create(null);insert(x,Y,X,Q,z){if(x.length===0){if(this.#$!==void 0)throw ZX;if(z)return;this.#$=Y;return}let[Z,...K]=x,V=Z==="*"?K.length===0?["","",mW]:["","",Zv]:Z==="/*"?["","",hW]:Z.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),W;if(V){let w=V[1],H=V[2]||Zv;if(w&&V[2]){if(H===".*")throw ZX;if(H=H.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(H))throw ZX}if(W=this.#Y[H],!W){if(Object.keys(this.#Y).some((U)=>U!==mW&&U!==hW))throw ZX;if(z)return;if(W=this.#Y[H]=new $,w!=="")W.#x=Q.varIndex++}if(!z&&w!=="")X.push([w,W.#x])}else if(W=this.#Y[Z],!W){if(Object.keys(this.#Y).some((w)=>w.length>1&&w!==mW&&w!==hW))throw ZX;if(z)return;W=this.#Y[Z]=new $}W.insert(K,Y,X,Q,z)}buildRegExpStr(){let Y=Object.keys(this.#Y).sort(xo0).map((X)=>{let Q=this.#Y[X];return(typeof Q.#x==="number"?`(${X})@${Q.#x}`:$o0.has(X)?`\\${X}`:X)+Q.buildRegExpStr()});if(typeof this.#$==="number")Y.unshift(`#${this.#$}`);if(Y.length===0)return"";if(Y.length===1)return Y[0];return"(?:"+Y.join("|")+")"}};var HT1=class{#$={varIndex:0};#x=new wT1;insert($,x,Y){let X=[],Q=[];for(let Z=0;;){let K=!1;if($=$.replace(/\{[^}]+\}/g,(V)=>{let W=`@\\${Z}`;return Q[Z]=[W,V],Z++,K=!0,W}),!K)break}let z=$.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let Z=Q.length-1;Z>=0;Z--){let[K]=Q[Z];for(let V=z.length-1;V>=0;V--)if(z[V].indexOf(K)!==-1){z[V]=z[V].replace(K,Q[Z][1]);break}}return this.#x.insert(z,x,X,this.#$,Y),X}buildRegExp(){let $=this.#x.buildRegExpStr();if($==="")return[/^$/,[],[]];let x=0,Y=[],X=[];return $=$.replace(/#(\d+)|@(\d+)|\.\*\$/g,(Q,z,Z)=>{if(z!==void 0)return Y[++x]=Number(z),"$()";if(Z!==void 0)return X[Number(Z)]=++x,"";return""}),[new RegExp(`^${$}`),Y,X]}};var Yo0=[/^$/,[],Object.create(null)],UT1=Object.create(null);function GT1($){return UT1[$]??=new RegExp($==="*"?"":`^${$.replace(/\/\*$|([.\\+*[^\]$()])/g,(x,Y)=>Y?`\\${Y}`:"(?:|/.*)")}$`)}function Qo0(){UT1=Object.create(null)}function Xo0($){let x=new HT1,Y=[];if($.length===0)return Yo0;let X=$.map((W)=>[!/\*|\/:/.test(W[0]),...W]).sort(([W,w],[H,U])=>W?1:H?-1:w.length-U.length),Q=Object.create(null);for(let W=0,w=-1,H=X.length;W<H;W++){let[U,J,q]=X[W];if(U)Q[J]=[q.map(([D])=>[D,Object.create(null)]),yW];else w++;let B;try{B=x.insert(J,w,U)}catch(D){throw D===ZX?new Xv(J):D}if(U)continue;Y[w]=q.map(([D,v])=>{let N=Object.create(null);v-=1;for(;v>=0;v--){let[L,u]=B[v];N[L]=u}return[D,N]})}let[z,Z,K]=x.buildRegExp();for(let W=0,w=Y.length;W<w;W++)for(let H=0,U=Y[W].length;H<U;H++){let J=Y[W][H]?.[1];if(!J)continue;let q=Object.keys(J);for(let B=0,D=q.length;B<D;B++)J[q[B]]=K[J[q[B]]]}let V=[];for(let W in Z)V[W]=Y[Z[W]];return[z,V,Q]}function QK($,x){if(!$)return;for(let Y of Object.keys($).sort((X,Q)=>Q.length-X.length))if(GT1(Y).test(x))return[...$[Y]];return}var Kv=class{name="RegExpRouter";#$;#x;constructor(){this.#$={[a0]:Object.create(null)},this.#x={[a0]:Object.create(null)}}add($,x,Y){let X=this.#$,Q=this.#x;if(!X||!Q)throw Error(Qv);if(!X[$])[X,Q].forEach((K)=>{K[$]=Object.create(null),Object.keys(K[a0]).forEach((V)=>{K[$][V]=[...K[a0][V]]})});if(x==="/*")x="*";let z=(x.match(/\/:/g)||[]).length;if(/\*$/.test(x)){let K=GT1(x);if($===a0)Object.keys(X).forEach((V)=>{X[V][x]||=QK(X[V],x)||QK(X[a0],x)||[]});else X[$][x]||=QK(X[$],x)||QK(X[a0],x)||[];Object.keys(X).forEach((V)=>{if($===a0||$===V)Object.keys(X[V]).forEach((W)=>{K.test(W)&&X[V][W].push([Y,z])})}),Object.keys(Q).forEach((V)=>{if($===a0||$===V)Object.keys(Q[V]).forEach((W)=>K.test(W)&&Q[V][W].push([Y,z]))});return}let Z=nB(x)||[x];for(let K=0,V=Z.length;K<V;K++){let W=Z[K];Object.keys(Q).forEach((w)=>{if($===a0||$===w)Q[w][W]||=[...QK(X[w],W)||QK(X[a0],W)||[]],Q[w][W].push([Y,z-V+K+1])})}}match=zv;buildAllMatchers(){let $=Object.create(null);return Object.keys(this.#x).concat(Object.keys(this.#$)).forEach((x)=>{$[x]||=this.#Y(x)}),this.#$=this.#x=void 0,Qo0(),$}#Y($){let x=[],Y=$===a0;if([this.#$,this.#x].forEach((X)=>{let Q=X[$]?Object.keys(X[$]).map((z)=>[z,X[$][z]]):[];if(Q.length!==0)Y||=!0,x.push(...Q);else if($!==a0)x.push(...Object.keys(X[a0]).map((z)=>[z,X[a0][z]]))}),!Y)return null;else return Xo0(x)}};var zo0=class{name="PreparedRegExpRouter";#$;#x;constructor($,x){this.#$=$,this.#x=x}#Y($,x){let Y=this.#$[$];Y[1].forEach((X)=>X&&X.push(x)),Object.values(Y[2]).forEach((X)=>X[0].push(x))}#z($,x,Y,X,Q){let z=this.#$[$];if(!Q)z[2][x][0].push([Y,{}]);else X.forEach((Z)=>{if(typeof Z==="number")z[1][Z].push([Y,Q]);else z[2][Z||x][0].push([Y,Q])})}add($,x,Y){if(!this.#$[$]){let Q=this.#$[a0],z={};for(let Z in Q[2])z[Z]=[Q[2][Z][0].slice(),yW];this.#$[$]=[Q[0],Q[1].map((Z)=>Array.isArray(Z)?Z.slice():0),z]}if(x==="/*"||x==="*"){let Q=[Y,{}];if($===a0)for(let z in this.#$)this.#Y(z,Q);else this.#Y($,Q);return}let X=this.#x[x];if(!X)throw Error(`Path ${x} is not registered`);for(let[Q,z]of X)if($===a0)for(let Z in this.#$)this.#z(Z,x,Y,Q,z);else this.#z($,x,Y,Q,z)}buildAllMatchers(){return this.#$}match=zv};var XC=class{name="SmartRouter";#$=[];#x=[];constructor($){this.#$=$.routers}add($,x,Y){if(!this.#x)throw Error(Qv);this.#x.push([$,x,Y])}match($,x){if(!this.#x)throw Error("Fatal error");let Y=this.#$,X=this.#x,Q=Y.length,z=0,Z;for(;z<Q;z++){let K=Y[z];try{for(let V=0,W=X.length;V<W;V++)K.add(...X[V]);Z=K.match($,x)}catch(V){if(V instanceof Xv)continue;throw V}this.match=K.match.bind(K),this.#$=[K],this.#x=void 0;break}if(z===Q)throw Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,Z}get activeRouter(){if(this.#x||this.#$.length!==1)throw Error("No active router has been determined yet.");return this.#$[0]}};var gW=Object.create(null),Zo0=($)=>{for(let x in $)return!0;return!1},JT1=class ${#$;#x;#Y;#z=0;#X=gW;constructor(x,Y,X){if(this.#x=X||Object.create(null),this.#$=[],x&&Y){let Q=Object.create(null);Q[x]={handler:Y,possibleKeys:[],score:0},this.#$=[Q]}this.#Y=[]}insert(x,Y,X){this.#z=++this.#z;let Q=this,z=BA1(Y),Z=[];for(let K=0,V=z.length;K<V;K++){let W=z[K],w=z[K+1],H=vA1(W,w),U=Array.isArray(H)?H[0]:W;if(U in Q.#x){if(Q=Q.#x[U],H)Z.push(H[1]);continue}if(Q.#x[U]=new $,H)Q.#Y.push(H),Z.push(H[1]);Q=Q.#x[U]}return Q.#$.push({[x]:{handler:X,possibleKeys:Z.filter((K,V,W)=>W.indexOf(K)===V),score:this.#z}}),Q}#Q(x,Y,X,Q,z){for(let Z=0,K=Y.#$.length;Z<K;Z++){let V=Y.#$[Z],W=V[X]||V[a0],w={};if(W!==void 0){if(W.params=Object.create(null),x.push(W),Q!==gW||z&&z!==gW)for(let H=0,U=W.possibleKeys.length;H<U;H++){let J=W.possibleKeys[H],q=w[W.score];W.params[J]=z?.[J]&&!q?z[J]:Q[J]??z?.[J],w[W.score]=!0}}}}search(x,Y){let X=[];this.#X=gW;let z=[this],Z=FE(Y),K=[],V=Z.length,W=null;for(let w=0;w<V;w++){let H=Z[w],U=w===V-1,J=[];for(let B=0,D=z.length;B<D;B++){let v=z[B],N=v.#x[H];if(N)if(N.#X=v.#X,U){if(N.#x["*"])this.#Q(X,N.#x["*"],x,v.#X);this.#Q(X,N,x,v.#X)}else J.push(N);for(let L=0,u=v.#Y.length;L<u;L++){let y=v.#Y[L],n=v.#X===gW?{}:{...v.#X};if(y==="*"){let K1=v.#x["*"];if(K1)this.#Q(X,K1,x,v.#X),K1.#X=n,J.push(K1);continue}let[U1,w1,h]=y;if(!H&&!(h instanceof RegExp))continue;let a=v.#x[U1];if(h instanceof RegExp){if(W===null){W=Array(V);let M1=Y[0]==="/"?1:0;for(let O1=0;O1<V;O1++)W[O1]=M1,M1+=Z[O1].length+1}let K1=Y.substring(W[w]),F1=h.exec(K1);if(F1){if(n[w1]=F1[0],this.#Q(X,a,x,v.#X,n),Zo0(a.#x)){a.#X=n;let M1=F1[0].match(/\//)?.length??0;(K[M1]||=[]).push(a)}continue}}if(h===!0||h.test(H))if(n[w1]=H,U){if(this.#Q(X,a,x,n,v.#X),a.#x["*"])this.#Q(X,a.#x["*"],x,n,v.#X)}else a.#X=n,J.push(a)}}let q=K.shift();z=q?J.concat(q):J}if(X.length>1)X.sort((w,H)=>{return w.score-H.score});return[X.map(({handler:w,params:H})=>[w,H])]}};var zC=class{name="TrieRouter";#$;constructor(){this.#$=new JT1}add($,x,Y){let X=nB(x);if(X){for(let Q=0,z=X.length;Q<z;Q++)this.#$.insert($,X[Q],Y);return}this.#$.insert($,x,Y)}match($,x){return this.#$.search($,x)}};var pW=class extends WT1{constructor($={}){super($);this.router=$.router??new XC({routers:[new Kv,new zC]})}};var Ko0=class{initApp;#$;constructor($){this.initApp=$?.initApp,this.#$=$?.defaultAppOptions}createApp=($)=>{let x=new pW($&&this.#$?{...this.#$,...$}:$??this.#$);if(this.initApp)this.initApp(x);return x};createMiddleware=($)=>$;createHandlers=(...$)=>{return $.filter((x)=>x!==void 0)}},qT1=($)=>new Ko0($);var S6=qT1();var DT1=($)=>{let x=Buffer.byteLength($.content,"utf-8");if($.meta)for(let[Y,X]of Object.entries($.meta))x+=Buffer.byteLength(Y,"utf-8")+Buffer.byteLength(X,"utf-8");return x},Vo0=1048576,Wo0=200,wo0=4194304,Ho0=()=>{};class ZC{clients=new Map;subscribers=new Set;logger;onError;maxBufferedBytes;now;replayBufferSize;replayBufferMaxBytes;replayBuffer=[];persistentReplay;exclusiveCursor=new Map;replayBufferBytes=0;eventsBroadcast=0;droppedSlowClients=0;lastBroadcastAt=null;latestOffset=0;constructor($={}){this.logger=$.logger,this.onError=$.onError??Ho0,this.maxBufferedBytes=$.maxBufferedBytes??Vo0,this.now=$.now??(()=>Date.now()),this.replayBufferSize=Math.max(0,$.replayBufferSize??Wo0),this.replayBufferMaxBytes=Math.max(0,$.replayBufferMaxBytes??wo0),this.persistentReplay=$.persistentReplay??null}getMetrics(){return{clients:this.clients.size,subscribers:this.subscribers.size,eventsBroadcast:this.eventsBroadcast,droppedSlowClients:this.droppedSlowClients,lastBroadcastAt:this.lastBroadcastAt?new Date(this.lastBroadcastAt).toISOString():null,latestOffset:this.latestOffset,oldestReplayableOffset:this.replayBuffer[0]?.offset??null}}replaySince($,x){let Y=this.replayBuffer[0]?.offset,X=this.persistentReplay&&(Y===void 0||$<Y-1),Q=this.replayBuffer.filter((V)=>V.offset>$&&this.matchesClient(V,x));if(!X)return Q;let z=this.persistentReplay?this.persistentReplay.loadSince($).filter((V)=>this.matchesClient(V,x)):[],Z=Y??Number.POSITIVE_INFINITY;return[...z.filter((V)=>V.offset<Z),...Q]}matchesClient($,x){let Y=$.meta?.target;if(Y&&Y!==x.subscriberId)return!1;let X=$.meta?.channelId;if(X&&X!==x.channel)return!1;let Q=$.meta?.connector;if(!Q)return!0;return x.connectors.includes(Q)}pickRecipients($){let x=new Map,Y=[];for(let[X,Q]of this.clients){if(!this.matchesClient($,Q))continue;if(Q.delivery==="exclusive"){let z=x.get(Q.channel)??[];z.push(X),x.set(Q.channel,z);continue}Y.push(X)}for(let[X,Q]of x){if(Q.length===0)continue;let z=this.exclusiveCursor.get(X)??0,Z=Q[z%Q.length];if(Z)Y.push(Z);this.exclusiveCursor.set(X,z+1)}return Y}addClient($,x){this.clients.set($,x)}removeClient($){this.clients.delete($)}getClientCount(){return this.clients.size}listChannels(){return[...this.clients.values()].map(($)=>({...$}))}subscribe($){return this.subscribers.add($),()=>{this.subscribers.delete($)}}broadcast($,x){this.latestOffset+=1;let Y={content:$,meta:x,offset:this.latestOffset},X=JSON.stringify(Y),Q=x?.connector;if(this.eventsBroadcast+=1,this.lastBroadcastAt=this.now(),this.replayBufferSize>0){let Z=DT1(Y);this.replayBuffer.push(Y),this.replayBufferBytes+=Z;while((this.replayBuffer.length>this.replayBufferSize||this.replayBufferBytes>this.replayBufferMaxBytes)&&this.replayBuffer.length>0){let K=this.replayBuffer.shift();if(K)this.replayBufferBytes-=DT1(K)}}let z=this.pickRecipients(Y);for(let Z of z){let K=Z.getBufferedAmount();if(K>this.maxBufferedBytes){let V=this.clients.get(Z);this.logger?.warn("dropping slow WS client (backpressure)",{channel:V?.channel,buffered:K,max:this.maxBufferedBytes});try{Z.close(1009,"backpressure")}catch{}this.clients.delete(Z),this.droppedSlowClients+=1;continue}Z.send(X)}for(let Z of this.subscribers)try{Z(Y)}catch(K){let V=K instanceof Error?K:Error(String(K));this.logger?.error("broadcast subscriber threw",{error:V.message}),this.onError(V,{component:"broadcaster.subscriber",offset:Y.offset,connector:Y.meta?.connector??null,channel:Y.meta?.channel??null})}return Y}seedLatestOffset($){if($>this.latestOffset)this.latestOffset=$}}var JD6=c.object({type:c.string(),content:c.string(),channel_id:c.string().nullable(),connector_id:c.string().nullable(),meta:c.record(c.string(),c.string()).nullable()});class KC{}import{Database as Uo0}from"bun:sqlite";import{existsSync as Go0,mkdirSync as Jo0}from"fs";import{dirname as qo0}from"path";var Do0=/^[a-z_][a-z0-9_]*$/,Bo0=500,vo0=new Set(["seq","ts","type","event"]),BT1=[["CREATE TABLE IF NOT EXISTS logs (seq INTEGER PRIMARY KEY, ts INTEGER NOT NULL, type TEXT, event TEXT NOT NULL)","CREATE INDEX IF NOT EXISTS idx_logs_ts ON logs (ts)","CREATE INDEX IF NOT EXISTS idx_logs_type ON logs (type)"],["DROP TABLE IF EXISTS leuco_log","CREATE TABLE IF NOT EXISTS logs (seq INTEGER PRIMARY KEY, ts INTEGER NOT NULL, type TEXT, event TEXT NOT NULL)","CREATE INDEX IF NOT EXISTS idx_logs_ts ON logs (ts)","CREATE INDEX IF NOT EXISTS idx_logs_type ON logs (type)"]];class KX{db;maxRows;maxAgeMs;maxBytes;targetBytes;now;indexes;extractIndexes;insertStmt;insertWithSeqStmt;maxSeqStmt;countStmt;trimRowsStmt;trimAgeStmt;trimOldestStmt;insertsSinceByteCheck=0;constructor($){if($.path!==":memory:"){let z=qo0($.path);if(!Go0(z))Jo0(z,{recursive:!0})}if(this.db=new Uo0($.path),this.db.run("PRAGMA journal_mode = WAL"),this.migrate(),this.maxRows=$.maxRows??null,this.maxAgeMs=$.maxAgeMs??null,this.maxBytes=$.maxBytes??null,this.targetBytes=$.targetBytes??($.maxBytes!==void 0?Math.floor($.maxBytes/4):null),this.now=$.now??(()=>Date.now()),this.indexes=$.indexes??[],this.indexes.length>0)Fo0(this.indexes),this.extractIndexes=$.extractIndexes??null,this.syncIndexColumns();else this.extractIndexes=null;let x=["ts","type","event",...this.indexes],Y=x.map(()=>"?").join(", ");this.insertStmt=this.db.prepare(`INSERT INTO logs (${x.join(", ")}) VALUES (${Y})`);let X=["seq",...x],Q=X.map(()=>"?").join(", ");this.insertWithSeqStmt=this.db.prepare(`INSERT INTO logs (${X.join(", ")}) VALUES (${Q})`),this.maxSeqStmt=this.db.prepare("SELECT COALESCE(MAX(seq), 0) AS max FROM logs"),this.countStmt=this.db.prepare("SELECT COUNT(*) AS n FROM logs"),this.trimRowsStmt=this.db.prepare("DELETE FROM logs WHERE seq <= (SELECT seq FROM logs ORDER BY seq DESC LIMIT 1 OFFSET ?)"),this.trimAgeStmt=this.db.prepare("DELETE FROM logs WHERE ts < ?"),this.trimOldestStmt=this.db.prepare("DELETE FROM logs WHERE seq IN (SELECT seq FROM logs ORDER BY seq ASC LIMIT ?)")}insert($){try{let x=this.buildInsertParams($.ts,$.event),Y=this.insertStmt.run(...x),X=Number(Y.lastInsertRowid);return this.trim(),{seq:X,ts:$.ts,event:$.event}}catch(x){return x instanceof Error?x:Error(String(x))}}insertMany($){if($.length===0)return[];try{let x=[];return this.db.transaction((X)=>{for(let Q of X){let z=this.buildInsertParams(Q.ts,Q.event),Z=this.insertStmt.run(...z);x.push({seq:Number(Z.lastInsertRowid),ts:Q.ts,event:Q.event})}})($),this.trim(),x}catch(x){return x instanceof Error?x:Error(String(x))}}write($){try{let x=[$.seq,...this.buildInsertParams($.ts,$.event)];this.insertWithSeqStmt.run(...x),this.trim()}catch(x){return x instanceof Error?x:Error(String(x))}}getMaxSeq(){let $=this.maxSeqStmt.get();return $?$.max:0}query($={}){let x=["seq > ?"],Y=[$.sinceSeq??0];if(typeof $.type==="string")x.push("type = ?"),Y.push($.type);if($.where)this.appendWhereConditions($.where,x,Y);let X=$.limit??1000;Y.push(X);let Q=$.order==="desc"?"DESC":"ASC",z=`SELECT seq, ts, type, event FROM logs WHERE ${x.join(" AND ")} ORDER BY seq ${Q} LIMIT ?`,K=this.db.prepare(z).all(...Y);if(Q==="DESC")K.reverse();return K.map(jo0)}getSchemaVersion(){return this.db.prepare("PRAGMA user_version").get()?.user_version??0}close(){this.db.close()}buildInsertParams($,x){let Y=Lo0(x),X=JSON.stringify(x);if(this.indexes.length===0)return[$,Y,X];let Q=this.extractIndexes?this.extractIndexes(x):null,z=this.indexes.map((Z)=>Q?.[Z]??null);return[$,Y,X,...z]}appendWhereConditions($,x,Y){let X=$;for(let Q of this.indexes){let z=X[Q];if(z===void 0)continue;if(z===null)x.push(`${Q} IS NULL`);else x.push(`${Q} = ?`),Y.push(z)}}trim(){if(this.maxRows!==null){let $=this.countStmt.get();if($&&$.n>this.maxRows)this.trimRowsStmt.run(this.maxRows)}if(this.maxAgeMs!==null)this.trimAgeStmt.run(this.now()-this.maxAgeMs);this.maybeTrimBytes()}maybeTrimBytes(){if(this.maxBytes===null||this.targetBytes===null)return;if(this.insertsSinceByteCheck+=1,this.insertsSinceByteCheck<Bo0)return;this.insertsSinceByteCheck=0;let $=this.byteSize();if($<=this.maxBytes)return;let x=this.countStmt.get()?.n??0;if(x===0)return;let Y=$-this.targetBytes,X=$/x,Q=Math.min(x,Math.ceil(Y/X));this.trimOldestStmt.run(Q),this.db.run("VACUUM")}byteSize(){let $=this.db.prepare("PRAGMA page_count").get()?.n??0,x=this.db.prepare("PRAGMA page_size").get()?.n??0;return $*x}clear(){this.db.run("DELETE FROM logs"),this.db.run("VACUUM"),this.insertsSinceByteCheck=0}syncIndexColumns(){let $=new Set(this.db.prepare("PRAGMA table_info(logs)").all().map((x)=>x.name));for(let x of this.indexes){if(!$.has(x))this.db.run(`ALTER TABLE logs ADD COLUMN ${x} TEXT`);this.db.run(`CREATE INDEX IF NOT EXISTS idx_logs_${x} ON logs (${x})`)}}migrate(){let x=this.db.prepare("PRAGMA user_version").get()?.user_version??0;if(x>=BT1.length)return;let Y=BT1.slice(x),X=x;for(let Q of Y)X+=1,this.db.transaction(()=>{for(let Z of Q)this.db.run(Z);this.db.run(`PRAGMA user_version = ${X}`)})()}}function Fo0($){for(let x of $){if(!Do0.test(x))throw Error(`invalid index column name: ${x}`);if(vo0.has(x))throw Error(`reserved index column name: ${x}`)}}function Lo0($){if(typeof $!=="object"||$===null)return null;if(!("type"in $))return null;let x=$.type;return typeof x==="string"?x:null}function jo0($){return{seq:$.seq,ts:$.ts,event:JSON.parse($.event)}}var vT1=2000;class VC extends KC{sink;now;logger;constructor($){super();this.now=$.now??(()=>Date.now()),this.logger=$.logger,this.sink=new KX({path:$.path,indexes:["channel_id","connector_id"],extractIndexes:(x)=>({channel_id:x.channel_id,connector_id:x.connector_id}),now:this.now,...$.maxRows!==void 0?{maxRows:$.maxRows}:{},...$.maxAgeMs!==void 0?{maxAgeMs:$.maxAgeMs}:{},...$.maxBytes!==void 0?{maxBytes:$.maxBytes}:{},...$.targetBytes!==void 0?{targetBytes:$.targetBytes}:{}})}record($){let x={type:$.meta?.event_type??"unknown",content:No0($.content),channel_id:$.channelId,connector_id:$.connectorId,meta:$.meta},Y=this.sink.write({seq:$.offset,ts:this.now(),event:x});if(Y instanceof Error)this.logger?.error("event log write failed",{offset:$.offset,error:Y.message})}loadSince($){let x=this.sink.query({sinceSeq:$}),Y=[];for(let X of x)Y.push({content:X.event.content,meta:X.event.meta??void 0,offset:X.seq});return Y}loadForChannel($){let x={channel_id:$.channelId};if($.connectorId!==void 0)x.connector_id=$.connectorId;let Y=this.sink.query({where:x,...$.sinceSeq!==void 0?{sinceSeq:$.sinceSeq}:{},...$.limit!==void 0?{limit:$.limit}:{}}),X=[];for(let Q of Y)X.push({content:Q.event.content,meta:Q.event.meta??void 0,offset:Q.seq});return X}findMaxOffset(){return this.sink.getMaxSeq()}clear(){this.sink.clear()}close(){this.sink.close()}}function No0($){if($.length<=vT1)return $;return`${$.slice(0,vT1)}...`}var Po0=()=>{},Io0=30000,Mo0=60000,_o0=30000,Oo0=($)=>new Promise((x)=>{setTimeout(x,$)});class LY{channels;notify;logger;onError;running=new Map;failureCounts=new Map;stats=new Map;healthCheckIntervalMs;maxBackoffMs;startTimeoutMs;sleep;now;healthCheckTimer=null;healthCheckInFlight=!1;pendingRetry=new Map;constructor($){this.channels=$.channels,this.notify=$.notify,this.logger=$.logger,this.onError=$.onError??Po0,this.healthCheckIntervalMs=$.healthCheckIntervalMs??Io0,this.maxBackoffMs=$.maxBackoffMs??Mo0,this.startTimeoutMs=$.startTimeoutMs??_o0,this.sleep=$.sleep??Oo0,this.now=$.now??(()=>Date.now())}static keyOf($,x){return`${$}/${x}`}isRunning($,x){return this.running.has(LY.keyOf($,x))}list(){return[...this.running.entries()].map(([$,x])=>{let Y=this.stats.get($);return{channelName:x.channelName,channelId:x.channelId,name:x.config.name,type:x.config.type,alive:x.listener.isAlive(),events:Y?.events??0,errors:Y?.errors??0,failureCount:this.failureCounts.get($)??0,lastEventAt:Y?.lastEventAt??null}})}async start($,x){let Y=LY.keyOf($,x);if(this.running.has(Y))return{ok:!0,reason:"already running"};let X=this.channels.createListener($,x);if(!X)return{ok:!1,reason:`connector "${x}" not found in channel "${$}"`};let Q=async(z,Z)=>{try{await this.notify($,x,z,Z),this.recordEvent(Y)}catch(K){throw this.recordError(Y),K}};try{return await Promise.race([X.listener.start(Q),this.sleep(this.startTimeoutMs).then(()=>{throw Error(`listener start timed out after ${this.startTimeoutMs}ms`)})]),this.running.set(Y,{config:X.config,channelName:$,channelId:X.channelId,listener:X.listener}),this.pendingRetry.delete(Y),this.ensureStats(Y),this.logger?.info(`${X.config.type} listener started`,{channel:$,connector:x}),{ok:!0}}catch(z){let Z=z instanceof Error?z:Error(String(z));return this.logger?.error(`${X.config.type} listener failed to start`,{channel:$,connector:x,error:Z.message}),this.onError(Z,{component:"listener-supervisor.start",channel:$,connector:x,type:X.config.type}),{ok:!1,reason:Z.message}}}async stop($,x){let Y=LY.keyOf($,x),X=this.running.get(Y);if(!X)return{ok:!0,reason:"not running"};try{return await X.listener.stop(),this.logger?.info(`${X.config.type} listener stopped`,{channel:$,connector:x}),{ok:!0}}catch(Q){let z=Q instanceof Error?Q:Error(String(Q));return this.logger?.error(`${X.config.type} listener failed to stop`,{channel:$,connector:x,error:z.message}),this.onError(z,{component:"listener-supervisor.stop",channel:$,connector:x,type:X.config.type}),{ok:!1,reason:z.message}}finally{this.running.delete(Y),this.failureCounts.delete(Y)}}async restart($,x){let Y=await this.stop($,x);if(!Y.ok)return Y;return await this.start($,x)}async startAll(){let $=this.channels.listAllConnectors(),x=await Promise.allSettled($.map((Y)=>this.start(Y.channelName,Y.name)));for(let Y=0;Y<x.length;Y++){let X=x[Y],Q=$[Y];if(X.status==="rejected"||X.status==="fulfilled"&&!X.value.ok){let z=LY.keyOf(Q.channelName,Q.name);this.pendingRetry.set(z,{channelName:Q.channelName,connectorName:Q.name})}}this.startHealthCheck()}async stopAll(){this.stopHealthCheck(),this.pendingRetry.clear();for(let[,$]of[...this.running.entries()])await this.stop($.channelName,$.config.name)}ensureStats($){let x=this.stats.get($);if(x)return x;let Y={events:0,errors:0,failureCount:0,lastEventAt:null};return this.stats.set($,Y),Y}recordEvent($){let x=this.ensureStats($);x.events+=1,x.lastEventAt=new Date(this.now()).toISOString()}recordError($){this.ensureStats($).errors+=1}startHealthCheck(){if(this.healthCheckTimer)return;this.healthCheckTimer=setInterval(()=>{this.runHealthCheck()},this.healthCheckIntervalMs),this.healthCheckTimer.unref()}stopHealthCheck(){if(!this.healthCheckTimer)return;clearInterval(this.healthCheckTimer),this.healthCheckTimer=null}async runHealthCheckForTest(){await this.runHealthCheck()}async runHealthCheck(){if(this.healthCheckInFlight)return;this.healthCheckInFlight=!0;try{for(let[$,x]of[...this.running.entries()]){if(x.listener.isAlive()){this.failureCounts.delete($);continue}await this.recoverDead(x.channelName,x.config.name,x.config.type)}for(let[$,x]of[...this.pendingRetry.entries()]){if(this.running.has($)){this.pendingRetry.delete($);continue}this.logger?.info("retrying failed listener",{channel:x.channelName,connector:x.connectorName});let Y=this.failureCounts.get($)??0,X=Math.min(1000*2**Y,this.maxBackoffMs);if(await this.sleep(X),(await this.start(x.channelName,x.connectorName)).ok)this.pendingRetry.delete($),this.failureCounts.delete($);else this.failureCounts.set($,Y+1)}}finally{this.healthCheckInFlight=!1}}async recoverDead($,x,Y){let X=LY.keyOf($,x),Q=this.failureCounts.get(X)??0,z=Math.min(1000*2**Q,this.maxBackoffMs);if(this.logger?.warn(`${Y} listener unhealthy, restarting`,{channel:$,connector:x,attempt:Q+1,backoffMs:z}),await this.stop($,x),await this.sleep(z),(await this.start($,x)).ok)this.failureCounts.delete(X),this.logger?.info(`${Y} listener recovered`,{channel:$,connector:x});else this.failureCounts.set(X,Q+1)}}var fo0=new X8,bo0=3000,co0=100,Ro0=200,ko0=($)=>new Promise((x)=>{setTimeout(x,$)}),Ao0=($)=>`funnel-gateway[${$}]`,To0=async($)=>{let x=$.now()+bo0;while($.now()<x){if($.pids.every((Y)=>!$.runner.isAlive(Y)))return;await $.sleep(co0)}for(let Y of $.pids){if(!$.runner.isAlive(Y))continue;try{$.runner.kill(Y,"SIGKILL")}catch{}}await $.sleep(Ro0)},FT1=async($)=>{let x=$.process??fo0,Y=$.logger,X=Ao0($.dir),Q=x.listProcessesContaining(X),z=[];for(let Z of Q){if(Z.pid===$.selfPid)continue;x.kill(Z.pid,"SIGTERM"),z.push(Z.pid),Y?.info("killed competing Slack gateway process",{pid:Z.pid,args:Z.command.slice(0,160)})}if(z.length===0)return z;return await To0({runner:x,pids:z,sleep:$.sleep??ko0,now:$.now??(()=>Date.now())}),z};var LT1=($,x,Y)=>{let X=$.req.raw.headers.get("Cookie");if(typeof x==="string"){if(!X)return;let z=x;if(Y==="secure")z="__Secure-"+x;else if(Y==="host")z="__Host-"+x;return jE(X,z)[z]}if(!X)return{};return jE(X)};var jT1=($,x)=>{return new Response($,{headers:{"Content-Type":x}}).formData()};var So0=/^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/,uo0=/^multipart\/form-data(;\s?boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/,Eo0=/^application\/x-www-form-urlencoded(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/,WC=($,x)=>{return async(Y,X)=>{let Q={},z=Y.req.header("Content-Type");switch($){case"json":if(!z||!So0.test(z))break;try{Q=await Y.req.json()}catch{throw new FY(400,{message:"Malformed JSON in request body"})}break;case"form":{if(!z||!(uo0.test(z)||Eo0.test(z)))break;let K;if(Y.req.bodyCache.formData)K=await Y.req.bodyCache.formData;else try{let W=await Y.req.arrayBuffer();K=await jT1(W,z),Y.req.bodyCache.formData=K}catch(W){let w="Malformed FormData request.";throw w+=W instanceof Error?` ${W.message}`:` ${String(W)}`,new FY(400,{message:w})}let V=Object.create(null);K.forEach((W,w)=>{if(w.endsWith("[]"))(V[w]??=[]).push(W);else if(Array.isArray(V[w]))V[w].push(W);else if(Object.hasOwn(V,w))V[w]=[V[w],W];else V[w]=W}),Q=V;break}case"query":Q=Object.fromEntries(Object.entries(Y.req.queries()).map(([K,V])=>{return V.length===1?[K,V[0]]:[K,V]}));break;case"param":Q=Y.req.param();break;case"header":Q=Y.req.header();break;case"cookie":Q=LT1(Y);break}let Z=await x(Q,Y);if(Z instanceof Response)return Z;return Y.req.addValidatedData($,Z),await X()}};function Co0($,x,Y,X){return WC($,async(Q,z)=>{let Z=Q;if($==="header"&&"_def"in x||$==="header"&&"_zod"in x){let V=Object.keys("in"in x?x.in.shape:x.shape),W=Object.fromEntries(V.map((w)=>[w.toLowerCase(),w]));Z=Object.fromEntries(Object.entries(Q).map(([w,H])=>[W[w]||w,H]))}let K=X&&X.validationFunction?await X.validationFunction(x,Z):await x.safeParseAsync(Z);if(Y){let V=await Y({data:Z,...K,target:$},z);if(V){if(V instanceof Response)return V;if("response"in V)return V.response}}if(!K.success)return z.json(K,400);return K.data})}var Vv=Co0;var r9=($)=>Vv("param",$,(x,Y)=>{if(x.success)return;let X=x.error.issues[0],Q=X?`${X.path.join(".")}: ${X.message}`:"invalid request";return Y.json({ok:!1,reason:Q},400)});var wC=c.lazy(()=>c.union([c.string(),c.number(),c.boolean(),c.null(),c.array(wC),c.record(c.string(),wC)])),yo0=c.object({method:c.string().min(1),path:c.string().min(1),body:wC.optional()}),NT1=S6.createHandlers(r9(c.object({channel:c.string().min(1),connector:c.string().min(1)})),async($)=>{let x=$.req.valid("param"),Y=await $.req.json().catch(()=>null),X=yo0.safeParse(Y);if(!X.success)throw new FY(400,{message:X.error.issues[0]?.message??"invalid body"});let Q=await $.var.deps.channels.call(x.channel,x.connector,{method:X.data.method,path:X.data.path,body:X.data.body});return $.json({ok:!0,result:Q})});var PT1=S6.createHandlers(r9(c.object({channel:c.string().min(1)})),Vv("json",rA1,($,x)=>{if($.success)return;let Y=$.error.issues[0],X=Y?`${Y.path.join(".")}: ${Y.message}`:"invalid body";return x.json({ok:!1,reason:X},400)}),($)=>{let x=$.req.valid("param"),Y=$.req.valid("json"),X=Y.target?{...Y.meta,target:Y.target}:Y.meta,z={ok:!0,offset:$.var.deps.emit({channel:x.channel,connector:Y.connector,content:Y.content,meta:X}).offset};return $.json(z)});import{existsSync as HC}from"fs";import{join as UC}from"path";var mo0=($)=>{if(typeof $!=="string"||$.length===0)return null;try{let x=JSON.parse($);if(x!==null&&typeof x==="object"&&"text"in x){let Y=String(x.text);return Y.length>80?`${Y.slice(0,80)}\u2026`:Y}}catch{return $.length>80?`${$.slice(0,80)}\u2026`:$}return $.length>80?`${$.slice(0,80)}\u2026`:$},ho0=($)=>{let Y=($.connectionErrors[$.connectionErrors.length-1]??null)?.detail??null;if($.connectors.length===0)return{status:"warn",message:"no connectors configured on this channel",nextActions:[`fnl channels ${$.name} connectors add <name> --type=slack ...`],rootCause:null};if(!$.listener)return{status:"error",message:"no listener running for this channel",nextActions:["fnl gateway restart"],rootCause:Y};if(!$.listener.alive)return{status:"error",message:"listener is dead",nextActions:["fnl gateway logs","fnl gateway restart"],rootCause:Y};if($.claudeClients===0)return{status:"warn",message:"no Claude connected to this channel",nextActions:[`fnl claude --channel ${$.name}`],rootCause:null};if($.listener.errors>0)return{status:"warn",message:"listener has errors",nextActions:["fnl gateway logs"],rootCause:Y};return{status:"ok",message:"healthy",nextActions:[],rootCause:null}},IT1=S6.createHandlers(async($)=>{let x=$.var.deps,Y=$.req.query("channel")??null,X=x.channels.list(),Q=Y?X.filter((q)=>q.name===Y||q.id===Y):X,z=x.supervisor.list(),Z=x.broadcaster.listChannels(),K=x.broadcaster.getMetrics(),V=Tx(),W=UC(V,"connector-raw.db"),w=UC(V,"connector-processed.db"),H=UC(V,"connector-connection.db"),U=HC(W)&&HC(w)&&HC(H),J=Q.map((q)=>{let B=z.find((y)=>y.channelName===q.name)??null,D=B?{alive:B.alive,events:B.events,errors:B.errors,lastEventAt:B.lastEventAt}:null,v=Z.filter((y)=>y.channel===q.id||y.channel===q.name).length,N=[],L=[];if(U){let y=new ux({rawPath:W,processedPath:w,connectionPath:H}),n=(()=>{try{return y.query("SELECT seq, ts, type, outcome, payload FROM processed WHERE channel_id = ? ORDER BY seq DESC LIMIT 10",[q.id])}finally{y.close()}})();if(!(n instanceof Error))for(let w1 of[...n].reverse()){let h=typeof w1.payload==="string"?w1.payload:null,a=null;if(h)try{let K1=JSON.parse(h);if(K1!==null&&typeof K1==="object"&&!Array.isArray(K1))a=K1}catch{a=null}N.push({seq:typeof w1.seq==="number"?w1.seq:null,ts:typeof w1.ts==="number"?w1.ts:null,type:typeof w1.type==="string"?w1.type:"?",outcome:typeof w1.outcome==="string"?w1.outcome:"?",payload:h,payloadParsed:a,preview:mo0(w1.payload)})}if(D&&(!D.alive||D.errors>0)||!D){let w1=new ux({rawPath:W,processedPath:w,connectionPath:H}),h=(()=>{try{return w1.query("SELECT ts, type, status, detail FROM connection WHERE channel_id = ? AND status IN ('auth-failed','error') ORDER BY seq DESC LIMIT 3",[q.id])}finally{w1.close()}})();if(!(h instanceof Error))for(let a of[...h].reverse())L.push({ts:typeof a.ts==="number"?a.ts:null,type:typeof a.type==="string"?a.type:"?",status:typeof a.status==="string"?a.status:"?",detail:typeof a.detail==="string"&&a.detail.length>0?a.detail:null})}}let u={id:q.id,name:q.name,connectors:q.connectors.map((y)=>y.name),listener:D,claudeClients:v,recentEvents:N,connectionErrors:L};return{...u,diagnosis:ho0(u)}});return $.json({pid:x.selfPid,uptimeMs:x.uptimeMs(),eventsBroadcast:K.eventsBroadcast,channels:J})});var MT1=S6.createHandlers(($)=>{let x=$.var.deps;return $.json({ok:!0,pid:x.selfPid,funnelDir:x.dir,clients:x.broadcaster.getClientCount(),listeners:x.supervisor.list()})});var _T1=S6.createHandlers(($)=>{return $.json({listeners:$.var.deps.supervisor.list()})});var OT1=S6.createHandlers(r9(c.object({channel:c.string().min(1),connector:c.string().min(1)})),async($)=>{let x=$.req.valid("param"),Y=await $.var.deps.supervisor.restart(x.channel,x.connector);return $.json(Y,Y.ok?200:400)});var fT1=S6.createHandlers(r9(c.object({channel:c.string().min(1),connector:c.string().min(1)})),async($)=>{let x=$.req.valid("param"),Y=await $.var.deps.supervisor.start(x.channel,x.connector);return $.json(Y,Y.ok?200:400)});var bT1=S6.createHandlers(r9(c.object({channel:c.string().min(1),connector:c.string().min(1)})),async($)=>{let x=$.req.valid("param"),Y=await $.var.deps.supervisor.stop(x.channel,x.connector);return $.json(Y,Y.ok?200:400)});var cT1=S6.createHandlers(($)=>{let x=$.var.deps;return $.json({ok:!0,pid:x.selfPid,funnelDir:x.dir,uptimeMs:x.uptimeMs(),clients:x.broadcaster.listChannels(),listeners:x.supervisor.list(),broadcaster:x.broadcaster.getMetrics()})});function go0(){return S6.createApp().onError(($,x)=>{if($ instanceof FY)return $.getResponse();let Y=$ instanceof Error?$.message:String($);return x.json({error:Y},500)}).get("/health",...MT1).get("/status",...cT1).get("/debug",...IT1).get("/listeners",..._T1).post("/listeners/:channel/:connector/start",...fT1).delete("/listeners/:channel/:connector",...bT1).post("/listeners/:channel/:connector/restart",...OT1).post("/channels/:channel/connectors/:connector/call",...NT1).post("/channels/:channel/publish",...PT1)}var RT1=go0();var do0="127.0.0.1",ao0=new Set(["127.0.0.1","localhost","::1","::ffff:127.0.0.1"]),so0=()=>no0(Tx(),"events.db"),oo0=()=>{};class GC{channels;configuredPort;configuredHostname;dbPath;process;logger;onError;selfPid;dir;killCompetingSlack;token;allowInsecureHost;broadcaster;eventLog;supervisor;nowMs;extraRoutes;startedAt=null;server=null;constructor($){this.channels=$.channels,this.configuredPort=$.port??r7(),this.configuredHostname=$.hostname??do0,this.dbPath=$.dbPath??so0(),this.process=$.process,this.logger=$.logger,this.onError=$.onError??oo0,this.selfPid=$.selfPid??globalThis.process.pid,this.dir=$.dir??W9,this.killCompetingSlack=$.killCompetingSlack??!0,this.token=$.token??"",this.allowInsecureHost=$.allowInsecureHost??!1,this.extraRoutes=$.extraRoutes??null;let x=$.clock;if(this.nowMs=x?()=>x.millis():()=>Date.now(),$.eventLog)this.eventLog=$.eventLog;else{let Y=lo0(this.dbPath);if(!po0(Y))io0(Y,{recursive:!0});this.eventLog=new VC({path:this.dbPath,now:this.nowMs,logger:this.logger})}this.broadcaster=new ZC({logger:this.logger,onError:this.onError,now:this.nowMs,persistentReplay:this.eventLog}),this.broadcaster.seedLatestOffset(this.eventLog.findMaxOffset()),this.supervisor=new LY({channels:this.channels,logger:this.logger,onError:this.onError,notify:async(Y,X,Q,z)=>{this.emit({channel:Y,connector:X,content:Q,meta:z})},now:this.nowMs})}get port(){return this.server?.port??this.configuredPort}get hostname(){return this.server?.hostname??this.configuredHostname}async start(){if(this.server)return;if(!this.token&&!ao0.has(this.configuredHostname)&&!this.allowInsecureHost)throw Error(`refusing to start gateway: hostname "${this.configuredHostname}" is reachable off-box but no token is set. Set a token, bind to loopback (127.0.0.1), or pass allowInsecureHost: true.`);let $=this.buildApp();await this.killCompetingSlackIfNeeded(),this.startedAt=this.nowMs(),this.server=Bun.serve({port:this.configuredPort,hostname:this.configuredHostname,development:!1,fetch:(x,Y)=>this.handleFetch(x,Y,$),websocket:{open:(x)=>this.handleWsOpen(x),close:(x)=>this.handleWsClose(x),message(){}}}),this.logServerStarted(),await this.bootListeners()}async stop(){if(await this.supervisor.stopAll(),this.server)this.server.stop(),this.server=null}getStatus(){return{clients:this.broadcaster.getClientCount(),channels:this.broadcaster.listChannels()}}getBroadcaster(){return this.broadcaster}getSupervisor(){return this.supervisor}getEventLog(){return this.eventLog}onEvent($){return this.broadcaster.subscribe($)}handleFetch($,x,Y){let X=new URL($.url);if(X.pathname==="/ws"&&$.headers.get("upgrade")==="websocket"){if(this.token&&!this.tokenMatchesUpgrade($))return new Response("unauthorized",{status:401});let Q=X.searchParams.get("channel")??"",z=Q?this.resolveChannel(Q):null;if(Q&&!z)return new Response(`unknown channel "${Q}"`,{status:404});let Z=z?.id??Q,K=z?.name??null,V=z?.connectors??[],W=z?.delivery??"fanout",w=X.searchParams.get("since"),H=w===null?Number.NaN:Number.parseInt(w,10),U=Number.isFinite(H)&&H>=0?H:void 0,J=X.searchParams.get("id")??void 0;if(x.upgrade($,{data:{channel:Z,channelName:K,connectors:V,delivery:W,subscriberId:J,since:U}}))return;return new Response("WebSocket upgrade failed",{status:400})}return Y.fetch($)}handleWsOpen($){if(typeof $.data.since==="number"){let x=this.broadcaster.replaySince($.data.since,$.data);for(let Y of x)$.send(JSON.stringify(Y))}this.broadcaster.addClient($,$.data),this.logger?.info("channel connected",{event_type:"system",action:"channel_connect",channel:$.data.channelName??"",channelId:$.data.channel,connectors:$.data.connectors.join(","),total:String(this.broadcaster.getClientCount())})}handleWsClose($){this.broadcaster.removeClient($),this.logger?.info("channel disconnected",{event_type:"system",action:"channel_disconnect",channel:$.data.channelName??"",channelId:$.data.channel,total:String(this.broadcaster.getClientCount())})}logServerStarted(){this.logger?.info("gateway started",{event_type:"system",action:"gateway_start",port:String(this.port),pid:String(this.selfPid)}),this.logger?.info("funnel gateway listening",{url:`http://localhost:${this.port}`,websocket:`ws://localhost:${this.port}/ws`,health:`http://localhost:${this.port}/health`})}buildApp(){let $=S6.createApp();if($.use((Y,X)=>{return Y.set("deps",{selfPid:this.selfPid,dir:this.dir,broadcaster:this.broadcaster,supervisor:this.supervisor,channels:this.channels,uptimeMs:()=>this.startedAt?this.nowMs()-this.startedAt:0,emit:(Q)=>this.emit(Q)}),X()}),this.token)$.use("/listeners/*",e7({expected:this.token})),$.use("/status",e7({expected:this.token})),$.use("/debug",e7({expected:this.token})),$.use("/channels/*",e7({expected:this.token}));return(this.extraRoutes?$.route("/",this.extraRoutes):$).route("/",RT1)}tokenMatchesUpgrade($){let x=($.headers.get("sec-websocket-protocol")??"").split(",").map((Q)=>Q.trim()).filter((Q)=>Q.length>0);for(let Q of x)if(Q.startsWith("funnel.token.")&&xv(Q.slice(13),this.token))return!0;let X=($.headers.get("authorization")??"").match(/^Bearer\s+(.+)$/i);if(X&&xv(X[1]??"",this.token))return!0;return!1}resolveChannel($){let x=this.channels.get($)??this.channels.getById($);if(!x)return null;return{id:x.id,name:x.name,connectors:x.connectors.map((Y)=>Y.name),delivery:x.delivery}}async killCompetingSlackIfNeeded(){if(!this.killCompetingSlack)return;if(!this.channels.listAllConnectors().some((Y)=>Y.type==="slack"))return;let x=await FT1({selfPid:this.selfPid,dir:this.dir,process:this.process,logger:this.logger});if(x.length>0)this.logger?.info("killed competing Slack gateway processes",{event_type:"system",action:"kill_competing",pids:x.join(",")})}async bootListeners(){await this.supervisor.startAll();for(let $ of this.supervisor.list())this.logger?.info(`${$.type} listener started: ${$.name}`,{event_type:"system",action:`${$.type}_connect`,channel:$.channelName,connector:$.name});this.logger?.info(`event store: ${this.dbPath}`),this.logger?.info("funnel gateway running")}emit($){let x=this.lookupChannelId($.channel),Y=x&&$.connector?this.lookupConnectorId(x,$.connector):null,X={...$.meta,channel:$.channel};if($.connector)X.connector=$.connector;if(x)X.channelId=x;if(Y)X.connectorId=Y;let Q=this.broadcaster.broadcast($.content,X);return this.eventLog.record({content:$.content,channelId:x??null,connectorId:Y??null,meta:X,offset:Q.offset}),{offset:Q.offset}}lookupChannelId($){return this.channels.get($)?.id??this.channels.getById($)?.id??null}lookupConnectorId($,x){return this.channels.getById($)?.connectors.find((X)=>X.name===x)?.id??null}}import{homedir as ro0}from"os";import{dirname as to0,join as kT1}from"path";var AT1="gateway.token",eo0=32,$r0=new z8,xr0=()=>{let $=new Uint8Array(eo0);return crypto.getRandomValues($),[...$].map((x)=>x.toString(16).padStart(2,"0")).join("")};class JC{fs;path;generate;constructor($={}){this.fs=$.fs??$r0,this.path=kT1($.dir??W9,AT1),this.generate=$.generate??xr0,Object.freeze(this)}read(){if(!this.fs.existsSync(this.path))return null;let $=this.fs.readFileSync(this.path).trim();return $.length>0?$:null}ensure(){let $=this.read();if($)return $;let x=this.generate();return this.fs.mkdirSync(to0(this.path),{recursive:!0}),this.fs.writeSecretFileSync(this.path,`${x}
1235
- `),x}getPath(){return this.path}}var eB6=kT1(ro0(),".funnel",AT1);var Yr0=c.object({channelName:c.string(),channelId:c.string(),name:c.string(),type:c.string(),alive:c.boolean()}),Qr0=c.object({listeners:c.array(Yr0)}),Xr0=c.object({reason:c.string().optional()}),qC={state:"offline"};class DC{port;isDaemonRunning;getToken;constructor($){this.port=$.port,this.isDaemonRunning=$.isDaemonRunning,this.getToken=$.getToken??(()=>null),Object.freeze(this)}async list(){if(!this.isDaemonRunning())return{state:"offline"};try{let $=await fetch(`${t7(this.port)}/listeners`,{headers:this.authHeaders()});if(!$.ok)return{state:"error",reason:`HTTP ${$.status}`};let x=Qr0.safeParse(await $.json());if(!x.success)return{state:"error",reason:"malformed daemon response"};return{state:"ok",listeners:x.data.listeners}}catch($){return{state:"error",reason:$ instanceof Error?$.message:String($)}}}async start($,x){if(!this.isDaemonRunning())return qC;return await this.call("POST",`/listeners/${this.path($,x)}/start`)}async stop($,x){if(!this.isDaemonRunning())return qC;return await this.call("DELETE",`/listeners/${this.path($,x)}`)}async restart($,x){if(!this.isDaemonRunning())return qC;return await this.call("POST",`/listeners/${this.path($,x)}/restart`)}path($,x){return`${encodeURIComponent($)}/${encodeURIComponent(x)}`}authHeaders(){let $=this.getToken();return $?{authorization:`Bearer ${$}`}:{}}async call($,x){try{let Y=await fetch(`${t7(this.port)}${x}`,{method:$,headers:this.authHeaders()});if(!Y.ok){let X=Xr0.safeParse(await Y.json().catch(()=>null));return{state:"error",reason:(X.success?X.data.reason:void 0)??`HTTP ${Y.status}`}}return{state:"ok"}}catch(Y){return{state:"error",reason:Y instanceof Error?Y.message:String(Y)}}}}var Zr0="/sandbox/.funnel",Kr0="/sandbox/tmp",Vr0=()=>{};class Wv{paths;channels;gateway;gatewayToken;publisher;listeners;claude;profiles;localConfig;localConfigSync;diagnostics;recovery;doctor;docs;fs;process;logger;clock;onError;constructor($={}){let x=$.dir??iB(),Y=$.tmpDir??Tx(),X=$.fs??new z8,Q=$.process??new X8,z=$.clock??new zX,Z=$.idGenerator??new s7;this.paths={dir:x,tmpDir:Y,settings:zr0(x,"settings.json")},this.fs=X,this.process=Q,this.logger=$.logger,this.clock=z,this.onError=$.onError??Vr0;let K=$.store??new BE({path:this.paths.settings,fs:X,idGenerator:Z}),V=new _E({descriptors:$.connectors??[],fs:X,process:Q,logger:this.logger,diagnosticLog:$.diagnosticLog,dir:x});this.profiles=new hE({store:K,idGenerator:Z,fs:X}),this.channels=new OE({store:K,registry:V,clock:z,idGenerator:Z,profileChecker:this.profiles}),this.gateway=new eE({fs:X,process:Q,clock:z,dir:x,tmpDir:Y,port:$.port}),this.gatewayToken=new JC({fs:X,dir:x}),this.publisher=new rE({port:this.gateway.getPort(),isDaemonRunning:()=>this.gateway.isRunning(),getToken:()=>this.gatewayToken.read()}),this.listeners=new DC({port:this.gateway.getPort(),isDaemonRunning:()=>this.gateway.isRunning(),getToken:()=>this.gatewayToken.read()});let W=new mE({fs:X});this.localConfig=new EE({fs:X}),this.localConfigSync=new yE({channels:this.channels,prompter:$.tokenPrompter??new iE}),this.claude=new fE({channels:this.channels,mcp:W,gateway:this.gateway,sessions:this.profiles,guard:new sB({fs:X,process:Q,dir:x}),process:Q,logger:this.logger}),this.diagnostics=new AE({gateway:this.gateway,gatewayToken:this.gatewayToken,channels:this.channels,publisher:this.publisher,tmpDir:Y}),this.recovery=new gE({gateway:this.gateway,listeners:this.listeners,channels:this.channels}),this.doctor=new TE({diagnostics:this.diagnostics,recovery:this.recovery}),this.docs=new uE,Object.freeze(this)}static inMemory($={}){return new Wv({...$,store:$.store??new sE,fs:$.fs??new lE,process:$.process??new aE,logger:$.logger??new dE,clock:$.clock??new oE,idGenerator:$.idGenerator??new nE,dir:$.dir??Zr0,tmpDir:$.tmpDir??Kr0})}gatewayServer($={}){return new GC({channels:this.channels,port:$.port,hostname:$.hostname,...$.eventLog?{eventLog:$.eventLog}:{dbPath:$.dbPath},process:this.process,clock:this.clock,logger:this.logger,onError:this.onError,dir:this.paths.dir,killCompetingSlack:$.killCompetingSlack,token:$.token??this.gatewayToken.ensure(),allowInsecureHost:$.allowInsecureHost,extraRoutes:$.extraRoutes})}createProcessGuard(){return new sB({fs:this.fs,process:this.process,dir:this.paths.dir})}async runGatewayForeground($={}){let x=$v(),X=$.caffeinate!==!1&&globalThis.process.platform==="darwin"?["caffeinate","-is","bun",x]:["bun",x];return this.process.attach(X)}gatewayClient(){let{port:$}=this.gateway.getStatus();return ME(t7($))}}import{appendFileSync as wr0,mkdirSync as Hr0}from"fs";import{dirname as Ur0,join as Gr0}from"path";var Wr0=[/xox[abprs]-[A-Za-z0-9-]{10,}/g,/xapp-[A-Za-z0-9-]{10,}/g,/gh[pousr]_[A-Za-z0-9]{20,}/g,/github_pat_[A-Za-z0-9_]{20,}/g,/Bot [A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{20,}/g,/Bearer [A-Za-z0-9._~+/-]{16,}/g],TT1=($)=>{let x=$;for(let Y of Wr0)x=x.replace(Y,"[redacted]");return x};var Jr0=()=>Gr0(Tx(),"funnel.log");class BC extends EW{file;now;constructor($={}){super();this.file=$.file??Jr0(),this.now=$.now??(()=>new Date),Object.freeze(this)}info($,x){this.write("info",$,x)}warn($,x){this.write("warn",$,x)}error($,x){this.write("error",$,x)}write($,x,Y){Hr0(Ur0(this.file),{recursive:!0});let X={time:this.now().toISOString(),level:$,message:x,...Y?{meta:Y}:{}};wr0(this.file,`${TT1(JSON.stringify(X))}
1235
+ `),x}getPath(){return this.path}}var eB6=kT1(ro0(),".funnel",AT1);var Yr0=c.object({channelName:c.string(),channelId:c.string(),name:c.string(),type:c.string(),alive:c.boolean()}),Qr0=c.object({listeners:c.array(Yr0)}),Xr0=c.object({reason:c.string().optional()}),qC={state:"offline"};class DC{port;isDaemonRunning;getToken;constructor($){this.port=$.port,this.isDaemonRunning=$.isDaemonRunning,this.getToken=$.getToken??(()=>null),Object.freeze(this)}async list(){if(!this.isDaemonRunning())return{state:"offline"};try{let $=await fetch(`${t7(this.port)}/listeners`,{headers:this.authHeaders()});if(!$.ok)return{state:"error",reason:`HTTP ${$.status}`};let x=Qr0.safeParse(await $.json());if(!x.success)return{state:"error",reason:"malformed daemon response"};return{state:"ok",listeners:x.data.listeners}}catch($){return{state:"error",reason:$ instanceof Error?$.message:String($)}}}async start($,x){if(!this.isDaemonRunning())return qC;return await this.call("POST",`/listeners/${this.path($,x)}/start`)}async stop($,x){if(!this.isDaemonRunning())return qC;return await this.call("DELETE",`/listeners/${this.path($,x)}`)}async restart($,x){if(!this.isDaemonRunning())return qC;return await this.call("POST",`/listeners/${this.path($,x)}/restart`)}path($,x){return`${encodeURIComponent($)}/${encodeURIComponent(x)}`}authHeaders(){let $=this.getToken();return $?{authorization:`Bearer ${$}`}:{}}async call($,x){try{let Y=await fetch(`${t7(this.port)}${x}`,{method:$,headers:this.authHeaders()});if(!Y.ok){let X=Xr0.safeParse(await Y.json().catch(()=>null));return{state:"error",reason:(X.success?X.data.reason:void 0)??`HTTP ${Y.status}`}}return{state:"ok"}}catch(Y){return{state:"error",reason:Y instanceof Error?Y.message:String(Y)}}}}var Zr0="/sandbox/.funnel",Kr0="/sandbox/tmp",Vr0=()=>{};class Wv{paths;channels;gateway;gatewayToken;publisher;listeners;claude;profiles;localConfig;localConfigSync;diagnostics;recovery;doctor;docs;fs;process;logger;clock;onError;constructor($={}){let x=$.dir??iB(),Y=$.tmpDir??Tx(),X=$.fs??new z8,Q=$.process??new X8,z=$.clock??new zX,Z=$.idGenerator??new s7;this.paths={dir:x,tmpDir:Y,settings:zr0(x,"settings.json")},this.fs=X,this.process=Q,this.logger=$.logger,this.clock=z,this.onError=$.onError??Vr0;let K=$.store??new BE({path:this.paths.settings,fs:X,idGenerator:Z}),V=new _E({descriptors:$.connectors??[],fs:X,process:Q,logger:this.logger,diagnosticLog:$.diagnosticLog,dir:x});this.profiles=new hE({store:K,idGenerator:Z,fs:X}),this.channels=new OE({store:K,registry:V,clock:z,idGenerator:Z,profileChecker:this.profiles}),this.gateway=new eE({fs:X,process:Q,clock:z,dir:x,tmpDir:Y,port:$.port}),this.gatewayToken=new JC({fs:X,dir:x}),this.publisher=new rE({port:this.gateway.getPort(),isDaemonRunning:()=>this.gateway.isRunning(),getToken:()=>this.gatewayToken.read()}),this.listeners=new DC({port:this.gateway.getPort(),isDaemonRunning:()=>this.gateway.isRunning(),getToken:()=>this.gatewayToken.read()});let W=new mE({fs:X});this.localConfig=new EE({fs:X}),this.localConfigSync=new yE({channels:this.channels,prompter:$.tokenPrompter??new iE}),this.claude=new fE({channels:this.channels,mcp:W,gateway:this.gateway,sessions:this.profiles,guard:new sB({fs:X,process:Q,dir:x}),process:Q,logger:this.logger,dir:x}),this.diagnostics=new AE({gateway:this.gateway,gatewayToken:this.gatewayToken,channels:this.channels,publisher:this.publisher,tmpDir:Y}),this.recovery=new gE({gateway:this.gateway,listeners:this.listeners,channels:this.channels}),this.doctor=new TE({diagnostics:this.diagnostics,recovery:this.recovery}),this.docs=new uE,Object.freeze(this)}static inMemory($={}){return new Wv({...$,store:$.store??new sE,fs:$.fs??new lE,process:$.process??new aE,logger:$.logger??new dE,clock:$.clock??new oE,idGenerator:$.idGenerator??new nE,dir:$.dir??Zr0,tmpDir:$.tmpDir??Kr0})}gatewayServer($={}){return new GC({channels:this.channels,port:$.port,hostname:$.hostname,...$.eventLog?{eventLog:$.eventLog}:{dbPath:$.dbPath},process:this.process,clock:this.clock,logger:this.logger,onError:this.onError,dir:this.paths.dir,killCompetingSlack:$.killCompetingSlack,token:$.token??this.gatewayToken.ensure(),allowInsecureHost:$.allowInsecureHost,extraRoutes:$.extraRoutes})}createProcessGuard(){return new sB({fs:this.fs,process:this.process,dir:this.paths.dir})}async runGatewayForeground($={}){let x=$v(),X=$.caffeinate!==!1&&globalThis.process.platform==="darwin"?["caffeinate","-is","bun",x]:["bun",x];return this.process.attach(X)}gatewayClient(){let{port:$}=this.gateway.getStatus();return ME(t7($))}}import{appendFileSync as wr0,mkdirSync as Hr0}from"fs";import{dirname as Ur0,join as Gr0}from"path";var Wr0=[/xox[abprs]-[A-Za-z0-9-]{10,}/g,/xapp-[A-Za-z0-9-]{10,}/g,/gh[pousr]_[A-Za-z0-9]{20,}/g,/github_pat_[A-Za-z0-9_]{20,}/g,/Bot [A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]{20,}/g,/Bearer [A-Za-z0-9._~+/-]{16,}/g],TT1=($)=>{let x=$;for(let Y of Wr0)x=x.replace(Y,"[redacted]");return x};var Jr0=()=>Gr0(Tx(),"funnel.log");class BC extends EW{file;now;constructor($={}){super();this.file=$.file??Jr0(),this.now=$.now??(()=>new Date),Object.freeze(this)}info($,x){this.write("info",$,x)}warn($,x){this.write("warn",$,x)}error($,x){this.write("error",$,x)}write($,x,Y){Hr0(Ur0(this.file),{recursive:!0});let X={time:this.now().toISOString(),level:$,message:x,...Y?{meta:Y}:{}};wr0(this.file,`${TT1(JSON.stringify(X))}
1236
1236
  `)}}var ST1=($)=>{let x=new pW;if($.token)x.use("/diagnostics",e7({expected:$.token})),x.use("/diagnostics/*",e7({expected:$.token})),x.use("/doctor",e7({expected:$.token}));return x.get("/diagnostics",async(Y)=>{let X=Y.req.query("channel");if(Y.req.query("all")!==void 0){let Z=await $.diagnostics.diagnoseAll();return Y.json(Z)}let z=await $.diagnostics.diagnose(X??void 0);if(!z)return Y.json({error:"channel not found"},404);return Y.json(z)}),x.get("/diagnostics/events",async(Y)=>{let X=Y.req.query("channel")??null,Q=Number(Y.req.query("limit")??"20"),z=await $.diagnostics.recentEvents(X,Q);return Y.json(z)}),x.get("/diagnostics/dropped",async(Y)=>{let X=Y.req.query("channel")??null,Q=Number(Y.req.query("limit")??"20"),z=await $.diagnostics.droppedEvents(X,Q);return Y.json(z)}),x.get("/diagnostics/errors",async(Y)=>{let X=Y.req.query("channel")??null,Q=Number(Y.req.query("limit")??"20"),z=await $.diagnostics.connectionErrors(X,Q);return Y.json(z)}),x.post("/diagnostics/replay",async(Y)=>{let X=await Y.req.json().catch(()=>({})),Q=typeof X.channel==="string"?X.channel:null,z=typeof X.seq==="number"?X.seq:void 0;if(!Q)return Y.json({error:"channel is required"},400);let Z=await $.diagnostics.replay(Q,z);return Y.json(Z)}),x.post("/doctor",async(Y)=>{let X=await Y.req.json().catch(()=>({})),Q=X.mode==="safe"||X.mode==="aggressive"||X.mode==="off"?X.mode:"off",z=await $.doctor.run(Q);return Y.json(z)}),x};var uT1=($)=>{if(!($ instanceof Error))return!1;if(("code"in $?String(Reflect.get($,"code")):"")==="EADDRINUSE")return!0;let Y=$.message;return Y.includes("EADDRINUSE")||Y.includes("address already in use")||Y.includes("in use")};import{chmodSync as Dr0}from"fs";var qr0=["started","connected","disconnected","auth-failed","stopped","error"],$F6=c.object({event_id:c.string(),type:c.string(),connector_id:c.string().nullable(),channel_id:c.string().nullable(),payload:c.string()}),xF6=c.object({event_id:c.string(),type:c.string(),connector_id:c.string().nullable(),channel_id:c.string().nullable(),outcome:c.string(),payload:c.string()}),ET1=c.object({type:c.string(),connector_id:c.string().nullable(),channel_id:c.string().nullable(),status:c.enum(qr0),detail:c.string()});class vC{}var Br0=262144;class jC extends vC{raw;processed;connection;now;logger;constructor($){super();this.now=$.now??(()=>Date.now()),this.logger=$.logger;let x=$.maxAgeMs!==void 0?{maxAgeMs:$.maxAgeMs}:{},Y={now:this.now,...x,...$.maxRows!==void 0?{maxRows:$.maxRows}:{}},X=$.rawMaxRows??$.maxRows,Q={now:this.now,...x,...X!==void 0?{maxRows:X}:{}};this.raw=new KX({path:$.rawPath,indexes:["event_id","connector_id","channel_id"],extractIndexes:(z)=>({event_id:z.event_id,connector_id:z.connector_id,channel_id:z.channel_id}),...Q}),this.processed=new KX({path:$.processedPath,indexes:["event_id","connector_id","channel_id","outcome"],extractIndexes:(z)=>({event_id:z.event_id,connector_id:z.connector_id,channel_id:z.channel_id,outcome:z.outcome}),...Y}),this.connection=new KX({path:$.connectionPath,indexes:["connector_id","channel_id","status"],extractIndexes:(z)=>({connector_id:z.connector_id,channel_id:z.channel_id,status:z.status}),...Y}),FC($.rawPath),FC($.processedPath),FC($.connectionPath),Object.freeze(this)}recordRaw($){let x={event_id:$.eventId,type:$.type,connector_id:$.connectorId,channel_id:$.channelId,payload:Lr0($.payload,$.type)};this.report("raw",this.raw.insert({ts:this.now(),event:x}))}recordProcessed($){let x={event_id:$.eventId,type:$.type,connector_id:$.connectorId,channel_id:$.channelId,outcome:$.outcome,payload:$.payload};this.report("processed",this.processed.insert({ts:this.now(),event:x}))}recordConnection($){let x={type:$.type,connector_id:$.connectorId,channel_id:$.channelId,status:$.status,detail:$.detail};this.report("connection",this.connection.insert({ts:this.now(),event:x}))}report($,x){if(x instanceof Error)this.logger?.error("diagnostic log insert failed",{table:$,error:x.message})}queryRaw($){return this.raw.query({...$.type!==void 0?{type:$.type}:{},...$.limit!==void 0?{limit:$.limit}:{},where:LC($),order:"desc"}).map((Y)=>({seq:Y.seq,ts:Y.ts,eventId:Y.event.event_id,type:Y.event.type,connectorId:Y.event.connector_id,channelId:Y.event.channel_id,payload:Y.event.payload}))}queryProcessed($){let x=LC($);if($.outcome!==void 0)x.outcome=$.outcome;return this.processed.query({...$.type!==void 0?{type:$.type}:{},...$.limit!==void 0?{limit:$.limit}:{},where:x,order:"desc"}).map((X)=>({seq:X.seq,ts:X.ts,eventId:X.event.event_id,type:X.event.type,connectorId:X.event.connector_id,channelId:X.event.channel_id,outcome:X.event.outcome,payload:X.event.payload}))}queryConnection($){let x=LC($);if($.status!==void 0)x.status=$.status;return this.connection.query({...$.type!==void 0?{type:$.type}:{},...$.limit!==void 0?{limit:$.limit}:{},where:x,order:"desc"}).map((X)=>({seq:X.seq,ts:X.ts,type:X.event.type,connectorId:X.event.connector_id,channelId:X.event.channel_id,status:Fr0(X.event.status),detail:X.event.detail}))}clear(){this.raw.clear(),this.processed.clear(),this.connection.clear()}close(){this.raw.close(),this.processed.close(),this.connection.close()}}var FC=($)=>{if($===":memory:")return;for(let x of["","-wal","-shm"])try{Dr0(`${$}${x}`,384)}catch{}},LC=($)=>{let x={};if($.connectorId!==void 0)x.connector_id=$.connectorId;if($.channelId!==void 0)x.channel_id=$.channelId;return x},vr0=ET1.shape.status,Fr0=($)=>{let x=vr0.safeParse($);return x.success?x.data:"error"},Lr0=($,x)=>{let Y=Buffer.byteLength($,"utf8");if(Y<=Br0)return $;return JSON.stringify({...Nr0($),_funnel_oversized:Y,_funnel_type:x})},jr0=["type","subtype","ts","channel","channel_type","user","bot_id"],Nr0=($)=>{try{let x=JSON.parse($);if(typeof x!=="object"||x===null)return{};let Y=x,X={};for(let Q of jr0)if(Y[Q]!==void 0)X[Q]=Y[Q];return X}catch{return{}}};var Or0=5000,fr0=50000,br0=604800000,NC=r7(),cr0=process.env.FUNNEL_HOST||"127.0.0.1",lW=iB(),Uv=wv(lW,"gateway.pid");process.title=`funnel-gateway[${lW}]`;var iW=new BC,Rr0=new X8;yT1(lW,{recursive:!0});if(Pr0(Uv)){let $=Number(Ir0(Uv,"utf-8").trim());if($>0&&Rr0.isAlive($))iW.error("funnel gateway already running",{pid:$}),process.exit(1)}_r0(Uv,String(process.pid));process.on("exit",()=>{try{Mr0(Uv)}catch{}});var Hv=Tx();yT1(Hv,{recursive:!0});var mT1=new jC({rawPath:wv(Hv,"connector-raw.db"),processedPath:wv(Hv,"connector-processed.db"),connectionPath:wv(Hv,"connector-connection.db"),rawMaxRows:Or0,maxRows:fr0,maxAgeMs:br0,logger:iW});process.on("exit",()=>{try{mT1.close()}catch{}});var Gv=new Wv({logger:iW,diagnosticLog:mT1,dir:lW,connectors:GA1()}),hT1=Gv.gatewayToken.ensure(),kr0=ST1({diagnostics:Gv.diagnostics,doctor:Gv.doctor,token:hT1}),gT1=Gv.gatewayServer({port:NC,hostname:cr0,extraRoutes:kr0,token:hT1});try{await gT1.start()}catch($){if(uT1($))iW.error(`gateway port ${NC} is already in use by another funnel daemon (a different repo/scope). Set FUNNEL_PORT to a distinct port, or stop the other daemon.`,{port:NC,dir:lW});else iW.error("gateway failed to start",{error:$ instanceof Error?$.message:String($)});process.exit(1)}var CT1=!1,pT1=async($)=>{if(CT1)return;CT1=!0;try{await Promise.race([gT1.stop(),new Promise((x)=>setTimeout(x,3000))])}catch{}process.exit($)};process.on("SIGINT",()=>{pT1(130)});process.on("SIGTERM",()=>{pT1(143)});
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as Settings, c as profileConfigSchema, i as SETTINGS_VERSION, l as settingsSchema, n as ChannelDeliveryMode, o as channelConfigSchema, r as ProfileConfig, s as channelDeliveryModeSchema, t as ChannelConfig } from "./settings-schema-D1xcOqRu.js";
2
- import { n as FunnelClaude, t as FileProcessGuard } from "./file-process-guard-DOlCr4GF.js";
2
+ import { n as FunnelClaude, t as FileProcessGuard } from "./file-process-guard-C_PLxfUX.js";
3
3
  import { n as FunnelIdGenerator, t as FunnelSettingsReader } from "./settings-reader-BIFB_j2f.js";
4
4
  import { A as FunnelConnectorAdapter, B as FunnelLogger, C as StoredRawEvent, D as FunnelConnectorListener, E as connectorRawEventSchema, F as DetachOptions, I as FunnelProcessRunner, L as ProcessSnapshot, M as BaseConnectorConfig, N as baseConnectorConfigSchema, O as NotifyFn, P as AttachOptions, R as RunOptions, S as StoredProcessedEvent, T as connectorProcessedEventSchema, _ as ConnectorQuery, a as ConnectorOperation, b as ConnectorRawRecord, c as CONNECTOR_CONNECTION_STATUSES, d as ConnectorConnectionRecord, f as ConnectorConnectionStatus, g as ConnectorProcessedRecord, h as ConnectorProcessedQuery, i as ConnectorListenerDeps, j as JsonValue, k as CallInput, l as ConnectorConnectionEvent, m as ConnectorProcessedEvent, n as ConnectorBuildContext, o as ConnectorOperationContext, p as ConnectorDiagnosticLog, r as ConnectorDescriptor, s as ConnectorUpdateContext, t as ConnectorAdapterDeps, u as ConnectorConnectionQuery, v as ConnectorRawEvent, w as connectorConnectionEventSchema, x as StoredConnectionEvent, y as ConnectorRawQuery, z as RunResult } from "./connector-descriptor-6SXJoszo.js";
5
5
  import { n as FunnelFileSystem, t as FileStat } from "./file-system-o51IsM0W.js";
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { t as FunnelLogger } from "./logger-B6iyNbxM.js";
5
5
  import { n as FunnelProcessRunner, t as NodeFunnelProcessRunner } from "./node-process-runner-DxTvycoK.js";
6
6
  import { n as FunnelIdGenerator, t as FunnelSettingsReader } from "./settings-reader-CtQ-Ix8_.js";
7
7
  import { a as resolveFunnelDir, c as channelConfigSchema, d as settingsSchema, f as baseConnectorConfigSchema, i as SETTINGS_PATH, l as channelDeliveryModeSchema, n as FUNNEL_DIR, o as resolveFunnelPort, p as NodeFunnelIdGenerator, r as FunnelSettingsStore, s as SETTINGS_VERSION, t as DEFAULT_GATEWAY_PORT, u as profileConfigSchema } from "./settings-store-CUKSeTXC.js";
8
- import { a as FunnelMcp, o as FileProcessGuard, s as FunnelClaude, t as renderYaml } from "./yaml-render-qW34NlYz.js";
8
+ import { a as FunnelMcp, o as FileProcessGuard, s as FunnelClaude, t as renderYaml } from "./yaml-render-93pX7EF7.js";
9
9
  import { a as toDiagnosticEvent, i as toDiagnosticConnectionError, n as previewOf, r as queryRows, t as FunnelDiagnostics } from "./funnel-diagnostics-CSiJmPlZ.js";
10
10
  import { t as ConnectorDiagnosticSqlReader } from "./diagnostic-sql-reader-C9zR-Csp.js";
11
11
  import { t as FunnelDoctor } from "./funnel-doctor-DiJCjHsg.js";
@@ -1026,7 +1026,8 @@ var Funnel = class Funnel {
1026
1026
  dir
1027
1027
  }),
1028
1028
  process,
1029
- logger: this.logger
1029
+ logger: this.logger,
1030
+ dir
1030
1031
  });
1031
1032
  this.diagnostics = new FunnelDiagnostics({
1032
1033
  gateway: this.gateway,
@@ -21,6 +21,7 @@ var FunnelClaude = class {
21
21
  process;
22
22
  idGenerator;
23
23
  logger;
24
+ dir;
24
25
  constructor(deps) {
25
26
  this.channels = deps.channels;
26
27
  this.mcp = deps.mcp;
@@ -30,6 +31,7 @@ var FunnelClaude = class {
30
31
  this.process = deps.process ?? defaultProcess$1;
31
32
  this.idGenerator = deps.idGenerator ?? defaultIdGenerator;
32
33
  this.logger = deps.logger;
34
+ this.dir = deps.dir;
33
35
  Object.freeze(this);
34
36
  }
35
37
  async launch(options) {
@@ -115,6 +117,7 @@ var FunnelClaude = class {
115
117
  for (const [key, value] of Object.entries(globalThis.process.env)) if (typeof value === "string") env[key] = value;
116
118
  env.FUNNEL_CHANNEL_ID = channelId;
117
119
  env.FUNNEL_PORT = String(resolveFunnelPort());
120
+ if (this.dir !== void 0) env.FUNNEL_DIR = this.dir;
118
121
  return env;
119
122
  }
120
123
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interactive-inc/claude-funnel",
3
- "version": "0.60.0",
3
+ "version": "0.60.1",
4
4
  "description": "Hub CLI that routes external events (Slack / GitHub / Discord) to Claude Code agents through subscription channels over MCP.",
5
5
  "keywords": [
6
6
  "bun",