@task-handoff/control-plane 0.0.24 → 0.0.25-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/cli.js +99 -6
  2. package/node_modules/node-pty/LICENSE +69 -0
  3. package/node_modules/node-pty/lib/conpty_console_list_agent.js +16 -0
  4. package/node_modules/node-pty/lib/conpty_console_list_agent.js.map +1 -0
  5. package/node_modules/node-pty/lib/eventEmitter2.js +47 -0
  6. package/node_modules/node-pty/lib/eventEmitter2.js.map +1 -0
  7. package/node_modules/node-pty/lib/eventEmitter2.test.js +30 -0
  8. package/node_modules/node-pty/lib/eventEmitter2.test.js.map +1 -0
  9. package/node_modules/node-pty/lib/index.js +52 -0
  10. package/node_modules/node-pty/lib/index.js.map +1 -0
  11. package/node_modules/node-pty/lib/interfaces.js +7 -0
  12. package/node_modules/node-pty/lib/interfaces.js.map +1 -0
  13. package/node_modules/node-pty/lib/shared/conout.js +11 -0
  14. package/node_modules/node-pty/lib/shared/conout.js.map +1 -0
  15. package/node_modules/node-pty/lib/terminal.js +190 -0
  16. package/node_modules/node-pty/lib/terminal.js.map +1 -0
  17. package/node_modules/node-pty/lib/terminal.test.js +139 -0
  18. package/node_modules/node-pty/lib/terminal.test.js.map +1 -0
  19. package/node_modules/node-pty/lib/testUtils.test.js +28 -0
  20. package/node_modules/node-pty/lib/testUtils.test.js.map +1 -0
  21. package/node_modules/node-pty/lib/types.js +7 -0
  22. package/node_modules/node-pty/lib/types.js.map +1 -0
  23. package/node_modules/node-pty/lib/unixTerminal.js +346 -0
  24. package/node_modules/node-pty/lib/unixTerminal.js.map +1 -0
  25. package/node_modules/node-pty/lib/unixTerminal.test.js +351 -0
  26. package/node_modules/node-pty/lib/unixTerminal.test.js.map +1 -0
  27. package/node_modules/node-pty/lib/utils.js +39 -0
  28. package/node_modules/node-pty/lib/utils.js.map +1 -0
  29. package/node_modules/node-pty/lib/windowsConoutConnection.js +125 -0
  30. package/node_modules/node-pty/lib/windowsConoutConnection.js.map +1 -0
  31. package/node_modules/node-pty/lib/windowsPtyAgent.js +320 -0
  32. package/node_modules/node-pty/lib/windowsPtyAgent.js.map +1 -0
  33. package/node_modules/node-pty/lib/windowsPtyAgent.test.js +90 -0
  34. package/node_modules/node-pty/lib/windowsPtyAgent.test.js.map +1 -0
  35. package/node_modules/node-pty/lib/windowsTerminal.js +199 -0
  36. package/node_modules/node-pty/lib/windowsTerminal.js.map +1 -0
  37. package/node_modules/node-pty/lib/windowsTerminal.test.js +219 -0
  38. package/node_modules/node-pty/lib/windowsTerminal.test.js.map +1 -0
  39. package/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  40. package/node_modules/node-pty/lib/worker/conoutSocketWorker.js.map +1 -0
  41. package/node_modules/node-pty/package.json +6 -0
  42. package/node_modules/node-pty/prebuilds/linux-arm64/pty.node +0 -0
  43. package/node_modules/node-pty/prebuilds/linux-x64/pty.node +0 -0
  44. package/package.json +6 -1
  45. package/ui/assets/{CodeBlockNode-DY4RuKD4.js → CodeBlockNode-CG3dYgrP.js} +1 -1
  46. package/ui/assets/{Tooltip-CQWQMSty.js → Tooltip-DMtaWPLO.js} +1 -1
  47. package/ui/assets/{abnfDiagram-VRR7QNED-DsfMcG6-.js → abnfDiagram-VRR7QNED-nhaqXJr5.js} +1 -1
  48. package/ui/assets/{arc-k6AxxGV3.js → arc-oB4-dhzC.js} +1 -1
  49. package/ui/assets/{architectureDiagram-ZJ3FMSHR-DtCd-0it.js → architectureDiagram-ZJ3FMSHR-BlCG68Pc.js} +1 -1
  50. package/ui/assets/{blockDiagram-677ZJIJ3-DwFbsl1F.js → blockDiagram-677ZJIJ3-C6h5WVvb.js} +1 -1
  51. package/ui/assets/{c4Diagram-LMCZKHZV-Q7KwsE1i.js → c4Diagram-LMCZKHZV-CcaXeps8.js} +1 -1
  52. package/ui/assets/channel-B8gf36w6.js +1 -0
  53. package/ui/assets/{chunk-2Q5K7J3B-BlNPHZvI.js → chunk-2Q5K7J3B-B5uXvc8d.js} +1 -1
  54. package/ui/assets/{chunk-32BRIVSS-BogzcefY.js → chunk-32BRIVSS-CCwTZovx.js} +1 -1
  55. package/ui/assets/{chunk-5VM5RSS4-BpCoLE8U.js → chunk-5VM5RSS4-BqKVfYWg.js} +1 -1
  56. package/ui/assets/{chunk-EX3LRPZG-B7CEHCwp.js → chunk-EX3LRPZG-C4rEd-82.js} +1 -1
  57. package/ui/assets/{chunk-JWPE2WC7-C3LxaCpa.js → chunk-JWPE2WC7-CuqZtFOR.js} +1 -1
  58. package/ui/assets/{chunk-MOJQB5TN-fNfBjZ88.js → chunk-MOJQB5TN-HJJJDlk6.js} +1 -1
  59. package/ui/assets/{chunk-RYQCIY6F-BDHDkvfA.js → chunk-RYQCIY6F-BhByCRmK.js} +1 -1
  60. package/ui/assets/{chunk-V7JOEXUC-C-LhPcLt.js → chunk-V7JOEXUC-HhkDGqHU.js} +1 -1
  61. package/ui/assets/{chunk-VR4S4FIN-BuAbUrtK.js → chunk-VR4S4FIN-OXy0zDCf.js} +1 -1
  62. package/ui/assets/{chunk-XXDRQBXY-D3PRa5B7.js → chunk-XXDRQBXY-TgHAZcAJ.js} +1 -1
  63. package/ui/assets/classDiagram-OUVF2IWQ-DDBQEAQb.js +1 -0
  64. package/ui/assets/classDiagram-v2-EOCWNBFH-DDBQEAQb.js +1 -0
  65. package/ui/assets/{cose-bilkent-JH36ORCC-DUKcfBjW.js → cose-bilkent-JH36ORCC-rt9QGSKr.js} +1 -1
  66. package/ui/assets/{cynefin-VYW2F7L2-DS7sNVvJ.js → cynefin-VYW2F7L2-ombeFg9o.js} +1 -1
  67. package/ui/assets/{cynefinDiagram-TSTJHNR4-BKHz03PH.js → cynefinDiagram-TSTJHNR4-B4iviSrX.js} +1 -1
  68. package/ui/assets/{dagre-VKFMJZFB-B5Vo1J4x.js → dagre-VKFMJZFB-CHSibGDJ.js} +1 -1
  69. package/ui/assets/{diagram-FQU43EPY-pLfSZUMG.js → diagram-FQU43EPY-BQGT2sPQ.js} +1 -1
  70. package/ui/assets/{diagram-G47NLZAW-xRcBdl0S.js → diagram-G47NLZAW-uQpV-Uwj.js} +1 -1
  71. package/ui/assets/{diagram-NH7WQ7WH-auUKIxtw.js → diagram-NH7WQ7WH-9chnS9pT.js} +1 -1
  72. package/ui/assets/{diagram-OA4YK3LP-C2ZLZfzq.js → diagram-OA4YK3LP-BJGrJsXo.js} +1 -1
  73. package/ui/assets/{diagram-WEI45ONY-DTYJe54C.js → diagram-WEI45ONY-CHjbZZwO.js} +1 -1
  74. package/ui/assets/{ebnfDiagram-CCIWWBDH-DK-aiw-r.js → ebnfDiagram-CCIWWBDH-l-adjY5b.js} +1 -1
  75. package/ui/assets/{erDiagram-Q63AITRT-D7YiZHII.js → erDiagram-Q63AITRT-DsaO7__D.js} +1 -1
  76. package/ui/assets/{flowDiagram-23GEKE2U-Bh8JTTh7.js → flowDiagram-23GEKE2U-MHXxyDEC.js} +1 -1
  77. package/ui/assets/{ganttDiagram-NO4QXBWP-z7Hcmezw.js → ganttDiagram-NO4QXBWP-4IbyyukS.js} +1 -1
  78. package/ui/assets/{gitGraphDiagram-IHSO6WYX-BRfit4vx.js → gitGraphDiagram-IHSO6WYX-CxikMKnI.js} +1 -1
  79. package/ui/assets/index-Dv7n3hRG.js +628 -0
  80. package/ui/assets/index-OSJfFR6q.css +1 -0
  81. package/ui/assets/{index10-2BsMptqF.js → index10-Q57GrecV.js} +1 -1
  82. package/ui/assets/{index11-DWamaI7a.js → index11-DD3nljPI.js} +1 -1
  83. package/ui/assets/{index5-Cg2pg0wT.js → index5-CIE43ma6.js} +1 -1
  84. package/ui/assets/{index6-CrFzuB2l.js → index6-gaFQxXMd.js} +1 -1
  85. package/ui/assets/{index7-ZsDuAsHr.js → index7-DJYIWNBW.js} +1 -1
  86. package/ui/assets/{index8-lgbsVfnN.js → index8-C5edV2Kd.js} +1 -1
  87. package/ui/assets/{infoDiagram-FWYZ7A6U-Di397Dzo.js → infoDiagram-FWYZ7A6U-CC0sa-Uh.js} +1 -1
  88. package/ui/assets/{ishikawaDiagram-FXEZZL3T-CsWhktkq.js → ishikawaDiagram-FXEZZL3T-BvEeVT2q.js} +1 -1
  89. package/ui/assets/{journeyDiagram-5HDEW3XC-C80Dem7i.js → journeyDiagram-5HDEW3XC-CIRjJowL.js} +1 -1
  90. package/ui/assets/{kanban-definition-HUTT4EX6-Cby688oD.js → kanban-definition-HUTT4EX6-CHvh4W_n.js} +1 -1
  91. package/ui/assets/{linear-DObmYJ4x.js → linear-BLvZIbXH.js} +1 -1
  92. package/ui/assets/{mermaid.core-D2zMmnq8.js → mermaid.core-C-XYcy9v.js} +4 -4
  93. package/ui/assets/{mhchem-CtUCkxPH.js → mhchem-DeTRvuGS.js} +1 -1
  94. package/ui/assets/{mindmap-definition-LN4V7U3C-Bu95TtSl.js → mindmap-definition-LN4V7U3C-BMmOEyHa.js} +1 -1
  95. package/ui/assets/{pegDiagram-2B236MQR-ChroY30p.js → pegDiagram-2B236MQR-C4miWiBe.js} +1 -1
  96. package/ui/assets/{pieDiagram-ENE6RG2P-BkSEl4GA.js → pieDiagram-ENE6RG2P-DhcLc3pw.js} +1 -1
  97. package/ui/assets/{quadrantDiagram-ABIIQ3AL-COn0Gvzf.js → quadrantDiagram-ABIIQ3AL-C6LkNGXB.js} +1 -1
  98. package/ui/assets/{railroadDiagram-RFXS5EU6-D9eRINIo.js → railroadDiagram-RFXS5EU6-BBfsNbJW.js} +1 -1
  99. package/ui/assets/{requirementDiagram-TGXJPOKE-BkO1q-cS.js → requirementDiagram-TGXJPOKE-csIPs_u_.js} +1 -1
  100. package/ui/assets/{sankeyDiagram-HTMAVEWB-BMvH4kir.js → sankeyDiagram-HTMAVEWB-DU8QC8Ca.js} +1 -1
  101. package/ui/assets/{sequenceDiagram-DBY2YBRQ-Dv1iencU.js → sequenceDiagram-DBY2YBRQ-Ba62Xdrj.js} +1 -1
  102. package/ui/assets/{sizeCapture-X5ZJPWSS-DOu32U63.js → sizeCapture-X5ZJPWSS-DqfXQuEd.js} +1 -1
  103. package/ui/assets/{stateDiagram-2N3HPSRC-DJroyIih.js → stateDiagram-2N3HPSRC-CsxjZylI.js} +1 -1
  104. package/ui/assets/stateDiagram-v2-6OUMAXLB-DwBBLlna.js +1 -0
  105. package/ui/assets/{swimlanes-5IMT3BWC-B6gy0VTN.js → swimlanes-5IMT3BWC-DbgLiO9W.js} +2 -2
  106. package/ui/assets/swimlanesDiagram-G3AALYLV-e-NMCvt8.js +8 -0
  107. package/ui/assets/{timeline-definition-FHXFAJF6-kqd66ccr.js → timeline-definition-FHXFAJF6-ljen9wnG.js} +1 -1
  108. package/ui/assets/{vennDiagram-L72KCM5P-CYKI69pR.js → vennDiagram-L72KCM5P-Cmx0uN0h.js} +1 -1
  109. package/ui/assets/{wardleyDiagram-EHGQE667-DcqLCmfb.js → wardleyDiagram-EHGQE667-CKJbrww3.js} +1 -1
  110. package/ui/assets/{xychartDiagram-FW5EYKEG-CX_-HrQi.js → xychartDiagram-FW5EYKEG-B6mqNi8J.js} +1 -1
  111. package/ui/index.html +2 -2
  112. package/ui/assets/channel-CN2sdAcY.js +0 -1
  113. package/ui/assets/classDiagram-OUVF2IWQ-DReNwvu_.js +0 -1
  114. package/ui/assets/classDiagram-v2-EOCWNBFH-DReNwvu_.js +0 -1
  115. package/ui/assets/index-DfD2y4As.css +0 -1
  116. package/ui/assets/index-n9YL0zlA.js +0 -624
  117. package/ui/assets/stateDiagram-v2-6OUMAXLB-DhawZ7jm.js +0 -1
  118. package/ui/assets/swimlanesDiagram-G3AALYLV-abthrBgs.js +0 -8
package/dist/cli.js CHANGED
@@ -1,6 +1,7 @@
1
- "use strict";var e=require("commander"),t=require("node:path"),n=require("node:fs"),i=require("node:crypto"),s=require("fastify"),r=require("@fastify/cookie"),o=require("@fastify/websocket"),a=require("zod"),d=require("node:util"),c=require("write-file-atomic"),l=require("ws"),p=require("node:http"),u=require("node:net"),g=require("node:stream"),h=require("telegramify-markdown"),m=require("node:fs/promises"),y=require("node:os"),f=require("dingtalk-stream"),I=require("@larksuiteoapi/node-sdk"),b=require("node:child_process"),v=require("tar"),w=require("tweetnacl");function S(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,i.get?i:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var A=S(v);function z(e,t){try{const i=JSON.parse(n.readFileSync(e,"utf8"));if(t&&i.name!==t)return;return"string"==typeof i.version&&i.version.trim()?i.version.trim():void 0}catch{return}}function k(e){if(e)try{return t.dirname(n.realpathSync(e))}catch{return}}function T(e,n=process.env,i=e){const s=n.TASK_HANDOFF_VERSION?.trim();if(s)return s;const r=i.split("/").at(-1),o=process.argv[1]?t.resolve(process.argv[1]):void 0,a=o?t.dirname(o):void 0,d=[k(o),a,process.cwd()].filter(e=>Boolean(e));for(const n of new Set(d)){let i=n;for(;;){const n=z(t.join(i,"package.json"),e);if(n)return n;const s=t.dirname(i);if(s===i)break;i=s}}let c;for(const e of new Set(d)){let n=e;for(;;){if(r){const e=z(t.join(n,"packages",r,"package.json"),i);if(e)return e}c||=z(t.join(n,"package.json"));const e=t.dirname(n);if(e===n)break;n=e}}return c||"unknown"}const E=20971520,C=512e3,x=41943040,N="ai-session.snapshot",O="ai-session.patch",_="ai-session.removed",R="ai-session.message-delta",P="ai-session.timeline-item",j="ai-session.unread.updated",D=a.z.string().trim().min(1).max(80),M=a.z.enum(["app-session","ai-session"]),L=a.z.enum(["running","waiting","idle","failed"]),q=a.z.object({instanceId:a.z.string().trim().min(1).max(160),sessionId:a.z.string().trim().min(1).max(120),unread:a.z.boolean(),sessionUpdatedAt:a.z.string().datetime(),updatedAt:a.z.string().datetime()}).strict(),$=a.z.enum(["thinking","tool","editing","approval","responding","unknown"]),B=a.z.object({id:a.z.string().trim().min(1).max(240).optional(),kind:a.z.string().trim().min(1).max(80).optional(),name:a.z.string().trim().min(1).max(120),inputPreview:a.z.string().trim().max(500).optional(),startedAt:a.z.string().datetime().optional()}).strict(),U=a.z.enum(["running","completed","failed","waiting"]),F=a.z.object({id:a.z.string().trim().min(1).max(240),turnId:a.z.string().trim().min(1).max(240)}).strict(),H=F.extend({type:a.z.literal("user-message"),text:a.z.string()}).strict(),W=F.extend({type:a.z.literal("ai-message"),text:a.z.string()}).strict(),G=F.extend({type:a.z.literal("activity"),activityKind:a.z.string().trim().min(1).max(120),title:a.z.string().trim().min(1).max(240),status:U.optional(),summary:a.z.string().max(4e3).optional(),input:a.z.string().max(1e5).optional(),output:a.z.string().max(1e6).optional(),paths:a.z.array(a.z.string().trim().min(1).max(4096)).max(500).optional(),exitCode:a.z.number().int().optional(),durationMs:a.z.number().int().nonnegative().optional()}).strict(),V=a.z.discriminatedUnion("type",[H,W,G]),K=a.z.object({sessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().min(1).max(240),items:a.z.array(V),generatedAt:a.z.string().datetime()}).strict(),J=a.z.object({sessionId:a.z.string().trim().min(1).max(120),turnId:a.z.string().trim().min(1).max(240),items:a.z.array(V),generatedAt:a.z.string().datetime()}).strict(),Y=a.z.enum(["pending-init","running","interrupted","completed","errored","shutdown","not-found"]),Q=a.z.enum(["started","interacted","interrupted"]),X=a.z.object({threadId:a.z.string().trim().min(1).max(240),path:a.z.string().trim().max(4096).optional(),status:Y,activity:Q.optional(),message:a.z.string().trim().max(1e3).optional(),updatedAt:a.z.string().datetime()}).strict(),Z=a.z.object({toolCalls:a.z.number().int().min(0).default(0),edits:a.z.number().int().min(0).default(0),approvals:a.z.number().int().min(0).default(0)}).strict().default({toolCalls:0,edits:0,approvals:0}),ee=a.z.object({send:a.z.boolean().optional(),interrupt:a.z.boolean().optional(),approval:a.z.boolean().optional(),fork:a.z.boolean().optional(),openApp:a.z.boolean().optional(),close:a.z.boolean().optional()}).strict(),te=a.z.object({kind:a.z.literal("fork"),parentProviderSessionId:a.z.string().trim().min(1).max(240),throughTurnId:a.z.string().trim().min(1).max(240).optional()}).strict(),ne=a.z.enum(["image","file"]),ie=a.z.object({id:a.z.string().trim().min(1).max(120),kind:ne,name:a.z.string().trim().min(1).max(240),mime:a.z.string().trim().min(1).max(120),size:a.z.number().int().min(0).max(Number.MAX_SAFE_INTEGER)}),se=a.z.union([ie.extend({source:a.z.object({type:a.z.literal("inline"),encoding:a.z.literal("base64"),data:a.z.string().min(1).max(31457280)}).strict()}).strict().superRefine((e,t)=>{const n="image"===e.kind?E:C;(e.size<=0||("file"===e.kind?e.size>=n:e.size>n))&&t.addIssue({code:a.z.ZodIssueCode.custom,path:["size"],message:`Inline ${e.kind} must be between 1 byte and ${n} bytes.`})}),ie.extend({source:a.z.object({type:a.z.literal("runtime-path"),path:a.z.string().trim().min(1).max(4096)}).strict()}).strict()]),re=ie.extend({sourceType:a.z.enum(["inline","runtime-path"])}).strict(),oe=a.z.union([a.z.object({id:a.z.string().trim().min(1).max(120),kind:ne.optional(),source:a.z.object({type:a.z.literal("upload-ref")}).strict().default({type:"upload-ref"})}).strict(),a.z.object({id:a.z.string().trim().min(1).max(120),kind:ne,name:a.z.string().trim().min(1).max(240),mime:a.z.string().trim().min(1).max(120),size:a.z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),source:a.z.object({type:a.z.literal("runtime-path"),path:a.z.string().trim().min(1).max(4096)}).strict()}).strict()]),ae=a.z.enum(["auto","queue","steer","immediate"]),de=a.z.enum(["ask","auto-review","full-access"]),ce=a.z.enum(["review","rename","goal","compact"]),le=a.z.object({command:ce,argument:a.z.string().trim().max(4e3).optional()}).strict().superRefine((e,t)=>{"rename"!==e.command||e.argument||t.addIssue({code:"custom",path:["argument"],message:"Rename requires a thread name."}),"review"!==e.command&&"compact"!==e.command||!e.argument||t.addIssue({code:"custom",path:["argument"],message:`${e.command} does not accept an argument.`})}),pe=a.z.object({command:ce,value:a.z.string().max(4e3).optional(),turnId:a.z.string().trim().min(1).max(240).optional()}).strict();a.z.enum(["skill","app","plugin"]);const ue=a.z.object({name:a.z.string().trim().min(1).max(240),path:a.z.string().trim().min(1).max(4096)}),ge=a.z.discriminatedUnion("kind",[ue.extend({kind:a.z.literal("skill"),path:a.z.string().trim().min(1).max(4096).refine(e=>e.startsWith("/"),"Skill paths must be absolute.")}).strict(),ue.extend({kind:a.z.literal("app"),path:a.z.string().trim().min(7).max(4096).regex(/^app:\/\/[^\s/]+$/,"App paths must use app://<id>.")}).strict(),ue.extend({kind:a.z.literal("plugin"),path:a.z.string().trim().min(10).max(4096).regex(/^plugin:\/\/[^\s/]+$/,"Plugin paths must use plugin://<id>.")}).strict()]),he=a.z.array(ge).max(20).default([]),me=a.z.enum(["plugin","skill","file","directory","app"]),ye=a.z.object({kind:me,name:a.z.string().trim().min(1).max(240),description:a.z.string().trim().max(1e3).optional(),path:a.z.string().trim().min(1).max(4096),icon:a.z.string().trim().max(4096).optional()}).strict().superRefine((e,t)=>{"skill"!==e.kind||e.path.startsWith("/")||t.addIssue({code:"custom",path:["path"],message:"Skill paths must be absolute."}),"app"!==e.kind||/^app:\/\/[^\s/]+$/.test(e.path)||t.addIssue({code:"custom",path:["path"],message:"App paths must use app://<id>."}),"plugin"!==e.kind||/^plugin:\/\/[^\s/]+$/.test(e.path)||t.addIssue({code:"custom",path:["path"],message:"Plugin paths must use plugin://<id>."}),"file"!==e.kind&&"directory"!==e.kind||!e.path.startsWith("/")&&!e.path.split(/[\\/]+/).includes("..")||t.addIssue({code:"custom",path:["path"],message:"File and directory paths must be relative to the session cwd."})}),fe=a.z.object({category:a.z.enum(["skills","plugins","apps","files"]),code:a.z.string().trim().min(1).max(160),message:a.z.string().trim().min(1).max(2e3)}).strict(),Ie=a.z.object({sessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().min(1).max(240),cwd:a.z.string().trim().min(1).max(4096),candidates:a.z.array(ye).max(1e3).default([]),diagnostics:a.z.array(fe).max(20).default([])}).strict(),be=a.z.object({query:a.z.string().trim().max(240).default("")}).strict(),ve=a.z.object({sessionId:a.z.string().trim().min(1).max(120),cwd:a.z.string().trim().min(1).max(4096),query:a.z.string().trim().max(240),requestId:a.z.string().trim().min(1).max(160),candidates:a.z.array(ye.refine(e=>"file"===e.kind||"directory"===e.kind,"File search only returns files and directories.")).max(200).default([]),complete:a.z.boolean().default(!1)}).strict(),we=a.z.object({message:a.z.string().trim().min(1).max(2e4),mode:ae.optional(),permissionMode:de.optional()}),Se=we.extend({attachments:a.z.array(se).max(6).default([]),references:he}).strict().superRefine((e,t)=>{e.attachments.reduce((e,t)=>e+("inline"===t.source.type?t.size:0),0)>x&&t.addIssue({code:a.z.ZodIssueCode.custom,path:["attachments"],message:"Inline attachments must be 41943040 bytes or less in total."})}),Ae=we.extend({attachments:a.z.array(oe).max(6).default([]),references:he}).strict(),ze=a.z.object({type:a.z.literal("runtime-path"),path:a.z.string().trim().min(1).max(4096).refine(e=>e.startsWith("/")||/^[A-Za-z]:[\\/]/.test(e),"Runtime paths must be absolute in the target controlled instance.")}).strict(),ke=Se.extend({agent:D,cwd:ze,cwdFolderId:a.z.string().trim().min(1).max(120).optional(),clientRequestId:a.z.string().trim().min(1).max(160)}).strict(),Te=a.z.object({mode:a.z.enum(["current-folder","worktree"]),branch:a.z.string().trim().min(1).max(1024)}).strict(),Ee=Ae.extend({agent:D,cwdFolderId:a.z.string().trim().min(1).max(120).optional(),gitSelection:Te.optional(),clientRequestId:a.z.string().trim().min(1).max(160)}).strict(),Ce=a.z.object({disposition:a.z.enum(["created","already-created"]),aiSessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().min(1).max(240),creationSource:a.z.literal("ai-session")}).strict(),xe=a.z.object({mode:a.z.enum(["current","managed-worktree"]).default("current")}).strict().default({mode:"current"}),Ne=a.z.object({clientRequestId:a.z.string().trim().min(1).max(160),throughTurnId:a.z.string().trim().min(1).max(240).optional(),workspace:xe.optional().default({mode:"current"})}).strict(),Oe=a.z.object({disposition:a.z.enum(["created","already-created"]),aiSessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().min(1).max(240),creationSource:a.z.literal("ai-session")}).strict(),_e=a.z.object({clientRequestId:a.z.string().trim().min(1).max(160)}).strict(),Re=a.z.object({disposition:a.z.enum(["opened","already-open"]),aiSessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().min(1).max(240),appSessionId:a.z.string().trim().min(1).max(120),creationSource:M}).strict(),Pe=a.z.object({clientRequestId:a.z.string().trim().min(1).max(160)}).strict(),je=a.z.object({disposition:a.z.enum(["closed","already-closed"]),aiSessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().min(1).max(240),creationSource:M}).strict();a.z.object({code:a.z.enum(["invalid-request","not-found","unsupported","provider-unavailable","materialization-failed","open-app-failed","close-failed","conflict"]),message:a.z.string().trim().min(1).max(4e3),retryable:a.z.boolean().default(!1),aiSessionId:a.z.string().trim().min(1).max(120).optional(),providerSessionId:a.z.string().trim().min(1).max(240).optional()}).strict();const De=a.z.object({decision:a.z.enum(["allow","deny","skip"])}).strict(),Me=a.z.object({expectedRevision:a.z.number().int().min(0),queueIds:a.z.array(a.z.string().trim().min(1).max(120)).max(100)}).strict(),Le=a.z.object({expectedRevision:a.z.number().int().min(0),message:a.z.string().trim().min(1).max(2e4)}).strict();a.z.object({code:a.z.string().trim().min(1).max(160),message:a.z.string(),instanceId:a.z.string().trim().min(1).max(160).optional(),nodeId:a.z.string().trim().min(1).max(160).optional(),route:a.z.string().trim().min(1).max(4096).optional()}).strict();const qe=a.z.object({id:a.z.string().trim().min(1).max(120),message:a.z.string().trim().min(1).max(2e4),attachments:a.z.array(re).max(6).default([]),references:he,permissionMode:de.optional(),status:a.z.enum(["queued","sending","failed"]).default("queued"),createdAt:a.z.string().datetime(),updatedAt:a.z.string().datetime(),error:a.z.string().trim().max(4e3).optional()}).strict(),$e=a.z.object({revision:a.z.number().int().min(0).default(0),pendingCount:a.z.number().int().min(0).default(0),items:a.z.array(qe).max(100).default([])}).strict().default({revision:0,pendingCount:0,items:[]}),Be=a.z.enum(["control","realtime","adapter-snapshot","transcript-tail","transcript-scan","process-scan","app-session"]),Ue=a.z.object({id:a.z.string().trim().min(1).max(240),status:a.z.enum(["running","completed"]),startedAt:a.z.string().datetime().optional(),completedAt:a.z.string().datetime().optional()}).strict(),Fe=a.z.object({id:a.z.string().trim().min(1).max(240),providerTurnId:a.z.string().trim().max(240).optional(),source:Be.optional(),userPrompt:a.z.string().trim().optional(),status:a.z.enum(["queued","running","waiting","completed","failed"]).default("running"),phase:$.optional(),summary:a.z.string().trim().max(1e3).optional(),lastMessage:a.z.string().trim().optional(),lastMessageItemId:a.z.string().trim().max(240).optional(),contextCompactions:a.z.array(Ue).max(20).optional(),revision:a.z.number().int().min(0).default(0),sourcePriority:a.z.number().int().min(0).max(100).optional(),snapshotVersion:a.z.number().int().min(0).optional(),observedAt:a.z.string().datetime().optional(),startedAt:a.z.string().datetime().optional(),updatedAt:a.z.string().datetime().optional(),completedAt:a.z.string().datetime().optional()}).strict(),He=Fe.pick({id:!0,providerTurnId:!0,userPrompt:!0,status:!0,phase:!0,summary:!0,lastMessage:!0,contextCompactions:!0,startedAt:!0,updatedAt:!0,completedAt:!0}).strict(),We=a.z.object({id:a.z.string().trim().min(1).max(120),agent:D,creationSource:M.default("app-session"),appSessionId:a.z.string().trim().max(120).optional(),appId:a.z.string().trim().max(120).optional(),providerSessionId:a.z.string().trim().max(240).optional(),lineage:te.optional(),providerMeta:a.z.record(a.z.string(),a.z.unknown()).optional(),appBindingKeys:a.z.array(a.z.string().trim().min(1).max(240)).max(20).optional(),actions:ee.optional(),activeTurnId:a.z.string().trim().max(240).optional(),title:a.z.string().trim().max(240).optional(),cwd:a.z.string().trim().max(4096).optional(),cwdFolderId:a.z.string().trim().min(1).max(120).optional(),userPrompt:a.z.string().trim().optional(),turns:a.z.array(Fe).max(50).optional(),status:L.default("running"),phase:$.default("unknown"),summary:a.z.string().trim().max(1e3).optional(),lastMessage:a.z.string().trim().optional(),lastMessageItemId:a.z.string().trim().max(240).optional(),currentTool:B.optional(),toolCallsSinceLastMessage:a.z.number().int().min(0).default(0),subAgents:a.z.array(X).max(50).default([]),transcriptPath:a.z.string().trim().max(4096).optional(),transcriptSize:a.z.number().int().min(0).optional(),startedAt:a.z.string().datetime(),updatedAt:a.z.string().datetime(),completedAt:a.z.string().datetime().optional(),error:a.z.string().trim().max(4e3).optional(),counters:Z,queue:$e}).strict(),Ge=a.z.object({session:We,provider:a.z.string().trim().min(1).max(80),action:a.z.enum(["send","queue","steer","interrupt","approval"]),decision:a.z.enum(["allow","deny","skip"]).optional(),turnId:a.z.string().trim().min(1).max(240).optional(),providerTurnId:a.z.string().trim().min(1).max(240).optional(),queueId:a.z.string().trim().min(1).max(120).optional()}).strict(),Ve=500,Ke=a.z.object({id:a.z.string().trim().min(1).max(120),agent:a.z.enum(["codex","claude"]),creationSource:M,providerSessionId:a.z.string().trim().min(1).max(240),lineage:te.optional(),title:a.z.string().trim().max(240).optional(),userPrompt:a.z.string().trim().optional(),lastMessage:a.z.string().trim().optional(),cwd:a.z.string().trim().min(1).max(4096),cwdFolderId:a.z.string().trim().min(1).max(120).optional(),lastActiveAt:a.z.string().datetime(),archivedAt:a.z.string().datetime()}).strict();a.z.object({schemaVersion:a.z.literal(1).default(1),items:a.z.array(Ke).max(Ve).default([])}).strict();const Je=a.z.object({items:a.z.array(Ke).max(Ve).default([])}).strict(),Ye=a.z.object({item:Ke,turns:a.z.array(He).max(50).default([])}).strict(),Qe=a.z.object({disposition:a.z.enum(["resumed","already-open"]),aiSessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().min(1).max(240),appSessionId:a.z.string().trim().min(1).max(120).optional(),creationSource:M}).strict(),Xe=We.pick({id:!0,agent:!0,creationSource:!0,appSessionId:!0,appId:!0,providerSessionId:!0,lineage:!0,providerMeta:!0,appBindingKeys:!0,actions:!0,activeTurnId:!0,title:!0,cwd:!0,cwdFolderId:!0,userPrompt:!0,turns:!0,status:!0,phase:!0,summary:!0,lastMessage:!0,lastMessageItemId:!0,currentTool:!0,toolCallsSinceLastMessage:!0,subAgents:!0,queue:!0,startedAt:!0,updatedAt:!0,error:!0}),Ze=a.z.object({runningCount:a.z.number().int().min(0).default(0),waitingCount:a.z.number().int().min(0).default(0),staleCount:a.z.number().int().min(0).default(0),sessions:a.z.array(Xe).default([]),updatedAt:a.z.string().datetime()}).strict(),et=a.z.object({streamId:a.z.string().trim().min(1).max(240),revision:a.z.number().int().min(0),lastEventAt:a.z.string().datetime(),snapshot:Ze}).strict(),tt=Ze.pick({runningCount:!0,waitingCount:!0,staleCount:!0,updatedAt:!0}).extend({idleCount:a.z.number().int().min(0).default(0),problemCount:a.z.number().int().min(0).default(0),revision:a.z.number().int().min(0).optional()});function nt(e,t={}){const n=e.sessions.filter(e=>"idle"===e.status).length,i=e.sessions.filter(e=>"failed"===e.status).length;return tt.parse({runningCount:e.runningCount,waitingCount:e.waitingCount,staleCount:e.staleCount,idleCount:n,problemCount:i,updatedAt:e.updatedAt,revision:t.revision})}const it=a.z.enum(["provider-event","app-session-created","app-session-updated","app-session-deleted","discovery-scan","control-action","heartbeat-sync","startup"]),st=a.z.object({streamId:a.z.string().trim().min(1).max(240),instanceId:a.z.string().trim().min(1).max(160),nodeId:a.z.string().trim().min(1).max(160).optional(),revision:a.z.number().int().min(0),previousRevision:a.z.number().int().min(0).optional(),traceId:a.z.string().trim().min(1).max(160),generatedAt:a.z.string().datetime(),reason:it}).strict(),rt=a.z.object({meta:st,snapshot:Ze}).strict(),ot=a.z.object({meta:st,upserted:a.z.array(Xe).default([]),removed:a.z.array(a.z.string().trim().min(1).max(120)).default([])}).strict(),at=a.z.object({meta:st,sessionIds:a.z.array(a.z.string().trim().min(1).max(120)).default([]),expiresAt:a.z.string().datetime()}).strict(),dt=a.z.object({instanceId:a.z.string().trim().min(1).max(160),nodeId:a.z.string().trim().min(1).max(160).optional(),sessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().min(1).max(240),turnId:a.z.string().trim().min(1).max(240),itemId:a.z.string().trim().min(1).max(240),delta:a.z.string().min(1),generatedAt:a.z.string().datetime()}).strict(),ct=a.z.object({instanceId:a.z.string().trim().min(1).max(160),nodeId:a.z.string().trim().min(1).max(160).optional(),sessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().min(1).max(240),item:V,generatedAt:a.z.string().datetime()}).strict(),lt=a.z.object({streamId:a.z.string().trim().min(1).max(240),instanceId:a.z.string().trim().min(1).max(160),sinceRevision:a.z.number().int().min(0),latestRevision:a.z.number().int().min(0),earliestRetainedRevision:a.z.number().int().min(0),syncRequired:a.z.boolean().default(!1),events:a.z.array(a.z.discriminatedUnion("type",[a.z.object({type:a.z.literal(N),payload:rt}).strict(),a.z.object({type:a.z.literal(O),payload:ot}).strict(),a.z.object({type:a.z.literal(_),payload:at}).strict()])).default([])}).strict(),pt=a.z.object({source:Be,sourcePriority:a.z.number().int().min(0).max(100).optional(),observedAt:a.z.string().datetime().optional(),snapshotVersion:a.z.number().int().min(0).optional()}).strict(),ut=pt.extend({type:a.z.literal("snapshot"),agent:a.z.string().trim().min(1).max(80),creationSource:M.optional(),appSessionId:a.z.string().trim().max(120).optional(),appId:a.z.string().trim().max(120).optional(),providerSessionId:a.z.string().trim().max(240).optional(),lineage:te.optional(),providerMeta:a.z.record(a.z.string(),a.z.unknown()).optional(),appBindingKeys:a.z.array(a.z.string().trim().min(1).max(240)).max(20).optional(),actions:ee.optional(),title:a.z.string().trim().max(240).optional(),cwd:a.z.string().trim().max(4096).optional(),cwdFolderId:a.z.string().trim().min(1).max(120).optional(),activeTurnId:a.z.string().trim().max(240).optional(),userPrompt:a.z.string().trim().optional(),turns:a.z.array(Fe).max(50).optional(),status:L.optional(),phase:$.optional(),summary:a.z.string().trim().max(1e3).optional(),lastMessage:a.z.string().trim().optional(),lastMessageItemId:a.z.string().trim().max(240).optional(),error:a.z.string().trim().max(4e3).optional(),currentTool:B.optional(),toolCallsSinceLastMessage:a.z.number().int().min(0).optional(),subAgents:a.z.array(X).max(50).optional(),transcriptPath:a.z.string().trim().max(4096).optional(),transcriptSize:a.z.number().int().min(0).optional(),replaceActivity:a.z.boolean().optional()}).strict(),gt=pt.extend({type:a.z.literal("event"),sessionId:a.z.string().trim().min(1).max(120),kind:a.z.enum(["lifecycle","send-ack","turn-started","user-message","assistant-message","approval-requested","turn-completed","session-error","tool-activity","sub-agent-activity","context-compaction"]),activeTurnId:a.z.string().trim().max(240).optional(),providerTurnId:a.z.string().trim().max(240).optional(),userPrompt:a.z.string().trim().optional(),text:a.z.string().optional(),itemId:a.z.string().trim().max(240).optional(),status:L.optional(),phase:$.optional(),summary:a.z.string().trim().max(1e3).optional(),error:a.z.string().trim().max(4e3).optional(),currentTool:B.nullable().optional(),toolCallsSinceLastMessage:a.z.number().int().min(0).optional(),subAgents:a.z.array(X).max(50).optional(),contextCompaction:Ue.optional(),counters:a.z.object({toolCalls:a.z.number().int().min(0).optional(),edits:a.z.number().int().min(0).optional(),approvals:a.z.number().int().min(0).optional()}).strict().optional()}).strict().superRefine((e,t)=>{if("session-error"!==e.kind||e.error||t.addIssue({code:"custom",path:["error"],message:"session-error events require error"}),"context-compaction"===e.kind?e.contextCompaction||t.addIssue({code:"custom",path:["contextCompaction"],message:"context-compaction events require contextCompaction"}):void 0!==e.contextCompaction&&t.addIssue({code:"custom",path:["contextCompaction"],message:"contextCompaction is only valid for context-compaction events"}),"sub-agent-activity"===e.kind?e.subAgents||t.addIssue({code:"custom",path:["subAgents"],message:"sub-agent-activity events require subAgents"}):void 0!==e.subAgents&&t.addIssue({code:"custom",path:["subAgents"],message:"subAgents is only valid for sub-agent-activity events"}),"tool-activity"!==e.kind)return void 0!==e.currentTool&&t.addIssue({code:"custom",path:["currentTool"],message:"currentTool is only valid for tool-activity events"}),void(void 0!==e.toolCallsSinceLastMessage&&t.addIssue({code:"custom",path:["toolCallsSinceLastMessage"],message:"toolCallsSinceLastMessage is only valid for tool-activity events"}));"currentTool"in e||t.addIssue({code:"custom",path:["currentTool"],message:"tool-activity events require currentTool"}),void 0===e.toolCallsSinceLastMessage&&t.addIssue({code:"custom",path:["toolCallsSinceLastMessage"],message:"tool-activity events require toolCallsSinceLastMessage"})});a.z.discriminatedUnion("type",[ut,gt]);const ht=a.z.object({type:a.z.literal("snapshot"),data:a.z.string(),pendingEscape:a.z.string(),cols:a.z.number().int().positive(),rows:a.z.number().int().positive()}).passthrough(),mt="app-session.snapshot",yt="app-session.patch",ft="app-session.removed",It=a.z.enum(["created","starting","running","stopping","stopped","exited","failed","closed","terminated","unknown"]),bt=a.z.enum(["tty","vnc","web"]);a.z.object({mode:bt,url:a.z.string().trim().min(1).max(4096),token:a.z.string().trim().min(1).max(512),expiresAt:a.z.string().datetime()}).strict(),a.z.object({revoked:a.z.boolean()}).strict();const vt=new Set(["stopped","failed","exited","closed","terminated"]),wt=a.z.object({type:a.z.enum(["app-session","provider-session","adapter-key"]),id:a.z.string().trim().min(1).max(240),agent:a.z.string().trim().min(1).max(80).optional(),adapter:a.z.string().trim().min(1).max(80).optional(),key:a.z.string().trim().min(1).max(240).optional()}).strict(),St=a.z.record(a.z.string(),a.z.unknown()).and(a.z.object({id:a.z.string().trim().min(1).max(160),appId:a.z.string().trim().min(1).max(160).optional(),title:a.z.string().trim().max(240).optional(),kind:a.z.string().trim().max(80).optional(),status:It.default("unknown"),bindings:a.z.array(wt).max(40).default([]),workspace:a.z.object({cwd:a.z.string().trim().max(4096).optional()}).strict().optional(),createdAt:a.z.string().datetime().optional(),updatedAt:a.z.string().datetime().optional()})),At=a.z.object({runningCount:a.z.number().int().min(0).default(0),problemCount:a.z.number().int().min(0).default(0),sessions:a.z.array(St).default([]),updatedAt:a.z.string().datetime()}).strict(),zt=a.z.object({streamId:a.z.string().trim().min(1).max(240),revision:a.z.number().int().min(0),lastEventAt:a.z.string().datetime(),snapshot:At}).strict();At.pick({runningCount:!0,problemCount:!0,updatedAt:!0}).extend({revision:a.z.number().int().min(0).optional()});const kt=a.z.enum(["app-session-created","app-session-updated","app-session-deleted","app-session-recovered","control-action","heartbeat-sync","startup"]),Tt=a.z.object({streamId:a.z.string().trim().min(1).max(240),instanceId:a.z.string().trim().min(1).max(160),nodeId:a.z.string().trim().min(1).max(160).optional(),revision:a.z.number().int().min(0),previousRevision:a.z.number().int().min(0).optional(),traceId:a.z.string().trim().min(1).max(160),generatedAt:a.z.string().datetime(),reason:kt}).strict(),Et=a.z.object({meta:Tt,snapshot:At}).strict(),Ct=a.z.object({meta:Tt,session:St}).strict(),xt=a.z.object({meta:Tt,sessionId:a.z.string().trim().min(1).max(160),tombstone:St.optional(),expiresAt:a.z.string().datetime().optional()}).strict(),Nt=a.z.object({streamId:a.z.string().trim().min(1).max(240),instanceId:a.z.string().trim().min(1).max(160),sinceRevision:a.z.number().int().min(0),latestRevision:a.z.number().int().min(0),earliestRetainedRevision:a.z.number().int().min(0),syncRequired:a.z.boolean().default(!1),events:a.z.array(a.z.discriminatedUnion("type",[a.z.object({type:a.z.literal(mt),payload:Et}).strict(),a.z.object({type:a.z.literal(yt),payload:Ct}).strict(),a.z.object({type:a.z.literal(ft),payload:xt}).strict()])).default([])}).strict();function Ot(e,t=(new Date).toISOString()){const n=e.map(e=>Rt(e));return At.parse({runningCount:n.filter(e=>"running"===e.status).length,problemCount:n.filter(e=>"failed"===e.status).length,sessions:n,updatedAt:t})}function _t(e,t=(new Date).toISOString()){return Ot(e.filter(e=>jt("string"==typeof e.status?e.status:void 0)),t)}function Rt(e){const t=Pt("string"==typeof e.status?e.status:void 0),n="string"==typeof e.id?e.id:"",i=function(e){const t=Bt(e.workspace),n=Bt(e.tty),i=Bt(e.launch),s=Bt(e.ai),r=Bt(s.claude),o=Ut(t.cwd)||Ut(n.cwd)||Ut(r.cwd)||Ut(i.cwd);return o?{cwd:o}:void 0}(e),{workspace:s,...r}=e;return St.parse({...r,status:t,bindings:$t([...(o=e.bindings,Array.isArray(o)?o.flatMap(e=>{const t=wt.safeParse(e);return t.success?[t.data]:[]}):[]),...n?[{type:"app-session",id:n}]:[],...Lt(e)]),...i?{workspace:i}:{}});var o}function Pt(e){const t=(e||"unknown").trim().toLowerCase();return"ended"===t?"closed":"terminating"===t?"stopping":It.options.includes(t)?t:"unknown"}function jt(e){return!vt.has(Pt(e))}function Dt(e){return"tty"===e.kind?"tty":"gui"===e.kind?"vnc":"web"===e.kind?"web":void 0}function Mt(e){return"app-session"===e.type?`app:${e.id}`:"provider-session"===e.type?`provider:${e.agent||""}:${e.id}`:`adapter:${e.adapter||""}:${e.key||e.id}`}function Lt(e){const t=Bt(e.ai),n=Bt(t.claude),i=Bt(t.appServer),s=Bt(e.launch),r=[],o=Ut(Bt(s.aiSessionResume).providerSessionId),a="codex"===e.appId||"claude"===e.appId?e.appId:void 0;a&&o&&r.push({type:"provider-session",agent:a,id:o});const d=Ut(n.short);d&&r.push({type:"adapter-key",adapter:"claude",agent:"claude",id:`short:${d}`,key:`short:${d}`});const c=Ut(n.providerSessionId);c&&r.push({type:"provider-session",agent:"claude",id:c});const l=Array.isArray(t.threadIds)?t.threadIds.filter(e=>"string"==typeof e&&Boolean(e.trim())):[],p=Ut(t.activeThreadId);for(const e of[...new Set([p,...l].filter(Boolean))])r.push({type:"provider-session",agent:"codex",id:e});const u=Ut(i.socketPath);return u&&r.push({type:"adapter-key",adapter:"codex-app-server",agent:"codex",id:`socket:${u}`,key:`socket:${u}`}),r}function qt(e){const t="string"==typeof e.id?e.id:"",n=Bt(e.ai),i=Ut(Bt(n.claude).short);return[t?`app:${t}`:"",i?`claude-short:${i}`:""]}function $t(e){const t=new Map;for(const n of e)t.set(Mt(n),n);return[...t.values()]}function Bt(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function Ut(e){return"string"==typeof e&&e.trim()?e.trim():""}function Ft(e=(new Date).toISOString()){return At.parse({runningCount:0,problemCount:0,sessions:[],updatedAt:e})}const Ht=a.z.string().trim().min(3).max(160).regex(/^[a-z][a-z0-9_-]*$/),Wt=a.z.string().datetime(),Gt=a.z.string().regex(/^sha256:[A-Za-z0-9_-]{43}$/),Vt=a.z.string().min(32).max(4096),Kt=a.z.strictObject({default:a.z.string().trim().min(1).max(160),translations:a.z.record(a.z.string().regex(/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/),a.z.string().trim().min(1).max(160)).default({})});function Jt(e){return Array.isArray(e)?`[${e.map(Jt).join(",")}]`:e&&"object"==typeof e?`{${Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${Jt(t)}`).join(",")}}`:JSON.stringify(e)}const Yt="2026-08-10",Qt="2026-08-10",Xt="2026-08-10",Zt=Object.freeze({AccountApi:"task-handoff:official-account-api",Binding:"task-handoff:control-plane-binding",CoordinatorControl:"task-handoff:coordinator-control",RelayAllocation:"task-handoff:relay-allocation",RelayClientAttach:"task-handoff:relay-client-attach",RelayControlPlaneAttach:"task-handoff:relay-control-plane-attach",RelayRevocation:"task-handoff:relay-revocation",ControlPlaneAccess:"task-handoff:control-plane-access"});a.z.strictObject({protocolVersion:a.z.literal("2026-08-10"),audience:a.z.literal(Zt.AccountApi)});const en=a.z.string().email().max(320).transform(e=>e.trim().toLowerCase()),tn=a.z.enum(["pending-verification","active","disabled","pending-deletion"]);a.z.strictObject({id:Ht,email:en,emailVerified:a.z.boolean(),hasPassword:a.z.boolean().optional(),totpEnabled:a.z.boolean().optional(),displayName:Kt.optional(),status:tn,createdAt:Wt}),a.z.strictObject({id:Ht,kind:a.z.enum(["browser","mobile"]),deviceName:a.z.string().trim().min(1).max(160),platform:a.z.string().trim().min(1).max(80).optional(),createdAt:Wt,lastSeenAt:Wt.optional(),expiresAt:Wt,revokedAt:Wt.optional()}),a.z.union([a.z.object({code:Vt,state:a.z.string().min(1).max(4096).optional(),redirectUri:a.z.string().url(),expiresAt:Wt}),a.z.object({authorizationUrl:a.z.string().url(),expiresAt:Wt})]),a.z.object({tokenType:a.z.literal("Bearer"),accessToken:Vt,accessExpiresAt:Wt,refreshCredential:Vt,accountId:Ht,deviceSessionId:Ht}),a.z.strictObject({enrollmentToken:Vt,secret:Vt,algorithm:a.z.literal("SHA1"),digits:a.z.literal(6),periodSeconds:a.z.literal(30),otpauthUri:a.z.string().url().startsWith("otpauth://totp/"),expiresAt:Wt});const nn=a.z.strictObject({controlPlaneId:Ht,algorithm:a.z.literal("Ed25519"),publicKey:a.z.string().regex(/^[A-Za-z0-9_-]{43}$/),fingerprint:Gt});a.z.strictObject({protocolVersion:a.z.literal(Yt),audience:a.z.literal(Zt.Binding),challengeId:Ht,challenge:Vt,serviceOrigin:a.z.string().url(),identity:nn,nonce:a.z.string().min(16).max(256),initiatingAdminSessionId:Ht,issuedAt:Wt,expiresAt:Wt}),a.z.strictObject({code:a.z.enum(["CONTROL_PLANE_ALREADY_BOUND","REVISION_CONFLICT","REVOCATION_PENDING","IDENTITY_CLONE_CONFLICT"]),controlPlaneId:Ht,expectedRevision:a.z.number().int().nonnegative().optional(),actualRevision:a.z.number().int().nonnegative().optional(),retryable:a.z.boolean()});const sn=a.z.strictObject({bindingId:Ht.optional(),controlPlaneId:Ht,displayName:Kt,publicKeyFingerprint:Gt,bindingRevision:a.z.number().int().positive(),remoteAccess:a.z.enum(["enabled","disabled","revocation-pending"]),leaseExpiresAt:Wt.optional(),lastConnectedAt:Wt.optional(),relayUsageBytes:a.z.number().int().nonnegative(),relayQuotaBytes:a.z.number().int().nonnegative().optional(),versionWarning:a.z.string().trim().min(1).max(500).optional(),errorCode:a.z.string().trim().min(1).max(160).optional()}),rn=a.z.enum(["interactive","stream","bulk"]),on=a.z.object({type:a.z.literal("tty-snapshot"),streamId:a.z.string().trim().min(1).optional(),data:a.z.string(),pendingEscape:a.z.string(),cols:a.z.number().int().positive(),rows:a.z.number().int().positive()}).passthrough(),an=a.z.strictObject({protocolVersion:a.z.literal(Qt),audience:a.z.literal(Zt.CoordinatorControl),connectionId:Ht,processInstanceId:Ht,controlPlaneId:Ht,publicKey:a.z.string().regex(/^[A-Za-z0-9_-]{43}$/),publicKeyFingerprint:Gt,bindingId:Ht.optional(),bindingRevision:a.z.number().int().positive().optional(),epoch:a.z.number().int().nonnegative(),capabilities:a.z.array(a.z.enum(["request","stream","websocket"])).min(1),issuedAt:Wt,expiresAt:Wt}).superRefine((e,t)=>{Boolean(e.bindingId)!==Boolean(e.bindingRevision)&&t.addIssue({code:"custom",message:"binding id and revision must be supplied together"})});an.safeExtend({signature:Vt}),a.z.strictObject({connectionId:Ht,controlPlaneId:Ht,bindingRevision:a.z.number().int().positive(),epoch:a.z.number().int().nonnegative(),relayId:Ht,relayRegion:a.z.string().trim().min(1).max(80),issuedAt:Wt,expiresAt:Wt});const dn=a.z.strictObject({protocolVersion:a.z.literal(Qt),audience:a.z.literal(Zt.ControlPlaneAccess),ticketId:Ht,accountId:Ht,deviceSessionId:Ht,controlPlaneId:Ht,bindingId:Ht,bindingRevision:a.z.number().int().positive(),targetPublicKeyFingerprint:Gt,nonce:a.z.string().min(16).max(256),trafficClasses:a.z.array(rn).min(1),issuedAt:Wt,expiresAt:Wt,signature:Vt});a.z.strictObject({audience:a.z.literal(Zt.ControlPlaneAccess),accountId:Ht,deviceSessionId:Ht,controlPlaneId:Ht,bindingId:Ht,bindingRevision:a.z.number().int().positive(),authenticatedAt:Wt,expiresAt:Wt,signature:Vt});const cn=a.z.enum(["client","control-plane"]),ln=a.z.strictObject({protocolVersion:a.z.literal(Xt),audience:a.z.enum([Zt.RelayClientAttach,Zt.RelayControlPlaneAttach]),allocationId:Ht,relayId:Ht,role:cn,controlPlaneId:Ht,accountId:Ht,deviceSessionId:Ht,bindingId:Ht,ticketId:Ht,bindingRevision:a.z.number().int().positive(),trafficClass:rn,nonce:a.z.string().min(16).max(256),issuedAt:Wt,expiresAt:Wt,signature:Vt}).superRefine((e,t)=>{const n="client"===e.role?Zt.RelayClientAttach:Zt.RelayControlPlaneAttach;e.audience!==n&&t.addIssue({code:"custom",path:["audience"],message:`audience must match ${e.role} role`})});a.z.object({allocationId:Ht,relayId:Ht,relayRegion:a.z.string().trim().min(1).max(80),relayUrl:a.z.string().url(),clientAttach:ln,expiresAt:Wt}),a.z.strictObject({channelId:Ht,allocationId:Ht,controlPlaneId:Ht,bindingRevision:a.z.number().int().positive(),trafficClass:rn,state:a.z.enum(["waiting-for-peer","handshaking","open","closing","closed"]),clientAttached:a.z.boolean(),controlPlaneAttached:a.z.boolean(),openedAt:Wt.optional(),leaseExpiresAt:Wt}),a.z.strictObject({protocolVersion:a.z.literal(Xt),channelId:Ht,sequence:a.z.number().int().nonnegative(),kind:a.z.enum(["handshake","data","cancel","window-update","close"]),ciphertext:a.z.string().max(1398102).optional(),creditBytes:a.z.number().int().positive().optional()}),a.z.strictObject({channelId:Ht,code:a.z.enum(["normal","expired","revoked","quota-exceeded","idle-timeout","slow-consumer","protocol-error","peer-disconnected"]),retryable:a.z.boolean()}),a.z.strictObject({protocolVersion:a.z.literal(Xt),audience:a.z.literal(Zt.RelayRevocation),revocationId:Ht,relayId:Ht.optional(),allocationId:Ht.optional(),accountId:Ht.optional(),deviceSessionId:Ht.optional(),bindingId:Ht.optional(),issuedAt:Wt,expiresAt:Wt,signature:Vt}).refine(e=>[e.allocationId,e.accountId,e.deviceSessionId,e.bindingId].some(Boolean),"revocation target is required"),a.z.strictObject({data:a.z.strictObject({protocolVersion:a.z.literal(Yt),items:a.z.array(sn)})}),Object.keys(sn.shape);const pn=a.z.object({ticketId:a.z.string().trim().min(3).max(160),deviceSessionId:a.z.string().trim().min(3).max(160),clientEphemeralPublicKey:a.z.string().regex(/^[A-Za-z0-9_-]{43}$/)});function un(){return Object.assign(new Error("End-to-end handshake is invalid."),{code:"E2E_HANDSHAKE_INVALID"})}a.z.object({serverEphemeralPublicKey:a.z.string().regex(/^[A-Za-z0-9_-]{43}$/),transcript:a.z.string().regex(/^[A-Za-z0-9_-]{43}$/),signature:a.z.string().regex(/^[A-Za-z0-9_-]{86}$/)});const gn=a.z.union([a.z.object({type:a.z.literal("schedule"),scheduleKind:a.z.literal("interval").default("interval"),intervalMs:a.z.number().int().min(1e3)}).strict(),a.z.object({type:a.z.literal("schedule"),scheduleKind:a.z.literal("daily"),timeOfDay:a.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/),timezone:a.z.string().trim().min(1).max(120)}).strict(),a.z.object({type:a.z.literal("schedule"),scheduleKind:a.z.literal("weekly"),weekdays:a.z.array(a.z.number().int().min(0).max(6)).min(1).max(7),timeOfDay:a.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/),timezone:a.z.string().trim().min(1).max(120)}).strict()]),hn=a.z.union([gn,a.z.object({type:a.z.literal("file-change"),roots:a.z.array(a.z.string().trim().min(1).max(4096)).min(1).max(50),globs:a.z.array(a.z.string().trim().min(1).max(500)).min(1).max(100),ignore:a.z.array(a.z.string().trim().min(1).max(500)).max(100).optional(),debounceMs:a.z.number().int().min(100).max(6e4).default(1500)}).strict(),a.z.object({type:a.z.literal("ai-session"),agent:a.z.string().trim().min(1).max(80).optional(),statuses:a.z.array(a.z.enum(["running","waiting","idle","failed"])).max(20).optional(),phases:a.z.array(a.z.enum(["thinking","tool","editing","approval","responding","unknown"])).max(20).optional()}).strict()]),mn=a.z.object({promptTemplate:a.z.string().trim().min(1).max(2e4)}).strict(),yn=a.z.object({cooldownMs:a.z.number().int().min(0).max(864e5).optional(),maxConcurrentRuns:a.z.number().int().min(1).max(20).default(1),whenBusy:a.z.enum(["skip","queue"]).default("skip")}).strict(),fn=a.z.object({configHash:a.z.string().trim().min(8).max(80),name:a.z.string().trim().min(1).max(160),description:a.z.string().trim().max(1e3).optional(),source:hn,action:mn,policy:yn.default({maxConcurrentRuns:1,whenBusy:"skip"}),createdAt:a.z.string().datetime(),updatedAt:a.z.string().datetime()}).strict(),In=a.z.object({type:a.z.literal("ai-session"),aiSessionId:a.z.string().trim().min(1).max(160)}).strict(),bn=a.z.object({configHash:a.z.string().trim().min(8).max(80),deploymentId:a.z.string().trim().min(1).max(240).optional(),instanceId:a.z.string().trim().min(1).max(160),origin:a.z.enum(["control-plane","controlled-instance"]).default("controlled-instance"),enabled:a.z.boolean().default(!0),target:In,localName:a.z.string().trim().min(1).max(160).optional(),createdAt:a.z.string().datetime(),updatedAt:a.z.string().datetime()}).strict(),vn=a.z.object({configHash:a.z.string().trim().min(8).max(80),deploymentId:a.z.string().trim().min(1).max(240).optional(),instanceId:a.z.string().trim().min(1).max(160),status:a.z.enum(["idle","running","disabled","error"]).default("idle"),lastTriggeredAt:a.z.string().datetime().optional(),lastCompletedAt:a.z.string().datetime().optional(),lastSkippedAt:a.z.string().datetime().optional(),lastError:a.z.string().trim().max(4e3).optional(),runCount:a.z.number().int().min(0).default(0),skippedCount:a.z.number().int().min(0).default(0)}).strict(),wn=a.z.object({id:a.z.string().trim().min(1).max(160),configHash:a.z.string().trim().min(8).max(80),deploymentId:a.z.string().trim().min(1).max(240).optional(),instanceId:a.z.string().trim().min(1).max(160),eventType:a.z.enum(["manual","schedule","file-change","ai-session"]),status:a.z.enum(["started","completed","failed","skipped"]),target:In,promptPreview:a.z.string().trim().max(500),eventSummary:a.z.string().trim().max(1e3).optional(),error:a.z.string().trim().max(4e3).optional(),startedAt:a.z.string().datetime(),completedAt:a.z.string().datetime().optional()}).strict();a.z.object({schemaVersion:a.z.literal(1).default(1),configs:a.z.array(fn).default([]),deployments:a.z.array(bn).default([]),runtime:a.z.array(vn).default([]),recentRuns:a.z.array(wn).default([])}).strict();const Sn=a.z.object({instanceId:a.z.string().trim().min(1).max(160),instanceName:a.z.string().trim().min(1).max(160),deployment:bn,runtime:vn.optional()}).strip(),An=wn.extend({instanceName:a.z.string().trim().min(1).max(160).optional()}).strip(),zn=a.z.object({configHash:a.z.string().trim().min(8).max(80),config:fn,deploymentCount:a.z.number().int().min(0),enabledCount:a.z.number().int().min(0),runningCount:a.z.number().int().min(0),errorCount:a.z.number().int().min(0),ownedByControlPlane:a.z.boolean(),controlPlaneDeploymentCount:a.z.number().int().min(0),deployments:a.z.array(Sn),recentRuns:a.z.array(An)}).strip(),kn=a.z.object({updatedAt:a.z.string().datetime(),triggers:a.z.array(zn)}).strip();function Tn(e){const t=xn({source:e.source,action:e.action,policy:yn.parse(e.policy||{})});return`trg_${function(e){const t=(new TextEncoder).encode(e),n=64*Math.ceil((t.length+9)/64),i=new Uint8Array(n);i.set(t),i[t.length]=128;const s=new DataView(i.buffer),r=8*t.length;s.setUint32(n-8,Math.floor(r/4294967296)),s.setUint32(n-4,r>>>0);const o=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),a=new Uint32Array(64);for(let e=0;e<n;e+=64){for(let t=0;t<16;t+=1)a[t]=s.getUint32(e+4*t);for(let e=16;e<64;e+=1){const t=a[e-15],n=a[e-2],i=Cn(t,7)^Cn(t,18)^t>>>3,s=Cn(n,17)^Cn(n,19)^n>>>10;a[e]=a[e-16]+i+a[e-7]+s>>>0}let[t,n,i,r,d,c,l,p]=o;for(let e=0;e<64;e+=1){const s=p+(Cn(d,6)^Cn(d,11)^Cn(d,25))+(d&c^~d&l)+En[e]+a[e]>>>0,o=t&n^t&i^n&i;p=l,l=c,c=d,d=r+s>>>0,r=i,i=n,n=t,t=s+((Cn(t,2)^Cn(t,13)^Cn(t,22))+o>>>0)>>>0}o[0]=o[0]+t>>>0,o[1]=o[1]+n>>>0,o[2]=o[2]+i>>>0,o[3]=o[3]+r>>>0,o[4]=o[4]+d>>>0,o[5]=o[5]+c>>>0,o[6]=o[6]+l>>>0,o[7]=o[7]+p>>>0}return[...o].map(e=>e.toString(16).padStart(8,"0")).join("")}(JSON.stringify(t)).slice(0,24)}`}a.z.object({name:fn.shape.name,description:fn.shape.description,source:hn,action:mn,policy:yn.partial().optional()}).strict();const En=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function Cn(e,t){return e>>>t|e<<32-t}function xn(e){return Array.isArray(e)?e.map(xn):e&&"object"==typeof e?Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,xn(t)])):e}const Nn="2026-08-01",On=a.z.string().regex(/^\d{4}-\d{2}-\d{2}$/,"Proxy protocol version must use YYYY-MM-DD format."),_n=a.z.string().trim().min(1).max(160).regex(/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/),Rn=a.z.string().datetime(),Pn=a.z.string().trim().min(32).max(4096),jn=_n,Dn=a.z.string().trim().max(2048).transform((e,t)=>{try{return function(e){const t=new URL(e.trim());if("https:"!==t.protocol||t.username||t.password||"/"!==t.pathname||t.search||t.hash)throw new Error("Proxy origin must be an HTTPS origin without credentials, path, query, or fragment.");return t.origin}(e)}catch(e){return t.addIssue({code:"custom",message:e instanceof Error?e.message:String(e)}),a.z.NEVER}}),Mn=a.z.string().trim().min(1).max(4096).transform((e,t)=>{try{return function(e){const t=e.trim();if(!t.startsWith("/")||t.startsWith("//")||t.includes("\\")||/%25/i.test(t))throw new Error("Proxy route must be a single-encoded node-agent relative route.");const n=t.split("?",1)[0];let i,s;try{i=n.split("/").map(e=>decodeURIComponent(e))}catch{throw new Error("Proxy route contains invalid percent encoding.")}if(i.some(e=>".."===e||"."===e))throw new Error("Proxy route cannot traverse outside the node-agent API.");try{s=new URL(t,"https://node-agent.invalid")}catch{throw new Error("Proxy route is invalid.")}if("https://node-agent.invalid"!==s.origin||s.username||s.password)throw new Error("Proxy route cannot select an absolute upstream URL.");return`${s.pathname}${s.search}`}(e)}catch(e){return t.addIssue({code:"custom",message:e instanceof Error?e.message:String(e)}),a.z.NEVER}}),Ln=new Set(["accept","accept-language","authorization","content-type","if-match","if-none-match","range","x-request-id"]),qn=new Set(["cache-control","content-disposition","content-language","content-length","content-range","content-type","etag","last-modified","x-request-id"]),$n="x-task-handoff-proxy-protocol-version",Bn="x-task-handoff-proxy-source-control-plane-id",Un="x-task-handoff-proxy-binding-key-id",Fn="x-task-handoff-proxy-credential",Hn={ProtocolUnsupported:"CONTROL_PLANE_PROXY_PROTOCOL_UNSUPPORTED",InviteInvalid:"CONTROL_PLANE_PROXY_INVITE_INVALID",InviteExpired:"CONTROL_PLANE_PROXY_INVITE_EXPIRED",InviteConsumed:"CONTROL_PLANE_PROXY_INVITE_CONSUMED",InviteRevoked:"CONTROL_PLANE_PROXY_INVITE_REVOKED",TargetUnavailable:"CONTROL_PLANE_PROXY_TARGET_UNAVAILABLE",TargetMismatch:"CONTROL_PLANE_PROXY_TARGET_MISMATCH",BindingUnknown:"CONTROL_PLANE_PROXY_BINDING_UNKNOWN",BindingRevoked:"CONTROL_PLANE_PROXY_BINDING_REVOKED",BindingIdentityConflict:"CONTROL_PLANE_PROXY_BINDING_IDENTITY_CONFLICT",AuthenticationFailed:"CONTROL_PLANE_PROXY_AUTHENTICATION_FAILED",RouteInvalid:"CONTROL_PLANE_PROXY_ROUTE_INVALID",HeaderInvalid:"CONTROL_PLANE_PROXY_HEADER_INVALID",ResourceLimit:"CONTROL_PLANE_PROXY_RESOURCE_LIMIT",SnapshotRequired:"CONTROL_PLANE_PROXY_SNAPSHOT_REQUIRED",Unavailable:"CONTROL_PLANE_PROXY_UNAVAILABLE",TransportFailed:"CONTROL_PLANE_PROXY_TRANSPORT_FAILED"},Wn=a.z.enum(Object.values(Hn)),Gn=a.z.object({code:Wn,message:a.z.string().trim().min(1).max(2048),retryable:a.z.boolean(),details:a.z.record(a.z.string(),a.z.unknown()).optional()}).strict(),Vn=a.z.enum(["active","revoked"]),Kn=a.z.object({id:_n,targetNodeId:_n,status:Vn,createdBy:_n,expiresAt:Rn,revokedAt:Rn.optional(),createdAt:Rn,updatedAt:Rn}).strict(),Jn=a.z.object({targetNodeId:_n,expiresInSeconds:a.z.number().int().min(60).max(3600).default(600)}).strict(),Yn=a.z.object({invite:Kn,token:a.z.string().trim().min(24).max(512),proxyOrigin:Dn,protocolVersion:On}).strict(),Qn=a.z.enum(["active","revoked"]),Xn=a.z.object({id:_n,claimId:_n,sourceControlPlaneId:_n,targetNodeId:_n,bindingKeyId:_n,status:Qn,revision:a.z.number().int().positive(),lastError:Gn.optional(),revokedAt:Rn.optional(),createdAt:Rn,updatedAt:Rn}).strict(),Zn=a.z.object({protocolVersion:On,inviteToken:a.z.string().trim().min(24).max(512).optional(),claimId:_n,sourceControlPlaneId:_n,targetNodeId:_n.optional(),bindingKeyId:_n,credential:Pn}).strict(),ei=a.z.object({sourceControlPlaneId:_n,bindingKeyId:_n,credential:Pn}).strict(),ti=a.z.object({id:_n,name:a.z.string().trim().min(1).max(160),status:a.z.enum(["unknown","online","offline","degraded"]),health:a.z.enum(["unknown","ok","degraded","failed"]),lastSeenAt:Rn.optional(),capabilities:a.z.record(a.z.string(),a.z.unknown()).default({})}).strict(),ni=a.z.object({protocolVersion:On,binding:Xn,streamId:_n,revision:a.z.number().int().nonnegative(),observedAt:Rn,target:ti}).strict(),ii=a.z.object({type:a.z.literal("control-plane-proxy.event"),protocolVersion:On,streamId:_n,bindingId:_n,sourceControlPlaneId:_n,targetNodeId:_n,revision:a.z.number().int().positive(),source:a.z.object({id:a.z.string().trim().min(1).max(512),seq:a.z.number().int().nonnegative()}).strict(),target:ti,event:a.z.object({type:a.z.string().trim().min(1).max(240),topic:a.z.string().trim().min(1).max(240),createdAt:Rn}).strict()}).strict(),si=a.z.object({type:a.z.literal("control-plane-proxy.events.ready"),protocolVersion:On,streamId:_n,bindingId:_n,sourceControlPlaneId:_n,targetNodeId:_n,latestRevision:a.z.number().int().nonnegative(),earliestRetainedRevision:a.z.number().int().nonnegative()}).strict(),ri=a.z.object({type:a.z.literal("control-plane-proxy.snapshot-required"),protocolVersion:On,streamId:_n,bindingId:_n,sourceControlPlaneId:_n,targetNodeId:_n,sinceRevision:a.z.number().int().nonnegative(),latestRevision:a.z.number().int().nonnegative(),earliestRetainedRevision:a.z.number().int().nonnegative(),error:Gn}).strict(),oi=a.z.discriminatedUnion("type",[ii,si,ri]),ai=a.z.object({protocolVersion:On,binding:Xn,target:ni.shape.target}).strict(),di=a.z.object({id:_n,claimId:_n,proxyOrigin:Dn,requestedName:a.z.string().trim().min(1).max(160).optional(),sourceControlPlaneId:_n,targetNodeId:_n.optional(),bindingKeyId:_n,credential:Pn,status:a.z.enum(["pending","compensation-required"]),createdAt:Rn,updatedAt:Rn,expiresAt:Rn}).strict();di.omit({credential:!0});const ci=a.z.object({id:_n,nodeId:_n,proxyOrigin:Dn,proxyBindingId:_n,targetNodeId:_n,sourceControlPlaneId:_n,bindingKeyId:_n,credential:Pn,createdAt:Rn,updatedAt:Rn}).strict(),li="2026-08-18",pi=new Set(["2026-08-01","2026-08-16","2026-08-17",li]),ui=a.z.string().regex(/^\d{4}-\d{2}-\d{2}$/,"Protocol version must use YYYY-MM-DD format."),gi=a.z.string().trim().min(1).max(120);function hi(){return{features:{appRuntime:!1,tty:!1,gui:!1,browser:!1,screenshots:!1,logs:!1,aiSessionWorkspaceSelection:!1,aiSessionPersistenceSettings:!1,aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}}}}const mi=a.z.object({sessionReadAgents:a.z.array(gi).max(100).default([]),turnReadAgents:a.z.array(gi).max(100).default([]),liveItemAgents:a.z.array(gi).max(100).default([])}).passthrough(),yi=a.z.object({appRuntime:a.z.boolean().default(!1),tty:a.z.boolean().default(!1),gui:a.z.boolean().default(!1),browser:a.z.boolean().default(!1),screenshots:a.z.boolean().default(!1),logs:a.z.boolean().default(!1),aiSessionWorkspaceSelection:a.z.boolean().default(!1),aiSessionPersistenceSettings:a.z.boolean().default(!1),aiSessionTimeline:mi.default(function(){return{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}})}).passthrough(),fi=a.z.object({features:yi.default(function(){return{appRuntime:!1,tty:!1,gui:!1,browser:!1,screenshots:!1,logs:!1,aiSessionWorkspaceSelection:!1,aiSessionPersistenceSettings:!1,aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}}})}).passthrough();function Ii(e){const t={features:{appRuntime:!1,tty:!1,gui:!1,browser:!1,screenshots:!1,logs:!1,aiSessionWorkspaceSelection:!1,aiSessionPersistenceSettings:!1,aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}}};if(!e||"object"!=typeof e||Array.isArray(e))return t;const n=e,i=n.features;if(!i||"object"!=typeof i||Array.isArray(i))return t;const s=i,r={appRuntime:!1,tty:!1,gui:!1,browser:!1,screenshots:!1,logs:!1,aiSessionWorkspaceSelection:!1,aiSessionPersistenceSettings:!1,aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}};for(const e of["appRuntime","tty","gui","browser","screenshots","logs","aiSessionWorkspaceSelection","aiSessionPersistenceSettings"]){const t=a.z.boolean().safeParse(s[e]);t.success&&(r[e]=t.data)}const o=mi.safeParse(s.aiSessionTimeline);return o.success&&(r.aiSessionTimeline=o.data),fi.parse({...n,features:{...s,...r}})}function bi(e,t){const n=function(e){return Ii(e).features.aiSessionTimeline}(e);return"session-read"===t?n.sessionReadAgents:"turn-read"===t?n.turnReadAgents:n.liveItemAgents}const vi=a.z.string().trim().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/),wi=a.z.string().datetime(),Si=a.z.record(a.z.string(),a.z.string()).default({}),Ai=a.z.record(a.z.string(),a.z.string()).default({});function zi(e){if(null!=e){if("string"==typeof e)return{encoding:"utf8",data:e};if(Buffer.isBuffer(e))return{encoding:"base64",data:e.toString("base64")};if(e instanceof ArrayBuffer)return{encoding:"base64",data:Buffer.from(e).toString("base64")};if(ArrayBuffer.isView(e))return{encoding:"base64",data:Buffer.from(e.buffer,e.byteOffset,e.byteLength).toString("base64")};throw new TypeError("Node tunnel request body must be a string or binary buffer.")}}a.z.object({encoding:a.z.enum(["utf8","base64"]),data:a.z.string()}).strict().superRefine((e,t)=>{"base64"===e.encoding&&Buffer.from(e.data,"base64").toString("base64")!==e.data&&t.addIssue({code:"custom",path:["data"],message:"Node tunnel binary body must use canonical base64 encoding."})});const ki=/^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$/,Ti=/^sha256:([a-fA-F0-9]{64})$/,Ei=/^(?:localhost|[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?)(?::[1-9][0-9]{0,4})?$/,Ci=/^[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*$/;function xi(e){const t=e.trim();if(!t||t.length>512||t.includes("://")||/\s/.test(t))throw new Error("Docker image reference must not contain a URL scheme or whitespace.");const n=t.indexOf("@");if(-1!==n&&n!==t.lastIndexOf("@"))throw new Error("Docker image reference contains more than one digest separator.");const i=-1===n?void 0:t.slice(n+1),s=-1===n?t:t.slice(0,n),r=i?Ti.exec(i):void 0;if(i&&!r)throw new Error("Docker image digest must use sha256 followed by 64 hexadecimal characters.");const o=s.lastIndexOf("/"),a=s.lastIndexOf(":"),d=a>o,c=d?s.slice(a+1):void 0,l=d?s.slice(0,a):s;if(c&&!ki.test(c))throw new Error("Docker image tag is invalid.");if(!c&&!r)throw new Error("Docker image reference must include an explicit tag or sha256 digest.");const p=l.split("/");if(!p.length||p.some(e=>!e))throw new Error("Docker image repository path is invalid.");const u=p.length>1&&(p[0].includes(".")||p[0].includes(":")||"localhost"===p[0]),g=u?p.slice(1):p;if(u&&!Ei.test(p[0].toLowerCase()))throw new Error("Docker image registry host or port is invalid.");if(!g.length||g.some(e=>!Ci.test(e)))throw new Error("Docker image repository names must be lowercase and use valid separators.");const h=p.map((e,t)=>u&&0===t?e.toLowerCase():e).join("/"),m=r?`sha256:${r[1].toLowerCase()}`:void 0;return`${h}${c?`:${c}`:""}${m?`@${m}`:""}`}function Ni(e){const t=xi(e),n=t.indexOf("@"),i=-1===n?void 0:t.slice(n+1),s=-1===n?t:t.slice(0,n),r=s.lastIndexOf("/"),o=s.lastIndexOf(":"),a=o>r;return{reference:t,repository:a?s.slice(0,o):s,tag:a?s.slice(o+1):void 0,digest:i}}const Oi=a.z.string().trim().min(1).max(512).transform((e,t)=>{try{return xi(e)}catch(e){return t.addIssue({code:"custom",message:e instanceof Error?e.message:String(e)}),a.z.NEVER}}),_i=a.z.string().trim().transform((e,t)=>{const n=Ti.exec(e);return n?`sha256:${n[1].toLowerCase()}`:(t.addIssue({code:"custom",message:"Docker image digest must use sha256 followed by 64 hexadecimal characters."}),a.z.NEVER)}),Ri=a.z.object({codexModelHash:vi.nullable().optional(),claudeModelHash:vi.nullable().optional()}).strict().default({}),Pi=a.z.object({imageId:vi,tag:a.z.string().trim().min(1).max(128).regex(ki).optional()}).strict(),ji=a.z.discriminatedUnion("type",[a.z.object({type:a.z.literal("image"),imageSelection:Pi}).strict(),a.z.object({type:a.z.literal("template"),environmentTemplateId:vi}).strict()]),Di=a.z.enum(["creating","ready","failed","deleting"]),Mi=a.z.enum(["linux","darwin","win32","freebsd","openbsd","aix","sunos","unknown"]),Li=a.z.enum(["x64","arm64","arm","ia32","ppc64","s390x","riscv64","unknown"]),qi=a.z.object({code:a.z.string().trim().min(1).max(120),message:a.z.string().trim().min(1).max(2048),phase:a.z.enum(["validate","commit","inspect","security-check","persist","delete","recovery"]).optional()}).strict(),$i=a.z.object({templateId:vi,nodeId:vi,imageId:_i,name:a.z.string().trim().min(1).max(160),platform:Mi,architecture:Li}).strict(),Bi=a.z.enum(["data","agent-home","workspace"]),Ui=a.z.object({deleteVolumes:a.z.boolean()}).strict(),Fi=a.z.object({role:Bi,name:a.z.string().trim().min(1).max(255),mountPath:a.z.string().trim().startsWith("/").max(4096),status:a.z.enum(["deleted","retained","missing","failed"]),error:a.z.object({code:a.z.string().trim().min(1).max(120),message:a.z.string().trim().min(1).max(2048)}).strict().optional()}).strict(),Hi=a.z.object({instanceId:vi,containerDeleted:a.z.boolean(),completed:a.z.boolean(),deletedVolumes:a.z.array(Fi),retainedVolumes:a.z.array(Fi),volumeResults:a.z.array(Fi)}).strict(),Wi={img_default:"market_taskhandoff_browser",img_codex:"market_taskhandoff_codex",img_ai:"market_taskhandoff_ai"};function Gi(e,t){if(e&&"object"==typeof e&&!Array.isArray(e)){const t=e;return{imageId:"string"==typeof t.imageId&&Wi[t.imageId]||t.imageId,..."string"==typeof t.tag?{tag:t.tag}:{}}}if("string"==typeof t)return{imageId:Wi[t]||t}}function Vi(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e,{defaultImageId:n,...i}=t;return{...i,defaultImageSelection:Gi(t.defaultImageSelection,n)}}const Ki=a.z.object({id:vi,name:a.z.string().trim().min(1).max(120),kind:a.z.enum(["tty","gui","web"]),source:a.z.enum(["builtin","custom"]),availability:a.z.enum(["available","missing-dependency"]),capabilities:a.z.object({automation:a.z.enum(["cdp"]).optional(),supportsCwdSelection:a.z.boolean().default(!1)}).strict().default({supportsCwdSelection:!1}),diagnosticCode:a.z.enum(["APP_EXECUTABLE_NOT_FOUND"]).optional()}).strict(),Ji=a.z.object({code:a.z.enum(["APP_CATALOG_INVALID"]),message:a.z.string().trim().min(1).max(500)}).strict(),Yi=a.z.object({items:a.z.array(Ki).max(256),observedAt:wi,issues:a.z.array(Ji).max(32).default([])}).strict(),Qi=a.z.object({id:vi,name:a.z.string().trim().min(1).max(160),sourceInstanceId:vi,nodeId:vi,imageId:_i.optional(),internalTag:a.z.string().trim().min(1).max(512).optional(),platform:Mi.optional(),architecture:Li.optional(),sizeBytes:a.z.number().int().nonnegative().optional(),status:Di,error:qi.optional(),createdAt:wi,updatedAt:wi}).strict().superRefine((e,t)=>{if("ready"===e.status)for(const n of["imageId","internalTag","platform","architecture","sizeBytes"])void 0===e[n]&&t.addIssue({code:"custom",path:[n],message:`Ready environment template requires ${n}.`});"failed"!==e.status||e.error||t.addIssue({code:"custom",path:["error"],message:"Failed environment template requires an error diagnostic."})}),Xi=a.z.enum(["apt","dnf","brew","npm"]),Zi=a.z.enum(["user","passwordless-sudo","root"]),es=a.z.object({platform:Mi,arch:Li,installers:a.z.array(Xi).max(8),privilege:Zi,installerAccess:a.z.object({npmGlobalWritable:a.z.boolean().optional()}).strict().optional()}).strict(),ts=a.z.enum(["installed","not-installed","broken","unsupported"]),ns=a.z.enum(["recipe","bundled","external","none"]),is=a.z.object({code:a.z.enum(["BUNDLED","EXTERNALLY_MANAGED","ALREADY_INSTALLED","NOT_INSTALLED","UNSUPPORTED_PLATFORM","INSTALLER_UNAVAILABLE","INSTALLER_NOT_WRITABLE","INSUFFICIENT_PRIVILEGE","OPERATION_IN_PROGRESS"]),message:a.z.string().trim().min(1).max(500)}).strict(),ss=a.z.object({id:vi,name:a.z.string().trim().min(1).max(120),kind:a.z.enum(["tty","gui","web"]),description:a.z.string().trim().max(500).optional(),state:ts,managementSource:ns,version:a.z.string().trim().max(120).optional(),canInstall:a.z.boolean(),canUninstall:a.z.boolean(),installReason:is.optional(),uninstallReason:is.optional(),activeJobId:vi.optional()}).strict(),rs=a.z.enum(["install","uninstall"]),os=a.z.enum(["queued","running","succeeded","failed","cancelled","interrupted"]),as=a.z.object({current:a.z.number().finite().nonnegative().optional(),total:a.z.number().finite().positive().optional(),unit:a.z.string().trim().min(1).max(40).optional()}).strict().refine(e=>void 0===e.total||void 0===e.current||e.current<=e.total,{message:"Progress current must not exceed total.",path:["current"]}),ds=a.z.object({executable:a.z.string().trim().min(1).max(4096),args:a.z.array(a.z.string().max(4096)).max(128)}).strict(),cs=a.z.object({code:a.z.string().trim().min(1).max(120).regex(/^[a-z0-9][a-z0-9._-]*$/),message:a.z.string().trim().min(1).max(4096),retryable:a.z.boolean(),sessionIds:a.z.array(vi).max(64).optional()}).strict(),ls=a.z.object({id:vi,requestId:vi.optional(),appId:vi,operation:rs,state:os,phase:a.z.string().trim().min(1).max(120).optional(),progress:as.optional(),command:ds.optional(),logTail:a.z.string().max(32768).optional(),logTruncated:a.z.boolean().optional(),error:cs.optional(),requestedAt:wi,startedAt:wi.optional(),finishedAt:wi.optional(),updatedAt:wi}).strict(),ps=a.z.object({streamId:vi,sequence:a.z.number().int().nonnegative(),capabilities:es,apps:a.z.array(ss).max(256),activeJobs:a.z.array(ls).max(256),recentJobs:a.z.array(ls).max(256),observedAt:wi}).strict(),us=a.z.object({requestId:vi.optional()}).strict(),gs=a.z.object({job:ls}).strict();a.z.object({type:a.z.literal("app-management"),streamId:vi,sequence:a.z.number().int().nonnegative(),observedAt:wi,job:ls.optional(),snapshot:ps.optional()}).strict().refine(e=>void 0!==e.job||void 0!==e.snapshot,{message:"An app management event requires a job or snapshot."});const hs=a.z.object({component:a.z.enum(["control-plane","node-agent","controlled-instance"]),packageName:a.z.string().trim().max(160).optional(),packageVersion:a.z.string().trim().max(80).optional(),protocolVersion:ui.optional(),buildId:a.z.string().trim().max(160).optional(),builtAt:a.z.string().trim().max(120).optional(),gitCommit:a.z.string().trim().max(120).optional(),imageRef:a.z.string().trim().max(512).optional(),imageDigest:a.z.string().trim().max(240).optional()}).strict(),ms=a.z.object({data:a.z.object({ok:a.z.literal(!0),role:a.z.literal("control-plane"),protocolVersion:ui,build:hs.extend({component:a.z.literal("control-plane"),packageVersion:a.z.string().trim().min(1).max(80)}).loose(),dataDir:a.z.string().min(1),serverTime:wi}).loose()}).loose(),ys=a.z.enum(["stable","beta","alpha"]),fs=a.z.object({packageName:a.z.literal("@task-handoff/controlled-instance"),version:a.z.string().trim().min(1).max(80),platform:a.z.string().trim().min(1).max(40),arch:a.z.string().trim().min(1).max(40),formatVersion:a.z.number().int().positive(),launcherAbi:a.z.number().int().positive(),entrypoint:a.z.string().trim().min(1).max(512),sha256:a.z.string().regex(/^[a-f0-9]{64}$/)}).strict(),Is=a.z.object({code:a.z.enum(["INSTANCE_RUNTIME_VERSION_MISMATCH","INSTANCE_RUNTIME_ARTIFACT_UNAVAILABLE","INSTANCE_RUNTIME_ARTIFACT_INVALID","INSTANCE_RUNTIME_INSTALL_FAILED","INSTANCE_RUNTIME_RESTART_FAILED","INSTANCE_RUNTIME_VERIFICATION_FAILED","INSTANCE_BASE_RUNTIME_INCOMPATIBLE","NODE_UPDATE_PREFLIGHT_FAILED","NODE_UPDATE_FAILED","LEGACY_INSTANCE_UPDATE_RETIRED"]),message:a.z.string().trim().min(1).max(4096),expectedVersion:a.z.string().trim().min(1).max(80).optional(),actualVersion:a.z.string().trim().min(1).max(80).optional(),retryable:a.z.boolean().default(!1)}).strict(),bs=a.z.object({desiredVersion:a.z.string().trim().min(1).max(80),actualVersion:a.z.string().trim().min(1).max(80).optional(),phase:a.z.enum(["pending","draining","installing","restarting","verifying","matched","failed"]),attempt:a.z.number().int().nonnegative().default(0),lastAttemptAt:wi.optional(),matchedAt:wi.optional(),error:Is.optional()}).strict(),vs=a.z.object({runningInstanceCount:a.z.number().int().nonnegative(),stoppedInstanceCount:a.z.number().int().nonnegative(),activeInstanceCount:a.z.number().int().nonnegative(),restartInstanceCount:a.z.number().int().nonnegative(),runningInstanceIds:a.z.array(vi).max(1024).default([]),stoppedInstanceIds:a.z.array(vi).max(1024).default([]),activeInstanceIds:a.z.array(vi).max(1024).default([])}).strict(),ws=a.z.object({phase:a.z.enum(["queued","updating-node","restarting-node","converging-instances","succeeded","degraded","failed"]),desiredVersion:a.z.string().trim().min(1).max(80),nodeVersion:a.z.string().trim().min(1).max(80).optional(),expectedInstanceIds:a.z.array(vi).max(1024).default([]),expectedInstanceCount:a.z.number().int().nonnegative(),matchedInstanceCount:a.z.number().int().nonnegative(),pendingInstanceCount:a.z.number().int().nonnegative(),failedInstanceCount:a.z.number().int().nonnegative(),deferredInstanceCount:a.z.number().int().nonnegative().default(0)}).strict(),Ss=a.z.object({channel:ys.default("stable")}).strict(),As=a.z.object({source:a.z.literal("npm"),channel:ys,currentVersion:a.z.string().trim().max(240).optional(),availableVersion:a.z.string().trim().min(1).max(240),artifactRef:a.z.string().trim().min(1).max(512).optional(),runtimeArtifacts:a.z.array(fs).default([]),impact:vs,updateAvailable:a.z.boolean(),supported:a.z.boolean().default(!0),reason:a.z.string().trim().max(2048).optional(),checkedAt:wi,preflightToken:a.z.string().trim().min(16).max(240).optional()}).strict(),zs=a.z.object({id:vi,nodeId:vi,source:a.z.literal("npm"),channel:ys,fromVersion:a.z.string().trim().max(240).optional(),toVersion:a.z.string().trim().min(1).max(240),artifactRef:a.z.string().trim().min(1).max(512).optional(),runtimeArtifacts:a.z.array(fs).default([]),impact:vs,rollout:ws,status:a.z.enum(["queued","updating-node","restarting-node","converging-instances","succeeded","degraded","failed"]),error:Is.optional(),startedAt:wi.optional(),completedAt:wi.optional(),createdAt:wi,updatedAt:wi}).strict(),ks=a.z.object({channel:ys,targetVersion:a.z.string().trim().min(1).max(240),preflightToken:a.z.string().trim().min(16).max(240)}).strict(),Ts=a.z.object({type:a.z.enum(["branch","tag","commit"]),name:a.z.string().trim().min(1).max(240).optional(),commit:a.z.string().trim().max(80).optional()}).strict(),Es=a.z.object({type:a.z.enum(["none","ssh-key","https-token"]).default("none"),secretId:a.z.string().trim().min(1).max(120).optional()}).strict(),Cs=a.z.object({depth:a.z.number().int().positive().max(1e5).optional(),submodules:a.z.boolean().default(!1),lfs:a.z.boolean().default(!1),subdirectory:a.z.string().trim().max(240).default("")}).strict();a.z.object({id:vi,name:a.z.string().trim().min(1).max(160),url:a.z.string().trim().min(1).max(2048),provider:a.z.string().trim().max(80).optional(),ref:Ts.default({type:"branch",name:"main"}),auth:Es.default({type:"none"}),clone:Cs.default({submodules:!1,lfs:!1,subdirectory:""}),defaultImageSelection:Pi.optional(),labels:Si,createdAt:wi,updatedAt:wi}).strict();const xs=a.z.object({id:vi,nodeId:vi,name:a.z.string().trim().min(1).max(160),path:a.z.string().trim().min(1).max(4096),defaultImageSelection:Pi.optional(),labels:Si,createdAt:wi,updatedAt:wi}).strict(),Ns=a.z.discriminatedUnion("type",[a.z.object({type:a.z.literal("git-repository"),repositoryId:vi.optional(),url:a.z.string().trim().min(1).max(2048),provider:a.z.string().trim().max(80).optional(),ref:Ts.default({type:"branch",name:"main"}),auth:Es.default({type:"none"}),clone:Cs.default({submodules:!1,lfs:!1,subdirectory:""})}).strict(),a.z.object({type:a.z.literal("git-template"),url:a.z.string().trim().min(1).max(2048),templateId:a.z.string().trim().min(1).max(120).optional(),ref:Ts.default({type:"branch",name:"main"}),auth:Es.default({type:"none"}),clone:Cs.default({submodules:!1,lfs:!1,subdirectory:""})}).strict(),a.z.object({type:a.z.literal("local-folder"),localFolderId:vi.optional(),path:a.z.string().trim().min(1).max(4096),ownerNodeId:vi.optional()}).strict()]),Os=a.z.object({mode:a.z.enum(["local-bind","git-clone","empty-volume","persistent-volume"]),path:a.z.string().trim().min(1).max(4096).default("/workspace"),volumeName:a.z.string().trim().max(240).optional(),readOnly:a.z.boolean().default(!1)}).strict(),_s=a.z.enum(["codex","claude"]),Rs=a.z.object({id:vi,name:a.z.string().trim().min(1).max(160),source:Ns,defaultImageSelection:Pi.optional(),defaultNodeId:vi.optional(),defaultRuntimeId:vi.optional(),workspacePolicy:Os,labels:Si,createdAt:wi,updatedAt:wi}).strict(),Ps=a.z.object({id:vi,name:a.z.string().trim().min(1).max(160),endpoint:a.z.string().trim().min(1).max(2048),key:a.z.string().trim().min(1).max(4096),model:a.z.string().trim().min(1).max(240),app:_s,enabled:a.z.boolean().default(!0),order:a.z.number().int().min(0).max(1e6).default(0),labels:Si,createdAt:wi,updatedAt:wi}).strict(),js=Ps.omit({key:!0}).extend({keyPreview:a.z.string().trim().min(1).max(160),keySet:a.z.boolean()}).strict(),Ds=js.extend({referenceCount:a.z.number().int().min(0)}).strict(),Ms=a.z.object({instanceId:vi,codexModelHash:vi.optional(),claudeModelHash:vi.optional(),updatedAt:wi}).strict(),Ls=a.z.discriminatedUnion("type",[a.z.object({type:a.z.literal("control-plane"),name:Ps.shape.name,enabled:Ps.shape.enabled,order:Ps.shape.order}).strict(),a.z.object({type:a.z.literal("node"),nodeId:vi,name:Ps.shape.name,enabled:Ps.shape.enabled,order:Ps.shape.order,referenceCount:a.z.number().int().min(0)}).strict()]),qs=a.z.object({id:vi,model:js,locations:a.z.array(Ls).min(1),referenceCount:a.z.number().int().min(0).default(0)}).strict(),$s=a.z.object({nodeId:vi,code:a.z.string().trim().min(1).max(120),message:a.z.string().trim().min(1).max(2e3)}).strict(),Bs=a.z.object({models:a.z.array(qs),nodeDiagnostics:a.z.array($s).default([]),updatedAt:wi}).strict();function Us(e){const t={app:_s.parse(e.app),endpoint:Ps.shape.endpoint.parse(e.endpoint),key:Ps.shape.key.parse(e.key),model:Ps.shape.model.parse(e.model)};return`mdl_${i.createHash("sha256").update(JSON.stringify(t)).digest("hex")}`}Ps.omit({id:!0,createdAt:!0,updatedAt:!0}).strict().partial().strict(),a.z.object({modelSelection:Ri,codexModelHash:vi.optional(),claudeModelHash:vi.optional()}).strict();const Fs=a.z.enum(["market","custom"]),Hs=a.z.enum(["active","deprecated","yanked"]),Ws=a.z.discriminatedUnion("kind",[a.z.object({kind:a.z.literal("builtin"),key:a.z.string().trim().min(1).max(120)}).strict(),a.z.object({kind:a.z.literal("remote"),url:a.z.string().trim().url().max(2048),mediaType:a.z.enum(["image/png","image/jpeg","image/webp"]).optional(),digest:_i.optional()}).strict()]),Gs={kind:"builtin",key:"default-image-cover"},Vs=a.z.array(a.z.string().trim().min(1).max(80)).default([]),Ks=a.z.array(a.z.string().trim().min(1).max(120)).default([]),Js=a.z.record(a.z.string().trim().min(2).max(35),a.z.string().trim().min(1).max(4096)),Ys=a.z.object({os:a.z.string().trim().min(1).max(40),architecture:a.z.string().trim().min(1).max(40),digest:_i.optional(),downloadSizeBytes:a.z.number().int().positive().optional(),unpackedSizeBytes:a.z.number().int().positive().optional()}).strict(),Qs=a.z.object({name:a.z.string().trim().min(1).max(128).regex(ki),version:a.z.string().trim().min(1).max(160).optional(),reference:Oi,manifestDigest:_i.optional(),publishedAt:wi.optional(),platforms:a.z.array(Ys).default([]),status:Hs.default("active")}).strict(),Xs=a.z.object({id:vi,publisher:a.z.string().trim().min(1).max(160),slug:a.z.string().trim().min(1).max(160),name:a.z.string().trim().min(1).max(160),description:a.z.string().trim().min(1).max(4096),localizedDescriptions:Js.optional(),cover:Ws.optional(),repository:a.z.string().trim().min(1).max(512),defaultTag:a.z.string().trim().min(1).max(128).regex(ki),tags:a.z.array(Qs).min(1),capabilities:Vs,optionalApps:Ks,defaultEnv:Ai,labels:Si,status:Hs.default("active")}).strict().superRefine((e,t)=>{e.tags.some(t=>t.name===e.defaultTag)||t.addIssue({code:"custom",path:["defaultTag"],message:"Market defaultTag must identify one of the image tags."})}),Zs=a.z.object({protocolVersion:ui,catalogId:vi,revision:a.z.string().trim().min(1).max(240),source:a.z.enum(["embedded","remote","cache"]),generatedAt:wi,expiresAt:wi.optional(),items:a.z.array(Xs)}).strict(),er=a.z.object({source:a.z.enum(["embedded","remote","cache"]),state:a.z.enum(["ready","refreshing","stale","failed"]),revision:a.z.string().trim().min(1).max(240),updatedAt:wi,error:a.z.string().trim().max(4096).optional()}).strict(),tr=a.z.object({id:vi,origin:a.z.literal("custom"),name:a.z.string().trim().min(1).max(160),description:a.z.string().trim().max(4096).optional(),localizedDescriptions:Js.optional(),cover:Ws.optional(),reference:Oi,repository:a.z.string().trim().min(1).max(512),tag:a.z.string().trim().min(1).max(128).regex(ki).optional(),pullPolicy:a.z.literal("if-not-present").default("if-not-present"),capabilities:Vs,optionalApps:Ks,defaultEnv:Ai,labels:Si,createdAt:wi,updatedAt:wi}).strict(),nr=a.z.object({name:a.z.string().trim().min(1).max(128).regex(ki),version:a.z.string().trim().min(1).max(160).optional(),reference:Oi,manifestDigest:_i.optional(),status:Hs}).strict(),ir=a.z.object({id:vi,origin:Fs,name:a.z.string().trim().min(1).max(160),description:a.z.string().trim().max(4096).optional(),localizedDescriptions:Js.optional(),cover:Ws,repository:a.z.string().trim().min(1).max(512),tag:a.z.string().trim().min(1).max(128).regex(ki).optional(),availableTags:a.z.array(nr),reference:Oi,digest:_i.optional(),downloadSizeBytes:a.z.number().int().positive().optional(),unpackedSizeBytes:a.z.number().int().positive().optional(),capabilities:Vs,optionalApps:Ks,defaultEnv:Ai,labels:Si,readOnly:a.z.boolean(),lifecycleStatus:Hs.optional(),market:a.z.object({catalogId:vi,catalogRevision:a.z.string().trim().min(1).max(240),publisher:a.z.string().trim().min(1).max(160),version:a.z.string().trim().min(1).max(160).optional()}).strict().optional()}).strict(),sr=a.z.object({id:vi,origin:Fs,name:a.z.string().trim().min(1).max(160),description:a.z.string().trim().max(4096).optional(),localizedDescriptions:Js.optional(),cover:Ws.optional(),repository:a.z.string().trim().min(1).max(512),tag:a.z.string().trim().min(1).max(128).regex(ki).optional(),requestedReference:Oi,resolvedDigest:_i.optional(),resolvedReference:Oi.optional(),downloadSizeBytes:a.z.number().int().positive().optional(),pullPolicy:a.z.literal("if-not-present").default("if-not-present"),capabilities:Vs,optionalApps:Ks,defaultEnv:Ai,labels:Si,market:a.z.object({catalogId:vi,catalogRevision:a.z.string().trim().min(1).max(240),publisher:a.z.string().trim().min(1).max(160),version:a.z.string().trim().min(1).max(160).optional()}).strict().optional(),createdAt:wi,updatedAt:wi}).strict(),rr=a.z.object({phase:a.z.enum(["checking-image","pulling-image","resolving-image","ready","failed"]),requestedReference:Oi,generation:a.z.number().int().nonnegative().default(0),error:a.z.string().trim().max(4096).optional(),startedAt:wi,updatedAt:wi}).strict(),or="image.pull.terminal.output",ar="image.pull.terminal.finished",dr=a.z.object({instanceId:vi,generation:a.z.number().int().nonnegative(),requestedReference:Oi,sequence:a.z.number().int().nonnegative(),observedAt:wi}).strict(),cr=dr.extend({data:a.z.string().min(1).max(65536),replay:a.z.boolean().optional()}).strict(),lr=dr.extend({outcome:a.z.enum(["succeeded","failed"])}).strict(),pr=dr.extend({status:a.z.enum(["connecting","pulling","extracting","complete","failed"]),layers:a.z.object({total:a.z.number().int().nonnegative(),completed:a.z.number().int().nonnegative(),downloaded:a.z.number().int().nonnegative(),downloading:a.z.number().int().nonnegative(),extracting:a.z.number().int().nonnegative()}).strict(),bytes:a.z.object({current:a.z.number().finite().nonnegative(),total:a.z.number().finite().positive()}).strict().optional(),percent:a.z.number().finite().min(0).max(100).optional(),message:a.z.string().trim().min(1).max(500),terminalTail:a.z.string().max(262144).optional(),terminalTruncated:a.z.boolean().optional()}).strict();function ur(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e,i=new Set(["id","origin","name","description","localizedDescriptions","cover","reference","repository","tag","image","registry","pullPolicy","capabilities","optionalApps","defaultEnv","labels","createdAt","updatedAt"]);for(const e of Object.keys(n))i.has(e)||t?.({imageId:"string"==typeof n.id?n.id:void 0,field:e});const s="string"==typeof n.id?n.id:void 0,r="string"==typeof n.image?n.image:void 0;void 0!==r&&t?.({imageId:s,field:"image"}),Object.prototype.hasOwnProperty.call(n,"registry")&&t?.({imageId:s,field:"registry"});let o,a="string"==typeof n.reference?n.reference:r;if(a)try{a=xi(a)}catch{if(!a.includes("@")&&a.lastIndexOf(":")<=a.lastIndexOf("/"))try{a=xi(`${a}:latest`),t?.({imageId:s,field:"reference:implicit-latest"})}catch{}}try{o=a?Ni(a):void 0}catch{}return{id:n.id,origin:"custom",name:n.name,description:n.description,localizedDescriptions:n.localizedDescriptions,cover:Br(n.cover,["kind","key","url","mediaType","digest"]),reference:o?.reference??a,repository:o?.repository??n.repository,tag:o?.tag??n.tag,pullPolicy:n.pullPolicy??"if-not-present",capabilities:n.capabilities,optionalApps:n.optionalApps,defaultEnv:n.defaultEnv,labels:n.labels,createdAt:n.createdAt,updatedAt:n.updatedAt}}const gr=a.z.discriminatedUnion("kind",[a.z.object({kind:a.z.literal("direct")}).strict(),a.z.object({kind:a.z.literal("control-plane-proxy"),proxyId:vi,proxyBindingId:vi,targetNodeId:vi}).strict()]),hr=a.z.object({reachability:a.z.enum(["unknown","reachable","unreachable"]),bindingStatus:a.z.enum(["unknown","active","revoked"]),bindingRevision:a.z.number().int().positive().optional(),streamId:a.z.string().trim().min(1).max(160).optional(),revision:a.z.number().int().nonnegative().optional(),observedAt:wi.optional(),target:ti.optional(),lastError:Gn.optional(),updatedAt:wi}).strict(),mr=a.z.object({id:vi,name:a.z.string().trim().min(1).max(160),connectionMode:a.z.enum(["local-ipc","local-loopback","direct-http","reverse-wss","control-plane-proxy"]).default("direct-http"),connectionPath:gr.default({kind:"direct"}),connectionEnabled:a.z.boolean().default(!0),auth:a.z.object({mode:a.z.enum(["local-static-key","paired-hmac","proxy-binding"]).default("local-static-key"),keyId:vi.optional(),secret:a.z.string().trim().max(4096).optional(),pairedAt:wi.optional(),pairing:a.z.object({status:a.z.enum(["pending","paired","expired"]).default("pending"),joinToken:a.z.string().trim().max(4096).optional(),expiresAt:wi.optional()}).strict().optional()}).strict().default({mode:"local-static-key"}),endpoint:a.z.string().trim().max(2048).optional(),controlEndpoint:a.z.string().trim().max(2048).optional(),containerEndpoint:a.z.string().trim().max(2048).optional(),publicWebBase:a.z.string().trim().max(2048).optional(),status:a.z.enum(["unknown","online","offline","degraded"]).default("unknown"),health:a.z.enum(["unknown","ok","degraded","failed"]).default("unknown"),capabilities:a.z.record(a.z.string(),a.z.unknown()).default({}),proxyState:hr.optional(),appInventory:Yi.optional(),labels:Si,lastSeenAt:wi.optional(),createdAt:wi,updatedAt:wi}).strict().superRefine((e,t)=>{"control-plane-proxy"===e.connectionPath.kind&&"control-plane-proxy"!==e.connectionMode&&t.addIssue({code:"custom",path:["connectionPath"],message:"Control-plane proxy paths require control-plane-proxy connection mode."}),"control-plane-proxy"===e.connectionMode&&"control-plane-proxy"!==e.connectionPath.kind&&t.addIssue({code:"custom",path:["connectionPath"],message:"Control-plane proxy nodes require a control-plane-proxy connection path."})}),yr=a.z.object({id:vi,nodeId:vi,name:a.z.string().trim().min(1).max(160),type:a.z.enum(["docker","kubernetes","local"]),status:a.z.enum(["unknown","online","offline","degraded"]).default("unknown"),accessStrategy:a.z.enum(["node-proxy","direct-port","kubernetes-ingress","kubernetes-port-forward"]).default("node-proxy"),capabilities:a.z.record(a.z.string(),a.z.unknown()).default({}),labels:Si,createdAt:wi,updatedAt:wi}).strict(),fr=a.z.object({instanceId:vi,runtimeKind:a.z.literal("docker"),state:a.z.enum(["pending","available","stopped","unavailable"]),sampledAt:wi,cpu:a.z.object({usagePercent:a.z.number().nonnegative()}).strict().optional(),memory:a.z.object({usageBytes:a.z.number().nonnegative(),limitBytes:a.z.number().nonnegative().optional(),usagePercent:a.z.number().nonnegative().optional()}).strict().optional(),network:a.z.object({rxBytes:a.z.number().nonnegative(),txBytes:a.z.number().nonnegative()}).strict().optional(),blockIo:a.z.object({readBytes:a.z.number().nonnegative(),writeBytes:a.z.number().nonnegative()}).strict().optional(),pids:a.z.number().int().nonnegative().optional(),error:a.z.string().trim().max(2048).optional()}).strict(),Ir=a.z.object({modelEndpointProbe:a.z.boolean().optional(),aiSessionHistoryLimit:a.z.boolean().optional(),folderPlaces:a.z.boolean().optional()}).strip(),br=a.z.object({ok:a.z.boolean().optional(),role:a.z.string().optional(),nodeId:vi.optional(),platform:Mi.optional(),arch:Li.optional(),protocolVersion:ui.optional(),capabilities:Ir.optional(),build:hs.strip().optional(),process:a.z.object({pid:a.z.number().int().positive(),startIdentity:a.z.string().trim().min(1).optional()}).strip().optional(),listener:a.z.object({host:a.z.string().trim().min(1),port:a.z.number().int().min(1).max(65535)}).strip().optional(),instanceProxy:a.z.object({requests:a.z.number().int().nonnegative(),active:a.z.number().int().nonnegative(),completed:a.z.number().int().nonnegative(),aborted:a.z.number().int().nonnegative(),limitRejected:a.z.number().int().nonnegative(),responseBytes:a.z.number().nonnegative(),totalDurationMs:a.z.number().nonnegative(),maxResponseBytes:a.z.number().int().nonnegative()}).partial().strip().optional(),serverTime:wi.optional()}).strip(),vr=a.z.object({bindScope:a.z.enum(["loopback","all-ipv4"]),port:a.z.number().int().min(1).max(65535)}).strict().extend({host:a.z.enum(["127.0.0.1","0.0.0.0"]),status:a.z.enum(["listening","error"]),source:a.z.enum(["bootstrap","persisted"]),error:a.z.string().trim().max(2048).optional()}).strict(),wr=a.z.object({nodeId:vi,joinToken:a.z.string().trim().min(1),expiresAt:wi}).passthrough(),Sr=a.z.object({nodeId:vi,keyId:vi,secret:a.z.string().regex(/^[A-Za-z0-9_-]{32,128}$/),pairedAt:wi}).strict(),Ar=a.z.object({id:vi,keyId:vi,name:a.z.string().trim().min(1).max(160).optional(),pairedAt:wi,updatedAt:wi,current:a.z.boolean()}).passthrough(),zr=a.z.object({keyId:vi,revoked:a.z.literal(!0),revokedAt:wi}).strict(),kr=a.z.object({id:vi,pairingKeyId:vi,url:a.z.string().trim().min(1).max(2048),name:a.z.string().trim().min(1).max(160).optional(),enabled:a.z.boolean(),createdAt:wi,updatedAt:wi,status:a.z.enum(["disabled","connecting","connected","reconnecting","failed"]),pingRttMs:a.z.number().nonnegative().optional(),pingRttP95Ms:a.z.number().nonnegative().optional(),consecutiveReconnects:a.z.number().int().nonnegative().optional(),nextRetryAt:wi.optional(),lastConnectedAt:wi.optional(),lastDisconnectedAt:wi.optional(),error:a.z.string().optional()}).passthrough(),Tr=a.z.object({pairing:Ar,connection:a.z.object({id:vi,pairingKeyId:vi,url:a.z.string().trim().min(1).max(2048),name:a.z.string().trim().min(1).max(160).optional(),enabled:a.z.boolean(),createdAt:wi,updatedAt:wi}).passthrough(),tunnel:a.z.object({status:a.z.enum(["disabled","saved","connecting","connected","failed"]),error:a.z.string().trim().max(2048).optional()}).passthrough()}).passthrough(),Er=a.z.object({deleted:a.z.boolean().optional()}).passthrough(),Cr=a.z.object({repository:a.z.string().trim().optional(),tag:a.z.string().trim().optional(),id:a.z.string().trim(),createdSince:a.z.string().trim().optional(),size:a.z.string().trim().optional(),sizeBytes:a.z.number().int().nonnegative().optional(),reference:a.z.string().trim().min(1),repoDigests:a.z.array(a.z.string().trim().min(1).max(512)).default([])}).passthrough(),xr=a.z.object({image:ir,status:a.z.enum(["available","pull-required","unknown"]),localImage:Cr.optional(),localSizeBytes:a.z.number().int().nonnegative().optional(),downloadSizeBytes:a.z.number().int().positive().optional(),unpackedSizeBytes:a.z.number().int().positive().optional(),error:a.z.string().trim().max(2048).optional()}).strict(),Nr=a.z.lazy(()=>a.z.object({name:a.z.string().trim().min(1),path:a.z.string().trim().min(1).max(4096),children:a.z.array(Nr)}).passthrough()),Or=a.z.object({kind:a.z.enum(["home","root"]),name:a.z.string().trim().min(1),path:a.z.string().trim().min(1).max(4096)}).passthrough(),_r=a.z.object({status:a.z.number().int().min(100).max(599).optional(),headers:a.z.record(a.z.string(),a.z.string()).optional(),bodyBase64:a.z.string().optional()}).passthrough(),Rr=a.z.object({strategy:a.z.enum(["node-proxy","direct-port","kubernetes-ingress","kubernetes-port-forward"]).default("node-proxy"),web:a.z.string().trim().max(2048).optional(),api:a.z.string().trim().max(2048).optional(),vnc:a.z.string().trim().max(2048).optional(),tty:a.z.string().trim().max(2048).optional(),logs:a.z.string().trim().max(2048).optional(),status:a.z.enum(["unknown","reachable","endpoint-unreachable"]).default("unknown")}).strict(),Pr=a.z.object({strategy:a.z.enum(["control-plane-proxy","direct-port","node-proxy","kubernetes-ingress","kubernetes-port-forward"]).default("control-plane-proxy"),web:a.z.string().trim().max(2048).optional(),api:a.z.string().trim().max(2048).optional(),ws:a.z.string().trim().max(2048).optional(),status:a.z.enum(["unknown","reachable","endpoint-unreachable"]).default("unknown")}).strict().default({strategy:"control-plane-proxy",status:"unknown"}),jr=a.z.object({mode:a.z.enum(["local-bind","git-clone","empty-volume","persistent-volume"]).optional(),status:a.z.enum(["unknown","pending","ready","failed"]).default("unknown"),path:a.z.string().trim().max(4096).optional(),resolvedCommit:a.z.string().trim().max(120).optional(),error:a.z.string().trim().max(2048).optional()}).passthrough(),Dr=a.z.object({id:vi,name:a.z.string().trim().min(1).max(160),projectId:vi.optional(),source:Ns,sourceSnapshot:a.z.record(a.z.string(),a.z.unknown()).default({}),modelSelection:Ri,nodeId:vi,runtimeId:vi,imageSelection:Pi.optional(),environmentSource:ji.optional(),environmentTemplateOrigin:$i.optional(),imageSnapshot:sr.optional(),imageProvisioning:rr.optional(),stateRevision:a.z.number().int().min(0).default(0),processIncarnationId:a.z.string().trim().min(1).max(120).optional(),status:a.z.enum(["created","provisioning","starting","registering","registered","running","stopping","stopped","deleting","failed","unhealthy"]).default("created"),health:a.z.enum(["unknown","ok","degraded","failed"]).default("unknown"),connectionStatus:a.z.enum(["unknown","online","offline","endpoint-unreachable"]).default("unknown"),agentStatus:a.z.enum(["unknown","online","offline"]).default("unknown"),targetStatus:a.z.enum(["unknown","reachable","endpoint-unreachable"]).default("unknown"),uiAccessStatus:a.z.enum(["unknown","reachable","endpoint-unreachable"]).default("unknown"),controlMode:a.z.enum(["standalone","controlled"]).default("controlled"),protocolVersion:ui.optional(),instanceVersion:a.z.string().trim().max(80).optional(),build:hs.optional(),runtimeVersion:bs.optional(),ready:a.z.boolean().default(!1),capabilities:fi.default(hi),appInventory:Yi.optional(),config:a.z.object({autoImportAgentConfigs:a.z.boolean().default(!0),defaultCodexPermissionMode:de.default("ask"),aiSessionHistoryLimit:a.z.number().int().min(1).max(Ve).default(50)}).strict().default({autoImportAgentConfigs:!0,defaultCodexPermissionMode:"ask",aiSessionHistoryLimit:50}),workspace:jr.default({status:"unknown"}),target:Rr.default({strategy:"direct-port",status:"unknown"}),access:Pr,apps:a.z.object({runningCount:a.z.number().int().min(0).default(0),problemCount:a.z.number().int().min(0).default(0),updatedAt:wi.optional(),revision:a.z.number().int().min(0).optional()}).strict().default({runningCount:0,problemCount:0}),aiSessions:Ze.default(()=>({runningCount:0,waitingCount:0,staleCount:0,sessions:[],updatedAt:(new Date).toISOString()})),triggers:a.z.object({enabledCount:a.z.number().int().min(0).default(0),runningCount:a.z.number().int().min(0).default(0),errorCount:a.z.number().int().min(0).default(0),configs:a.z.array(a.z.object({configHash:a.z.string().trim().min(1),config:fn,deployments:a.z.array(bn).default([]),runtime:a.z.array(vn).default([])}).strict()).default([]),recentRuns:a.z.array(wn).default([])}).strict().optional(),runtime:a.z.object({kind:a.z.string().trim().max(80).optional(),containerName:a.z.string().trim().max(240).optional(),containerId:a.z.string().trim().max(240).optional(),workspacePath:a.z.string().trim().max(4096).optional(),pid:a.z.number().int().positive().optional(),port:a.z.number().int().positive().max(65535).optional(),labels:a.z.record(a.z.string(),a.z.string()).default({})}).strict().default({labels:{}}),registrationToken:a.z.string().trim().min(1).max(240).optional(),lastHeartbeatAt:wi.optional(),createdAt:wi,updatedAt:wi}).strict(),Mr="instance.lifecycle.snapshot",Lr=a.z.object({instanceId:Dr.shape.id,revision:a.z.number().int().min(0),updatedAt:wi,status:Dr.shape.status.unwrap(),health:Dr.shape.health.unwrap(),connectionStatus:Dr.shape.connectionStatus.unwrap(),accessStatus:a.z.enum(["reachable","endpoint-unreachable"]),imageProvisioning:rr.optional(),workspace:jr,runtime:Dr.shape.runtime.unwrap(),runtimeVersion:bs.optional(),ready:a.z.boolean(),lastHeartbeatAt:wi.optional()}).strict();function qr(e,t,n,i,s){if(!t||"object"!=typeof t||Array.isArray(t))return;let r=structuredClone(t);for(let t=0;t<20;t+=1){const t=e.safeParse(r);if(t.success)return t.data;let n=!1;for(const e of t.error.issues){if("unrecognized_keys"!==e.code)continue;const t=$r(r,e.path);if(t&&"object"==typeof t&&!Array.isArray(t))for(const i of e.keys)Object.prototype.hasOwnProperty.call(t,i)&&(delete t[i],n=!0)}if(!n){const n=structuredClone(r);let i=!1;for(const e of t.error.issues){if(!e.path.length||"string"!=typeof e.path.at(-1))continue;const t=$r(n,e.path.slice(0,-1)),s=e.path.at(-1);t&&"object"==typeof t&&!Array.isArray(t)&&Object.prototype.hasOwnProperty.call(t,s)&&(delete t[s],i=!0)}if(i){const t=e.safeParse(n);if(t.success)return t.data}break}}}function $r(e,t){let n=e;for(const e of t){if(!n||"object"!=typeof n)return;n=n[e]}return n}function Br(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e;return Object.fromEntries(t.filter(e=>Object.prototype.hasOwnProperty.call(n,e)).map(e=>[e,n[e]]))}a.z.object({instanceId:vi.optional(),projectId:vi.optional(),source:Ns.optional(),nodeId:vi.optional(),runtimeId:vi.optional(),imageSelection:Pi.optional(),instanceVersion:a.z.string().trim().max(80).optional(),protocolVersion:ui,build:hs.optional(),controlMode:a.z.enum(["standalone","controlled"]).default("controlled"),capabilities:fi.default(hi),appInventory:Yi.optional(),target:Rr.default({strategy:"direct-port",status:"unknown"}),workspace:jr.default({status:"unknown"}),registrationToken:a.z.string().trim().max(240).optional(),processIncarnationId:a.z.string().trim().min(1).max(120).optional()}).strict().superRefine((e,t)=>{pi.has(e.protocolVersion)&&!e.appInventory&&t.addIssue({code:"custom",path:["appInventory"],message:"Current protocol register payload requires appInventory."})}),a.z.object({status:Dr.shape.status.optional(),health:Dr.shape.health.optional(),protocolVersion:ui,build:hs.optional(),capabilities:Dr.shape.capabilities.optional(),appInventory:Yi.optional(),apps:Dr.shape.apps.optional(),aiSessions:Dr.shape.aiSessions.optional(),triggers:Dr.shape.triggers.optional(),workspace:jr.optional(),target:Rr.partial().optional(),processIncarnationId:a.z.string().trim().min(1).max(120).optional()}).strict().superRefine((e,t)=>{pi.has(e.protocolVersion)&&!e.appInventory&&t.addIssue({code:"custom",path:["appInventory"],message:"Current protocol heartbeat payload requires appInventory."})});const Ur=a.z.enum(["web","telegram","wechat","dingding","lark"]),Fr=a.z.object({id:vi,channel:Ur,name:a.z.string().trim().min(1).max(160),enabled:a.z.boolean().default(!1),token:a.z.string().trim().max(4096).optional(),defaultChatId:a.z.string().trim().max(240).optional(),allowedUserIds:a.z.array(a.z.string().trim().min(1).max(240)).default([]),pollIntervalMs:a.z.number().int().positive().max(6e4).default(3e3),settings:a.z.record(a.z.string(),a.z.unknown()).default({}),createdAt:wi,updatedAt:wi}).strict(),Hr=a.z.object({id:vi,channel:Ur,bridgeId:vi.optional(),chatSessionId:a.z.string().trim().min(1).max(240),userId:a.z.string().trim().max(240).optional(),activeProjectId:vi.optional(),activeInstanceId:vi.optional(),activeAiSessionId:a.z.string().trim().min(1).max(120).optional(),lastUsedAt:wi,createdAt:wi,updatedAt:wi}).strict(),Wr=a.z.object({source:a.z.object({type:a.z.literal("chat-gateway").default("chat-gateway"),channel:Ur,bridgeId:vi.optional(),chatSessionId:a.z.string().trim().min(1).max(240),userId:a.z.string().trim().max(240).optional()}).strict(),message:a.z.object({text:a.z.string().trim().max(2e4).default(""),attachments:a.z.array(se).max(6).default([])}).strict().superRefine((e,t)=>{e.attachments.reduce((e,t)=>e+("inline"===t.source.type?t.size:0),0)>x&&t.addIssue({code:a.z.ZodIssueCode.custom,path:["attachments"],message:"Inline attachments must be 41943040 bytes or less in total."})}),target:a.z.object({instanceId:vi,aiSessionId:a.z.string().trim().min(1).max(120)}).strict().optional()}).strict(),Gr=a.z.object({id:vi,instanceId:vi,projectId:vi.optional(),aiSessionId:a.z.string().trim().min(1).max(120),providerSessionId:a.z.string().trim().max(240).optional(),result:a.z.string().default(""),timeoutMs:a.z.number().positive().optional(),source:a.z.string().trim().max(120).optional(),kind:a.z.enum(["task","approval"]).default("task"),status:a.z.enum(["pending","unreachable"]).default("pending"),error:a.z.string().trim().max(2048).optional(),lastSeenAt:wi}).strict();function Vr(e){return!1!==e.ready&&(!e.runtimeVersion||["matched","failed"].includes(e.runtimeVersion.phase))}const Kr=6048e5;function Jr(e,n){const i=t.resolve(e),s=t.resolve(i,n);if(t.dirname(s)!==i||t.basename(s)!==n)throw new Error(`Retention entry is not a direct child of its managed root: ${n}`);return s}function Yr(e){if(n.existsSync(e)){const t=n.lstatSync(e);if(!t.isDirectory()||t.isSymbolicLink())throw new Error(`Managed persistence path must be a real directory: ${e}`)}n.mkdirSync(e,{recursive:!0,mode:448}),n.chmodSync(e,448)}function Qr(e){return e.startsWith("ai-session.")||e.startsWith("ai.session.")?"ai.sessions":e.startsWith("app-session.")?"app.sessions":e.startsWith("app.management")?"apps":e.startsWith("trigger.")?"triggers":e.startsWith("instance.")?"instances":e.startsWith("node.")?"nodes":e.startsWith("project.")?"projects":e.startsWith("model.")?"models":e.startsWith("image.")?"images":e.startsWith("market.")?"market":"system"}const Xr=a.z.enum(["ai.sessions","app.sessions"]),Zr=a.z.object({topic:Xr,instanceId:a.z.string().trim().min(1).max(160),streamId:a.z.string().trim().min(1).max(240),latestRevision:a.z.number().int().min(0),earliestRetainedRevision:a.z.number().int().min(0)}).strict(),eo=a.z.object({protocolVersion:a.z.literal(1),streams:a.z.array(Zr)}).strict(),to=a.z.object({authentication:a.z.enum(["required","disabled"]),aiSessions:a.z.boolean(),nodes:a.z.boolean(),instanceBoard:a.z.boolean(),triggers:a.z.boolean().optional()}).strict(),no=a.z.object({version:a.z.literal(1),kind:a.z.literal("control-plane"),controlPlaneId:a.z.string().trim().min(1).max(160),publicKey:a.z.object({algorithm:a.z.literal("Ed25519"),encoding:a.z.literal("base64url"),value:a.z.string().regex(/^[A-Za-z0-9_-]{43}$/),fingerprint:a.z.string().regex(/^sha256:[A-Za-z0-9_-]{43}$/)}).strict(),capabilities:to,protocolVersion:a.z.string().regex(/^\d{4}-\d{2}-\d{2}$/),issuedAt:a.z.string().datetime(),expiresAt:a.z.string().datetime()}).strict(),io=a.z.object({data:a.z.object({payload:no,signature:a.z.string().regex(/^[A-Za-z0-9_-]{86}$/)}).strict()}).strict(),so=a.z.object({id:a.z.string().trim().min(8).max(160),name:a.z.string().trim().min(1).max(160),platform:a.z.enum(["ios","android"]),appVersion:a.z.string().trim().min(1).max(80).optional()}).strict(),ro=a.z.object({username:a.z.string().trim().min(1).max(80),password:a.z.string().min(1).max(4096),device:so}).strict(),oo=a.z.object({id:a.z.string().trim().min(1),username:a.z.string().trim().min(1).max(80),role:a.z.enum(["viewer","operator","admin"]),createdAt:a.z.string().datetime(),updatedAt:a.z.string().datetime(),lastLoginAt:a.z.string().datetime().optional()}).strict(),ao=a.z.object({id:a.z.string().trim().min(1),expiresAt:a.z.string().datetime(),createdAt:a.z.string().datetime(),lastSeenAt:a.z.string().datetime().optional(),device:so,user:oo}).strict();a.z.object({data:a.z.object({sessionToken:a.z.string().trim().min(32),session:ao}).strict()}).strict(),a.z.object({data:a.z.array(ao)}).strict(),a.z.object({data:a.z.object({revoked:a.z.boolean()}).strict()}).strict();function co(e,t=448){n.mkdirSync(e,{recursive:!0,mode:t}),n.chmodSync(e,t)}function lo(e,i,s={}){const r=s.directoryMode??448,o=s.fileMode??384;co(t.dirname(e),r),c.sync(e,`${JSON.stringify(i,null,2)}\n`,{encoding:"utf8",mode:o}),n.chmodSync(e,o)}function po(e,t){console.warn(JSON.stringify({message:e,...t}))}function uo(e){return e&&"object"==typeof e&&"issues"in e?{issues:e.issues}:{error:e instanceof Error?e.message:String(e)}}function go(e,t){const i=t.logger||po;let s;try{s=JSON.parse(n.readFileSync(e,"utf8"))}catch(t){return void i("stored JSON could not be read",{filePath:e,...uo(t)})}if(!t.schema)return s;const r=t.sanitize?t.sanitize(s):s,o=t.schema.safeParse(r);if(o.success)return o.data;const a="strip"in t.schema&&"function"==typeof t.schema.strip?t.schema.strip().safeParse(r):void 0;if(a?.success)return i("unknown stored fields were ignored",{filePath:e,issues:o.error.issues}),a.data;i("stored record failed validation and was isolated",{filePath:e,issues:o.error.issues})}function ho(e){return`${e}_${i.randomUUID().replace(/-/g,"").slice(0,20)}`}function mo(){return i.randomBytes(24).toString("base64url")}class yo{directory;options;permissionsInitialized=!1;constructor(e,t={}){this.directory=e,this.options=t}init(){if(this.permissionsInitialized&&n.existsSync(this.directory))return;co(this.directory,this.options.directoryMode??448);const e=this.options.fileMode??384;for(const i of n.readdirSync(this.directory).filter(e=>e.endsWith(".json")))n.chmodSync(t.join(this.directory,i),e);this.permissionsInitialized=!0}filePath(e){return t.join(this.directory,`${e}.json`)}list(){return this.init(),n.readdirSync(this.directory).filter(e=>e.endsWith(".json")).sort().flatMap(e=>{const n=go(t.join(this.directory,e),this.options);return n?[n]:[]})}get(e){this.init();const t=this.filePath(e);return n.existsSync(t)?go(t,this.options):void 0}put(e){const t=this.options.sanitize?this.options.sanitize(e):e,n=this.options.schema?this.options.schema.parse(t):t;return lo(this.filePath(n.id),n,this.options),n}patch(e,t){const n=this.get(e);if(!n)return;const i={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:(new Date).toISOString()};return this.put(i)}delete(e){const t=this.filePath(e);return!!n.existsSync(t)&&(n.unlinkSync(t),!0)}}class fo{filePathValue;defaults;options;constructor(e,t,n={}){this.filePathValue=e,this.defaults=t,this.options=n}init(){co(t.dirname(this.filePathValue),this.options.directoryMode??448),n.existsSync(this.filePathValue)?n.chmodSync(this.filePathValue,this.options.fileMode??384):this.put(this.defaults())}get(){return this.init(),n.existsSync(this.filePathValue)?go(this.filePathValue,this.options)??this.defaults():this.defaults()}put(e){const t=this.options.sanitize?this.options.sanitize(e):e,n=this.options.schema?this.options.schema.parse(t):t;return lo(this.filePathValue,n,this.options),n}}const Io=d.promisify(i.scrypt),bo="task_handoff_cp_session",vo=a.z.enum(["disabled","password"]),wo=a.z.string().trim().min(1).max(80).regex(/^[a-zA-Z0-9_.@-]+$/),So=a.z.string().min(8).max(4096),Ao=a.z.object({username:wo,password:So}).strict(),zo=a.z.object({username:a.z.string().trim().min(1).max(80),password:a.z.string().min(1).max(4096)}).strict(),ko=a.z.object({currentPassword:a.z.string().min(1).max(4096),newPassword:So}).strict(),To=a.z.object({username:wo,password:So}).strict(),Eo=a.z.object({id:a.z.string().trim().min(1),createdAt:a.z.string().datetime(),updatedAt:a.z.string().datetime()}),Co=Eo.extend({username:wo,passwordHash:a.z.string().trim().min(1),role:a.z.enum(["viewer","operator","admin"]),lastLoginAt:a.z.string().datetime().optional()}).strict(),xo=Eo.extend({userId:a.z.string().trim().min(1),tokenHash:a.z.string().trim().min(1),expiresAt:a.z.string().datetime(),lastSeenAt:a.z.string().datetime().optional(),clientType:a.z.enum(["web","mobile"]).default("web"),device:so.optional()}).strict().refine(e=>"mobile"!==e.clientType||Boolean(e.device),{path:["device"],message:"Mobile sessions require device metadata."});function No(){return(new Date).toISOString()}function Oo(e,t){return Number.isInteger(e)&&Number(e)>0?Number(e):t}class _o{options;sourceFailures=new Map;usernameFailures=new Map;concurrent=0;constructor(e={}){this.options=function(e={}){return{windowMs:Oo(e.windowMs,9e5),maxFailuresPerSource:Oo(e.maxFailuresPerSource,20),maxFailuresPerUsername:Oo(e.maxFailuresPerUsername,10),maxConcurrent:Oo(e.maxConcurrent,4)}}(e)}begin(e,t){const n=Date.now();if(this.assertBucketAvailable(this.sourceFailures,e,this.options.maxFailuresPerSource,n),this.assertBucketAvailable(this.usernameFailures,t,this.options.maxFailuresPerUsername,n),this.concurrent>=this.options.maxConcurrent)throw Ro("Too many password verifications are already in progress.",1e3);this.concurrent+=1}finish(){this.concurrent=Math.max(0,this.concurrent-1)}recordFailure(e,t){const n=Date.now();this.record(this.sourceFailures,e,n),this.record(this.usernameFailures,t,n),this.sourceFailures.size+this.usernameFailures.size>1e4&&(this.pruneAll(n),this.trimOldest(this.sourceFailures,5e3),this.trimOldest(this.usernameFailures,5e3))}assertBucketAvailable(e,t,n,i){const s=this.currentFailures(e,t,i);if(!(s.length<n))throw Ro("Too many failed sign-in attempts. Try again later.",s[0]+this.options.windowMs-i)}record(e,t,n){const i=this.currentFailures(e,t,n);i.push(n),e.set(t,i)}currentFailures(e,t,n){const i=n-this.options.windowMs,s=(e.get(t)||[]).filter(e=>e>i);return s.length?e.set(t,s):e.delete(t),s}pruneAll(e){for(const[t]of this.sourceFailures)this.currentFailures(this.sourceFailures,t,e);for(const[t]of this.usernameFailures)this.currentFailures(this.usernameFailures,t,e)}trimOldest(e,t){for(;e.size>t;){const t=e.keys().next().value;if(void 0===t)return;e.delete(t)}}}function Ro(e,t){const n=new Error(e);return Object.assign(n,{statusCode:429,code:"AUTH_LOGIN_RATE_LIMITED",retryable:!0,retryAfterSeconds:Math.max(1,Math.ceil(t/1e3))}),n}function Po(e){return i.createHash("sha256").update(e).digest("base64url")}async function jo(e){const t=i.randomBytes(16).toString("base64url");return`scrypt$${t}$${(await Io(e,t,64)).toString("base64url")}`}async function Do(e,t){const[n,s,r]=t.split("$");if("scrypt"!==n||!s||!r)return!1;const o=await Io(e,s,64),a=Buffer.from(r,"base64url");return a.length===o.length&&i.timingSafeEqual(a,o)}function Mo(e){return{id:e.id,username:e.username,role:e.role,createdAt:e.createdAt,updatedAt:e.updatedAt,lastLoginAt:e.lastLoginAt}}function Lo(e,t){return ao.parse({id:e.id,expiresAt:e.expiresAt,createdAt:e.createdAt,lastSeenAt:e.lastSeenAt,device:e.device,user:Mo(t)})}class qo{mode;users;sessions;loginRateLimiter;bootstrapAdminInProgress=!1;credentialUpdateInProgress=!1;constructor(e,t={}){this.mode=function(e={}){return vo.parse(e.mode||process.env.TASK_HANDOFF_CONTROL_PLANE_AUTH_MODE||"disabled")}(t),this.users=new yo(e.authUsersDir,{schema:Co}),this.sessions=new yo(e.authSessionsDir,{schema:xo}),this.loginRateLimiter=new _o(t.loginRateLimit)}init(){this.users.init(),this.sessions.init()}enabled(){return"password"===this.mode}state(){return{mode:this.mode,enabled:this.enabled(),requiresBootstrap:this.enabled()&&0===this.users.list().length}}async bootstrapAdmin(e){if(!this.enabled()){const e=new Error("Control Plane authentication is disabled.");throw Object.assign(e,{statusCode:400,code:"AUTH_DISABLED"}),e}if(this.bootstrapAdminInProgress){const e=new Error("Control Plane admin initialization is already in progress.");throw Object.assign(e,{statusCode:409,code:"AUTH_BOOTSTRAP_IN_PROGRESS"}),e}if(this.users.list().length>0){const e=new Error("Control Plane admin user already exists.");throw Object.assign(e,{statusCode:409,code:"AUTH_BOOTSTRAP_ALREADY_DONE"}),e}const t=Ao.parse(e);this.bootstrapAdminInProgress=!0;try{const e=No();return Mo(this.users.put({id:ho("user"),username:t.username,passwordHash:await jo(t.password),role:"admin",createdAt:e,updatedAt:e}))}finally{this.bootstrapAdminInProgress=!1}}async login(e,t={}){if(!this.enabled()){const e=new Error("Control Plane authentication is disabled.");throw Object.assign(e,{statusCode:400,code:"AUTH_DISABLED"}),e}const n=zo.parse(e),i=await this.authenticate(n.username,n.password,t),s=this.createSession(i,"web");return{user:Mo(i),sessionToken:s.token,expiresAt:s.record.expiresAt}}async loginMobile(e,t={}){const n=ro.parse(e),i=await this.authenticate(n.username,n.password,t),s=this.createSession(i,"mobile",n.device);return{sessionToken:s.token,session:Lo(s.record,i)}}async changePassword(e,t,n={}){const i=this.resolveSessionToken(e,"web");if(!i){const e=new Error("Sign in to change the password.");throw Object.assign(e,{statusCode:401,code:"CONTROL_PLANE_AUTH_REQUIRED"}),e}const s=ko.parse(t);if(this.credentialUpdateInProgress){const e=new Error("Control Plane credentials are already being updated.");throw Object.assign(e,{statusCode:409,code:"AUTH_CREDENTIAL_UPDATE_IN_PROGRESS"}),e}this.credentialUpdateInProgress=!0;const r=String(n.sourceId||"unknown").trim()||"unknown",o=i.storedUser.username.toLocaleLowerCase("en-US");let a=!1;try{if(this.loginRateLimiter.begin(r,o),a=!0,!await Do(s.currentPassword,i.storedUser.passwordHash)){this.loginRateLimiter.recordFailure(r,o);const e=new Error("The current password is incorrect.");throw Object.assign(e,{statusCode:400,code:"AUTH_CURRENT_PASSWORD_INVALID"}),e}if(await Do(s.newPassword,i.storedUser.passwordHash)){const e=new Error("The new password must be different from the current password.");throw Object.assign(e,{statusCode:400,code:"AUTH_PASSWORD_UNCHANGED"}),e}const e=No(),t=this.users.put({...i.storedUser,passwordHash:await jo(s.newPassword),updatedAt:e});this.revokeUserSessions(t.id);const n=this.createSession(t,"web");return{user:Mo(t),sessionToken:n.token,expiresAt:n.record.expiresAt}}finally{a&&this.loginRateLimiter.finish(),this.credentialUpdateInProgress=!1}}async replaceCredentials(e){const t=To.parse(e),n=this.users.list();if(0===n.length){const e=new Error("Control Plane administrator has not been initialized.");throw Object.assign(e,{statusCode:409,code:"AUTH_ACCOUNT_NOT_INITIALIZED"}),e}if(1!==n.length){const e=new Error("The account to update is ambiguous.");throw Object.assign(e,{statusCode:409,code:"AUTH_ACCOUNT_AMBIGUOUS"}),e}const i=No(),s=this.users.put({...n[0],username:t.username,passwordHash:await jo(t.password),updatedAt:i});return this.revokeUserSessions(s.id),Mo(s)}async authenticate(e,t,n){if(!this.enabled()){const e=new Error("Control Plane authentication is disabled.");throw Object.assign(e,{statusCode:400,code:"AUTH_DISABLED"}),e}const i=String(n.sourceId||"unknown").trim()||"unknown",s=e.toLocaleLowerCase("en-US");this.loginRateLimiter.begin(i,s);try{const n=this.users.list().find(t=>t.username===e);if(!n||!await Do(t,n.passwordHash)){this.loginRateLimiter.recordFailure(i,s);const e=new Error("Invalid username or password.");throw Object.assign(e,{statusCode:401,code:"AUTH_LOGIN_FAILED"}),e}const r=No();return this.users.put({...n,lastLoginAt:r,updatedAt:r})}finally{this.loginRateLimiter.finish()}}createSession(e,t,n){const i=No(),s=mo(),r=this.sessions.put({id:ho("mobile"===t?"msess":"sess"),userId:e.id,tokenHash:Po(s),expiresAt:new Date(Date.now()+12096e5).toISOString(),createdAt:i,updatedAt:i,lastSeenAt:i,clientType:t,...n?{device:n}:{}});return{record:r,token:`${r.id}.${s}`}}revokeUserSessions(e){for(const t of this.sessions.list())t.userId===e&&this.sessions.delete(t.id)}async userForSessionToken(e){const t=this.resolveSessionToken(e,"web");return t?.user}async userForMobileSessionToken(e){const t=this.resolveSessionToken(e,"mobile");return t?.user}resolveSessionToken(e,t){if(!this.enabled()||!e)return;const[n,i]=e.split(".");if(!n||!i)return;const s=this.sessions.get(n);if(!s||t&&s.clientType!==t||s.expiresAt<=No()||s.tokenHash!==Po(i))return;const r=this.users.get(s.userId);if(!r)return;const o=No();return{session:this.sessions.put({...s,lastSeenAt:o,updatedAt:o}),user:Mo(r),storedUser:r}}async currentSession(e,t="web"){const n=this.state(),i="mobile"===t?await this.userForMobileSessionToken(e):await this.userForSessionToken(e);return{...n,authenticated:!this.enabled()||Boolean(i),user:i}}logout(e){const t=e?.split(".")[0];return t&&this.sessions.delete(t),{ok:!0}}mobileSessions(e){const t=this.resolveSessionToken(e);if(t)return this.sessions.list().filter(e=>"mobile"===e.clientType&&e.userId===t.storedUser.id&&e.expiresAt>No()).map(e=>Lo(e,t.storedUser))}revokeMobileSession(e,t){const n=this.resolveSessionToken(e);if(!n)return;const i=this.sessions.get(t);return!(!i||"mobile"!==i.clientType||i.userId!==n.storedUser.id)&&this.sessions.delete(i.id)}}function $o(e,t){let n=Wo(t);for(let t=0;t<100;t+=1){const t=e.safeParse(n);if(t.success)return t;const i=Uo(t.error.issues);let s=!1;for(const e of i){const t=Ho(n,e.path);if(t&&"object"==typeof t&&!Array.isArray(t))for(const n of e.keys)Object.prototype.hasOwnProperty.call(t,n)&&(delete t[n],s=!0)}if(!s)return t}return e.safeParse(n)}function Bo(e,t){const n=$o(e,t);if(!n.success)throw n.error;return n.data}function Uo(e,t=[]){const n=[];for(const i of e){if("unrecognized_keys"===i.code){n.push({code:"unrecognized_keys",keys:i.keys,path:[...t,...i.path]});continue}if("invalid_union"!==i.code||!Array.isArray(i.errors))continue;const e=i.errors.filter(e=>Array.isArray(e));if(!e.length)continue;const s=e.reduce((e,t)=>Fo(t)<Fo(e)?t:e);n.push(...Uo(s,[...t,...i.path]))}return n}function Fo(e){return e.reduce((e,t)=>{if("unrecognized_keys"===t.code)return e;if("invalid_union"!==t.code||!Array.isArray(t.errors))return e+1;const n=t.errors.filter(e=>Array.isArray(e));return e+(n.length?Math.min(...n.map(Fo)):1)},0)}function Ho(e,t){let n=e;for(const e of t){if(!n||"object"!=typeof n)return;n=n[e]}return n}function Wo(e){return Array.isArray(e)?e.map(Wo):e&&"object"==typeof e?Object.getPrototypeOf(e)!==Object.prototype&&null!==Object.getPrototypeOf(e)?e:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,Wo(t)])):e}const Go=a.z.enum(["import","export"]),Vo=a.z.object({id:a.z.string().trim().min(1).max(120),label:a.z.string().trim().min(1).max(120),directoryName:a.z.string().trim().min(1).max(120)}).strict(),Ko=a.z.object({direction:Go,programIds:a.z.array(a.z.string().trim().min(1).max(120)).min(1).max(20).refine(e=>new Set(e).size===e.length,"Config sync program ids must be unique."),workspaceFolder:a.z.string().trim().min(1).max(1e3)}).strict(),Jo=a.z.object({import:a.z.string().trim().min(1).max(1e3).default("."),export:a.z.string().trim().min(1).max(1e3).default(".")}).strict(),Yo=a.z.object({programs:a.z.array(Vo),preferences:Jo}).strict(),Qo=a.z.object({id:a.z.string().trim().min(1).max(120),type:a.z.enum(["file","dir"]),projectPath:a.z.string().trim().min(1).max(1e3),containerPath:a.z.string().trim().min(1).max(1e3),source:a.z.string().trim().min(1).max(4096),target:a.z.string().trim().min(1).max(4096),status:a.z.enum(["copied","skipped_missing_source","failed"]),error:a.z.string().trim().max(4096).optional()}).strict(),Xo=a.z.object({preset:a.z.object({id:a.z.string().trim().min(1).max(120),label:a.z.string().trim().min(1).max(120),projectRoot:a.z.string().trim().min(1).max(1e3)}).strict(),direction:Go,items:a.z.array(Qo).max(100)}).strict(),Zo=a.z.object({direction:Go,workspaceFolder:a.z.string().trim().min(1).max(1e3),programs:a.z.array(Xo).min(1).max(20)}).strict(),ea=a.z.string().trim().min(1).max(160).regex(/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/),ta=a.z.string().datetime(),na=a.z.string().trim().min(1).max(255).refine(e=>!(/[\u0000-\u001f\u007f ~^:?*[\\]/.test(e)||e.includes("..")||e.endsWith(".")||e.endsWith("/")),"Invalid Git name."),ia=a.z.string().min(1).max(4096).refine(e=>!(e.includes("\0")||e.startsWith("/")||e.startsWith("\\")||/^[a-zA-Z]:[\\/]/.test(e))&&e.split("/").every(e=>e.length>0&&"."!==e&&".."!==e&&".git"!==e),"Path must be a safe repository-relative path."),sa=a.z.enum(["ai-session","app-session"]),ra=a.z.enum(["available","session-not-found","session-inactive","cwd-missing","cwd-inaccessible","git-unavailable","not-worktree"]),oa=a.z.enum(["branch","detached","unborn"]),aa=a.z.enum(["review-changes","resolve-conflicts","publish-branch","push","pull","diverged","up-to-date"]),da=a.z.enum(["conflict","staged","unstaged","untracked"]),ca=a.z.enum(["added","modified","deleted","renamed","copied","type-changed","unmerged","untracked"]),la=a.z.object({state:oa,oid:a.z.string().regex(/^[0-9a-f]{40,64}$/).optional(),branch:a.z.string().min(1).max(1024).optional()}).strict(),pa=a.z.object({ref:a.z.string().min(1).max(2048),remote:na,branch:a.z.string().min(1).max(1024),ahead:a.z.number().int().nonnegative(),behind:a.z.number().int().nonnegative()}).strict(),ua=a.z.object({id:ea,isCurrent:a.z.boolean(),isMain:a.z.boolean(),managed:a.z.boolean(),head:la,dirty:a.z.boolean(),locked:a.z.boolean(),lockReason:a.z.string().max(1e3).optional(),prunable:a.z.boolean(),activeAiSessionIds:a.z.array(ea).max(256).default([]),activeAppSessionIds:a.z.array(ea).max(256).default([])}).strict(),ga=a.z.enum(["main-worktree","external-worktree","outside-workspace-roots","dirty","locked","prunable","session-occupied","path-inaccessible"]),ha=ua.extend({canCreateAiSession:a.z.boolean(),canRemove:a.z.boolean(),createAiSessionBlockers:a.z.array(ga).max(16).default([]),removeBlockers:a.z.array(ga).max(16).default([])}).strict(),ma=a.z.object({repositoryId:ea,repositoryContextId:ea,snapshotId:ea,items:a.z.array(ha).max(1e4)}).strict(),ya=a.z.object({conflicts:a.z.number().int().nonnegative(),staged:a.z.number().int().nonnegative(),unstaged:a.z.number().int().nonnegative(),untracked:a.z.number().int().nonnegative()}).strict(),fa=a.z.object({name:na,fetchUrl:a.z.string().max(4096).optional(),pushUrl:a.z.string().max(4096).optional()}).strict(),Ia=a.z.object({availability:ra,sessionKind:sa,sessionId:ea,observedAt:ta,snapshotId:ea.optional(),repositoryId:ea.optional(),repositoryContextId:ea.optional(),repositoryRoot:a.z.string().min(1).max(4096).optional(),displayName:a.z.string().trim().min(1).max(255).optional(),cwdRelativePath:a.z.string().max(4096).optional(),head:la.optional(),upstream:pa.optional(),currentWorktree:ua.optional(),changes:ya.optional(),remotes:a.z.array(fa).max(128).optional(),primaryAction:aa.optional()}).strict(),ba=a.z.enum(["directory","file","symlink","submodule","nested-repository","special"]),va=a.z.object({executable:a.z.boolean(),gitMode:a.z.enum(["100644","100755","120000","160000"]).optional()}).strict(),wa=a.z.object({name:a.z.string().min(1).max(1024),path:ia,kind:ba,traversable:a.z.boolean(),editable:a.z.boolean(),size:a.z.number().int().nonnegative().optional(),mode:va.optional()}).strict();a.z.object({path:a.z.string().max(4096),entries:a.z.array(wa).max(1e4),snapshotId:ea}).strict();const Sa=a.z.string().min(16).max(160).regex(/^[a-zA-Z0-9_.:-]+$/),Aa=a.z.object({path:ia,content:a.z.string(),byteLength:a.z.number().int().nonnegative(),version:Sa,mode:va}).strict(),za=a.z.object({path:ia,oldPath:ia.optional(),scope:da,status:ca,version:Sa,binary:a.z.boolean().default(!1)}).strict(),ka=a.z.object({snapshotId:ea,summary:ya,entries:a.z.array(za).max(1e5)}).strict();a.z.object({file:Aa.optional(),snapshotId:ea,context:Ia,changes:ka}).strict();const Ta=a.z.object({kind:a.z.enum(["metadata","hunk","context","addition","deletion"]),content:a.z.string(),oldLine:a.z.number().int().positive().optional(),newLine:a.z.number().int().positive().optional(),oldStart:a.z.number().int().nonnegative().optional(),oldCount:a.z.number().int().nonnegative().optional(),newStart:a.z.number().int().nonnegative().optional(),newCount:a.z.number().int().nonnegative().optional(),heading:a.z.string().optional(),hunkId:a.z.string().min(1).max(200).optional()}).strict();a.z.object({path:ia,oldPath:ia.optional(),scope:da,binary:a.z.boolean(),complete:a.z.boolean(),truncated:a.z.boolean(),byteLimit:a.z.number().int().positive(),content:a.z.string(),lines:a.z.array(Ta).max(2e5),contextGaps:a.z.array(a.z.object({gapId:a.z.string().min(1).max(500),beforeHunkId:a.z.string().min(1).max(200).optional(),afterHunkId:a.z.string().min(1).max(200).optional(),lines:a.z.array(Ta).max(6e3),startLineCount:a.z.number().int().nonnegative().max(3e3),hasMore:a.z.boolean()}).strict()).max(2e4),version:Sa,snapshotId:ea}).strict();const Ea=a.z.object({name:a.z.string().min(1).max(1024),oid:a.z.string().regex(/^[0-9a-f]{40,64}$/),kind:a.z.enum(["local","remote-tracking"]),current:a.z.boolean(),upstream:a.z.string().min(1).max(2048).optional(),ahead:a.z.number().int().nonnegative().optional(),behind:a.z.number().int().nonnegative().optional(),checkedOutWorktreeIds:a.z.array(ea).max(256).default([])}).strict(),Ca=a.z.object({snapshotId:ea,branches:a.z.array(Ea).max(1e5)}).strict();a.z.object({snapshotId:ea,context:Ia,branches:Ca}).strict(),a.z.object({ok:a.z.literal(!0),snapshotId:ea,context:Ia,changes:ka.optional(),commitOid:a.z.string().regex(/^[0-9a-f]{40,64}$/).optional()}).strict();const xa=a.z.enum(["REPOSITORY_REQUEST_INVALID","REPOSITORY_SESSION_NOT_FOUND","REPOSITORY_SESSION_INACTIVE","REPOSITORY_CWD_MISSING","REPOSITORY_CWD_INACCESSIBLE","REPOSITORY_GIT_UNAVAILABLE","REPOSITORY_NOT_WORKTREE","REPOSITORY_PATH_INVALID","REPOSITORY_PATH_FORBIDDEN","REPOSITORY_FILE_NOT_FOUND","REPOSITORY_FILE_EXISTS","REPOSITORY_FILE_UNSUPPORTED","REPOSITORY_FILE_TOO_LARGE","REPOSITORY_FILE_BINARY","REPOSITORY_FILE_STALE","REPOSITORY_STATE_STALE","REPOSITORY_WORKTREE_NOT_FOUND","REPOSITORY_WORKTREE_OCCUPIED","REPOSITORY_WORKTREE_UNSAFE","REPOSITORY_BRANCH_INVALID","REPOSITORY_BRANCH_OCCUPIED","REPOSITORY_BRANCH_UNMERGED","REPOSITORY_CONFLICT","REPOSITORY_DIRTY","REPOSITORY_NOTHING_TO_COMMIT","REPOSITORY_IDENTITY_MISSING","REPOSITORY_HOOK_FAILED","REPOSITORY_SIGNING_FAILED","REPOSITORY_AUTHENTICATION_FAILED","REPOSITORY_NON_FAST_FORWARD","REPOSITORY_UPSTREAM_MISSING","REPOSITORY_COMMAND_TIMEOUT","REPOSITORY_OUTPUT_LIMIT","REPOSITORY_OPERATION_ABORTED","REPOSITORY_OPERATION_FAILED"]);a.z.object({ok:a.z.literal(!1),error:a.z.object({code:xa,message:a.z.string().trim().min(1).max(2e3),retryable:a.z.boolean(),details:a.z.record(a.z.string(),a.z.union([a.z.string(),a.z.number(),a.z.boolean()])).optional()}).strict()}).strict();const Na=a.z.object({expectedSnapshotId:ea}).strict(),Oa=a.z.object({path:ia,expectedVersion:Sa}).strict();a.z.object({path:ia,content:a.z.string().max(4194304),expectedAbsent:a.z.literal(!0),expectedSnapshotId:ea}).strict(),a.z.object({path:ia,content:a.z.string().max(4194304),expectedVersion:Sa,expectedSnapshotId:ea}).strict(),a.z.object({path:ia,destination:ia,expectedVersion:Sa,expectedDestinationAbsent:a.z.literal(!0),expectedSnapshotId:ea}).strict(),a.z.object({path:ia,expectedVersion:Sa,expectedSnapshotId:ea,confirm:a.z.literal(!0)}).strict(),Na.extend({paths:a.z.array(Oa).min(1).max(1e3)}).strict(),Na.extend({paths:a.z.array(Oa).min(1).max(1e3)}).strict(),Na.extend({paths:a.z.array(Oa).min(1).max(1e3),confirm:a.z.literal(!0)}).strict(),Na.extend({paths:a.z.array(Oa).min(1).max(1e3),confirm:a.z.literal(!0)}).strict(),Na.extend({message:a.z.string().trim().min(1).max(65536)}).strict();const _a=a.z.discriminatedUnion("mode",[a.z.object({mode:a.z.literal("new-branch"),branchName:na,startRef:a.z.string().trim().min(1).max(2048),expectedSnapshotId:ea}).strict(),a.z.object({mode:a.z.literal("existing-branch"),branchName:na,expectedSnapshotId:ea}).strict()]);Na.extend({worktreeId:ea,confirm:a.z.literal(!0)}).strict(),a.z.object({worktreeId:ea,worktrees:ma}).strict(),a.z.object({removedWorktreeId:ea,branchRetained:a.z.boolean(),worktrees:ma}).strict();const Ra=a.z.discriminatedUnion("type",[a.z.object({type:a.z.literal("current")}).strict(),a.z.object({type:a.z.literal("worktree"),repositoryContextId:ea,worktreeId:ea}).strict()]);a.z.object({agent:a.z.enum(["codex","claude"]),workspaceSelection:Ra,message:a.z.string().trim().min(1).max(2e4),clientRequestId:ea,permissionMode:a.z.enum(["ask","auto-review","full-access"]).optional()}).strict(),a.z.object({agent:a.z.enum(["codex","claude"]),worktree:_a,message:a.z.string().trim().min(1).max(2e4),clientRequestId:ea,permissionMode:a.z.enum(["ask","auto-review","full-access"]).optional()}).strict(),a.z.object({aiSessionId:ea,providerSessionId:a.z.string().trim().min(1).max(240),worktreeId:ea,disposition:a.z.literal("started")}).strict();const Pa=a.z.object({name:a.z.string().min(1).max(1024),kind:a.z.enum(["branch","head"]).default("branch"),current:a.z.boolean(),currentFolderSelectable:a.z.boolean(),worktreeSelectable:a.z.boolean(),worktreeCheckout:a.z.enum(["attached","detached"]).default("attached"),currentFolderReason:a.z.enum(["dirty","session-occupied","branch-occupied"]).optional(),worktreeReason:a.z.enum(["current-branch","branch-occupied","worktree-unavailable"]).optional()}).strict(),ja=a.z.object({availability:ra,currentBranch:a.z.string().min(1).max(1024).optional(),dirty:a.z.boolean().default(!1),branches:a.z.array(Pa).max(1e5).default([])}).strict();a.z.object({cwd:ze}).strict();const Da=Te;ke.extend({gitSelection:Da}).strict(),Na.extend({name:na}).strict(),Na.extend({branch:a.z.string().trim().min(1).max(2048)}).strict(),Na.extend({name:na,remoteTrackingRef:a.z.string().trim().min(1).max(2048)}).strict(),Na.extend({name:na,confirm:a.z.literal(!0)}).strict(),Na.extend({remote:na}).strict(),Na.extend({remote:na,sourceBranch:na,targetBranch:na,setUpstream:a.z.boolean(),confirmSetUpstream:a.z.boolean().optional()}).strict().refine(e=>!e.setUpstream||!0===e.confirmSetUpstream,{message:"Setting an upstream requires explicit confirmation.",path:["confirmSetUpstream"]}),Na.extend({remote:na,sourceBranch:na,targetBranch:na}).strict();class Ma{options;resumeSnapshotRefreshFailures=0;lastResumeSnapshotRefreshFailure;constructor(e){this.options=e}async resolveApproval(e,t,n){return Bo(Ge,await this.post(e,Ua(t,"approval"),{decision:n}))}async listHistory(e){return Bo(Je,await this.get(e,"/ai-sessions/history"))}async historyDetail(e,t){return Bo(Ye,await this.get(e,`/ai-sessions/history/${encodeURIComponent(t)}`))}async timeline(e,t){const n=await this.options.requireInstance(e);if(!function(e){return bi(e.capabilities,"session-read").length>0}(n))throw function(){const e=new Error("The controlled instance does not support AI session Timeline reads.");return Object.assign(e,{statusCode:409,code:"AI_SESSION_TIMELINE_UNSUPPORTED"}),e}();return Bo(K,await this.options.request(n,Ua(t,"timeline"),{method:"GET"}))}async turnTimeline(e,t,n){const i=await this.options.requireInstance(e);if(!function(e){return bi(e.capabilities,"turn-read").length>0}(i))throw function(){const e=new Error("The controlled instance does not support per-turn AI session Timeline reads.");return Object.assign(e,{statusCode:409,code:"AI_SESSION_TURN_TIMELINE_UNSUPPORTED"}),e}();return Bo(J,await this.options.request(i,`${Ua(t,"turns")}/${encodeURIComponent(n)}/timeline`,{method:"GET"}))}async resume(e,t){const n=Bo(Qe,await this.post(e,Ua(t,"resume"),{}));return await this.refreshAfterCommittedResume(e,t),n}async create(e,t){Ha(t.attachments||[]);const n=await this.options.requireInstance(e),i=La(n);if(t.gitSelection&&!i)throw qa();const s=t.permissionMode||("codex"===t.agent?n.config.defaultCodexPermissionMode:void 0),r=t.gitSelection?"/repository/ai-session-workspace/create":"/ai-sessions",{cwdFolderId:o,...a}=t;return Bo(Ce,await this.options.request(n,r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...a,...i&&o?{cwdFolderId:o}:{},...s?{permissionMode:s}:{}})}))}async inspectWorkspace(e,t){const n=await this.options.requireInstance(e);if(!La(n))throw qa();return Bo(ja,await this.options.request(n,"/repository/ai-session-workspace/inspect",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cwd:t})}))}async fork(e,t,n){const i=Bo(Oe,await this.post(e,Ua(t,"fork"),n));try{await this.options.refreshSnapshots()}catch(n){try{this.options.warn?.({instanceId:e,aiSessionId:t,providerSessionId:i.providerSessionId,code:$a(n),message:Ba(n)},"AI session Fork committed but snapshot refresh failed")}catch{}}return i}async openApp(e,t,n){return Bo(Re,await this.post(e,Ua(t,"open-app"),{clientRequestId:n}))}async close(e,t,n){return Bo(je,await this.post(e,Ua(t,"close"),{clientRequestId:n}))}async refreshAfterCommittedResume(e,t){try{await this.options.refreshSnapshots()}catch(n){const i={instanceId:e,aiSessionId:t,code:$a(n),message:Ba(n),occurredAt:(new Date).toISOString()};this.resumeSnapshotRefreshFailures+=1,this.lastResumeSnapshotRefreshFailure=i;try{this.options.warn?.(i,"AI session resumed but snapshot refresh failed")}catch{}}}diagnostics(){return{resumeSnapshotRefreshFailures:this.resumeSnapshotRefreshFailures,lastResumeSnapshotRefreshFailure:this.lastResumeSnapshotRefreshFailure}}async sendMessage(e,t,n,i,s=[],r=[],o){Ha(s);const a=await this.options.requireInstance(e);s.some(e=>"runtime-path"===e.source.type)&&function(e,t){if(!e.some(e=>"runtime-path"===e.source.type)||"local"===t)return;const n=new Error("Runtime path attachments are currently available only for Local Runtime instances.");throw Object.assign(n,{statusCode:400,code:"AI_SESSION_RUNTIME_PATH_UNSUPPORTED"}),n}(s,(await this.options.requireRuntime(a.nodeId,a.runtimeId)).type);const d=a.aiSessions.sessions.find(e=>e.id===t),c=o||("codex"===d?.agent?a.config.defaultCodexPermissionMode:void 0);return Bo(Ge,await this.options.request(a,Ua(t,"messages"),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({message:n,...i?{mode:i}:{},...s.length?{attachments:s}:{},...r.length?{references:r}:{},...c?{permissionMode:c}:{}})}))}async mentionCatalog(e,t){return Bo(Ie,await this.get(e,Ua(t,"mentions")))}async searchMentionFiles(e,t,n){return Bo(ve,await this.post(e,Ua(t,"mentions/files"),{query:n}))}async executeCommand(e,t,n){return Bo(pe,await this.post(e,Ua(t,"commands"),n))}async queue(e,t){return Bo($e,await this.get(e,Ua(t,"queue")))}async steerQueuedMessage(e,t,n){return Bo(Ge,await this.post(e,Fa(t,n,"steer"),{}))}async retryQueuedMessage(e,t,n){return Bo(We,await this.post(e,Fa(t,n,"retry"),{}))}async removeQueuedMessage(e,t,n){const i=await this.options.requireInstance(e);return Bo(We,await this.options.request(i,Fa(t,n),{method:"DELETE"}))}async editQueuedMessage(e,t,n,i){const s=Le.parse(i);return Bo(We,await this.patch(e,Fa(t,n),s))}async reorderQueuedMessages(e,t,n){const i=Me.parse(n);return Bo(We,await this.patch(e,Ua(t,"queue/reorder"),i))}async interrupt(e,t){return Bo(Ge,await this.post(e,Ua(t,"interrupt"),{}))}async get(e,t){return this.options.request(await this.options.requireInstance(e),t)}async post(e,t,n){return this.options.request(await this.options.requireInstance(e),t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}async patch(e,t,n){return this.options.request(await this.options.requireInstance(e),t,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}}function La(e){return Ii(e.capabilities).features.aiSessionWorkspaceSelection}function qa(){const e=new Error("The controlled instance does not support AI session workspace selection.");return Object.assign(e,{statusCode:409,code:"AI_SESSION_WORKSPACE_SELECTION_UNSUPPORTED"}),e}function $a(e){return e&&"object"==typeof e&&"code"in e&&"string"==typeof e.code?e.code:"AI_SESSION_SNAPSHOT_REFRESH_FAILED"}function Ba(e){return e instanceof Error?e.message:String(e)}function Ua(e,t){return`/ai-sessions/${encodeURIComponent(e)}/${t}`}function Fa(e,t,n){return`${Ua(e,"queue")}/${encodeURIComponent(t)}${n?`/${n}`:""}`}function Ha(e){if(e.reduce((e,t)=>e+("inline"===t.source.type?t.size:0),0)<=x)return;const t=new Error("Inline attachments must be 41943040 bytes or less in total.");throw Object.assign(t,{statusCode:400,code:"AI_SESSION_ATTACHMENTS_TOO_LARGE"}),t}function Wa(e,t,n,i){const s=i&&"object"==typeof i?i:{};return{nodeId:e.id,route:"string"==typeof s.route?s.route:t,method:n,code:"string"==typeof s.code?s.code:"NODE_AGENT_REQUEST_FAILED",message:i instanceof Error?i.message:String(i),statusCode:"number"==typeof s.statusCode?s.statusCode:void 0,issues:Array.isArray(s.issues)?s.issues:void 0}}class Ga{requestImpl;logger;constructor(e){this.requestImpl=e.request,this.logger=e.logger}async request(e,t,n={}){const i=n.method||"GET";let s,r;try{s=await this.requestImpl(e,t,n)}catch(n){throw this.logger?.warn?.({nodeId:e.id,route:t,method:i,error:n instanceof Error?n.message:String(n),errorCode:"NODE_AGENT_TRANSPORT_FAILED"},"node agent transport failed"),n}try{r=await s.json()}catch(n){this.logger?.warn?.({nodeId:e.id,route:t,method:i,statusCode:s.status,error:n instanceof Error?n.message:String(n),errorCode:"NODE_AGENT_RESPONSE_INVALID_JSON"},"node agent response was not valid json");const r=new Error(`Node agent ${e.id} returned invalid JSON for ${t}.`);throw Object.assign(r,{statusCode:502,code:"NODE_AGENT_RESPONSE_INVALID_JSON",nodeId:e.id,route:t}),r}if(!s.ok){const n=new Error(r.error?.message||`Node agent request failed with HTTP ${s.status}`);throw Object.assign(n,{statusCode:s.status,code:r.error?.code||"NODE_AGENT_REQUEST_FAILED",nodeId:e.id,route:t}),this.logger?.warn?.({nodeId:e.id,route:t,method:i,statusCode:s.status,errorCode:r.error?.code||"NODE_AGENT_REQUEST_FAILED",error:n.message},"node agent request failed"),n}return this.logger?.info?.({nodeId:e.id,route:t,method:i,statusCode:s.status},"node agent request ok"),r.data??r}async requestSchema(e,t,n,i={}){return this.parse(e,t,n,await this.request(e,t,i),i.method||"GET")}parse(e,t,n,i,s="GET"){const r=$o(n,i);if(r.success)return r.data;this.logger?.warn?.({nodeId:e.id,route:t,method:s,errorCode:"NODE_AGENT_PROTOCOL_INVALID",issues:r.error.issues},"node agent protocol response did not match schema");const o=new Error(`Node agent ${e.id} returned invalid protocol data for ${t}.`);throw Object.assign(o,{statusCode:502,code:"NODE_AGENT_PROTOCOL_INVALID",nodeId:e.id,route:t,issues:r.error.issues}),o}}class Va{client;fleetRequestTimeoutMs;runtimeSnapshots=new Map;instanceSnapshots=new Map;constructor(e,t={}){this.client=e,this.fleetRequestTimeoutMs=Number.isFinite(t.fleetRequestTimeoutMs)&&Number(t.fleetRequestTimeoutMs)>0?Number(t.fleetRequestTimeoutMs):2e3}request(e,t,n={}){return this.client.request(e,t,n)}health(e){return this.client.requestSchema(e,"/health",br)}checkUpdate(e,t){return this.client.requestSchema(e,"/updates/check",As,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}applyUpdate(e,t){return this.client.requestSchema(e,"/updates/apply",zs,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}listUpdateJobs(e){return this.client.requestSchema(e,"/updates/jobs",a.z.array(zs))}getExternalListener(e){return this.client.requestSchema(e,"/settings/external-listener",vr)}updateExternalListener(e,t){return this.client.requestSchema(e,"/settings/external-listener",vr,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}createPairingInvite(e,t={}){return this.client.requestSchema(e,"/pairing/invites",wr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t&&"object"==typeof t?t:{})})}createControlPlaneConnection(e,t){return this.client.requestSchema(e,"/control-plane-connections",Tr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}listControlPlanePairings(e){return this.client.requestSchema(e,"/control-plane-pairings",a.z.array(Ar))}deleteControlPlanePairing(e,t){return this.client.requestSchema(e,`/control-plane-pairings/${encodeURIComponent(t)}`,Er,{method:"DELETE"})}listControlPlaneConnections(e){return this.client.requestSchema(e,"/control-plane-connections",a.z.array(kr))}deleteControlPlaneConnection(e,t){return this.client.requestSchema(e,`/control-plane-connections/${encodeURIComponent(t)}`,Er,{method:"DELETE"})}listDockerImages(e){return this.client.requestSchema(e,"/docker/images",a.z.array(Cr))}listFolderTree(e,t={}){const n=new URLSearchParams;t.path&&n.set("path",t.path),void 0!==t.depth&&n.set("depth",String(t.depth));const i=n.toString();return this.client.requestSchema(e,"/folders/tree"+(i?`?${i}`:""),a.z.array(Nr))}listFolderPlaces(e){return this.client.requestSchema(e,"/folders/places",a.z.array(Or))}listLocalFolders(e,t={}){return this.client.requestSchema(e,"/local-folders",a.z.array(xs),t)}createLocalFolder(e,t){return this.client.requestSchema(e,"/local-folders",xs,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}async requireLocalFolder(e,t){const n=(await this.listLocalFolders(e)).find(e=>e.id===t);if(!n){const n=new Error(`Local folder ${t} was not found on node ${e.id}.`);throw Object.assign(n,{statusCode:404,code:"NODE_LOCAL_FOLDER_NOT_FOUND",nodeId:e.id,route:"/local-folders"}),n}return n}listRuntimes(e,t={}){return this.client.requestSchema(e,"/runtimes",a.z.array(yr),t)}createRuntime(e,t){return this.client.requestSchema(e,"/runtimes",yr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}updateRuntime(e,t,n){const i=`/runtimes/${encodeURIComponent(t)}`;return this.client.requestSchema(e,i,yr,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}checkRuntime(e,t){const n=`/runtimes/${encodeURIComponent(t)}/check`;return this.client.requestSchema(e,n,yr,{method:"POST"})}deleteRuntime(e,t){return this.client.requestSchema(e,`/runtimes/${encodeURIComponent(t)}`,Er,{method:"DELETE"})}deleteLocalFolder(e,t){return this.client.requestSchema(e,`/local-folders/${encodeURIComponent(t)}`,Er,{method:"DELETE"})}listModels(e,t={}){return this.client.requestSchema(e,"/models",a.z.array(Ds),t)}createModel(e,t){return this.client.requestSchema(e,"/models",Ds,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}deployModel(e,t,n){return this.client.requestSchema(e,`/models/${encodeURIComponent(t)}/deploy`,Ds,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}updateModel(e,t,n){return this.client.requestSchema(e,`/models/${encodeURIComponent(t)}`,Ds,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}deleteModel(e,t){return this.client.requestSchema(e,`/models/${encodeURIComponent(t)}`,Er,{method:"DELETE"})}discoverModels(e,t){return this.client.requestSchema(e,"/models/discover",a.z.object({models:a.z.array(a.z.object({id:a.z.string(),ownedBy:a.z.string().optional()}).strict()),latencyMs:a.z.number().nonnegative()}).strict(),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}testModel(e,t){return this.client.requestSchema(e,"/models/test",a.z.object({success:a.z.literal(!0),latencyMs:a.z.number().nonnegative()}).strict(),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}assignInstanceModels(e,t,n){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/model-assignment`,a.z.object({assignment:Ms,instance:Dr}).strict(),{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}async listFleetModels(e,t={}){return(await Promise.allSettled(e.map(async e=>({node:e,models:await this.listModels(e,t)})))).reduce((t,n,i)=>{if("fulfilled"===n.status)t.items.push(...n.value.models.map(e=>({nodeId:n.value.node.id,model:e})));else{const s=e[i];s&&t.nodeErrors.push(Wa(s,"/models","GET",n.reason))}return t},{items:[],nodeErrors:[]})}async listFleetRuntimes(e,t={}){return this.listFleetFromSnapshots(e,"/runtimes",t,this.runtimeSnapshots,async(e,t)=>({items:await this.listRuntimes(e,t),nodeErrors:[]}))}listInstances(e,t={}){return this.listInstancesWithDiagnostics(e,t).then(e=>e.items)}async listInstancesWithDiagnostics(e,t={}){return this.client.requestSchema(e,"/instances",a.z.array(a.z.unknown()),t).then(t=>t.reduce((t,n)=>{const i=this.normalizeInstance(e,n);return i.instance&&t.items.push(i.instance),i.error&&t.nodeErrors.push(i.error),t},{items:[],nodeErrors:[]}))}createInstance(e,t){return this.client.requestSchema(e,"/instances",Dr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}updateInstance(e,t,n){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}`,Dr,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}deleteInstance(e,t,n){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/delete`,Hi,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}listEnvironmentTemplates(e,t={}){return this.client.requestSchema(e,"/environment-templates",a.z.array(Qi),t)}getEnvironmentTemplate(e,t,n={}){return this.client.requestSchema(e,`/environment-templates/${encodeURIComponent(t)}`,Qi,n)}createEnvironmentTemplate(e,t,n){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/environment-templates`,Qi,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}deleteEnvironmentTemplate(e,t){return this.client.requestSchema(e,`/environment-templates/${encodeURIComponent(t)}`,a.z.object({deleted:a.z.boolean(),templateId:Qi.shape.id}).strict(),{method:"DELETE"})}startInstance(e,t,n={}){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/start`,Dr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}retryInstanceImageProvisioning(e,t){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/image-provisioning/retry`,Dr,{method:"POST"})}stopInstance(e,t){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/stop`,Dr,{method:"POST"})}restartInstance(e,t,n={}){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/restart`,Dr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}instanceResourceMetrics(e,t){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/metrics`,fr)}proxyRawInstance(e,t,n){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/proxy/raw`,_r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}async listFleetInstances(e,t={}){return this.listFleetFromSnapshots(e,"/instances",t,this.instanceSnapshots,(e,t)=>this.listInstancesWithDiagnostics(e,t))}async listFleetFromSnapshots(e,t,n,i,s){const r=new Set(e.map(e=>e.id));for(const e of i.keys())r.has(e)||i.delete(e);return(await Promise.all(e.map(async e=>{const r=this.fleetConnectionKey(e);try{this.requireFleetNodeReady(e,t);const o=await this.withFleetDeadline(e,t,n,t=>s(e,t));return i.set(e.id,{connectionKey:r,items:[...o.items]}),o}catch(n){const s=i.get(e.id);return{items:s?.connectionKey===r?[...s.items]:[],nodeErrors:[Wa(e,t,"GET",n)]}}}))).reduce((e,t)=>(e.items.push(...t.items),e.nodeErrors.push(...t.nodeErrors),e),{items:[],nodeErrors:[]})}fleetConnectionKey(e){return JSON.stringify([e.id,e.connectionMode,e.controlEndpoint,e.endpoint,e.auth.mode,e.auth.keyId])}requireFleetNodeReady(e,t){const n=e.connectionPhase,i="reverse-wss"!==e.connectionMode&&"control-plane-proxy"!==e.connectionMode;if(!n||"healthy"===n||i)return;const s=new Error(`Node agent ${e.id} is ${n}; serving its latest fleet snapshot.`);throw Object.assign(s,{code:"NODE_AGENT_CONNECTION_PENDING",nodeId:e.id,route:t}),s}async withFleetDeadline(e,t,n,i){const s=new AbortController,r=Object.assign(new Error(`Node agent ${e.id} did not return ${t} before the fleet aggregation deadline.`),{code:"NODE_AGENT_FLEET_TIMEOUT",nodeId:e.id,route:t}),o=new Promise((e,t)=>{const n=()=>t(s.signal.reason||r);s.signal.aborted?n():s.signal.addEventListener("abort",n,{once:!0})}),a=()=>s.abort(n.signal?.reason);n.signal?.aborted?a():n.signal?.addEventListener("abort",a,{once:!0});const d=setTimeout(()=>s.abort(r),this.fleetRequestTimeoutMs);d.unref?.();try{return await Promise.race([i({...n,signal:s.signal}),o])}finally{clearTimeout(d),n.signal?.removeEventListener("abort",a)}}normalizeInstance(e,t){const n=(i=t,Dr.safeParse(function(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e,n=new Set(Object.keys(Dr.shape)),i={};for(const[e,s]of Object.entries(t))n.has(e)&&(i[e]=s);if(t.capabilities&&"object"==typeof t.capabilities&&!Array.isArray(t.capabilities)){const e={...t.capabilities};Object.prototype.hasOwnProperty.call(e,"apps")&&delete e.apps,i.capabilities=Ii(e)}else i.capabilities=Ii(void 0);i.appInventory=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e;Object.keys(t).some(e=>!["observedAt","items","issues"].includes(e));const n={observedAt:t.observedAt,items:Array.isArray(t.items)?t.items.map(e=>{e&&"object"==typeof e&&!Array.isArray(e)&&Object.keys(e).some(e=>!["id","name","kind","source","availability","capabilities","diagnosticCode"].includes(e));const t=Br(e,["id","name","kind","source","availability","diagnosticCode"]);return!t||"object"!=typeof t||Array.isArray(t)?t:{...t,capabilities:Br(e.capabilities,["automation","supportsCwdSelection"])}}):t.items,issues:Array.isArray(t.issues)?t.issues.map(e=>Br(e,["code","message"])):t.issues},i=Yi.safeParse(n);return i.success?i.data:void 0}(t.appInventory,"string"==typeof t.id&&t.id),i.source=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e,n=t.type,i=Ns.options.find(e=>e.shape.type.value===n);if(!i)return e;const s="local-folder"===n?["type","localFolderId","path","ownerNodeId"]:"git-template"===n?["type","url","templateId","ref","auth","clone"]:["type","repositoryId","url","provider","ref","auth","clone"],r=Br(t,s);if("local-folder"!==n){const e=qr(Ts,Br(t.ref,["type","name","commit"])),n=qr(Es,Br(t.auth,["type","secretId"])),i=qr(Cs,Br(t.clone,["depth","submodules","lfs","subdirectory"]));e?r.ref=e:delete r.ref,n?r.auth=n:delete r.auth,i?r.clone=i:delete r.clone}const o=qr(i,r);return o?(Object.keys(t).some(e=>!s.includes(e)),o):r}(t.source,"string"==typeof t.id&&t.id),i.sourceSnapshot=t.sourceSnapshot&&"object"==typeof t.sourceSnapshot&&!Array.isArray(t.sourceSnapshot)?t.sourceSnapshot:{},i.build=qr(hs,t.build,0,0,"string"==typeof t.id&&t.id),i.aiSessions=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e,n=Array.isArray(t.sessions)?t.sessions.flatMap((e,t)=>{const n=qr(Xe,e);return n?[n]:[]}):[],i={runningCount:"number"==typeof t.runningCount&&Number.isInteger(t.runningCount)&&t.runningCount>=0?t.runningCount:0,waitingCount:"number"==typeof t.waitingCount&&Number.isInteger(t.waitingCount)&&t.waitingCount>=0?t.waitingCount:0,staleCount:"number"==typeof t.staleCount&&Number.isInteger(t.staleCount)&&t.staleCount>=0?t.staleCount:0,sessions:n,updatedAt:wi.safeParse(t.updatedAt).success?t.updatedAt:(new Date).toISOString()};return Object.keys(t).some(e=>!["runningCount","waitingCount","staleCount","sessions","updatedAt"].includes(e)),Ze.parse(i)}(t.aiSessions,"string"==typeof t.id&&t.id),i.triggers=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e;Object.keys(t).some(e=>!["enabledCount","runningCount","errorCount","configs","recentRuns"].includes(e));const n=(e,t,n)=>Array.isArray(e)?e.flatMap((e,n)=>{const i=qr(t,e);return i?[i]:[]}):[],i=Array.isArray(t.configs)?t.configs.flatMap((e,t)=>{if(!e||"object"!=typeof e||Array.isArray(e))return[];const i=e;Object.keys(i).some(e=>!["configHash","config","deployments","runtime"].includes(e));const s=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e,n=Br(t,["configHash","name","description","createdAt","updatedAt"]);if(t.source&&"object"==typeof t.source&&!Array.isArray(t.source)){const e=t.source,i="schedule"===e.type?"interval"===e.scheduleKind?["type","scheduleKind","intervalMs"]:"daily"===e.scheduleKind?["type","scheduleKind","timeOfDay","timezone"]:["type","scheduleKind","weekdays","timeOfDay","timezone"]:"file-change"===e.type?["type","roots","globs","ignore","debounceMs"]:["type","agent","statuses","phases"];n.source=Br(e,i)}return n.action=Br(t.action,["promptTemplate"]),n.policy=Br(t.policy,["cooldownMs","maxConcurrentRuns","whenBusy"]),qr(fn,n)}(i.config);return"string"==typeof i.configHash&&s?[{configHash:i.configHash,config:s,deployments:n(i.deployments,bn),runtime:n(i.runtime,vn)}]:[]}):[];return{enabledCount:"number"==typeof t.enabledCount&&Number.isInteger(t.enabledCount)&&t.enabledCount>=0?t.enabledCount:0,runningCount:"number"==typeof t.runningCount&&Number.isInteger(t.runningCount)&&t.runningCount>=0?t.runningCount:0,errorCount:"number"==typeof t.errorCount&&Number.isInteger(t.errorCount)&&t.errorCount>=0?t.errorCount:0,configs:i,recentRuns:n(t.recentRuns,wn)}}(t.triggers,"string"==typeof t.id&&t.id),i.apps=qr(Dr.shape.apps.unwrap(),Br(t.apps,["runningCount","problemCount","updatedAt","revision"]),0,0,"string"==typeof t.id&&t.id)||{runningCount:0,problemCount:0},i.config=qr(Dr.shape.config.unwrap(),Br(t.config,["autoImportAgentConfigs","defaultCodexPermissionMode","aiSessionHistoryLimit"]),0,0,"string"==typeof t.id&&t.id)||{autoImportAgentConfigs:!0,defaultCodexPermissionMode:"ask",aiSessionHistoryLimit:50},i.modelSelection=qr(Ri.unwrap(),Br(t.modelSelection,["codexModelHash","claudeModelHash"]),0,0,"string"==typeof t.id&&t.id)||{},i.imageSnapshot=function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e,i=ur(n),{reference:s,...r}=i,o=n.requestedReference??s;let a;try{a="string"==typeof o?Ni(o):void 0}catch{}const d={img_default:"market_taskhandoff_browser",img_codex:"market_taskhandoff_codex",img_ai:"market_taskhandoff_ai"},c="string"==typeof n.id?n.id:"string"==typeof t?t:void 0,l="market"===n.origin||c&&d[c]?"market":"custom";return void 0!==n.image||n.reference,{...r,id:c&&d[c]?d[c]:c,origin:l,repository:a?.repository??n.repository,tag:a?.tag??n.tag,requestedReference:a?.reference??o,resolvedDigest:n.resolvedDigest,resolvedReference:n.resolvedReference,downloadSizeBytes:n.downloadSizeBytes,market:"market"===l?Br(n.market,["catalogId","catalogRevision","publisher","version"])??{catalogId:"task_handoff_embedded",catalogRevision:"legacy",publisher:"task-handoff"}:void 0}}(t.imageSnapshot,t.imageId,"string"==typeof t.id&&t.id);const s="string"==typeof t.imageId?{img_default:"market_taskhandoff_browser",img_codex:"market_taskhandoff_codex",img_ai:"market_taskhandoff_ai"}[t.imageId]||t.imageId:void 0,r=Br(t.imageSelection,["imageId","tag"]);i.imageSelection=r||(s?{imageId:s,tag:i.imageSnapshot?.tag}:void 0),i.imageProvisioning=qr(rr,Br(t.imageProvisioning,["phase","requestedReference","generation","error","startedAt","updatedAt"]),0,0,"string"==typeof t.id&&t.id),i.runtimeVersion=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e,n=e=>{if("string"!=typeof e)return;const t=e.trim();return t&&t.length<=80?t:void 0},i=n(t.desiredVersion);if(!i)return;const s=new Set(bs.shape.phase.options),r="string"==typeof t.phase?t.phase:"pending",o=s.has(r)?r:{idle:"pending",queued:"pending",checking:"pending",downloading:"installing",updating:"installing",completed:"matched",succeeded:"matched",ready:"matched",error:"failed"}[r]||"pending";let a;if(t.error&&"object"==typeof t.error&&!Array.isArray(t.error)){const e=t.error,i="string"==typeof e.message?e.message.trim().slice(0,4096):"";if(i){const t=new Set(Is.shape.code.options),s="string"==typeof e.code&&t.has(e.code)?e.code:"INSTANCE_RUNTIME_INSTALL_FAILED";e.code;const r=n(e.expectedVersion),o=n(e.actualVersion);a={code:s,message:i,...r?{expectedVersion:r}:{},...o?{actualVersion:o}:{},retryable:!0===e.retryable}}}"string"==typeof t.error&&t.error.trim()&&(a={code:"INSTANCE_RUNTIME_INSTALL_FAILED",message:t.error.trim().slice(0,4096),expectedVersion:i,...n(t.actualVersion)?{actualVersion:n(t.actualVersion)}:{},retryable:!1});const d=n(t.actualVersion),c=wi.safeParse(t.lastAttemptAt),l=wi.safeParse(t.matchedAt);return void 0!==t.lastAttemptAt&&c.success,void 0!==t.matchedAt&&l.success,{desiredVersion:i,...d?{actualVersion:d}:{},phase:o,attempt:"number"==typeof t.attempt&&Number.isInteger(t.attempt)&&t.attempt>=0?t.attempt:0,...c.success?{lastAttemptAt:c.data}:{},...l.success?{matchedAt:l.data}:{},...a?{error:a}:{}}}(t.runtimeVersion,"string"==typeof t.id&&t.id),i.workspace=qr(jr,t.workspace,0,0,"string"==typeof t.id&&t.id)||{status:"unknown"},i.environmentSource=qr(ji,t.environmentSource,0,0,"string"==typeof t.id&&t.id),i.environmentTemplateOrigin=qr($i,t.environmentTemplateOrigin,0,0,"string"==typeof t.id&&t.id),i.runtime=qr(Dr.shape.runtime.unwrap(),t.runtime,0,0,"string"==typeof t.id&&t.id)||{labels:{}},i.target=qr(Rr,Br(t.target??t.endpoints,["strategy","web","api","vnc","tty","logs","status"]),0,0,"string"==typeof t.id&&t.id)||{strategy:"direct-port",status:"unknown"},i.access=qr(Pr,Br(t.access,["strategy","web","api","ws","status"]),0,0,"string"==typeof t.id&&t.id)||{strategy:"control-plane-proxy",status:"unknown"};for(const[e,t]of Object.entries(Dr.shape))Object.prototype.hasOwnProperty.call(i,e)&&!t.safeParse(i[e]).success&&t.safeParse(void 0).success&&delete i[e];return i}(i)));var i;if(n.success)return n.data.protocolVersion&&n.data.protocolVersion!==li?(this.client.logger?.warn?.({nodeId:e.id,instanceId:n.data.id,expectedProtocolVersion:li,actualProtocolVersion:n.data.protocolVersion,errorCode:"PROTOCOL_VERSION_MISMATCH"},"node instance protocol version mismatch"),{instance:n.data}):{instance:n.data};const s=t&&"object"==typeof t?t:{},r="string"==typeof s.id?s.id:void 0;return this.client.logger?.warn?.({nodeId:e.id,instanceId:r,errorCode:"NODE_INSTANCE_PAYLOAD_INVALID",issues:n.error.issues.map(e=>({path:e.path.join("."),message:e.message}))},"node instance payload invalid"),{error:{nodeId:e.id,route:"/instances",method:"GET",code:"NODE_INSTANCE_PAYLOAD_INVALID",message:r?`Node instance ${r} payload is invalid.`:"Node instance payload is invalid.",statusCode:502,issues:n.error.issues}}}}function Ka(e){return e.readyState===(e.OPEN??1)}function Ja(e){const t=Buffer.isBuffer(e)?e.toString("utf8"):"string"==typeof e?e:"";if(Buffer.byteLength(t,"utf8")<=123)return t;let n="";for(const e of t){const t=`${n}${e}`;if(Buffer.byteLength(t,"utf8")>123)break;n=t}return n}function Ya(e){if("number"==typeof e&&Number.isInteger(e))return e>=3e3&&e<=4999||e>=1e3&&e<=1014&&1004!==e&&1005!==e&&1006!==e?e:void 0}function Qa(e,t,n){e.close(Ya(t),Ja(n)||void 0)}function Xa(e,t,n,i){if(Ka(e))for(const e of t.splice(0))if(i(e),!n(e))return}function Za(e,t,n={}){const i=n.pendingFrameLimit??256,s=n.maxFrameBytes??8388608,r=n.maxTotalBytes??1073741824,o=n.maxBufferedBytes??16777216;let a=!1,d=Ka(t);const c=[],l=[];let p,u=0,g=0,h=0;const m=e=>Buffer.isBuffer(e)||e instanceof ArrayBuffer||ArrayBuffer.isView(e)?e.byteLength:Buffer.byteLength("string"==typeof e?e:String(e),"utf8"),y=(i,o)=>{const a=m(o);return h+=a,n.onFrame?.(i,a),!(a>s||h>r)||(Qa(e,1009,"WebSocket bridge traffic limit exceeded."),Qa(t,1009,"WebSocket bridge traffic limit exceeded."),!1)},f=()=>{p&&(clearTimeout(p),p=void 0)},I=(n,i)=>{const s=i.bytes;if((n.bufferedAmount??0)+s>o)return Qa(e,1013,"WebSocket bridge consumer is too slow."),Qa(t,1013,"WebSocket bridge consumer is too slow."),!1;try{return function(e,t){e.send(t.data,{binary:t.isBinary})}(n,i),!0}catch{return Qa(e,1011,"WebSocket bridge send failed."),Qa(t,1011,"WebSocket bridge send failed."),!1}},b=(n,s,r)=>{if(s.length>=i)return Qa(e,1011,"WebSocket bridge pending frame limit exceeded."),void Qa(t,1011,"WebSocket bridge pending frame limit exceeded.");const a="upstream"===n?u:g;if((("upstream"===n?t:e).bufferedAmount??0)+a+r.bytes>o)return Qa(e,1013,"WebSocket bridge consumer is too slow."),void Qa(t,1013,"WebSocket bridge consumer is too slow.");s.push(r),"upstream"===n?u+=r.bytes:g+=r.bytes};return n.upstreamOpenTimeoutMs&&!d&&(p=setTimeout(()=>{d||a||(Qa(e,1011,"Upstream websocket did not open."),Qa(t))},n.upstreamOpenTimeoutMs)),e.on("open",()=>Xa(e,l,t=>I(e,t),e=>{g-=e.bytes})),t.on("open",()=>{f(),d=!0,n.onUpstreamOpen?.(),Xa(t,c,e=>I(t,e),e=>{u-=e.bytes})}),e.on("message",(e,n=!1)=>{if(!y("client-to-upstream",e))return;const i={data:e,isBinary:Boolean(n),bytes:m(e)};Ka(t)?I(t,i):b("upstream",c,i)}),t.on("message",(t,n=!1)=>{if(!y("upstream-to-client",t))return;const i={data:t,isBinary:Boolean(n),bytes:m(t)};Ka(e)?I(e,i):b("client",l,i)}),t.on("close",(t,i)=>{f(),n.onUpstreamClose?.(t,i),(d||a||!n.onUpstreamCloseBeforeOpen?.())&&Qa(e,t,i)}),t.on("error",t=>{n.onUpstreamError?.(t),(d||a||!n.onUpstreamErrorBeforeOpen?.(t))&&Qa(e)}),e.on("close",(e,i)=>{f(),a=!0,n.onClientClose?.(e,i),Qa(t,e,i)}),e.on("error",e=>{f(),a=!0,n.onClientError?.(e),Qa(t,1011,"WebSocket bridge client failed.")}),{close:(n,i)=>{f(),Qa(t,n,i),Qa(e,n,i)}}}const ed="TASK_HANDOFF_NODE_AGENT_V1",td=6e4,nd="/api/node-tunnel";function id(e,t){if("paired-hmac"===e.auth.mode&&e.auth.secret){if(!e.auth.keyId){const t=new Error(`Node ${e.id} paired-HMAC auth is missing keyId.`);throw Object.assign(t,{statusCode:500,code:"NODE_AGENT_REMOTE_KEY_ID_MISSING"}),t}return function(e){const t=e.timestamp||(new Date).toISOString(),n=e.nonce||i.randomBytes(18).toString("base64url"),s=sd(e.body||""),r=rd(e.secret,{keyId:e.keyId,method:e.method,pathWithQuery:e.pathWithQuery,timestamp:t,nonce:n,bodySha256:s});return{"x-taskhandoff-node-id":e.nodeId,"x-taskhandoff-key-id":e.keyId,"x-taskhandoff-timestamp":t,"x-taskhandoff-nonce":n,"x-taskhandoff-body-sha256":s,"x-taskhandoff-signature":r}}({nodeId:e.id,keyId:e.auth.keyId,secret:e.auth.secret,method:t.method,pathWithQuery:t.pathWithQuery,body:t.body})}const n="local-ipc"!==e.connectionMode&&"local-loopback"!==e.connectionMode||"local-static-key"!==e.auth.mode?void 0:e.auth.secret;return n?{authorization:`Bearer ${n}`}:{}}function sd(e=""){return i.createHash("sha256").update(e).digest("hex")}function rd(e,t){return i.createHmac("sha256",e).update(function(e){return[ed,e.keyId,e.method.toUpperCase(),e.pathWithQuery,e.timestamp,e.nonce,e.bodySha256].join("\n")}(t)).digest("hex")}function od(e){if(e.startsWith("ipc://"))return decodeURIComponent(e.slice(6))}function ad(e,t=process.platform){if(!function(e,t=process.platform){if("win32"===t)return e.startsWith("\\\\.\\pipe\\");const i=n.statSync(e),s=process.getuid?.();return void 0===s||i.uid===s}(e,t)){const e=new Error("Local node agent IPC socket is not owned by the current user.");throw Object.assign(e,{statusCode:403,code:"NODE_AGENT_IPC_OWNER_INVALID"}),e}}function dd(e,t){return Number.isFinite(e)&&Number(e)>0?Number(e):t}function cd(e,t){const n=AbortSignal.timeout(t);return e?AbortSignal.any([e,n]):n}async function ld(e,t,n,i={}){const s=od(t);return s?(ad(s),async function(e,t,n={}){const i=n.method||"GET",s="string"==typeof n.body||n.body instanceof Buffer?n.body:void 0===n.body||null===n.body?void 0:String(n.body),r=new Headers(n.headers||{});return void 0===s||r.has("content-length")||r.set("content-length",String(Buffer.byteLength(s))),new Promise((o,a)=>{const d=p.request({socketPath:e,method:i,path:`/api/node-agent${t}`,headers:Object.fromEntries(r.entries())},e=>{const t=e.statusCode||500;o(new Response("HEAD"!==i&&204!==t&&205!==t&&304!==t?g.Readable.toWeb(e):null,{status:t,headers:e.headers}))});d.on("error",a);const c=()=>d.destroy(new DOMException("The operation was aborted.","AbortError"));n.signal?.aborted?c():n.signal?.addEventListener("abort",c,{once:!0}),d.once("close",()=>n.signal?.removeEventListener("abort",c)),void 0!==s&&d.write(s),d.end()})}(s,n,i)):e(`${t.replace(/\/$/,"")}/api/node-agent${n}`,i)}function pd(e){const t=e.controlEndpoint||e.endpoint;if(!t){const e=new Error("Node agent direct HTTP mode requires an endpoint.");throw Object.assign(e,{statusCode:400,code:"NODE_AGENT_ENDPOINT_REQUIRED"}),e}return t}function ud(e,t,n,i){const s=pd(e),r=od(s),o=`/api/node-agent${t}`;if(r)return ad(r),function(e,t,n,i={}){const s=`/api/node-agent${t}`,r={createConnection:()=>u.connect(e),headers:{host:"task-handoff-node-agent.local",...i}};return n&&(Array.isArray(n)?n.length>0:n.trim().length>0)?new l.WebSocket(`ws://task-handoff-node-agent.local${s}`,n,r):new l.WebSocket(`ws://task-handoff-node-agent.local${s}`,r)}(r,t,n,i);const a=new URL(o,s.replace(/\/$/,""));return a.protocol="https:"===a.protocol?"wss:":"ws:",n?new l.WebSocket(a.toString(),n,{headers:i}):new l.WebSocket(a.toString(),{headers:i})}function gd(e,t,n){const i=new Headers(n),s=id(e,t);for(const[e,t]of Object.entries(s))"authorization"===e&&i.has(e)||i.set(e,t);return Object.fromEntries(i.entries())}function hd(e=fetch,t={}){const n=t.openWebSocket||ud,i=dd(t.requestTimeoutMs,3e4),s=dd(t.streamHeaderTimeoutMs,3e4),r=dd(t.websocketOpenTimeoutMs,1e4);return{request:async(t,n,s={})=>{const r=pd(t),o=s.method||"GET",a="string"==typeof s.body||s.body instanceof Buffer?s.body:void 0===s.body||null===s.body?void 0:String(s.body),d=gd(t,{method:o,pathWithQuery:`/api/node-agent${n}`,body:a||""},s.headers);return ld(e,r,n,{...s,body:a,headers:d,signal:cd(s.signal,i)})},requestStream:async(t,n,i={})=>{const r=pd(t),o=i.method||"GET",a="string"==typeof i.body||i.body instanceof Buffer?i.body:void 0===i.body||null===i.body?void 0:String(i.body),d=gd(t,{method:o,pathWithQuery:`/api/node-agent${n}`,body:a||""},i.headers),c=new AbortController,l=i.signal?AbortSignal.any([i.signal,c.signal]):c.signal;return async function(t,s,o){const c=setTimeout(()=>o.abort(Object.assign(new Error("Node agent response header timed out."),{code:"NODE_AGENT_RESPONSE_HEADER_TIMEOUT"})),s);c.unref?.();try{return await ld(e,r,n,{...i,body:a,headers:d,signal:l})}finally{clearTimeout(c)}}(0,s,c)},proxyWebSocket(e,t,i,s,o={}){const a=gd(e,{method:"GET",pathWithQuery:`/api/node-agent${i}`},o),d=n(e,i,s,a);return Za(t,d,{upstreamOpenTimeoutMs:r,onUpstreamError:()=>t.close(1011,"Instance websocket proxy failed."),onUpstreamErrorBeforeOpen:()=>!0}),{ping:()=>{const e=d.ping;if(!e)throw new Error("Direct node-agent websocket does not support ping.");e.call(d)},onPong:e=>d.on("pong",e)}}}}class md{direct;tunnel;proxy;constructor(e){this.direct=e.direct,this.tunnel=e.tunnel,this.proxy=e.proxy}setTunnel(e){this.tunnel=e}setProxy(e){this.proxy=e}resolve(e){if(!1===e.connectionEnabled){const e=new Error("Node agent connection is disabled locally.");throw Object.assign(e,{statusCode:409,code:"NODE_AGENT_CONNECTION_DISABLED"}),e}if("control-plane-proxy"===e.connectionMode){if(!this.proxy){const e=new Error("Control-plane proxy transport is not available.");throw Object.assign(e,{statusCode:503,code:"CONTROL_PLANE_PROXY_TRANSPORT_UNAVAILABLE"}),e}return this.proxy}if("reverse-wss"!==e.connectionMode)return this.direct;if(!this.tunnel){const e=new Error("Reverse node agent transport is not available.");throw Object.assign(e,{statusCode:503,code:"NODE_AGENT_REVERSE_TRANSPORT_UNAVAILABLE"}),e}return this.tunnel}}function yd(e,t,n,i){const s=new Error(e,void 0===i?void 0:{cause:i});return Object.assign(s,{code:t,statusCode:n,retryable:n>=500}),s}function fd(e,t){if("control-plane-proxy"!==e.connectionPath.kind)throw yd("Control-plane proxy transport requires a proxy connection path.","CONTROL_PLANE_PROXY_CONFIGURATION_INVALID",400);const n=t(e);if(!n)throw yd("Control-plane proxy credential is missing.","CONTROL_PLANE_PROXY_CREDENTIAL_REQUIRED",503);if(n.nodeId!==e.id||n.proxyBindingId!==e.connectionPath.proxyBindingId||n.targetNodeId!==e.connectionPath.targetNodeId)throw yd("Control-plane proxy credential does not match the node connection identity.","CONTROL_PLANE_PROXY_CREDENTIAL_MISMATCH",409);return n}function Id(e,t){const n=new Headers(t);n.set($n,Nn),n.set(Bn,e.sourceControlPlaneId),n.set(Un,e.bindingKeyId),n.set(Fn,e.credential);const s=jn.safeParse(n.get("x-request-id"));return n.set("x-request-id",s.success?s.data:`proxy_request_${i.randomUUID().replace(/-/g,"")}`),Object.fromEntries(n.entries())}function bd(e){const t=Mn.safeParse(e);if(t.success)return t.data;const n=yd("Control-plane proxy route is invalid.",Hn.RouteInvalid,400);throw Object.assign(n,{issues:t.error.issues}),n}function vd(e,t,n){return t?new l.WebSocket(e,t,{headers:n}):new l.WebSocket(e,{headers:n})}class wd{credentialForNode;fetchImpl;openWebSocket;constructor(e){this.credentialForNode=e.credentialForNode,this.fetchImpl=e.fetchImpl||fetch,this.openWebSocket=e.openWebSocket||vd}async fetch(e,t,n={}){const i=fd(e,this.credentialForNode),s=function(e,t){const n=new URL(bd(t),"https://node-agent.invalid"),i=new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}/http${n.pathname}`,e.proxyOrigin);return i.search=n.search,i}(i,t);try{return await this.fetchImpl(s,{...n,headers:Id(i,n.headers)})}catch(e){if(function(e){return e instanceof Error&&("AbortError"===e.name||"ABORT_ERR"===e.code)}(e))throw e;throw yd(`Trusted control-plane proxy ${i.proxyOrigin} is unavailable.`,"CONTROL_PLANE_PROXY_UNAVAILABLE",503,e)}}request(e,t,n={}){return this.fetch(e,t,n)}requestStream(e,t,n={}){return this.fetch(e,t,n)}proxyWebSocket(e,t,n,i,s={}){const r=fd(e,this.credentialForNode),o=this.openWebSocket(function(e,t){const n=new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}/websocket`,e.proxyOrigin);return n.protocol="wss:",n.searchParams.set("route",bd(t)),n}(r,n).toString(),i,Id(r,s));return Za(t,o,{onUpstreamError:()=>t.close(1011,"Control-plane proxy websocket failed."),onUpstreamErrorBeforeOpen:()=>!0}),{ping:()=>{const e=o.ping;if(!e)throw new Error("Control-plane proxy websocket does not support ping.");e.call(o)},onPong:e=>o.on("pong",e)}}}const Sd=new Set(Object.keys(di.shape)),Ad=new Set(Object.keys(ci.shape));function zd(e,t,n){if(!e||"object"!=typeof e||Array.isArray(e))return e;const i=e,s=Object.keys(i).filter(e=>!t.has(e));return s.length&&n?.(s),Object.fromEntries([...t].filter(e=>e in i).map(e=>[e,i[e]]))}function kd(e){const{credential:t,...n}=e;return n}class Td{pendingClaims;nodeCredentials;identity;constructor(e,t){this.pendingClaims=new yo(e.pendingClaimsDir,{schema:di,sanitize:e=>function(e){return zd(e,Sd,e=>t?.("unknown stored pending proxy claim fields were ignored",{fields:e}))}(e),logger:t,directoryMode:448,fileMode:384}),this.nodeCredentials=new yo(e.nodeCredentialsDir,{schema:ci,sanitize:e=>function(e){return zd(e,Ad,e=>t?.("unknown stored proxy node credential fields were ignored",{fields:e}))}(e),logger:t,directoryMode:448,fileMode:384}),this.identity=new fo(e.identityPath,()=>({controlPlaneId:ho("control_plane")}),{schema:a.z.object({controlPlaneId:a.z.string().trim().min(1).max(160)}).strip(),logger:t,directoryMode:448,fileMode:384})}init(e=Date.now()){return this.pendingClaims.init(),this.nodeCredentials.init(),this.identity.init(),this.gcPendingClaims(e)}controlPlaneId(){return this.identity.get().controlPlaneId}pendingClaimByClaimId(e){return this.pendingClaims.list().find(t=>t.claimId===e)}putPendingClaim(e){const t=this.pendingClaimByClaimId(e.claimId);if(!t)return this.pendingClaims.put(e);if(t.proxyOrigin!==e.proxyOrigin||t.requestedName!==e.requestedName||t.sourceControlPlaneId!==e.sourceControlPlaneId||t.targetNodeId!==e.targetNodeId||t.bindingKeyId!==e.bindingKeyId||t.credential!==e.credential){const e=new Error("Pending proxy claim identity conflicts with an existing claim.");throw Object.assign(e,{code:"CONTROL_PLANE_PROXY_BINDING_IDENTITY_CONFLICT",statusCode:409}),e}return t}publicPendingClaims(){return this.pendingClaims.list().map(kd)}nodeCredential(e){return this.nodeCredentials.list().find(t=>t.nodeId===e)}putNodeCredential(e){const t=this.nodeCredential(e.nodeId);if(t&&(t.proxyOrigin!==e.proxyOrigin||t.proxyBindingId!==e.proxyBindingId||t.targetNodeId!==e.targetNodeId||t.sourceControlPlaneId!==e.sourceControlPlaneId||t.bindingKeyId!==e.bindingKeyId||t.credential!==e.credential)){const e=new Error("Proxy node credential conflicts with the existing node identity.");throw Object.assign(e,{code:"CONTROL_PLANE_PROXY_NODE_IDENTITY_CONFLICT",statusCode:409}),e}return t||this.nodeCredentials.put(e)}deleteNodeCredential(e){const t=this.nodeCredential(e);return!!t&&this.nodeCredentials.delete(t.id)}gcNodeCredentials(e){const t=[];for(const n of this.nodeCredentials.list())e(n)||(this.nodeCredentials.delete(n.id),t.push(n.id));return t}promotePendingClaim(e,t){const n=this.pendingClaimByClaimId(e);if(!n)return;if(n.proxyOrigin!==t.proxyOrigin||n.sourceControlPlaneId!==t.sourceControlPlaneId||void 0!==n.targetNodeId&&n.targetNodeId!==t.targetNodeId||n.bindingKeyId!==t.bindingKeyId||n.credential!==t.credential){const e=new Error("Proxy node credential does not match the pending claim identity.");throw Object.assign(e,{code:"CONTROL_PLANE_PROXY_BINDING_IDENTITY_CONFLICT",statusCode:409}),e}const i=this.putNodeCredential(t);return this.pendingClaims.delete(n.id),i}markCompensationRequired(e){const t=this.pendingClaimByClaimId(e);if(t)return this.pendingClaims.patch(t.id,{status:"compensation-required"})}cancelPendingClaim(e,t){const n=this.pendingClaimByClaimId(e);return n?t?(this.pendingClaims.patch(n.id,{status:"compensation-required"}),{deleted:!1,compensationRequired:!0}):{deleted:this.pendingClaims.delete(n.id),compensationRequired:!1}:{deleted:!1,compensationRequired:!1}}completePendingClaimCompensation(e){const t=this.pendingClaimByClaimId(e);return!(!t||"compensation-required"!==t.status)&&this.pendingClaims.delete(t.id)}gcPendingClaims(e=Date.now()){const t=[];for(const n of this.pendingClaims.list()){if("compensation-required"===n.status)continue;const i=Date.parse(n.expiresAt);!Number.isFinite(i)||i>e||(this.pendingClaims.delete(n.id),t.push(n.id))}return t}}const Ed=a.z.string().trim().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/),Cd=a.z.string().datetime(),xd=a.z.object({sessionReadAgents:a.z.array(a.z.string().trim().min(1).max(120)).max(100).default([]),turnReadAgents:a.z.array(a.z.string().trim().min(1).max(120)).max(100).default([]),liveItemAgents:a.z.array(a.z.string().trim().min(1).max(120)).max(100).default([])}).passthrough();const Nd=a.z.object({aiSessionTimeline:xd.default(function(){return{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}})}).passthrough(),Od=a.z.enum(["connecting","handshaking","healthy","reconnecting","suspect","offline"]),_d=a.z.enum(["start","stop","restart","retry-image"]);a.z.object({instanceId:Ed,revision:a.z.number().int().nonnegative(),updatedAt:Cd,status:a.z.enum(["created","provisioning","starting","registering","registered","running","stopping","stopped","deleting","failed","unhealthy"]),health:a.z.enum(["unknown","ok","degraded","failed"]),connectionStatus:a.z.enum(["unknown","online","offline","endpoint-unreachable"]),ready:a.z.boolean(),lastHeartbeatAt:Cd.optional()}).strip();const Rd=a.z.object({code:a.z.string().trim().min(1).max(120),message:a.z.string().trim().min(1).max(2048)}).strict(),Pd=a.z.object({id:Ed,name:a.z.string().trim().min(1).max(160),status:a.z.enum(["unknown","online","offline","degraded"]),health:a.z.enum(["unknown","ok","degraded","failed"]),connectionMode:a.z.enum(["local-ipc","local-loopback","direct-http","reverse-wss","control-plane-proxy"]),connectionPhase:Od.optional(),lastSeenAt:Cd.optional(),observedAt:Cd,capabilities:a.z.array(a.z.string().trim().min(1).max(120)).max(256),error:Rd.optional()}).strict();a.z.array(Pd);const jd=a.z.object({id:a.z.string().trim().min(1).max(120),name:a.z.string().trim().min(1).max(120),kind:a.z.enum(["tty","gui","web"]),supportsCwdSelection:a.z.boolean()}).strict(),Dd=a.z.object({id:Ed,name:a.z.string().trim().min(1).max(160),nodeId:Ed,status:a.z.enum(["created","provisioning","starting","registering","registered","running","stopping","stopped","deleting","failed","unhealthy"]),health:a.z.enum(["unknown","ok","degraded","failed"]),connectionStatus:a.z.enum(["unknown","online","offline","endpoint-unreachable"]),ready:a.z.boolean(),capabilities:Nd.default({aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}}),config:a.z.object({defaultCodexPermissionMode:de.default("ask")}).strict().default({defaultCodexPermissionMode:"ask"}),lastHeartbeatAt:Cd.optional(),heartbeatAgeMs:a.z.number().int().nonnegative().optional(),observedAt:Cd,runtime:a.z.object({id:Ed,name:a.z.string().trim().min(1).max(160).optional(),type:a.z.enum(["docker","kubernetes","local"]).optional()}).strict(),workspace:a.z.object({status:a.z.enum(["unknown","pending","ready","failed"]),path:a.z.string().trim().max(4096).optional()}).strict(),protocol:a.z.object({version:a.z.string().optional(),compatible:a.z.boolean(),warning:a.z.string().trim().min(1).max(500).optional()}).strict(),aiSessions:tt,availableActions:a.z.array(_d).max(4).default([]),availableApps:a.z.array(jd).max(256).default([]),availableAgents:a.z.array(jd).max(256),error:Rd.optional()}).strict();function Md(e){if(!e||"object"!=typeof e)return;const t=e,n=hs.safeParse(t.build),i=Mi.safeParse(t.platform),s=Li.safeParse(t.arch),r=Ir.safeParse(t.capabilities);return{..."boolean"==typeof t.ok?{ok:t.ok}:{},..."string"==typeof t.role?{role:t.role}:{},..."string"==typeof t.nodeId?{nodeId:t.nodeId}:{},..."string"==typeof t.protocolVersion?{protocolVersion:t.protocolVersion}:{},...i.success?{platform:i.data}:{},...s.success?{arch:s.data}:{},...r.success?{capabilities:r.data}:{},...n.success?{build:n.data}:{},..."string"==typeof t.serverTime?{serverTime:t.serverTime}:{}}}function Ld(e){const{agent:t,...n}=e.capabilities,{secret:i,...s}=e.auth,r=s.pairing?{...s.pairing,joinToken:void 0}:void 0,o=Md(t);return{...e,auth:r?{...s,pairing:r}:s,capabilities:o?{...n,agent:o}:n}}function qd(e){return"local-folder"===e.type?{mode:"local-bind",path:"/workspace",readOnly:!1}:{mode:"git-clone",path:"/workspace",readOnly:!1}}function $d(e){return function(e){const{registrationToken:t,target:n,agentStatus:i,targetStatus:s,uiAccessStatus:r,...o}=e;return o}(function(e){const t=`/instances/${encodeURIComponent(e.id)}`,n={strategy:"control-plane-proxy",web:`${t}/`,api:`${t}/api`,ws:`${t}/api`,status:"online"===e.connectionStatus||"online"===e.agentStatus?"reachable":"endpoint-unreachable"};return{...e,access:n}}(e))}function Bd(e){const{key:t,...n}=e;return{...n,keyPreview:(i=e.key,i.length<=8?"set":`${i.slice(0,4)}...${i.slice(-4)}`),keySet:!0};var i}function Ud(){return(new Date).toISOString()}function Fd(e){return e?e instanceof Headers?Object.fromEntries(e.entries()):Array.isArray(e)?Object.fromEntries(e.map(([e,t])=>[e,t])):Object.fromEntries(Object.entries(e).map(([e,t])=>[e,String(t)])):{}}function Hd(e){const t=String(e||"").split(":");if(3===t.length&&"ai"===t[1]&&t[0]&&t[2])return{instanceId:t[0],aiSessionId:t[2]}}function Wd(e){return e instanceof Error?e.message:String(e)}function Gd(e,t){const n=new Error(t);throw Object.assign(n,{statusCode:404,code:e}),n}a.z.array(Dd);const Vd=a.z.object({proxyOrigin:Dn,inviteToken:a.z.string().trim().min(24).max(512),name:a.z.string().trim().min(1).max(160).optional()}).strict(),Kd=a.z.object({data:a.z.object({binding:Xn,closed:a.z.object({abortedRequests:a.z.number().int().nonnegative(),closedSockets:a.z.number().int().nonnegative()}).strict()}).strict()}).strict();class Jd{claimOperations=new Map;options;constructor(e){this.options=e}listPendingClaims(){return this.options.privateStore.publicPendingClaims()}async claimNode(e){const t=Vd.parse(e),n=Ud(),i=ho("proxy_claim"),s={id:i,claimId:i,proxyOrigin:t.proxyOrigin,...t.name?{requestedName:t.name}:{},sourceControlPlaneId:this.options.privateStore.controlPlaneId(),bindingKeyId:ho("proxy_key"),credential:mo(),status:"pending",createdAt:n,updatedAt:n,expiresAt:new Date(Date.now()+864e5).toISOString()};return this.options.privateStore.putPendingClaim(s),this.withClaimLock(s.claimId,()=>this.completeClaim(s,t.inviteToken))}async resumeClaim(e){return this.withClaimLock(e,async()=>{const t=this.options.privateStore.pendingClaimByClaimId(e);return t||Gd("CONTROL_PLANE_PROXY_CLAIM_NOT_FOUND",`Proxy claim ${e} was not found.`),this.completeClaim(t)})}async cancelClaim(e,t=!1){return this.withClaimLock(e,async()=>{const n=this.options.privateStore.pendingClaimByClaimId(e);if(!n)return{deleted:!1,compensationRequired:!1,remoteRevoke:"not-required"};if("pending"===n.status)return{...this.options.privateStore.cancelPendingClaim(e,!1),remoteRevoke:"not-required"};if(t)return{deleted:this.options.privateStore.completePendingClaimCompensation(e),compensationRequired:!1,remoteRevoke:"not-required",forced:!0,orphanRisk:!0};let i;try{i=await this.requestClaim(n)}catch(e){throw this.compensationError(n,"Trusted control-plane proxy is unavailable; claim cancellation requires retry.",e,503,"CONTROL_PLANE_PROXY_COMPENSATION_REQUIRED",!0,{forceDeleteAllowed:!0,forceDeleteReason:"proxy-unavailable"})}const s=await this.responsePayload(i);if(!i.ok){const t=s?.error?.code;if(t===Hn.InviteInvalid||t===Hn.BindingRevoked||t===Hn.BindingUnknown)return{deleted:this.options.privateStore.completePendingClaimCompensation(e),compensationRequired:!1,remoteRevoke:t===Hn.InviteInvalid?"not-created":"already-revoked"};throw this.compensationError(n,s?.error?.message||`Proxy claim recovery failed with HTTP ${i.status}.`,void 0,i.status,t,s?.error?.retryable)}const r=Bo(ai,s?.data);this.requireClaimResultIdentity(n,r);const o=this.compensationCredential(n,r);let a;try{a=await this.revokeBinding(o)}catch(e){throw this.compensationError(n,"Trusted control-plane proxy is unavailable; binding revocation requires retry.",e,503,"CONTROL_PLANE_PROXY_COMPENSATION_REQUIRED",!0,{forceDeleteAllowed:!0,forceDeleteReason:"proxy-unavailable"})}const d=await this.responsePayload(a);if(!a.ok&&d?.error?.code!==Hn.BindingRevoked&&d?.error?.code!==Hn.BindingUnknown)throw this.compensationError(n,d?.error?.message||`Proxy binding revoke failed with HTTP ${a.status}.`,void 0,a.status,d?.error?.code,d?.error?.retryable);if(a.ok)try{this.requireRevocationReceipt(d,o)}catch(e){throw this.compensationError(n,"Proxy binding revocation returned an invalid receipt; compensation requires retry.",e,502,Hn.TransportFailed,!0)}return{deleted:this.options.privateStore.completePendingClaimCompensation(e),compensationRequired:!1,remoteRevoke:a.ok?"revoked":"already-revoked"}})}applyTargetSnapshot(e,t){const n=this.requireProxyNodeIdentity(e,t.binding.id,t.binding.targetNodeId);return this.putTargetState(n,t.target,{reachability:"reachable",bindingStatus:t.binding.status,bindingRevision:t.binding.revision,streamId:t.streamId,revision:t.revision,observedAt:t.observedAt})}applyTargetEvent(e,t){const n=this.requireProxyNodeIdentity(e,void 0,t.targetNodeId),i=n.proxyState;if(!i?.streamId||i.streamId!==t.streamId||void 0===i.revision||t.revision!==i.revision+1){const e=new Error("Proxy target event does not continue the authoritative snapshot cursor.");throw Object.assign(e,{code:Hn.SnapshotRequired,statusCode:409,retryable:!0}),e}return this.putTargetState(n,t.target,{...i,reachability:"reachable",bindingStatus:"revoked"===i.bindingStatus?"revoked":"active",revision:t.revision,observedAt:t.event.createdAt})}markUnavailable(e,t){const n=this.requireProxyNodeIdentity(e),i=Ud();return this.options.nodes.put(mr.parse({...n,status:"degraded",health:"degraded",proxyState:{...n.proxyState,reachability:"unreachable",bindingStatus:n.proxyState?.bindingStatus??"unknown",lastError:t,updatedAt:i},updatedAt:i}))}markBindingRevoked(e,t){const n=this.requireProxyNodeIdentity(e),i=Ud();return this.options.nodes.put(mr.parse({...n,status:"degraded",health:"degraded",proxyState:{...n.proxyState,reachability:"reachable",bindingStatus:"revoked",lastError:t,updatedAt:i},updatedAt:i}))}assertIdentityPatch(e,t){const n=t.connectionMode??e.connectionMode,i=t.connectionPath??e.connectionPath,s=t.auth??e.auth,r="control-plane-proxy"===e.connectionMode||"control-plane-proxy"===e.connectionPath.kind||"proxy-binding"===e.auth.mode,o="control-plane-proxy"===n||"control-plane-proxy"===i.kind||"proxy-binding"===s.mode,a=n!==e.connectionMode||JSON.stringify(i)!==JSON.stringify(e.connectionPath)||JSON.stringify(s)!==JSON.stringify(e.auth);if((r||o)&&a){const e=new Error("Proxy node connection identity can only be changed through the control-plane proxy lifecycle API.");throw Object.assign(e,{statusCode:409,code:"CONTROL_PLANE_PROXY_IDENTITY_IMMUTABLE",retryable:!1}),e}}async deleteNode(e,t=!1){if("control-plane-proxy"!==e.connectionMode)return{deleted:this.options.deleteNode(e.id),revoke:{mode:"not-proxied",orphanRisk:!1}};const n=this.options.privateStore.nodeCredential(e.id);if(!n){if(!t){const e=new Error("Proxy node credential is missing; remote binding cannot be revoked.");throw Object.assign(e,{statusCode:409,code:"CONTROL_PLANE_PROXY_CREDENTIAL_REQUIRED",retryable:!1,details:{forceDeleteAllowed:!0,forceDeleteReason:"credential-missing"}}),e}return this.forceDeleteNode(e.id)}let i;try{i=await this.revokeBinding(n)}catch(n){if(t)return this.forceDeleteNode(e.id);const i=new Error("Trusted control-plane proxy is unavailable; the binding was not revoked.",{cause:n});throw Object.assign(i,{statusCode:503,code:"CONTROL_PLANE_PROXY_REVOKE_UNAVAILABLE",retryable:!0,details:{forceDeleteAllowed:!0,forceDeleteReason:"proxy-unavailable"}}),i}const s=await this.responsePayload(i);if(!i.ok){if(s?.error?.code===Hn.BindingRevoked||s?.error?.code===Hn.BindingUnknown){const t=s.error.details?.bindingId;if(t===n.proxyBindingId)return this.finishRevokedNodeDelete(e.id)}const t=new Error(s?.error?.message||`Proxy binding revoke failed with HTTP ${i.status}.`);throw Object.assign(t,{statusCode:i.status,code:s?.error?.code||"CONTROL_PLANE_PROXY_REVOKE_FAILED",retryable:s?.error?.retryable??i.status>=500,details:{...(r=s?.error?.details,r&&"object"==typeof r&&!Array.isArray(r)?r:{}),forceDeleteAllowed:!1}}),t}var r;try{this.requireRevocationReceipt(s,n)}catch(e){if(e&&"object"==typeof e){const t=e;t.details={...t.details||{},forceDeleteAllowed:!1}}throw e}return this.finishRevokedNodeDelete(e.id)}async completeClaim(e,t){let n;this.options.privateStore.markCompensationRequired(e.claimId);try{n=await this.requestClaim(e,t)}catch(t){const n=new Error(`Trusted control-plane proxy ${e.proxyOrigin} is unavailable.`,{cause:t});throw Object.assign(n,{statusCode:503,code:"CONTROL_PLANE_PROXY_UNAVAILABLE",retryable:!0,claimId:e.claimId}),n}const i=await this.responsePayload(n);if(!n.ok){const t=i?.error?.retryable??n.status>=500;t||this.options.privateStore.completePendingClaimCompensation(e.claimId);const s=new Error(i?.error?.message||`Proxy claim failed with HTTP ${n.status}.`);throw Object.assign(s,{statusCode:n.status,code:i?.error?.code||"CONTROL_PLANE_PROXY_CLAIM_FAILED",retryable:t,details:i?.error?.details,claimId:e.claimId}),s}const s=Bo(ai,i?.data);this.requireClaimResultIdentity(e,s);const r=this.options.nodes.get(s.target.id),o="control-plane-proxy"===r?.connectionMode&&"control-plane-proxy"===r.connectionPath.kind&&r.connectionPath.proxyBindingId===s.binding.id&&r.connectionPath.targetNodeId===s.target.id;if(r&&!o){this.options.privateStore.markCompensationRequired(e.claimId);const t=new Error(`Node ${s.target.id} already exists with another connection identity.`);throw Object.assign(t,{statusCode:409,code:"CONTROL_PLANE_PROXY_NODE_IDENTITY_CONFLICT",claimId:e.claimId}),t}const a={id:`proxy_credential_${s.target.id}`,nodeId:s.target.id,proxyOrigin:e.proxyOrigin,proxyBindingId:s.binding.id,targetNodeId:s.target.id,sourceControlPlaneId:e.sourceControlPlaneId,bindingKeyId:e.bindingKeyId,credential:e.credential,createdAt:e.createdAt,updatedAt:Ud()},d=r||mr.parse({id:s.target.id,name:e.requestedName||s.target.name,connectionMode:"control-plane-proxy",connectionPath:{kind:"control-plane-proxy",proxyId:new URL(e.proxyOrigin).host,proxyBindingId:s.binding.id,targetNodeId:s.target.id},connectionEnabled:!0,auth:{mode:"proxy-binding"},status:s.target.status,health:s.target.health,capabilities:s.target.capabilities,proxyState:{reachability:"reachable",bindingStatus:s.binding.status,bindingRevision:s.binding.revision,observedAt:Ud(),target:s.target,updatedAt:Ud()},labels:{},lastSeenAt:s.target.lastSeenAt,createdAt:Ud(),updatedAt:Ud()});r||this.options.nodes.put(d);try{this.options.privateStore.promotePendingClaim(e.claimId,a)}catch(e){throw r||this.options.nodes.delete(d.id),e}return{node:Ld(d),binding:s.binding}}requireProxyNodeIdentity(e,t,n){const i=this.options.requireNode(e);if("control-plane-proxy"!==i.connectionMode||"control-plane-proxy"!==i.connectionPath.kind||void 0!==t&&i.connectionPath.proxyBindingId!==t||void 0!==n&&i.connectionPath.targetNodeId!==n){const e=new Error("Proxy state identity does not match the node connection path.");throw Object.assign(e,{code:Hn.BindingIdentityConflict,statusCode:409,retryable:!1}),e}return i}putTargetState(e,t,n){const i=Ud();return this.options.nodes.put(mr.parse({...e,name:t.name,status:t.status,health:t.health,capabilities:t.capabilities,lastSeenAt:t.lastSeenAt,proxyState:{...n,target:t,updatedAt:i},updatedAt:i}))}requestClaim(e,t){return this.options.fetchImpl(new URL("/api/node-proxy/claims",e.proxyOrigin),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({protocolVersion:Nn,...t?{inviteToken:t}:{},claimId:e.claimId,sourceControlPlaneId:e.sourceControlPlaneId,...e.targetNodeId?{targetNodeId:e.targetNodeId}:{},bindingKeyId:e.bindingKeyId,credential:e.credential})})}revokeBinding(e){return this.options.fetchImpl(new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}`,e.proxyOrigin),{method:"DELETE",headers:Id(e)})}async responsePayload(e){return e.json().catch(()=>{})}requireRevocationReceipt(e,t){const n=$o(Kd,e),i=n.success?n.data.data.binding:void 0;if(!i||i.id!==t.proxyBindingId||i.sourceControlPlaneId!==t.sourceControlPlaneId||i.targetNodeId!==t.targetNodeId||i.bindingKeyId!==t.bindingKeyId||"revoked"!==i.status){const e=new Error("Proxy binding revocation receipt does not match the local binding identity.");throw Object.assign(e,{statusCode:502,code:Hn.TransportFailed,retryable:!0,details:{bindingId:t.proxyBindingId}}),e}return i}requireClaimResultIdentity(e,t){if(t.binding.claimId!==e.claimId||t.binding.sourceControlPlaneId!==e.sourceControlPlaneId||t.binding.bindingKeyId!==e.bindingKeyId||t.binding.targetNodeId!==t.target.id||void 0!==e.targetNodeId&&t.binding.targetNodeId!==e.targetNodeId){const t=new Error("Proxy claim response does not match the persisted pending identity.");throw Object.assign(t,{statusCode:409,code:Hn.BindingIdentityConflict,retryable:!1,claimId:e.claimId,compensationRequired:!0}),t}}compensationCredential(e,t){return{id:`proxy_compensation_${t.binding.id}`,nodeId:t.target.id,proxyOrigin:e.proxyOrigin,proxyBindingId:t.binding.id,targetNodeId:t.target.id,sourceControlPlaneId:e.sourceControlPlaneId,bindingKeyId:e.bindingKeyId,credential:e.credential,createdAt:e.createdAt,updatedAt:Ud()}}compensationError(e,t,n,i=503,s="CONTROL_PLANE_PROXY_COMPENSATION_REQUIRED",r=!0,o){const a=new Error(t,void 0===n?void 0:{cause:n});return Object.assign(a,{statusCode:i,code:s,retryable:r,claimId:e.claimId,compensationRequired:!0,...o?{details:o}:{}}),a}async withClaimLock(e,t){const n=(this.claimOperations.get(e)??Promise.resolve()).catch(()=>{}).then(t);this.claimOperations.set(e,n);try{return await n}finally{this.claimOperations.get(e)===n&&this.claimOperations.delete(e)}}finishRevokedNodeDelete(e){const t=this.options.deleteNode(e);return this.options.privateStore.deleteNodeCredential(e),{deleted:t,revoke:{mode:"revoked",orphanRisk:!1}}}forceDeleteNode(e){const t=this.options.deleteNode(e);return this.options.privateStore.deleteNodeCredential(e),{deleted:t,revoke:{mode:"forced",orphanRisk:!0}}}}const Yd=a.z.object({id:Rs.shape.id.optional(),name:Rs.shape.name,source:Ns,defaultImageSelection:Rs.shape.defaultImageSelection,defaultNodeId:Rs.shape.defaultNodeId,defaultRuntimeId:Rs.shape.defaultRuntimeId,workspacePolicy:Os.optional(),labels:Rs.shape.labels.optional()}).strict(),Qd=Yd.omit({id:!0}).partial().strict();function Xd(e){return 1===Array.from(e).length&&!/[\p{L}\p{N}\s]/u.test(e)&&"/"!==e&&"\\"!==e}const Zd=a.z.string().refine(Xd,"Mention trigger must be one printable non-alphanumeric character other than / or \\.");function ec(e){return 1===Array.from(e).length&&!/[\p{L}\p{N}\s]/u.test(e)&&"\\"!==e}const tc=a.z.string().refine(ec,"Command trigger must be one printable non-alphanumeric character other than \\."),nc=a.z.object({publicBaseUrl:a.z.string().trim().max(2048).optional(),updateChannel:ys.default("stable"),mentionTrigger:Zd.default("@"),commandTrigger:tc.default("/"),diagnosticLogs:a.z.boolean().default(!1)}).strict().refine(e=>e.mentionTrigger!==e.commandTrigger,{path:["commandTrigger"],message:"Command and mention triggers must be different."}),ic=a.z.object({publicBaseUrl:a.z.string().trim().max(2048).optional(),updateChannel:ys.optional(),mentionTrigger:Zd.optional(),commandTrigger:tc.optional(),diagnosticLogs:a.z.boolean().optional()}).strict(),sc=a.z.object({id:tr.shape.id.optional(),name:tr.shape.name,description:tr.shape.description,cover:tr.shape.cover,reference:tr.shape.reference,pullPolicy:tr.shape.pullPolicy.optional(),capabilities:a.z.array(a.z.string().trim().min(1).max(80)).optional(),optionalApps:a.z.array(a.z.string().trim().min(1).max(120)).optional(),defaultEnv:tr.shape.defaultEnv.optional(),labels:tr.shape.labels.optional()}).strict(),rc=sc.omit({id:!0}).partial().strict(),oc=a.z.object({name:Fr.shape.name.optional(),channel:Fr.shape.channel.optional(),enabled:a.z.boolean().optional(),token:Fr.shape.token,defaultChatId:Fr.shape.defaultChatId,allowedUserIds:a.z.array(a.z.string().trim().min(1).max(240)).optional(),pollIntervalMs:Fr.shape.pollIntervalMs.optional(),settings:Fr.shape.settings.optional()}).strict(),ac=oc.extend({channel:Fr.shape.channel,name:Fr.shape.name.optional()}),dc=fn.extend({id:fn.shape.configHash}),cc=a.z.object({name:fn.shape.name,description:fn.shape.description,source:hn,action:mn,policy:yn.partial().optional()}).strict(),lc=cc,pc=a.z.object({instanceIds:a.z.array(Dr.shape.id).min(1),target:In,enabled:a.z.boolean().optional()}).strict(),uc=a.z.object({configHash:fn.shape.configHash,enabled:a.z.boolean().optional()}).strict(),gc=a.z.object({mode:a.z.enum(["local-static-key","paired-hmac","proxy-binding"]).default("local-static-key"),keyId:mr.shape.id.optional(),secret:a.z.string().trim().max(4096).optional(),pairedAt:mr.shape.createdAt.optional(),pairing:a.z.object({status:a.z.enum(["pending","paired","expired"]).default("pending"),joinToken:a.z.string().trim().max(4096).optional(),expiresAt:mr.shape.createdAt.optional()}).strict().optional()}).strict(),hc=a.z.object({autoImportAgentConfigs:a.z.boolean().optional(),defaultCodexPermissionMode:de.optional(),aiSessionHistoryLimit:a.z.number().int().min(1).max(Ve).optional()}).strict(),mc=a.z.object({id:Dr.shape.id.optional(),name:Dr.shape.name.optional(),projectId:Dr.shape.projectId,source:Ns.optional(),sourceSnapshot:a.z.record(a.z.string(),a.z.unknown()).optional(),nodeId:Dr.shape.nodeId.optional(),runtimeId:Dr.shape.runtimeId.optional(),environmentSource:ji.optional(),imageSelection:Dr.shape.imageSelection,config:hc.optional(),modelSelection:Dr.shape.modelSelection.optional(),start:a.z.boolean().default(!1)}).strict().superRefine((e,t)=>{e.environmentSource&&e.imageSelection&&t.addIssue({code:"custom",path:["environmentSource"],message:"environmentSource and imageSelection are mutually exclusive."})}),yc=a.z.object({name:Dr.shape.name.optional(),config:hc.optional(),modelSelection:Dr.shape.modelSelection.optional()}).strict(),fc=a.z.object({name:Ps.shape.name,endpoint:Ps.shape.endpoint,key:Ps.shape.key,model:Ps.shape.model,app:Ps.shape.app,enabled:Ps.shape.enabled.optional(),order:Ps.shape.order.optional(),labels:Ps.shape.labels.optional()}).strict(),Ic=fc.partial().strict(),bc=a.z.object({endpoint:Ps.shape.endpoint,key:Ps.shape.key.optional(),existingModelId:Ps.shape.id.optional()}).strict(),vc=bc.extend({model:Ps.shape.model,app:Ps.shape.app}).strict(),wc=a.z.object({id:mr.shape.id.optional(),name:mr.shape.name,connectionMode:mr.shape.connectionMode.optional(),connectionPath:mr.shape.connectionPath.optional(),connectionEnabled:mr.shape.connectionEnabled.optional(),auth:gc.optional(),joinToken:a.z.string().trim().min(1).max(4096).optional(),endpoint:mr.shape.endpoint,controlEndpoint:mr.shape.controlEndpoint,containerEndpoint:mr.shape.containerEndpoint,publicWebBase:mr.shape.publicWebBase,status:a.z.enum(["unknown","online","offline","degraded"]).optional(),health:a.z.enum(["unknown","ok","degraded","failed"]).optional(),capabilities:mr.shape.capabilities.optional(),labels:mr.shape.labels.optional(),lastSeenAt:mr.shape.lastSeenAt}).strict(),Sc=a.z.object({name:mr.shape.name.optional(),connectionMode:mr.shape.connectionMode.unwrap().optional(),connectionPath:mr.shape.connectionPath.unwrap().optional(),connectionEnabled:mr.shape.connectionEnabled.unwrap().optional(),auth:gc.optional(),endpoint:mr.shape.endpoint,controlEndpoint:mr.shape.controlEndpoint,containerEndpoint:mr.shape.containerEndpoint,publicWebBase:mr.shape.publicWebBase,status:mr.shape.status.unwrap().optional(),health:mr.shape.health.unwrap().optional(),capabilities:mr.shape.capabilities.unwrap().optional(),labels:mr.shape.labels.unwrap().optional(),lastSeenAt:mr.shape.lastSeenAt}).strict(),Ac=a.z.object({controlPlaneUrl:a.z.string().trim().url().max(2048),joinToken:a.z.string().trim().min(1).max(4096),controlPlaneName:a.z.string().trim().min(1).max(160).optional(),activate:a.z.boolean().optional()}).strict(),zc=a.z.object({nodeName:a.z.string().trim().min(1).max(160).optional(),expiresInMs:a.z.number().int().positive().max(36e5).optional()}).strict(),kc=a.z.object({id:a.z.string().min(1),endpoint:a.z.string().min(1),nodeId:a.z.string().min(1),keyId:a.z.string().min(1),secret:a.z.string().min(1),pairedAt:a.z.string().min(1),createdAt:a.z.string().min(1),updatedAt:a.z.string().min(1)}).strict();class Tc{options;activePendingPairingRevokes=new Set;constructor(e){this.options=e}async syncLocal(){const e={[this.options.localNodeLabel]:"true",[this.options.builtinNodeLabel]:"true"},t=process.env.TASK_HANDOFF_NODE_AGENT_TOKEN?.trim()||void 0,n=process.env.TASK_HANDOFF_NODE_AGENT_CONTROL_ENDPOINT||process.env.TASK_HANDOFF_NODE_AGENT_ENDPOINT||"http://127.0.0.1:8091",i=function(e){return od(e)?"local-ipc":"local-loopback"}(n),s=mr.parse({id:"node_local_probe",name:"Local Node Probe",connectionMode:i,auth:{mode:"local-static-key",secret:t},labels:e,createdAt:Ud(),updatedAt:Ud()}),r=await this.inspect(n,s),o=Ud(),a=this.options.nodes.get(r.nodeId);for(const e of this.options.nodes.list())"true"===e.labels[this.options.localNodeLabel]&&e.id!==r.nodeId&&this.options.nodes.delete(e.id);return this.options.nodes.put(mr.parse({...a||{},id:r.nodeId,name:a?.name||"Local Node",connectionMode:i,auth:{mode:"local-static-key",secret:t},endpoint:n,controlEndpoint:n,containerEndpoint:process.env.TASK_HANDOFF_NODE_AGENT_CONTAINER_URL,publicWebBase:process.env.TASK_HANDOFF_INSTANCE_PUBLIC_WEB_BASE,status:"online",health:"ok",capabilities:{...a?.capabilities||{},agent:Md(r.data)},labels:{...a?.labels||{},...e},createdAt:a?.createdAt||o,updatedAt:o}))}async create(e){const t=wc.parse(e),n=Ud(),i=t.connectionMode||"direct-http";let s="auth"in(e&&"object"==typeof e&&!Array.isArray(e)?e:{})?t.auth:{mode:"local-ipc"===i||"local-loopback"===i?"local-static-key":"paired-hmac"};const r="direct-http"===i||"reverse-wss"===i;if(r&&"paired-hmac"!==s.mode)throw Ec("Remote node connections require paired-HMAC authentication.","NODE_AGENT_REMOTE_REQUIRES_PAIRED_HMAC");const o=t.controlEndpoint||t.endpoint;if(!o&&"reverse-wss"!==i)throw Ec("Node agent direct HTTP mode requires an endpoint.","NODE_AGENT_ENDPOINT_REQUIRED");const a=t.joinToken&&o?await this.completePairing(o,t.joinToken):void 0;let d,c=!1;try{if(d=a&&o?this.pendingPairingRevoke(o,a):void 0,d&&(this.activePendingPairingRevokes.add(d.id),this.options.pendingPairingRevokes?.put(d)),a){if(a.invalidResponse||a.unsafePublicIdentifiers)throw Object.assign(new Error("Node agent pairing response reflected secret material in a public identifier."),{statusCode:502,code:"NODE_AGENT_PAIRING_RESPONSE_INVALID"});s={mode:"paired-hmac",keyId:a.keyId,secret:a.secret,pairedAt:a.pairedAt,pairing:{status:"paired"}}}if(r&&!s.secret)throw Ec("Remote node connections require a paired node secret or join token.","NODE_AGENT_REMOTE_SECRET_REQUIRED");if(r&&!s.keyId)throw Ec("Remote node connections require a paired key id.","NODE_AGENT_REMOTE_KEY_ID_REQUIRED");const e=t.id||a?.nodeId||ho("node"),u=mr.parse({id:e,name:t.name,connectionMode:i,auth:s,labels:t.labels||{},createdAt:n,updatedAt:n}),g="reverse-wss"===i&&(t.id||a?.nodeId)?void 0:await this.inspect(o||"",u),h=t.id||a?.nodeId||g?.nodeId||e;if(!h)throw Ec("Node id is required.","NODE_ID_REQUIRED");if(a&&t.id&&t.id!==a.nodeId)throw Ec(`Paired node id ${a.nodeId} does not match requested node id ${t.id}.`,"NODE_AGENT_ID_MISMATCH");if(t.id&&g?.nodeId&&g.nodeId!==t.id)throw Ec(`Node agent id ${g.nodeId} does not match requested node id ${t.id}.`,"NODE_AGENT_ID_MISMATCH");if(a&&g?.nodeId&&g.nodeId!==a.nodeId)throw Object.assign(new Error("Node agent health identity did not match the completed pairing."),{statusCode:502,code:"NODE_AGENT_PAIRING_IDENTITY_MISMATCH"});const{joinToken:m,...y}=t,f=mr.parse({...y,id:h,connectionMode:i,auth:s,endpoint:o,controlEndpoint:o,status:t.status||(g?"online":"unknown"),health:t.health||(g?"ok":"unknown"),capabilities:{...t.capabilities||{},...g?{agent:Md(g.data)}:{}},labels:t.labels||{},createdAt:n,updatedAt:n});if(a&&(l=f,p=a.secret,_c(Ld(l),p)))throw Object.assign(new Error("Node agent health response reflected pairing secret material."),{statusCode:502,code:"NODE_AGENT_PAIRING_SECRET_REFLECTED"});c=!0;const I=this.options.nodes.put(f);return this.clearPendingPairingRevoke(d,a),I}catch(e){if(a&&o){const t=this.pairingPersistence(a);if("present"===t.state)return this.clearPendingPairingRevoke(d,a),t.node;if("unknown"===t.state&&c)throw Rc(Object.assign(new Error("Node creation persistence outcome is uncertain; pairing compensation is pending."),{statusCode:503,code:"NODE_AGENT_PAIRING_PERSISTENCE_UNCERTAIN",retryable:!0}),a.secret);throw await this.compensatePairing(o,a,e),this.clearPendingPairingRevoke(d,a),Rc(e,a.secret)}throw e}finally{d&&this.activePendingPairingRevokes.delete(d.id)}var l,p}async recoverPendingPairingRevokes(){const e=(this.options.pendingPairingRevokes?.list()||[]).filter(e=>!this.activePendingPairingRevokes.has(e.id));await Promise.all(e.map(async e=>{try{const t={nodeId:e.nodeId,keyId:e.keyId,secret:e.secret,pairedAt:e.pairedAt,invalidResponse:!1,unsafePublicIdentifiers:!1},n=this.pairingPersistence(t);if("present"===n.state)return void this.clearPendingPairingRevoke(e,t);if("unknown"===n.state)return;await this.compensatePairing(e.endpoint,t,Object.assign(new Error("Recovering a pending pairing revocation."),{code:"NODE_AGENT_PAIRING_REVOCATION_PENDING"})),this.clearPendingPairingRevoke(e,t)}catch{}}))}pendingPairingRevoke(e,t){if(!this.options.pendingPairingRevokes)return;const n=Ud();return kc.parse({id:ho("pairing_revoke"),endpoint:e,nodeId:t.nodeId,keyId:t.keyId,secret:t.secret,pairedAt:t.pairedAt,createdAt:n,updatedAt:n})}pairingPersistence(e){let t;try{t=this.options.nodes.get(e.nodeId)}catch{return{state:"unknown"}}return"paired-hmac"===t?.auth.mode&&t.auth.keyId===e.keyId&&t.auth.secret===e.secret?{state:"present",node:t}:{state:"absent"}}clearPendingPairingRevoke(e,t){if(e)try{this.options.pendingPairingRevokes?.delete(e.id)}catch(e){try{this.options.warn({nodeId:t?Nc(t.nodeId,t.secret):void 0,keyId:t?Nc(t.keyId,t.secret):void 0,errorCode:"NODE_AGENT_PAIRING_OUTBOX_CLEANUP_FAILED"},"node agent pairing outbox cleanup failed; recovery will retry")}catch{}}}async inspect(e,t){const n="/health",i=t?id(t,{method:"GET",pathWithQuery:`/api/node-agent${n}`}):{},s=await ld(this.options.fetchImpl,e,n,{headers:i}),r=await s.json().catch(()=>({}));if(!s.ok)throw this.options.warn(Oc({nodeEndpoint:e,statusCode:s.status,errorCode:"NODE_AGENT_HEALTH_FAILED"},t?.auth.secret),"node agent health check failed"),Object.assign(new Error(r.error?.message||`Node agent health check failed with HTTP ${s.status}`),{statusCode:s.status,code:"NODE_AGENT_HEALTH_FAILED"});const o="string"==typeof r.data?.nodeId&&r.data.nodeId.trim()?r.data.nodeId.trim():void 0;if(!o)throw this.options.warn(Oc({nodeEndpoint:e,errorCode:"NODE_AGENT_ID_MISSING"},t?.auth.secret),"node agent health response missing node id"),Object.assign(new Error("Node agent health response did not include nodeId."),{statusCode:502,code:"NODE_AGENT_ID_MISSING"});const a=$o(hs,r.data?.build);return r.data?.protocolVersion!==li&&this.options.warn(Oc({nodeId:o,nodeEndpoint:e,expectedProtocolVersion:li,actualProtocolVersion:r.data?.protocolVersion,build:a.success?a.data:void 0,errorCode:"PROTOCOL_VERSION_MISMATCH"},t?.auth.secret),"node agent protocol version mismatch"),this.options.info(Oc({nodeId:o,nodeEndpoint:e,protocolVersion:r.data.protocolVersion,build:a.success?a.data:void 0},t?.auth.secret),"node agent health check ok"),{nodeId:o,data:r.data||{}}}async completePairing(e,t){const n=await this.options.fetchImpl(`${e.replace(/\/$/,"")}/api/node-agent/pairing/complete`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({joinToken:t,controlPlaneName:"Control Plane"})}),i=await n.json().catch(()=>({}));if(!n.ok)throw Object.assign(new Error(i.error?.message||`Node agent pairing failed with status ${n.status}.`),{statusCode:n.status,code:"NODE_AGENT_PAIRING_FAILED"});const s=i.data;if("string"!=typeof s?.nodeId||!s.nodeId.trim()||"string"!=typeof s?.keyId||!s.keyId.trim()||"string"!=typeof s?.secret||!s.secret.trim())throw Object.assign(new Error("Node agent pairing response did not include nodeId, keyId, and secret."),{statusCode:502,code:"NODE_AGENT_PAIRING_RESPONSE_INVALID"});const r=$o(Sr,s),o=s.nodeId.trim(),a=s.keyId.trim(),d=s.secret.trim();return{nodeId:o,keyId:a,secret:d,pairedAt:r.success?r.data.pairedAt:Ud(),invalidResponse:!r.success,unsafePublicIdentifiers:o.includes(d)||a.includes(d)}}async compensatePairing(e,t,n){const i="/pairing/current",s=`/api/node-agent${i}`,r={id:t.nodeId,connectionMode:"direct-http",auth:{mode:"paired-hmac",keyId:t.keyId,secret:t.secret}};try{const o=await ld(this.options.fetchImpl,e,i,{method:"DELETE",headers:id(r,{method:"DELETE",pathWithQuery:s}),signal:AbortSignal.timeout(1e4)}),a=await o.json().catch(()=>({}));if(!o.ok)throw Object.assign(new Error(`Node agent pairing revoke failed with HTTP ${o.status}.`),{statusCode:o.status,code:xc(a.error?.code,t.secret,"NODE_AGENT_PAIRING_REVOKE_FAILED"),retryable:408===o.status||429===o.status||o.status>=500});const d=$o(zr,a.data);if(!d.success)throw Object.assign(new Error("Node agent pairing revoke receipt was invalid."),{statusCode:502,code:"NODE_AGENT_PAIRING_REVOKE_RECEIPT_INVALID",retryable:!1});if(d.data.keyId!==t.keyId)throw Object.assign(new Error("Node agent pairing revoke receipt did not match the paired key."),{statusCode:502,code:"NODE_AGENT_PAIRING_REVOKE_RECEIPT_MISMATCH",retryable:!1});try{this.options.info({nodeId:Nc(t.nodeId,t.secret),keyId:Nc(t.keyId,t.secret),originalErrorCode:Cc(n,t.secret)},"node agent pairing revoked after node creation failed")}catch{}}catch(e){const i={nodeId:Nc(t.nodeId,t.secret),keyId:Nc(t.keyId,t.secret),originalErrorCode:Cc(n,t.secret),compensationErrorCode:Cc(e,t.secret)};try{this.options.warn(i,"node agent pairing compensation failed")}catch{}throw Object.assign(new Error("Node creation failed after pairing, and the remote pairing could not be revoked."),{statusCode:502,code:"NODE_AGENT_PAIRING_COMPENSATION_FAILED",retryable:(o=e,!o||"object"!=typeof o||!("retryable"in o)||"boolean"!=typeof o.retryable||o.retryable),details:i})}var o}}function Ec(e,t){return Object.assign(new Error(e),{statusCode:400,code:t})}function Cc(e,t){return xc(e&&"object"==typeof e&&"code"in e?e.code:void 0,t,"UNKNOWN_ERROR")}function xc(e,t,n){return"string"!=typeof e||!/^[A-Z][A-Z0-9_]{0,127}$/.test(e)||e.includes(t)?n:e}function Nc(e,t){return e.includes(t)?"[redacted]":e}function Oc(e,t){if(!t)return e;const n=e=>"string"==typeof e?e.includes(t)?"[redacted]":e:Array.isArray(e)?e.map(n):e&&"object"==typeof e?Object.fromEntries(Object.entries(e).map(([e,i])=>[e.includes(t)?"[redacted-key]":e,n(i)])):e;return n(e)}function _c(e,t){return"string"==typeof e?e.includes(t):Array.isArray(e)?e.some(e=>_c(e,t)):!(!e||"object"!=typeof e)&&Object.entries(e).some(([e,n])=>e.includes(t)||_c(n,t))}function Rc(e,t){const n=e instanceof Error&&!e.message.includes(t)?e.message:"Node creation failed after pairing.",i=e&&"object"==typeof e&&"statusCode"in e&&"number"==typeof e.statusCode?e.statusCode:502,s=Object.assign(new Error(n),{statusCode:i,code:Cc(e,t)});return e&&"object"==typeof e&&"retryable"in e&&"boolean"==typeof e.retryable&&Object.assign(s,{retryable:e.retryable}),s}class Pc{values=new Map;put(e,t,n=Date.now()){this.prune(n),this.values.set(e,t)}take(e,t=Date.now()){this.prune(t);const n=this.values.get(e);return n&&this.values.delete(e),n}peek(e,t=Date.now()){return this.prune(t),this.values.get(e)}delete(e,t=Date.now()){this.prune(t);const n=this.values.get(e);return n&&this.values.delete(e),n}list(e=Date.now()){return this.prune(e),[...this.values.values()]}prune(e=Date.now()){for(const[t,n]of this.values)Date.parse(n.expiresAt)<=e&&this.values.delete(t)}}const jc=a.z.object({joinToken:a.z.string().trim().min(1).max(4096),nodeId:mr.shape.id,nodeName:mr.shape.name.optional(),keyId:a.z.string().trim().min(1).max(160),secret:a.z.string().trim().min(1).max(4096),pairedAt:a.z.string().datetime().optional()}).strict();class Dc{options;invites=new Pc;constructor(e){this.options=e}createInvite(e={}){const t=zc.parse(e&&"object"==typeof e?e:{}),n=mo(),i={id:ho("node_join"),tokenHash:Mc(n),expiresAt:new Date(Date.now()+(t.expiresInMs||6e5)).toISOString(),...t.nodeName?{nodeName:t.nodeName}:{}};return this.invites.put(i.tokenHash,i),{id:i.id,joinToken:n,expiresAt:i.expiresAt}}complete(e){const t=jc.parse(e),n=Mc(t.joinToken),i=this.invites.take(n);if(!i)throw Object.assign(new Error("Node join token is invalid or expired."),{statusCode:401,code:"NODE_JOIN_TOKEN_INVALID"});const s=Ud();if(this.options.nodes.get(t.nodeId))throw Object.assign(new Error(`Node ${t.nodeId} already exists in this control-plane.`),{statusCode:409,code:"NODE_JOIN_NODE_ALREADY_EXISTS"});return this.options.nodes.put(mr.parse({id:t.nodeId,name:t.nodeName||i.nodeName||t.nodeId,connectionMode:"reverse-wss",auth:{mode:"paired-hmac",keyId:t.keyId,secret:t.secret,pairedAt:t.pairedAt||s,pairing:{status:"paired"}},status:"unknown",health:"unknown",capabilities:{},labels:{},createdAt:s,updatedAt:s}))}}function Mc(e){return i.createHash("sha256").update(e).digest("hex")}function Lc(e,t){const n=qc(e);return n.pathname=`${n.pathname.replace(/\/+$/,"")}/${t.replace(/^\/+/,"")}`,n.search="",n.hash="",n.toString()}function qc(e){let t;try{t=new URL(e.trim())}catch{throw Fc("MODEL_ENDPOINT_INVALID","The model endpoint must be a valid HTTP or HTTPS URL.",400)}if("http:"!==t.protocol&&"https:"!==t.protocol||t.username||t.password)throw Fc("MODEL_ENDPOINT_INVALID","The model endpoint must be an HTTP or HTTPS URL without embedded credentials.",400);return t}async function $c(e,t,n){try{return await e(t,{...n,redirect:"error",signal:AbortSignal.timeout(15e3)})}catch(e){const t=e&&"object"==typeof e&&"name"in e&&"TimeoutError"===e.name;throw Fc(t?"MODEL_ENDPOINT_TIMEOUT":"MODEL_ENDPOINT_UNREACHABLE",t?"The model endpoint timed out.":"The model endpoint could not be reached.",t?504:502)}}async function Bc(e,t){const n=await e.text();if(n.length>1e6)throw Fc(t,"The model endpoint response was too large.",502);try{const e=JSON.parse(n);if(!e||"object"!=typeof e||Array.isArray(e))throw new Error("not an object");return e}catch{throw Fc(t,"The model endpoint returned invalid JSON.",502)}}function Uc(e,t){return Fc(e,401===t||403===t?"The model endpoint rejected the API key.":"The model endpoint rejected the request.",502,t)}function Fc(e,t,n,i){return Object.assign(new Error(t),{code:e,statusCode:n,...i?{details:{upstreamStatus:i}}:{}})}function Hc(e,t){e.includes(t)||e.push(t)}function Wc(e){const t=new Set;return e.filter(e=>!t.has(e.id)&&(t.add(e.id),!0))}class Gc{options;constructor(e){this.options=e}list(){return this.listAll().map(Bd)}async listFederated(e){const t=await this.options.gateway.listFleetModels(this.options.listNodes(),{signal:e}),n=new Map;for(const e of this.listAll())n.set(e.id,{id:e.id,model:Bd(e),locations:[{type:"control-plane",name:e.name,enabled:e.enabled,order:e.order}],referenceCount:0});for(const{nodeId:e,model:i}of t.items){const{referenceCount:t,...s}=i,r=n.get(i.id);r?(r.locations.push({type:"node",nodeId:e,name:i.name,enabled:i.enabled,order:i.order,referenceCount:i.referenceCount}),r.referenceCount+=i.referenceCount):n.set(i.id,{id:i.id,model:s,locations:[{type:"node",nodeId:e,name:i.name,enabled:i.enabled,order:i.order,referenceCount:i.referenceCount}],referenceCount:i.referenceCount})}return Bs.parse({models:[...n.values()].sort((e,t)=>e.model.order-t.model.order||e.model.name.localeCompare(t.model.name)),nodeDiagnostics:t.nodeErrors.map(e=>({nodeId:e.nodeId,code:e.code,message:e.message})),updatedAt:Ud()})}create(e){const t=fc.parse(e),n=Ud(),i=Us(t),s=this.options.models.get(i),r=Ps.parse({...t,id:i,enabled:t.enabled??!0,order:t.order??this.nextOrder(),labels:t.labels||{},createdAt:s?.createdAt||n,updatedAt:n});return Bd(this.options.models.put(r))}update(e,t){const n=Ic.parse(t),i=this.requireSecret(e),s=Ps.parse({...i,...n,key:n.key?.trim()?n.key:i.key,createdAt:i.createdAt,updatedAt:Ud()}),r=Us(s);return Bd(this.options.models.put(Ps.parse({...s,id:r})))}delete(e){return this.requireSecret(e),this.options.models.delete(e)}reorder(e){const t=[...new Set(e)],n=new Map(this.options.models.list().map(e=>[e.id,e]));for(const e of t)n.has(e)||Gd("MODEL_NOT_FOUND",`Model ${e} was not found.`);return t.forEach((e,t)=>{const i=n.get(e);this.options.models.put(Ps.parse({...i,order:100*(t+1),updatedAt:Ud()}))}),this.list()}createOnNode(e,t){return this.options.gateway.createModel(this.options.requireNode(e),t)}updateOnNode(e,t,n){return this.options.gateway.updateModel(this.options.requireNode(e),t,n)}deleteOnNode(e,t){return this.options.gateway.deleteModel(this.options.requireNode(e),t)}discover(e){const t=bc.parse(e);return async function(e,t){const n=function(e){const t=qc(e),n=[],i=t.pathname.split("/").filter(Boolean).at(-1)||"";return Hc(n,Lc(t.toString(),/^v\d+$/.test(i)?"models":"v1/models")),Hc(n,new URL("/v1/models",t.origin).toString()),Hc(n,new URL("/models",t.origin).toString()),n}(t.endpoint),i=Date.now();let s;for(const r of n){const n=await $c(e,r,{method:"GET",headers:{accept:"application/json",authorization:`Bearer ${t.key}`}});if(404===n.status||405===n.status){s=n.status;continue}if(!n.ok)throw Uc("MODEL_DISCOVERY_FAILED",n.status);const o=await Bc(n,"MODEL_DISCOVERY_RESPONSE_INVALID"),a=Array.isArray(o.data)?o.data:void 0;if(!a)throw Fc("MODEL_DISCOVERY_RESPONSE_INVALID","The model endpoint returned an invalid model list.",502);return{models:Wc(a.flatMap(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return[];const t=e,n="string"==typeof t.id?t.id.trim():"";if(!n)return[];const i="string"==typeof t.owned_by?t.owned_by.trim():"";return[{id:n,...i?{ownedBy:i}:{}}]}).sort((e,t)=>e.id.localeCompare(t.id))),latencyMs:Date.now()-i}}throw Fc("MODEL_DISCOVERY_UNSUPPORTED","No compatible model-list endpoint was found for this endpoint.",502,s)}(this.options.fetchImpl,this.resolvePrivateInput(t))}test(e){const t=vc.parse(e);return async function(e,t){const n=Date.now(),i="codex"===t.app?await $c(e,Lc(t.endpoint,"responses"),{method:"POST",headers:{accept:"application/json",authorization:`Bearer ${t.key}`,"content-type":"application/json"},body:JSON.stringify({model:t.model,input:"Reply with OK.",max_output_tokens:32,stream:!1})}):await $c(e,function(e){const t=qc(e),n=t.pathname.split("/").filter(Boolean).at(-1)||"";return Lc(t.toString(),/^v\d+$/.test(n)?"messages":"v1/messages")}(t.endpoint),{method:"POST",headers:{accept:"application/json","anthropic-version":"2023-06-01","content-type":"application/json","x-api-key":t.key},body:JSON.stringify({model:t.model,max_tokens:8,messages:[{role:"user",content:"Reply with OK."}]})});if(!i.ok)throw Uc("MODEL_TEST_FAILED",i.status);if((await Bc(i,"MODEL_TEST_RESPONSE_INVALID")).error)throw Fc("MODEL_TEST_RESPONSE_INVALID","The model endpoint returned an error payload.",502);return{success:!0,latencyMs:Date.now()-n}}(this.options.fetchImpl,this.resolvePrivateInput(t))}discoverOnNode(e,t){const n=this.options.requireNode(e);return Vc(n),this.options.gateway.discoverModels(n,t)}testOnNode(e,t){const n=this.options.requireNode(e);return Vc(n),this.options.gateway.testModel(n,t)}require(e,t=!1){const n=this.requireSecret(e);return t?n:Bd(n)}async prepareAssignment(e,t){const n=await this.options.gateway.listModels(e),i={...null===t.codexModelHash?{codexModelHash:null}:t.codexModelHash?.trim()?{codexModelHash:t.codexModelHash.trim()}:{},...null===t.claudeModelHash?{claudeModelHash:null}:t.claudeModelHash?.trim()?{claudeModelHash:t.claudeModelHash.trim()}:{}},s=async(t,i)=>{if(null===i)return;const s=i?this.listAll().find(e=>e.id===i):this.listAll().find(e=>e.enabled&&e.app===t);if(s)return Kc(s,t),await this.options.gateway.deployModel(e,s.id,s),s.id;if(!i)return;const r=n.find(e=>e.id===i);return r||Gd("MODEL_NOT_FOUND",`Model ${i} was not found on control-plane or node ${e.id}.`),Kc(r,t),r.id};return{modelSelection:i,codexModelHash:await s("codex",i.codexModelHash),claudeModelHash:await s("claude",i.claudeModelHash)}}async ensureInstanceAssignment(e){const t=this.options.requireNode(e.nodeId),n=await this.prepareAssignment(t,e.modelSelection);return this.options.gateway.assignInstanceModels(t,e.id,n)}listAll(){return this.options.models.list().map(e=>this.normalize(e)).sort((e,t)=>e.order-t.order||e.createdAt.localeCompare(t.createdAt)||e.id.localeCompare(t.id))}requireSecret(e){const t=this.options.models.get(e);return t||Gd("MODEL_NOT_FOUND",`Model ${e} was not found.`),this.normalize(t)}normalize(e){const t=function(e){if(e&&"object"==typeof e&&!Array.isArray(e)){const t={...e};if(!("app"in t)){const e=Array.isArray(t.apps)?t.apps:[];t.app=e.includes("claude")&&!e.includes("codex")?"claude":"codex"}return delete t.apps,Ps.parse(t)}return Ps.parse(e)}(e);return t!==e&&this.options.models.put(t),t}nextOrder(){return this.options.models.list().reduce((e,t)=>Math.max(e,t.order),0)+100}resolvePrivateInput(e){const t=e.key?.trim()||(e.existingModelId?this.requireSecret(e.existingModelId).key:"");if(!t)throw Object.assign(new Error("An API key is required to contact the model endpoint."),{statusCode:400,code:"MODEL_API_KEY_REQUIRED"});return{...e,key:t}}}function Vc(e){const t=e.capabilities.agent,n=t&&"object"==typeof t&&!Array.isArray(t)?t.capabilities:void 0;if(!n||"object"!=typeof n||Array.isArray(n)||!0!==n.modelEndpointProbe)throw Object.assign(new Error("This node agent does not support model endpoint discovery or testing."),{statusCode:409,code:"NODE_MODEL_ENDPOINT_PROBE_UNSUPPORTED"})}function Kc(e,t){if(e.app!==t)throw Object.assign(new Error(`Model ${e.id} is not a ${t} model.`),{statusCode:400,code:"MODEL_APP_MISMATCH"});if(!e.enabled)throw Object.assign(new Error(`Model ${e.id} is disabled.`),{statusCode:400,code:"MODEL_DISABLED"})}class Jc{requireNode;nodeAgentTransport;constructor(e){this.requireNode=e.requireNode,this.nodeAgentTransport=e.nodeAgentTransport}async request(e,t,n={}){if(!e.target.web||"online"!==e.connectionStatus&&"online"!==e.agentStatus){const t=new Error(`Instance ${e.name} is not reachable.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_UNREACHABLE"}),t}Yc(e);const i=this.requireNode(e.nodeId),s=await this.nodeAgentTransport(i).request(i,`/instances/${encodeURIComponent(e.id)}/proxy`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({path:`/api/${t.replace(/^\/+/,"")}`,method:n.method||"GET",headers:Fd(n.headers),body:(r=n.body,"string"==typeof r?r:null==r?void 0:String(r))})});var r;const o=await s.json().catch(()=>({}));if(!s.ok){const n=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e,n="string"==typeof t.code&&t.code.trim()?t.code:void 0,i="string"==typeof t.message&&t.message?t.message:void 0,s=t.details&&"object"==typeof t.details&&!Array.isArray(t.details)?t.details:void 0;return n||i?{code:n,message:i,details:s}:void 0}(o.error),i=n?.message||function(e){if(!e||"object"!=typeof e||Array.isArray(e))return"";const t=e.message;return"string"==typeof t?t:""}(o.error)||`Instance request failed with HTTP ${s.status}`,r=new Error(i);throw Object.assign(r,{statusCode:s.status,code:n?.code||"INSTANCE_REQUEST_FAILED",...n?.details?{details:n.details}:{},instanceId:e.id,nodeId:e.nodeId,route:t}),r}return o.data??o}async proxyHttp(e,t,n={}){if("online"!==e.connectionStatus&&"online"!==e.agentStatus){const t=new Error(`Instance ${e.name} is not reachable.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_UNREACHABLE"}),t}if(!e.target.web){const t=new Error(`Instance ${e.name} web endpoint is not reachable.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_WEB_UNREACHABLE"}),t}Yc(e);const i=this.requireNode(e.nodeId),s=await this.nodeAgentTransport(i).requestStream(i,`/instances/${encodeURIComponent(e.id)}/proxy/stream`,{method:"POST",headers:{"content-type":"application/json"},signal:n.signal,body:JSON.stringify({path:t,method:n.method||"GET",headers:Fd(n.headers),...(r=n.body,null==r?{}:"string"==typeof r?{body:r}:Buffer.isBuffer(r)?{bodyBase64:r.toString("base64")}:r instanceof Uint8Array?{bodyBase64:Buffer.from(r).toString("base64")}:{body:String(r)})})});var r;return{status:s.status||502,headers:Object.fromEntries(s.headers.entries()),body:s.body}}proxyWebSocket(e,t,n,i,s={}){if(!e.target.web||"online"!==e.connectionStatus&&"online"!==e.agentStatus){const t=new Error(`Instance ${e.name} web endpoint is not reachable.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_WEB_UNREACHABLE"}),t}Yc(e);const r=this.requireNode(e.nodeId),o=n.startsWith("/")?n.slice(1):n;this.nodeAgentTransport(r).proxyWebSocket(r,t,`/instances/${encodeURIComponent(e.id)}/proxy/ws/${o}`,i,s)}async reportHeartbeat(e,t){if(!e.registrationToken)return;const n=this.requireNode(e.nodeId),i=`/instances/${encodeURIComponent(e.id)}/heartbeat`,s={method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.registrationToken}`},body:JSON.stringify(t)},r=await this.nodeAgentTransport(n).request(n,i,s),o=await r.json().catch(()=>({}));if(!r.ok){const e=new Error(o.error?.message||`Instance heartbeat sync failed with HTTP ${r.status}`);throw Object.assign(e,{statusCode:r.status,code:"INSTANCE_HEARTBEAT_SYNC_FAILED"}),e}}}function Yc(e){if(Vr(e))return;const t=new Error(`Instance ${e.name} is not ready.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_NOT_READY",runtimePhase:e.runtimeVersion?.phase}),t}class Qc{read(e){const t=new Map(e.projects.map(e=>[e.id,e])),n=new Map(e.images.map(e=>[e.id,e])),i=new Map(e.nodes.map(e=>[e.id,e])),s=new Map(e.runtimes.map(e=>[`${e.nodeId}:${e.id}`,e])),r=Date.now();return{items:e.instances.map(e=>function(e){const t=e.instance.lastHeartbeatAt?e.currentTime-Date.parse(e.instance.lastHeartbeatAt):void 0,n=void 0!==t&&t>3e4?"offline":e.instance.connectionStatus,i=$d(e.instance);return{...i,aiSessions:nt(i.aiSessions),connectionStatus:n,heartbeatAgeMs:t,project:e.project,image:e.image,node:e.node?Ld(e.node):void 0,runtime:e.runtime,protocolCompatible:!e.instance.protocolVersion||e.instance.protocolVersion===li}}({instance:e,currentTime:r,project:e.projectId?t.get(e.projectId):void 0,image:e.imageSnapshot||(e.imageSelection?n.get(e.imageSelection.imageId):void 0),node:i.get(e.nodeId),runtime:s.get(`${e.nodeId}:${e.runtimeId}`)})),nodeErrors:e.nodeErrors||[]}}}class Xc{options;constructor(e){this.options=e}async create(e){const t=mc.parse(e),n=t.projectId?this.options.requireProject(t.projectId):void 0,i=t.runtimeId||n?.defaultRuntimeId||"runtime_local_docker",s=t.nodeId||n?.defaultNodeId||this.options.defaultNodeId();if(!s)throw el("At least one node connection is required before creating an instance.",400,"NODE_REQUIRED");const r=this.options.requireNode(s),o=await this.options.requireRuntime(r.id,i),a=o.capabilities.requiresImage??"local"!==o.type,d=t.environmentSource||(t.imageSelection?{type:"image",imageSelection:t.imageSelection}:void 0)||(a&&n?.defaultImageSelection?{type:"image",imageSelection:n.defaultImageSelection}:void 0);if("template"===d?.type&&"docker"!==o.type)throw el(`Runtime ${o.name} does not support environment templates.`,409,"ENVIRONMENT_TEMPLATE_RUNTIME_UNSUPPORTED");const c="image"===d?.type?d.imageSelection:void 0,l=c?this.options.resolveImageSelection(c):void 0,p="template"===d?.type?await this.options.gateway.getEnvironmentTemplate(r,d.environmentTemplateId):void 0;if(p&&"ready"!==p.status)throw el(`Environment template ${p.id} is ${p.status}.`,409,"ENVIRONMENT_TEMPLATE_NOT_READY");if(p&&p.nodeId!==r.id)throw el(`Environment template ${p.id} belongs to node ${p.nodeId}.`,409,"ENVIRONMENT_TEMPLATE_NODE_MISMATCH");if(a&&!l&&!p)throw el(`Runtime ${o.name} requires an image.`,400,"RUNTIME_IMAGE_REQUIRED");const u=await this.resolveSource({node:r,runtime:o,project:n,source:t.source,sourceSnapshot:t.sourceSnapshot,imageOption:l}),g=await this.options.prepareModels(r,t.modelSelection||{}),h=l?function(e){const t=Ud();return{id:e.id,origin:e.origin,name:e.name,description:e.description,localizedDescriptions:e.localizedDescriptions,cover:e.cover,repository:e.repository,tag:e.tag,requestedReference:e.reference,resolvedDigest:e.digest,resolvedReference:e.digest?`${e.repository}@${e.digest}`:void 0,downloadSizeBytes:e.downloadSizeBytes,pullPolicy:"if-not-present",capabilities:e.capabilities,optionalApps:e.optionalApps,defaultEnv:e.defaultEnv,labels:e.labels,market:e.market,createdAt:t,updatedAt:t}}(l):void 0,m=await this.options.gateway.createInstance(r,{id:t.id,name:t.name,runtimeId:i,...d?{environmentSource:d}:{},...l&&h?{image:h}:{},projectId:n?.id,source:u.value,sourceSnapshot:u.snapshot,config:t.config,modelSelection:{}});let y=m;try{y=(await this.options.gateway.assignInstanceModels(r,m.id,g)).instance}catch(e){throw await this.options.gateway.deleteInstance(r,m.id,{deleteVolumes:!0}).catch(()=>{}),e}let f={status:"not-requested"};if(t.start)try{y=await this.options.gateway.startInstance(r,y.id),f={status:"started"}}catch(e){f={status:"failed",error:Zc(e,"INSTANCE_START_FAILED")},y=await this.options.gateway.listInstances(r).then(e=>e.find(e=>e.id===y.id)||y).catch(()=>y)}return{...$d(y),registrationToken:y.registrationToken,startOutcome:f}}async resolveSource(e){let t=e.source||e.project?.source,n=e.sourceSnapshot||(e.project?e.project:{});if(!t)throw el("Instance source is required.",400,"INSTANCE_SOURCE_REQUIRED");if("local"===e.runtime.type&&"local-folder"!==t.type)throw el("Localhost runtime currently supports local folder sources only.",400,"LOCAL_RUNTIME_REQUIRES_LOCAL_FOLDER");if("local-folder"!==t.type)return{value:t,snapshot:n};if(t.ownerNodeId&&t.ownerNodeId!==e.node.id)throw el(`Local folder ${t.path} belongs to node ${t.ownerNodeId}, not ${e.node.id}.`,400,"LOCAL_FOLDER_REQUIRES_OWNER_NODE");const i=t.localFolderId?await this.options.requireLocalFolder(e.node,t.localFolderId):await this.options.gateway.createLocalFolder(e.node,{name:"string"==typeof n.name?n.name:"Local folder",path:t.path,defaultImageSelection:e.imageOption?{imageId:e.imageOption.id,tag:e.imageOption.tag}:void 0});return t={...t,localFolderId:i.id,ownerNodeId:i.nodeId,path:i.path},n=i,{value:t,snapshot:n}}}function Zc(e,t){const n=e&&"object"==typeof e?e:{};return{code:"string"==typeof n.code&&n.code.trim()?n.code:t,message:"string"==typeof n.message&&n.message.trim()?n.message:String(e)}}function el(e,t,n){return Object.assign(new Error(e),{statusCode:t,code:n})}class tl{triggers;listInstances;requireInstance;instanceRequest;constructor(e){this.triggers=e.triggers,this.listInstances=e.listInstances,this.requireInstance=e.requireInstance,this.instanceRequest=e.instanceRequest}async listTriggers(){const e=await this.listInstances(),t=new Map;for(const e of this.triggers.list())t.set(e.configHash,{configHash:e.configHash,config:nl(e),deploymentCount:0,enabledCount:0,runningCount:0,errorCount:0,ownedByControlPlane:!0,controlPlaneDeploymentCount:0,deployments:[],recentRuns:[]});for(const n of e){const e=n.triggers;for(const i of e?.configs||[]){const s=t.get(i.configHash)||{configHash:i.configHash,config:i.config,deploymentCount:0,enabledCount:0,runningCount:0,errorCount:0,ownedByControlPlane:!1,controlPlaneDeploymentCount:0,deployments:[],recentRuns:[]},r=(i.deployments||[]).map(e=>({instanceId:n.id,instanceName:n.name,deployment:e,runtime:(i.runtime||[]).find(t=>t.deploymentId?t.deploymentId===e.deploymentId:t.configHash===e.configHash)}));s.deploymentCount+=r.length,s.enabledCount+=r.filter(e=>Boolean(e.deployment.enabled)).length,s.controlPlaneDeploymentCount+=r.filter(e=>"control-plane"===e.deployment.origin).length,s.runningCount+=(i.runtime||[]).filter(e=>"running"===e.status).length,s.errorCount+=(i.runtime||[]).filter(e=>"error"===e.status).length,s.deployments.push(...r),s.recentRuns.push(...(e.recentRuns||[]).filter(e=>e.configHash===i.configHash).map(e=>({...e,instanceId:n.id,instanceName:n.name}))),t.set(i.configHash,s)}}return kn.parse({updatedAt:(new Date).toISOString(),triggers:[...t.values()].sort((e,t)=>String(e.config.name||e.configHash).localeCompare(String(t.config.name||t.configHash)))})}createTrigger(e){const t=cc.parse(e||{}),n=Ud(),i={maxConcurrentRuns:t.policy?.maxConcurrentRuns??1,whenBusy:t.policy?.whenBusy??"skip",cooldownMs:t.policy?.cooldownMs},s=Tn({source:t.source,action:t.action,policy:i}),r=dc.parse({id:s,configHash:s,name:t.name,description:t.description,source:t.source,action:t.action,policy:i,createdAt:n,updatedAt:n});return this.triggers.put(r)}async updateTrigger(e,t){const n=this.requireTrigger(e),i=lc.parse(t||{}),s=Ud(),r={maxConcurrentRuns:i.policy?.maxConcurrentRuns??1,whenBusy:i.policy?.whenBusy??"skip",cooldownMs:i.policy?.cooldownMs},o=Tn({source:i.source,action:i.action,policy:r});if(o!==e&&this.triggers.get(o)){const e=new Error(`Trigger ${o} already exists.`);throw Object.assign(e,{statusCode:409,code:"TRIGGER_ALREADY_EXISTS"}),e}const a=dc.parse({id:o,configHash:o,name:i.name,description:i.description,source:i.source,action:i.action,policy:r,createdAt:n.createdAt,updatedAt:s}),d=await this.listInstances(),c=[];for(const t of d){const n=t.triggers?.configs?.find(t=>t.configHash===e),i=(n?.deployments||[]).filter(e=>"control-plane"===e.origin);if(o!==e)for(const n of i){const i="ai-session"===n.target.type?il(n.target.aiSessionId,o):n.deploymentId,s=await this.instanceRequest(t,"/triggers",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:a.name,description:a.description,source:a.source,action:a.action,policy:a.policy,deployment:{deploymentId:i,origin:"control-plane",enabled:n.enabled,target:n.target,localName:n.localName}})}),r=n.deploymentId||n.configHash;await this.instanceRequest(t,`/triggers/${encodeURIComponent(e)}/deployments/${encodeURIComponent(r)}`,{method:"DELETE"}),c.push({instanceId:t.id,deploymentId:i,data:s})}else i.length&&c.push({instanceId:t.id,data:await this.instanceRequest(t,`/triggers/${encodeURIComponent(e)}`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({name:a.name,description:a.description??null})})})}return this.triggers.put(a),o!==e&&this.triggers.delete(e),{previousConfigHash:e,trigger:a,results:c}}async deleteTrigger(e){const t=this.triggers.delete(e),n=await this.listInstances(),i=[];for(const t of n){const n=t.triggers?.configs?.find(t=>t.configHash===e);if(!n)continue;const s=(n.deployments||[]).filter(e=>"control-plane"===e.origin);if(!s.length)continue;const r=n.deployments.every(e=>"control-plane"===e.origin);for(const n of s)try{const s=n.deploymentId?`/triggers/${encodeURIComponent(e)}/deployments/${encodeURIComponent(n.deploymentId)}`:r?`/triggers/${encodeURIComponent(e)}`:void 0;if(!s){i.push({instanceId:t.id,configHash:e,deploymentId:n.deploymentId,deleted:!1,skipped:"missing-deployment-id"});continue}const o=await this.instanceRequest(t,s,{method:"DELETE"});if(i.push({instanceId:t.id,configHash:e,deploymentId:n.deploymentId,deleted:!0,data:o}),!n.deploymentId)break}catch(s){i.push({instanceId:t.id,configHash:e,deploymentId:n.deploymentId,deleted:!1,error:s instanceof Error?s.message:String(s)})}}return t||i.length||Gd("TRIGGER_NOT_FOUND",`Trigger ${e} was not found.`),{configHash:e,deletedTemplate:t,results:i}}async applyTrigger(e,t){const n=this.requireTrigger(e),i=pc.parse(t||{}),s=[];for(const e of i.instanceIds){const t=await this.requireInstance(e);s.push({instanceId:e,data:await this.instanceRequest(t,"/triggers",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:n.name,description:n.description,source:n.source,action:n.action,policy:n.policy,deployment:{origin:"control-plane",enabled:i.enabled??!0,target:i.target}})})})}return{configHash:e,results:s}}async listInstanceTriggers(e){const t=await this.requireInstance(e);return this.instanceRequest(t,"/triggers")}async bindAiSessionTrigger(e,t,n){const i=uc.parse(n||{}),s=this.requireTrigger(i.configHash),r=await this.requireInstance(e);return this.instanceRequest(r,"/triggers",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:s.name,description:s.description,source:s.source,action:s.action,policy:s.policy,deployment:{deploymentId:il(t,i.configHash),origin:"control-plane",enabled:i.enabled??!0,target:{type:"ai-session",aiSessionId:t}}})})}async unbindAiSessionTrigger(e,t,n){const i=await this.requireInstance(e),s=il(t,n);return this.instanceRequest(i,`/triggers/${encodeURIComponent(n)}/deployments/${encodeURIComponent(s)}`,{method:"DELETE"})}async runInstanceTrigger(e,t,n={}){const i=await this.requireInstance(e);return this.instanceRequest(i,`/triggers/${encodeURIComponent(t)}/run`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n||{})})}requireTrigger(e){const t=this.triggers.get(e);return t||Gd("TRIGGER_NOT_FOUND",`Trigger ${e} was not found.`),t}}function nl(e){return{configHash:e.configHash,name:e.name,...void 0!==e.description?{description:e.description}:{},source:e.source,action:e.action,policy:e.policy,createdAt:e.createdAt,updatedAt:e.updatedAt}}function il(e,t){return`ai_${Buffer.from(e).toString("base64url")}_${t}`}class sl{options;constructor(e){this.options=e}getSettings(){return nc.parse(this.options.settings.get())}updateSettings(e){const t=ic.parse(e),n=nc.parse({...this.getSettings(),...t,..."publicBaseUrl"in t?{publicBaseUrl:t.publicBaseUrl?.trim()||void 0}:{}});return this.options.settings.put(n)}seedDefaults(){}listProjects(){return this.options.projects.list().map(e=>this.normalizeProjectRecord(e))}getProject(e){const t=this.options.projects.get(e);return t?this.normalizeProjectRecord(t):void 0}createProject(e){const t=Yd.parse(e),n=Ud(),i=Ns.parse(t.source);return this.options.projects.put(Rs.parse({...t,id:t.id||ho("proj"),source:i,defaultImageSelection:t.defaultImageSelection||{imageId:"market_taskhandoff_browser"},defaultNodeId:t.defaultNodeId||this.options.defaultNodeId(),defaultRuntimeId:t.defaultRuntimeId||"runtime_local_docker",workspacePolicy:Os.parse(t.workspacePolicy||qd(i)),labels:t.labels||{},createdAt:n,updatedAt:n}))}updateProject(e,t){const n=Qd.parse(t),i=this.requireProject(e),s=n.source?Ns.parse(n.source):i.source;return this.options.projects.put(Rs.parse({...i,...n,id:e,source:s,workspacePolicy:n.workspacePolicy?Os.parse(n.workspacePolicy):i.workspacePolicy,createdAt:i.createdAt,updatedAt:Ud()}))}deleteProject(e){return this.options.projects.delete(e)}requireProject(e){const t=this.getProject(e);return t||Gd("PROJECT_NOT_FOUND",`Project ${e} was not found.`),t}listImages(){return this.options.images.list()}getMarketCatalog(){return{catalog:this.options.market.getCatalog(),status:this.options.market.getStatus()}}listImageOptions(e){return[...this.options.market.getCatalog().items.map(t=>this.marketImageOption(t,void 0,e,!0)),...this.listImages().map(e=>this.customImageOption(e))]}resolveImageSelection(e,t){const n=this.options.market.getCatalog().items.find(t=>t.id===e.imageId);if(n)return this.marketImageOption(n,e.tag,t);const i=this.options.images.get(e.imageId);if(i||Gd("IMAGE_NOT_FOUND",`Image ${e.imageId} was not found.`),e.tag&&e.tag!==i.tag)throw Object.assign(new Error(`Custom image ${i.id} cannot override its stored tag.`),{statusCode:400,code:"CUSTOM_IMAGE_TAG_OVERRIDE"});return this.customImageOption(i)}createImage(e){const t=sc.parse(e),n=Ud(),i=Ni(t.reference);return this.options.images.put(tr.parse({...t,id:t.id||ho("img"),origin:"custom",reference:i.reference,repository:i.repository,tag:i.tag,pullPolicy:t.pullPolicy||"if-not-present",capabilities:t.capabilities||[],optionalApps:t.optionalApps||[],defaultEnv:t.defaultEnv||{},labels:t.labels||{},createdAt:n,updatedAt:n}))}updateImage(e,t){const n=rc.parse(t),i=this.requireImage(e),s=Ni(n.reference||i.reference);return this.options.images.put(tr.parse({...i,...n,id:e,origin:"custom",reference:s.reference,repository:s.repository,tag:s.tag,createdAt:i.createdAt,updatedAt:Ud()}))}deleteImage(e){return this.options.images.delete(e)}requireImage(e){if(this.options.market.getCatalog().items.some(t=>t.id===e))throw Object.assign(new Error(`Market image ${e} is read-only.`),{statusCode:403,code:"MARKET_IMAGE_READ_ONLY"});const t=this.options.images.get(e);return t||Gd("IMAGE_NOT_FOUND",`Image ${e} was not found.`),t}normalizeProjectRecord(e){const t=function(e){if(e&&"object"==typeof e&&!Array.isArray(e)){const t={...Vi(e)};return"defaultRuntimeId"in t||(t.defaultRuntimeId="runtime_local_docker"),Rs.parse(t)}return Rs.parse(e)}(e);return t!==e&&this.options.projects.put(t),t}customImageOption(e){return ir.parse({id:e.id,origin:"custom",name:e.name,description:e.description,localizedDescriptions:e.localizedDescriptions,cover:e.cover||Gs,repository:e.repository,tag:e.tag,availableTags:e.tag?[{name:e.tag,reference:e.reference,status:"active"}]:[],reference:e.reference,capabilities:e.capabilities,optionalApps:e.optionalApps,defaultEnv:e.defaultEnv,labels:e.labels,readOnly:!1})}marketImageOption(e,t,n,i=!1){if("yanked"===e.status&&!i)throw Object.assign(new Error(`Market image ${e.id} is no longer selectable.`),{statusCode:409,code:"MARKET_IMAGE_YANKED"});const s=t||e.defaultTag,r=e.tags.find(e=>e.name===s);if(!r)throw Object.assign(new Error(`Market image ${e.id} does not provide tag ${s}.`),{statusCode:400,code:"MARKET_IMAGE_TAG_NOT_FOUND"});if("yanked"===r.status&&!i)throw Object.assign(new Error(`Market image tag ${e.id}:${s} is no longer selectable.`),{statusCode:409,code:"MARKET_IMAGE_TAG_YANKED"});const o=r.platforms.find(e=>!(n?.os&&e.os!==n.os||n?.architecture&&e.architecture!==n.architecture)),a=this.options.market.getCatalog();return ir.parse({id:e.id,origin:"market",name:e.name,description:e.description,localizedDescriptions:e.localizedDescriptions,cover:e.cover||Gs,repository:e.repository,tag:r.name,availableTags:e.tags.map(e=>({name:e.name,version:e.version,reference:e.reference,manifestDigest:e.manifestDigest,status:e.status})),reference:r.reference,digest:o?.digest||r.manifestDigest,downloadSizeBytes:o?.downloadSizeBytes,unpackedSizeBytes:o?.unpackedSizeBytes,capabilities:e.capabilities,optionalApps:e.optionalApps,defaultEnv:e.defaultEnv,labels:e.labels,readOnly:!0,lifecycleStatus:"yanked"===r.status||"yanked"===e.status?"yanked":"deprecated"===r.status||"deprecated"===e.status?"deprecated":"active",market:{catalogId:a.catalogId,catalogRevision:a.revision,publisher:e.publisher,version:r.version}})}}function rl(e){const t=Ni(e.reference),n=t.tag||"latest";return{id:e.id,publisher:"task-handoff",slug:e.slug,name:e.name,description:e.description,localizedDescriptions:e.localizedDescriptions,cover:Gs,repository:t.repository,defaultTag:n,tags:[{name:n,reference:t.reference,platforms:[],status:"active"}],capabilities:e.capabilities,optionalApps:e.optionalApps,defaultEnv:{},labels:{"task-handoff.image.kind":"controlled-instance","task-handoff.image.profile":e.slug},status:"active"}}function ol(){const e=(t=process.env.TASK_HANDOFF_BUILT_AT)&&!Number.isNaN(Date.parse(t))?new Date(t).toISOString():(new Date).toISOString();var t;return Zs.parse({protocolVersion:"2026-07-29",catalogId:"task_handoff_embedded",revision:process.env.TASK_HANDOFF_VERSION||"0.0.1",source:"embedded",generatedAt:e,items:[rl({id:"market_taskhandoff_codex",slug:"codex",name:"TaskHandoff Codex",description:"Minimal Codex runtime with terminal and Codex.",localizedDescriptions:{"zh-CN":"最小 Codex 运行环境,包含终端和 Codex。"},reference:process.env.TASK_HANDOFF_CONTROLLED_CODEX_IMAGE||"huadream/task-handoff-controlled-codex:latest",capabilities:["terminal","codex"],optionalApps:["terminal-tty"]}),rl({id:"market_taskhandoff_ai",slug:"ai",name:"TaskHandoff Codex + Claude",description:"AI development runtime with Codex, Claude, and terminal.",localizedDescriptions:{"zh-CN":"AI 开发运行环境,包含 Codex、Claude 和终端。"},reference:process.env.TASK_HANDOFF_CONTROLLED_AI_IMAGE||"huadream/task-handoff-controlled-ai:latest",capabilities:["terminal","codex","claude"],optionalApps:["terminal-tty"]}),rl({id:"market_taskhandoff_webcap",slug:"webcap",name:"TaskHandoff WebCap",description:"Browser automation runtime with WebCap, Codex, Claude, Chromium, and VNC.",localizedDescriptions:{"zh-CN":"浏览器自动化运行环境,包含 WebCap、Codex、Claude、Chromium 和 VNC。"},reference:process.env.TASK_HANDOFF_CONTROLLED_WEB_CAP_IMAGE||"huadream/task-handoff-controlled-webcap:latest",capabilities:["browser","terminal","gui-terminal","web-cap","codex","claude"],optionalApps:["chromium","terminal-tty","gui-terminal"]}),rl({id:"market_taskhandoff_browser",slug:"browser",name:"TaskHandoff Browser",description:"Full runtime with Codex, Claude, Chromium, VNC, and code-server.",localizedDescriptions:{"zh-CN":"完整运行环境,包含 Codex、Claude、Chromium、VNC 和 code-server。"},reference:process.env.TASK_HANDOFF_CONTROLLED_BROWSER_IMAGE||"huadream/task-handoff-controlled-browser:latest",capabilities:["browser","terminal","gui-terminal","vscode-web","codex","claude"],optionalApps:["chromium","terminal-tty","gui-terminal","vscode-web"]})]})}class al{async loadCatalog(){return ol()}}class dl{snapshot;status;constructor(e=ol()){this.snapshot=Zs.parse(e),this.status=er.parse({source:this.snapshot.source,state:"ready",revision:this.snapshot.revision,updatedAt:this.snapshot.generatedAt})}getCatalog(){return this.snapshot}getStatus(){return this.status}acceptCandidate(e){const t=Zs.safeParse(e);return t.success?(this.snapshot=t.data,this.status=er.parse({source:t.data.source,state:"ready",revision:t.data.revision,updatedAt:(new Date).toISOString()}),{accepted:!0,snapshot:t.data}):(this.status=er.parse({...this.status,state:"failed",updatedAt:(new Date).toISOString(),error:t.error.message}),{accepted:!1,error:t.error})}recordRefreshFailure(e){return this.status=er.parse({...this.status,state:this.snapshot?"stale":"failed",updatedAt:(new Date).toISOString(),error:e instanceof Error?e.message:String(e)}),this.snapshot}async refresh(e){try{const t=await e.loadCatalog();return this.acceptCandidate(t)}catch(e){return this.recordRefreshFailure(e),{accepted:!1,error:e}}}}class cl{records=new Map;options;constructor(e){this.options=e}create(e){const t=i.randomBytes(this.options.tokenBytes).toString("base64url"),n={...e,token:t,expiresAt:new Date(Date.now()+(e.ttlMs||this.options.ttlMs)).toISOString()};return this.records.set(t,n),n}resolve(e,t){const n=this.records.get(e);if(!n)throw this.invalidError();if(n.expiresAt<=(new Date).toISOString())throw this.records.delete(e),this.invalidError();if(t&&!t(n))throw this.invalidError();return n}revoke(e,t){const n=this.resolve(e,t);return this.records.delete(e),n}invalidError(){const e=new Error(this.options.invalidMessage);return Object.assign(e,{statusCode:this.options.invalidStatusCode||400,code:this.options.invalidCode}),e}}class ll{requireInstance;listAppSessions;tokens=new cl({invalidMessage:"App access link is invalid or expired.",invalidCode:"APP_ACCESS_TOKEN_INVALID",invalidStatusCode:401,tokenBytes:24,ttlMs:9e5});constructor(e){this.requireInstance=e.requireInstance,this.listAppSessions=e.listAppSessions}createToken(e){return this.tokens.create({instanceId:e.instanceId,sessionId:e.sessionId,mode:e.mode,ttlMs:e.ttlMs})}async createSessionToken(e){await this.requireInstance(e.instanceId);const t=await this.requireSession(e.instanceId,e.sessionId),n=Dt(t);if("vnc"!==n){const e=new Error("This app session does not expose a VNC view.");throw Object.assign(e,{statusCode:409,code:"APP_SESSION_ACCESS_UNAVAILABLE"}),e}if("running"!==t.status){const e=new Error("The app session is not running.");throw Object.assign(e,{statusCode:409,code:"APP_SESSION_NOT_RUNNING"}),e}return this.createToken({...e,mode:n})}resolveToken(e,t){return this.tokens.resolve(e,e=>!t||e.mode===t)}revokeToken(e,t){this.tokens.revoke(e,e=>e.instanceId===t.instanceId&&e.sessionId===t.sessionId)}async proxyTarget(e,t,n=""){const i=this.resolveToken(e,t),s=await this.requireInstance(i.instanceId),r=await this.requireSession(i.instanceId,i.sessionId);return{access:i,instance:s,session:r,path:pl(t,i.sessionId,r,n)}}async requireSession(e,t){const n=await this.listAppSessions(),i=n.instances.find(t=>t.instanceId===e)?.appSessions.sessions.find(e=>gl(e.id)===t);if(i)return i;const s=new Error("App session was not found.");throw Object.assign(s,{statusCode:404,code:"APP_SESSION_NOT_FOUND"}),s}}function pl(e,t,n,i=""){return"tty"===e?`/api/apps/sessions/${encodeURIComponent(t)}/tty`:"vnc"===e?i?function(e,t){const n=`/${t.replace(/^\/+/,"")}`,i=n.split("?",1)[0]||"/",s=encodeURIComponent(e);if(!["/api/novnc/",`/api/apps/sessions/${s}/web/`,`/api/apps/sessions/${s}/vnc`,`/api/apps/sessions/${s}/novnc/`].some(e=>i===e.replace(/\/$/,"")||i.startsWith(e))){const e=new Error("App access token cannot be used for this path.");throw Object.assign(e,{statusCode:403,code:"APP_ACCESS_PATH_FORBIDDEN"}),e}return n}(t,i):gl(ul(n.vnc).noVncPath)||`/api/apps/sessions/${encodeURIComponent(t)}/web/`:gl(ul(n.web).webPath)||`/api/apps/sessions/${encodeURIComponent(t)}/web/`}function ul(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function gl(e){return"string"==typeof e&&e.trim()?e.trim():void 0}const hl={allow:"a",deny:"d",skip:"s"};function ml(e){return i.createHash("sha256").update(e).digest("base64url").slice(0,Math.ceil(16))}class yl{tokens=new cl({invalidMessage:"Chat action expired.",invalidCode:"CHAT_ACTION_TOKEN_INVALID",tokenBytes:9,ttlMs:6e5});create(e){return this.tokens.create({type:e.type,instanceId:"instanceId"in e?e.instanceId:void 0,appId:"appId"in e?e.appId:void 0,routeId:"routeId"in e?e.routeId:void 0,decision:"decision"in e?e.decision:void 0,ttlMs:e.ttlMs})}resolve(e,t){return this.tokens.resolve(e,e=>!t||e.type===t)}pendingDecisionCallbackData(e,t){return`task_handoff:cp_p:v1:${hl[t]}:${ml(e)}`}}function fl(e){const{token:t,...n}=e;return{...n,settings:bl(e.settings),tokenSet:Boolean(e.token)}}function Il(e,t){if(!t)return e;const n={...e};for(const[e,i]of Object.entries(t))void 0!==i&&""!==i&&(n[e]=i);return n}function bl(e){const t={...e};return"string"==typeof t.clientSecret&&t.clientSecret&&(delete t.clientSecret,t.clientSecretSet=!0),"string"==typeof t.appSecret&&t.appSecret&&(delete t.appSecret,t.appSecretSet=!0),t}class vl{chatBridges;chatSessions;constructor(e){this.chatBridges=e.chatBridges,this.chatSessions=e.chatSessions}list(){return this.chatBridges.list().map(fl)}require(e){const t=this.chatBridges.get(e);return t||Gd("CHAT_BRIDGE_NOT_FOUND",`Chat bridge ${e} was not found.`),t}create(e){const t=ac.parse(e),n=Ud(),i=Fr.parse({...t,id:ho(`chat_${t.channel}`),name:t.name||(s=t.channel,r=this.chatBridges.list().filter(e=>e.channel===t.channel).length+1,`${"telegram"===s?"Telegram":"wechat"===s?"WeChat":"dingding"===s?"DingDing":"lark"===s?"Lark":"Web"} ${r}`),enabled:t.enabled??!1,allowedUserIds:t.allowedUserIds||[],pollIntervalMs:t.pollIntervalMs||3e3,settings:Il({},t.settings),createdAt:n,updatedAt:n});var s,r;return this.chatBridges.put(i),fl(i)}update(e,t){const n=oc.parse(t),i=this.require(e),s=Il(i.settings,n.settings),r=Fr.parse({...i,...n,id:e,channel:i.channel,name:n.name||i.name,settings:s,updatedAt:Ud()});return this.chatBridges.put(r),fl(r)}delete(e){const t=this.chatBridges.delete(e);if(t)for(const t of this.chatSessions.list())t.bridgeId===e&&this.chatSessions.delete(t.id);return t}}class wl{chatSessions;constructor(e){this.chatSessions=e.chatSessions}list(){return this.chatSessions.list()}require(e){const t=this.chatSessions.get(e);return t||Gd("CHAT_SESSION_NOT_FOUND",`Chat session ${e} was not found.`),t}upsert(e){const t=Ud(),n=(i=e.channel,s=e.chatSessionId,`${e.bridgeId||i}:${s.replace(/[^a-zA-Z0-9_.:-]/g,"_")}`);var i,s;const r=this.chatSessions.get(n),o=Hr.parse({...r||{},...e,id:n,channel:e.channel,bridgeId:e.bridgeId,chatSessionId:e.chatSessionId,lastUsedAt:t,createdAt:r?.createdAt||t,updatedAt:t});return this.chatSessions.put(o),o}}function Sl(e){return{inline_keyboard:e.map(e=>e.map(e=>({text:e.text,...e.url?{url:e.url}:{callback_data:e.callbackData||""}})))}}function Al(e,t=40){return Sl(e.slice(0,t).map(e=>[e]))}function zl(e){return Buffer.from(e,"utf8").toString("base64url")}function kl(e){const t=El(e).inline_keyboard,n=Array.isArray(t)?t:[],i=[];for(const e of n)if(Array.isArray(e))for(const t of e){const e=El(t),n=String(e.callback_data||""),s=String(e.text||"").trim();s&&n&&i.push({text:s,id:`th_cb_${zl(n)}`})}return i.slice(0,40)}function Tl(e,t){const n=String(e||"").replace(/\s+/g," ").trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-3))}...`}function El(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function Cl(e){return(e.aiSessions?.sessions||[]).filter(t=>function(e,t){const n=(e.apps?.sessions||[]).filter(Pl);if(t.appSessionId&&n.some(e=>e.id===t.appSessionId))return!0;const i=new Set(t.appBindingKeys||[]);return Boolean(i.size&&n.some(e=>function(e){return[...Rt(e).bindings.map(Mt),...qt(e)].filter(Boolean)}(e).some(e=>i.has(e))))}(e,t))}function xl(e){return"waiting"===e.status?4:"failed"===e.status?3:"running"===e.status?2:"idle"===e.status?1:0}function Nl(e){return[e.cwd||"",e.agent||"",e.providerSessionId||e.id].join("\0")}function Ol(e){const t=e.session.title||e.session.userPrompt||e.session.summary||e.session.lastMessage||"",n=t?` - ${Tl(t,18)}`:"";return`${e.instance.name} - ${e.session.agent} ${e.session.status}${n}`}function _l(e,t=(e,t)=>`task_handoff:approval:${e.id}:${t}`){return Al(e.flatMap(e=>"approval"!==e.kind?[]:[{text:Tl(`Allow ${e.instance?.name||e.instanceId} / ${e.aiSessionId}`,56),callbackData:t(e,"allow")},{text:Tl(`Skip ${e.instance?.name||e.instanceId} / ${e.aiSessionId}`,56),callbackData:t(e,"skip")},{text:Tl(`Deny ${e.instance?.name||e.instanceId} / ${e.aiSessionId}`,56),callbackData:t(e,"deny")}]))}function Rl(e){const t=`${e.project?.name||e.projectId} / ${e.instance?.name||e.instanceId}`,n="approval"===e.kind?`/approve ${e.id} | /deny ${e.id} | /skip ${e.id}`:`/reply ${e.id} <message>`;return`[${t}] ${e.kind} ${e.id}: ${e.result}\n${n}`}function Pl(e){const t=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return jt("string"==typeof t.status?t.status:void 0)}class jl{deps;targets;constructor(e,t){this.deps=e,this.targets=t}async handleAiSessionsCommand(e){const t=await this.targets.aiSessionChoices(e),n=t.find(e=>e.active),i=t.map(e=>function(e){const t=e.session.userPrompt||e.session.summary||e.session.lastMessage||"",n=e.active?"* ":"",i=e.session.phase&&"unknown"!==e.session.phase?`/${e.session.phase}`:"";return`${n}${e.index+1}. ${e.projectName} / ${e.instance.name} - ${e.session.agent} - ${e.session.status}${i} - ${e.session.id}${t?` - ${t}`:""}`}(e));return{accepted:!0,routed:!1,binding:e,instances:t.map(e=>e.instance),reply:t.length?["Select AI session",`Current ${n?`${n.projectName} / ${n.instance.name} / ${n.session.id}`:await this.targets.renderChatTarget(e)}, total ${t.length}`,"",...i].join("\n"):"No AI sessions found.",replyMarkup:t.length?Al(t.map(e=>({text:`${e.active?"✓ ":""}${Ol(e)}`,callbackData:`task_handoff:cp_session:${e.index}`}))):void 0}}async handleAiSessionCommand(e,t){const n=String(t[0]||"").trim();if(!n)return this.handleAiSessionsCommand(e);const i=await this.targets.findAiSession(n);if(!i)return{accepted:!1,routed:!1,binding:e,reply:`AI session ${n} was not found. Try /sessions.`};const s=i.instance.projectId?this.deps.getProject(i.instance.projectId):void 0;return{accepted:!0,routed:!1,binding:this.deps.upsertChatSession({...e,activeProjectId:s?.id||e.activeProjectId,activeInstanceId:i.instance.id,activeAiSessionId:i.session.id}),instance:i.instance,aiSession:i.session,reply:`Active AI session: ${i.instance.name} / ${i.session.agent} ${i.session.id}`}}async handleAiSessionIndexAction(e,t){const n=(await this.targets.aiSessionChoices(e)).find(e=>e.index===t);if(!n)return{accepted:!1,routed:!1,binding:e,reply:"AI session was not found. Use /session to refresh the list.",replyMarkup:void 0};const i=this.deps.upsertChatSession({...e,activeProjectId:n.projectId||e.activeProjectId,activeInstanceId:n.instance.id,activeAiSessionId:n.session.id}),s=await this.handleAiSessionsCommand(i);return{...s,accepted:!0,binding:i,instance:n.instance,aiSession:n.session,message:`selected ${n.session.id}`,reply:[`Current chat is bound to AI session ${n.session.id}`,"",s.reply].join("\n")}}async handleAiSessionInterruptCommand(e){if(!e.activeInstanceId||!e.activeAiSessionId)return{accepted:!1,routed:!1,binding:e,reply:"No active AI session is selected. Use /sessions and /session <id> first."};const t=await this.deps.requireControlledInstance(e.activeInstanceId,!0),n=await this.deps.interruptAiSession(t.id,e.activeAiSessionId);return{accepted:!0,routed:!0,binding:e,instance:$d(t),aiSession:n,reply:`Interrupt sent to ${t.name} / ${e.activeAiSessionId}.`}}}function Dl(e){return e.providerTurnId||e.turnId||""}function Ml(e){return jt(Bl(e.status))}function Ll(e,t){const n=Bl(t.appId)||"App",i=Bl(t.title).trim();if(i&&i!==n)return i;const s=function(e,t){for(const n of e.appInventory?.items||[])if(n.id===t)return n.name;return""}(e,n);return s||n}function ql(e){const t=function(e){return"online"!==e.connectionStatus?[]:(e.appInventory?.items||[]).filter(e=>"available"===e.availability)}(e),n=new Map;for(const e of t){const t=Ul(e);t&&!n.has(t.id)&&n.set(t.id,t)}return[...n.values()]}function $l(e,t,n,i){const s=Bl(t.id)&&function(e,t){const n=Dt(e);if(!n)return;return`/apps/access/${n}?token=${encodeURIComponent(t(n))}`}(t,i)||`/instances/${encodeURIComponent(e.id)}/`,r=function(e,t){const n=Bl(t);if(n&&new RegExp("^https?://","i").test(n))return new URL(e,n.endsWith("/")?n:n+"/").toString()}(s,n);return{text:r||s,url:r}}function Bl(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function Ul(e){if("string"==typeof e&&e.trim())return{id:e,label:Fl(e)};const t=function(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}(e),n=Bl(t.id).trim();return n?{id:n,label:Bl(t.name).trim()||Fl(n)}:void 0}function Fl(e){return{"terminal-tty":"Terminal","gui-terminal":"GUI Terminal",chromium:"Chromium",browser:"Browser","vscode-web":"VS Code"}[e]||e.replace(/[-_]+/g," ").replace(/\b\w/g,e=>e.toUpperCase())}class Hl{deps;targets;constructor(e,t){this.deps=e,this.targets=t}async handleInstancesCommand(e){const t=await this.targets.instancesForBinding(e);return{accepted:!0,routed:!1,binding:e,instances:t,reply:(n=t.length,0===n?"No controlled instances are registered yet.":`Instances: ${n}. Tap an instance to create an app.`),replyMarkup:t.length?Al(t.map(e=>{return{text:Tl(e.name||e.id,56),callbackData:(t=this.deps.createChatActionToken({type:"instance-app-menu",instanceId:e.id}).token,`task_handoff:cp_i:${t}`)};var t})):void 0};var n}async handleInstanceAppMenuAction(e,t){const n=(await this.targets.instancesForBinding(e)).find(e=>e.id===t);if(!n)return{accepted:!1,routed:!1,binding:e,reply:"Instance not found."};const i=ql(n);return{accepted:!0,routed:!1,binding:e,instance:n,message:`Select an app for ${n.name}.`,reply:i.length?`New app for ${n.name}`:`No launchable apps for ${n.name}.`,replyMarkup:i.length?Al(i.map(e=>{return{text:Tl(e.label,56),callbackData:(t=this.deps.createChatActionToken({type:"launch-app",instanceId:n.id,appId:e.id}).token,`task_handoff:cp_a:${t}`)};var t})):void 0}}async handleLaunchAppAction(e,t,n){const i=(await this.targets.instancesForBinding(e)).find(e=>e.id===t);if(!i)return{accepted:!1,routed:!1,binding:e,reply:"Instance not found."};const s=ql(i).find(e=>e.id===n);return s?{accepted:!0,routed:!1,binding:e,instance:i,session:await this.deps.launchAppSession(i.id,s.id),message:`${s.label} launched`,reply:`Launched ${s.label} on ${i.name}.`}:{accepted:!1,routed:!1,binding:e,reply:`App ${n} is not launchable for ${i.name}.`}}async handleAppsCommand(e){const t=await this.deps.boardAsync(),n=new Map(t.map(e=>[e.id,e])),i=(await this.deps.listAppSessions()).instances.flatMap(e=>{const t=n.get(e.instanceId);return t?e.appSessions.sessions.filter(Ml).filter(e=>Boolean(Bl(e.id))).map(e=>({instance:t,session:e,link:$l(t,e,this.deps.controlPlanePublicBaseUrl(),n=>this.deps.createAppAccessToken({instanceId:t.id,sessionId:Bl(e.id)||"",mode:n}).token)})):[]}),s=i.filter(e=>e.link.url).map(e=>({text:Tl(`${e.instance.name} · ${Ll(e.instance,e.session)}`,56),url:e.link.url}));return{accepted:!0,routed:!1,binding:e,instances:t,reply:(r=i.length,o=s.length,0===r?"No app sessions found.":0===o?`App sessions: ${r}. Set the control plane public URL in Settings > Appearance to open them from chat.`:`App sessions: ${r}. Tap a button to open.`),replyMarkup:s.length?Al(s):void 0};var r,o}}class Wl{deps;targets;constructor(e,t){this.deps=e,this.targets=t}async forwardChatMessage(e,t){const n=t.target?.instanceId||e.activeInstanceId||"",i=t.target?.aiSessionId||e.activeAiSessionId,s=await this.deps.requireControlledInstance(n,!0),r=s.projectId?this.deps.requireProject(s.projectId):void 0;if("online"!==s.connectionStatus){const e=new Error(`Instance ${s.name} is not reachable.`);throw Object.assign(e,{statusCode:409,code:"CHAT_TARGET_UNREACHABLE"}),e}if(i){const n=await this.trySendAiSessionMessage(e,s.id,i,t.message.text,t.message.attachments,!t.target);return n.ok?this.sentResult(e,r,s,i,n.aiSession):this.failedSendResult(n.binding,r,s,n.reply)}const o=await this.targets.defaultAiSessionIdForInstance(s.id);if(o){const n=this.deps.upsertChatSession({...e,activeAiSessionId:o}),i=await this.trySendAiSessionMessage(n,s.id,o,t.message.text,t.message.attachments);return i.ok?this.sentResult(n,r,s,o,i.aiSession):this.failedSendResult(i.binding,r,s,i.reply)}return{accepted:!1,routed:!1,binding:e,project:r||void 0,instance:$d(s),reply:`No active AI session is selected for ${s.name}. Use /sessions and /session <id> first.`}}async trySendAiSessionMessage(e,t,n,i,s=[],r=!0){try{return{ok:!0,binding:e,aiSession:await this.deps.sendAiSessionMessage(t,n,i||"请查看附件。",void 0,s)}}catch(t){return function(e){return"AI_SESSION_NOT_FOUND"===(e&&"object"==typeof e?e:{}).code}(t)?{ok:!1,binding:r?this.deps.upsertChatSession({...e,activeAiSessionId:void 0}):e,reply:`The selected AI session ${n} no longer exists. Use /session to choose an active AI session.`}:{ok:!1,binding:e,reply:`Failed to send to AI session ${n}: ${Wd(t)}`}}}failedSendResult(e,t,n,i){return{accepted:!1,routed:!1,binding:e,project:t||void 0,instance:$d(n),reply:i}}sentResult(e,t,n,i,s){return{accepted:!0,routed:!0,binding:e,project:t||void 0,instance:$d(n),aiSession:s,instanceId:n.id,aiSessionId:i,turnId:(r=s,r.turnId||r.providerTurnId||r.session.activeTurnId||""),providerTurnId:Dl(s),reply:`Sent to ${t?.name||n.sourceSnapshot.name||"Source"} / ${n.name} / ${i}.`};var r}}class Gl{deps;constructor(e){this.deps=e}async handlePendingCommand(e){const t=await this.deps.listPendingRoutes(),n=e.activeInstanceId?t.filter(t=>t.instanceId===e.activeInstanceId):t;return{accepted:!0,routed:!1,binding:e,pending:n,reply:n.length?n.map(Rl).join("\n"):"No pending routes.",replyMarkup:n.length?_l(n,(e,t)=>this.deps.pendingDecisionCallbackData(e.id,t)):void 0}}async handlePendingDecisionCommand(e,t,n){const i=Hd(t[0]);return i?i.aiSessionId?{accepted:!0,routed:!0,binding:e,pending:i,aiSession:await this.deps.resolveAiSessionApproval(i.instanceId,i.aiSessionId,n),reply:`${n} sent for ${i.instanceId}:${i.aiSessionId}.`}:{accepted:!1,routed:!1,binding:e,pending:i,reply:"Only AI session pending routes are supported here."}:{accepted:!1,routed:!1,binding:e,reply:`Usage: /${"allow"===n?"approve":n} <instance-id:pending-id>`}}async handlePendingReplyCommand(e,t){const n=Hd(t[0]),i=t.slice(1).join(" ").trim();return n&&i?n.aiSessionId?{accepted:!0,routed:!0,binding:e,pending:n,aiSession:await this.deps.sendAiSessionMessage(n.instanceId,n.aiSessionId,i),reply:`Reply sent for ${n.instanceId}:${n.aiSessionId}.`}:{accepted:!1,routed:!1,binding:e,pending:n,reply:"Only AI session pending routes are supported here."}:{accepted:!1,routed:!1,binding:e,reply:"Usage: /reply <instance-id:pending-id> <message>"}}}class Vl{deps;targets;constructor(e,t){this.deps=e,this.targets=t}async handleUseCommand(e,t){if(0===t.length)return{accepted:!0,routed:!1,binding:e,instances:await this.targets.instancesForBinding(e),reply:await this.targets.renderUseHelp(e)};if(t.length>=2){const n=this.targets.resolveProject(t[0]),i=await this.targets.resolveInstance(t[1],n.id),s=this.deps.upsertChatSession({...e,activeProjectId:n.id,activeInstanceId:i.id,activeAiSessionId:await this.targets.defaultAiSessionIdForInstance(i.id)});return{accepted:!0,routed:!1,binding:s,reply:await this.targets.renderTargetSelected(s)}}const n=t[0],i=await this.targets.findInstance(n);if(i){const t=i.projectId?this.deps.requireProject(i.projectId):void 0,n=this.deps.upsertChatSession({...e,activeProjectId:t?.id,activeInstanceId:i.id,activeAiSessionId:await this.targets.defaultAiSessionIdForInstance(i.id)});return{accepted:!0,routed:!1,binding:n,reply:await this.targets.renderTargetSelected(n)}}const s=this.targets.resolveProject(n),r=(await this.deps.boardAsync()).filter(e=>e.projectId===s.id),o=r.filter(e=>"running"===e.status&&"online"===e.connectionStatus);if(1===o.length){const t=this.deps.upsertChatSession({...e,activeProjectId:s.id,activeInstanceId:o[0].id,activeAiSessionId:await this.targets.defaultAiSessionIdForInstance(o[0].id)});return{accepted:!0,routed:!1,binding:t,reply:await this.targets.renderTargetSelected(t)}}return{accepted:!0,routed:!1,binding:this.deps.upsertChatSession({...e,activeProjectId:s.id,activeInstanceId:void 0,activeAiSessionId:void 0}),instances:r,reply:`${s.name} selected. Choose an instance with /use ${s.id} <instance-id-or-name>.\n${this.targets.renderInstanceLines(r)}`}}async handleProjectCommand(e,t){if(0===t.length)return{accepted:!1,routed:!1,binding:e,reply:"Usage: /project <project-id-or-name>"};const n=this.targets.resolveProject(t[0]),i=e.activeInstanceId?await this.deps.requireControlledInstance(e.activeInstanceId).catch(()=>{}):void 0,s=this.deps.upsertChatSession({...e,activeProjectId:n.id,activeInstanceId:i?.projectId===n.id?i.id:void 0,activeAiSessionId:i?.projectId===n.id?e.activeAiSessionId:void 0});return{accepted:!0,routed:!1,binding:s,reply:`Active project: ${n.name}${s.activeInstanceId?"":". Choose an instance with /use."}`}}}class Kl{deps;constructor(e){this.deps=e}async instancesForBinding(e){const t=await this.deps.boardAsync();return e.activeProjectId?t.filter(t=>t.projectId===e.activeProjectId):t}async fullInstancesForBinding(e){const t=await this.deps.listNodeInstances();return e.activeProjectId?t.filter(t=>t.projectId===e.activeProjectId):t}async renderUseHelp(e){return`Active target: ${await this.renderChatTarget(e)}\nUse /instances to list targets, then /use <instance-id-or-name>. Use /sessions to choose an AI session when there is more than one.`}async renderChatStatus(e){const t=e.activeInstanceId?(await this.deps.boardAsync()).find(t=>t.id===e.activeInstanceId):void 0;return t?`Active target: ${await this.renderChatTarget(e)}\nStatus: ${t.status}, connection: ${t.connectionStatus}`:`Active target: ${await this.renderChatTarget(e)}`}async renderChatHelp(e){return["TaskHandoff chat commands:","/help - show this help","/status or /target - show the active project, instance, and AI session","/instances - list controlled instances","/apps - list app sessions","/use <instance-id-or-name> - choose an active instance","/use <project-id-or-name> <instance-id-or-name> - choose a project and instance","/project <project-id-or-name> - narrow instance selection to a project","/sessions - list all AI sessions","/session <ai-session-id> - choose an active AI session","/pending - list waiting approvals","/approve <instance-id:pending-id>, /deny <...>, /skip <...> - answer approvals","/reply <instance-id:pending-id> <message> - reply to a waiting session","/cancel - interrupt the active AI session","","Send normal text after selecting a target; if there is only one AI session, it is selected automatically.",`Current target: ${await this.renderChatTarget(e)}`].join("\n")}renderInstanceLines(e){return e.map(e=>`${e.name} (${e.id}) - ${e.status}/${e.connectionStatus}`).join("\n")}async renderChatTarget(e){const t=e.activeProjectId?this.deps.getProject(e.activeProjectId):void 0,n=e.activeInstanceId?await this.deps.requireControlledInstance(e.activeInstanceId).catch(()=>{}):void 0,i=e.activeAiSessionId||"none";return`${t?.name||e.activeProjectId||"none"} / ${n?.name||e.activeInstanceId||"none"} / ${i}`}async renderTargetSelected(e){const t=await this.renderChatTarget(e);return e.activeAiSessionId?`Active target: ${t}`:`Active target: ${t}\nNo AI session selected yet. Use /sessions and /session <id>, or send a message once exactly one session is available.`}async defaultAiSessionIdForInstance(e){const t=await this.aiSessionSnapshotForInstance(e),n=(await this.deps.boardAsync()).find(t=>t.id===e),i=(await this.deps.listAppSessions()).instances.find(t=>t.instanceId===e),s=n?{...n,apps:{...n.apps,sessions:i?.appSessions.sessions||[]}}:void 0,r=t&&n?Cl({...s,aiSessions:t}):t?.sessions||[];return 1===r.length?r[0].id:void 0}async aiSessionChoices(e){return(await this.boardInstancesForBinding({},{refresh:!0})).flatMap(t=>Cl(t).map(n=>({index:0,projectId:t.projectId,projectName:t.project?.name||("string"==typeof t.sourceSnapshot.name?t.sourceSnapshot.name:"Source"),instance:t,session:n,active:e.activeInstanceId===t.id&&e.activeAiSessionId===n.id}))).sort((e,t)=>{const n=xl(t.session)-xl(e.session);return n||(String(e.instance.name||"").localeCompare(String(t.instance.name||""))||e.instance.id.localeCompare(t.instance.id)||Nl(e.session).localeCompare(Nl(t.session)))}).map((e,t)=>({...e,index:t}))}async boardInstancesForBinding(e,t={}){const n=await this.deps.boardAsync(),i=await this.deps.listAiSessions(t),s=await this.deps.listAppSessions(t),r=new Map(i.instances.map(e=>[e.instanceId,e.aiSessions])),o=new Map(s.instances.map(e=>[e.instanceId,e.appSessions])),a=n.map(e=>{return{...e,apps:{...e.apps,sessions:o.get(e.id)?.sessions||[]},aiSessions:r.get(e.id)||(t=e.aiSessions.updatedAt,{runningCount:0,waitingCount:0,staleCount:0,sessions:[],updatedAt:t})};var t});return e.activeProjectId?a.filter(t=>t.projectId===e.activeProjectId):a}async findAiSession(e){const t=await this.boardInstancesForBinding({},{refresh:!0});for(const n of t){const t=(n.aiSessions?.sessions||[]).find(t=>t.id===e||t.providerSessionId===e);if(t)return{instance:n,session:t}}}async aiSessionSnapshotForInstance(e){const t=await this.deps.listAiSessions();return t.instances.find(t=>t.instanceId===e)?.aiSessions}resolveProject(e){const t=this.deps.getProject(e)||this.deps.listProjects().find(t=>t.name===e);return t||Gd("PROJECT_NOT_FOUND",`Project ${e} was not found.`),t}async resolveInstance(e,t){const n=await this.findInstance(e,t);return n||Gd("CONTROLLED_INSTANCE_NOT_FOUND",`Controlled instance ${e} was not found.`),n}async findInstance(e,t){return(await this.deps.listNodeInstances()).find(n=>!(n.id!==e&&n.name!==e||t&&n.projectId!==t))}}class Jl{deps;targets;sender;appCommands;pendingCommands;aiSessionCommands;targetCommands;constructor(e){this.deps=e,this.targets=new Kl(e),this.sender=new Wl(e,this.targets),this.appCommands=new Hl(e,this.targets),this.pendingCommands=new Gl(e),this.aiSessionCommands=new jl(e,this.targets),this.targetCommands=new Vl(e,this.targets)}async handleChatGatewayMessage(e){const t=Wr.parse(e),n=this.deps.upsertChatSession({channel:t.source.channel,bridgeId:t.source.bridgeId,chatSessionId:t.source.chatSessionId,userId:t.source.userId}),i=t.message.text.trim();return i.startsWith("/")?this.handleChatCommand(n,i):i||t.message.attachments.length?n.activeInstanceId?this.sender.forwardChatMessage(n,t):{accepted:!1,routed:!1,binding:n,reply:await this.targets.renderUseHelp(n)}:{accepted:!1,routed:!1,binding:n,reply:""}}async handleChatGatewayAction(e){const t=this.deps.upsertChatSession({channel:e.source.channel,bridgeId:e.source.bridgeId,chatSessionId:e.source.chatSessionId,userId:e.source.userId});return"ai-session"===e.action.type?this.aiSessionCommands.handleAiSessionIndexAction(t,e.action.index):"instance-app-menu"===e.action.type?this.appCommands.handleInstanceAppMenuAction(t,e.action.instanceId):"launch-app"===e.action.type?this.appCommands.handleLaunchAppAction(t,e.action.instanceId,e.action.appId):"pending-decision"===e.action.type?this.pendingCommands.handlePendingDecisionCommand(t,[e.action.routeId],e.action.decision):{accepted:!1,routed:!1,binding:t,reply:"Unknown action."}}async handleChatCommand(e,t){const[n="",...i]=t.split(/\s+/),s=n.replace(/@[\w_]+$/,"");switch(s.toLowerCase()){case"/help":case"/start":return{accepted:!0,routed:!1,binding:e,reply:await this.targets.renderChatHelp(e)};case"/sessions":return this.aiSessionCommands.handleAiSessionsCommand(e);case"/session":return this.aiSessionCommands.handleAiSessionCommand(e,i);case"/cancel":case"/interrupt":return this.aiSessionCommands.handleAiSessionInterruptCommand(e);case"/pending":return this.pendingCommands.handlePendingCommand(e);case"/approve":return this.pendingCommands.handlePendingDecisionCommand(e,i,"allow");case"/deny":return this.pendingCommands.handlePendingDecisionCommand(e,i,"deny");case"/skip":return this.pendingCommands.handlePendingDecisionCommand(e,i,"skip");case"/reply":return this.pendingCommands.handlePendingReplyCommand(e,i);case"/instances":return this.appCommands.handleInstancesCommand(e);case"/apps":return this.appCommands.handleAppsCommand(e);case"/use":return this.targetCommands.handleUseCommand(e,i);case"/project":return this.targetCommands.handleProjectCommand(e,i);case"/status":case"/target":return{accepted:!0,routed:!1,binding:e,instance:e.activeInstanceId?(await this.deps.boardAsync()).find(t=>t.id===e.activeInstanceId):void 0,reply:await this.targets.renderChatStatus(e)};default:return{accepted:!1,routed:!1,binding:e,reply:`Unknown command: ${s||n}. Try /help.`}}}}const Yl=a.z.object({id:a.z.string().trim().min(1),preferences:Jo,createdAt:a.z.string().datetime(),updatedAt:a.z.string().datetime()}).strict();function Ql(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e,n=t.preferences&&"object"==typeof t.preferences&&!Array.isArray(t.preferences)?t.preferences:{};return{id:t.id,preferences:{import:"string"==typeof n.import&&n.import.trim()?n.import:".",export:"string"==typeof n.export&&n.export.trim()?n.export:"."},createdAt:t.createdAt,updatedAt:t.updatedAt}}function Xl(){return Jo.parse({})}function Zl(e){return/^[a-z]:[\\/]/i.test(e)||/^[\\/]{2}[^\\/]+[\\/]+[^\\/]+/.test(e)}function ep(e){return Zl(e)?t.win32:t.posix}class tp{retiredRoot;legacyControlledInstancesDir;legacyNodeRuntimesDir;legacyNodeJoinInvitesDir;paths;options;constructor(e,n={}){this.paths=e,this.options=n,this.retiredRoot=t.join(e.dataDir,"retired-persistence"),this.legacyControlledInstancesDir=t.join(e.dataDir,"controlled-instances"),this.legacyNodeRuntimesDir=t.join(e.dataDir,"node-runtimes"),this.legacyNodeJoinInvitesDir=t.join(e.dataDir,"node-join-invites")}run(){return this.removePersistedInvites(),this.retireLegacyProjection("controlled-instances",this.legacyControlledInstancesDir,!0),this.retireLegacyProjection("node-runtimes",this.legacyNodeRuntimesDir,!1),function(e){if(!n.existsSync(e.trashRoot))return[];const t=e.nowMs??Date.now(),i=e.retentionMs??Kr,s=[];for(const r of n.readdirSync(e.trashRoot,{withFileTypes:!0})){const o=Jr(e.trashRoot,r.name);try{const e=Number(r.name.split("-",1)[0]);if(!Number.isFinite(e)||e+i>t)continue;const a=n.lstatSync(o);a.isSymbolicLink()?n.unlinkSync(o):a.isDirectory()?n.rmSync(o,{recursive:!0,force:!0}):n.unlinkSync(o),s.push(o)}catch(t){e.logger?.("retired persistence entry cleanup failed",{path:o,error:t instanceof Error?t.message:String(t)})}}return s}({trashRoot:this.retiredRoot,retentionMs:this.options.retentionMs??Kr,nowMs:this.now(),logger:this.options.logger})}removePersistedInvites(){n.existsSync(this.legacyNodeJoinInvitesDir)&&n.rmSync(this.legacyNodeJoinInvitesDir,{recursive:!0,force:!0})}retireLegacyProjection(e,i,s){if(!n.existsSync(i))return;const r=n.lstatSync(i);if(!r.isDirectory()||r.isSymbolicLink())return n.rmSync(i,{force:!0}),void this.options.logger?.("invalid legacy persistence path was removed",{store:e});n.readdirSync(i).length?(s&&this.redactLegacyInstanceCredentials(i),function(e){const t=Jr(e.sourceRoot,e.entryName);if(!n.existsSync(t))return;const i=n.lstatSync(t);if(!i.isDirectory()||i.isSymbolicLink())throw new Error(`Retention source must be a real directory: ${t}`);Yr(e.trashRoot);const s=e.nowMs??Date.now();let r=0,o=`${s}-${e.entryName}`;for(;n.existsSync(Jr(e.trashRoot,o));)r+=1,o=`${s}-${r}-${e.entryName}`;const a=Jr(e.trashRoot,o);n.renameSync(t,a)}({sourceRoot:this.paths.dataDir,entryName:t.basename(i),trashRoot:this.retiredRoot,nowMs:this.now()}),this.options.logger?.("legacy control-plane persistence was retired",{store:e})):n.rmdirSync(i)}redactLegacyInstanceCredentials(e){for(const i of n.readdirSync(e,{withFileTypes:!0})){if(!i.isFile()||i.isSymbolicLink())continue;const s=t.join(e,i.name);try{const e=JSON.parse(n.readFileSync(s,"utf8"));delete e.registrationToken,c.sync(s,`${JSON.stringify(e,null,2)}\n`,{encoding:"utf8",mode:384}),n.chmodSync(s,384)}catch(e){n.rmSync(s,{force:!0}),this.options.logger?.("unreadable legacy instance record was removed",{filePath:s,error:e instanceof Error?e.message:String(e)})}}Yr(e)}now(){return this.options.now?.()??Date.now()}}const np="task-handoff.control-plane.local",ip="task-handoff.control-plane.builtin";function sp(e){return"true"===e.labels[np]}function rp(e){return"true"===e.labels[ip]}class op{projects;models;modelService;images;nodes;pendingPairingRevokes;chatSessions;chatBridges;triggers;nodeJoinService;configSyncPreferences;settings;paths;fetchImpl;dockerCommandRunner;logger;diagnosticLogsState;nodeConnectionRuntime;appAccessService;persistenceMaintenance;chatActionTokenService=new yl;nodeAgentTransportResolver;proxyPrivateStore;proxyLifecycle;nodeConnectionManager;nodeAgentGateway;controlledInstanceGateway;aiSessionActionService;controlledInstanceCreator;instanceBoardReader=new Qc;controlPlaneTriggerService;catalogService;marketCatalogService;chatBridgeService;chatSessionService;chatSessionRuntime;aiSessionSnapshotProvider;appSessionSnapshotProvider;constructor(e,n={}){this.paths=e,this.fetchImpl=n.fetchImpl||fetch,this.dockerCommandRunner=n.dockerCommandRunner,this.nodeConnectionRuntime=n.nodeConnectionRuntime,this.persistenceMaintenance=new tp(e,{logger:(e,t)=>this.logWarn(t,e)});const i=e=>({schema:e,logger:(e,t)=>this.logWarn(t,e)});this.proxyPrivateStore=new Td(function(e){const n=t.resolve(e,"control-plane-proxy");return{pendingClaimsDir:t.join(n,"pending-claims"),nodeCredentialsDir:t.join(n,"node-credentials"),identityPath:t.join(n,"identity.json")}}(e.dataDir),(e,t)=>this.logWarn(t,e)),this.nodeAgentTransportResolver=new md({direct:hd(this.fetchImpl),tunnel:n.nodeAgentTransport,proxy:new wd({credentialForNode:e=>this.proxyPrivateStore.nodeCredential(e.id),fetchImpl:this.fetchImpl})});const s=(r=process.env.TASK_HANDOFF_DIAGNOSTIC_LOGS,["1","true","yes","on"].includes(String(r||"").trim().toLowerCase()));var r;this.diagnosticLogsState=s,this.settings=new fo(e.settingsPath,()=>nc.parse({diagnosticLogs:s}),{...i(nc),sanitize:e=>function(e,t={}){if(!e||"object"!=typeof e||Array.isArray(e))return{};const n={...e};return"string"==typeof n.mentionTrigger&&Xd(n.mentionTrigger)||(n.mentionTrigger="@"),"string"==typeof n.commandTrigger&&ec(n.commandTrigger)&&n.commandTrigger!==n.mentionTrigger||(n.commandTrigger="/"),"boolean"!=typeof n.diagnosticLogs&&(n.diagnosticLogs=t.diagnosticLogs??!1),n}(e,{diagnosticLogs:s})}),this.logger=n.logger?{info:(e,t)=>{this.diagnosticLogsEnabled()&&n.logger?.info?.(e,t)},warn:(e,t)=>{this.diagnosticLogsEnabled()&&n.logger?.warn?.(e,t)},error:(e,t)=>{this.diagnosticLogsEnabled()&&n.logger?.error?.(e,t)}}:void 0;const o=new Ga({request:(e,t,n)=>this.nodeAgentFetch(e,t,n),logger:this.logger});this.nodeAgentGateway=new Va(o),this.controlledInstanceGateway=new Jc({requireNode:e=>this.requireNode(e),nodeAgentTransport:e=>this.nodeAgentTransportResolver.resolve(e)}),this.aiSessionActionService=new Ma({requireInstance:e=>this.requireControlledInstance(e,!0),request:(e,t,n)=>this.instanceRequest(e,t,n),requireRuntime:(e,t)=>this.requireNodeRuntimeOnNode(e,t),refreshSnapshots:()=>Promise.all([this.listAppSessions({refresh:!0}),this.listAiSessions({refresh:!0})]),warn:(e,t)=>this.logWarn(e,t)}),this.projects=new yo(e.projectsDir,{...i(Rs),sanitize:Vi}),this.models=new yo(e.modelsDir,i(Ps)),this.modelService=new Gc({models:this.models,gateway:this.nodeAgentGateway,listNodes:()=>this.listNodes(),requireNode:e=>this.requireNode(e),fetchImpl:this.fetchImpl}),this.images=new yo(e.imagesDir,{...i(tr),sanitize:e=>ur(e,e=>this.logWarn(e,"legacy image profile field was migrated"))}),this.nodes=new yo(e.nodesDir,{...i(mr),sanitize:e=>function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e,i=new Set(["id","name","connectionMode","connectionPath","connectionEnabled","auth","endpoint","controlEndpoint","containerEndpoint","publicWebBase","status","health","capabilities","proxyState","appInventory","labels","lastSeenAt","createdAt","updatedAt"]);for(const e of Object.keys(n))i.has(e)||t?.({field:e});const s=n.auth&&"object"==typeof n.auth&&!Array.isArray(n.auth)?Br(n.auth,["mode","keyId","secret","pairedAt","pairing"]):n.auth;s&&"object"==typeof s&&"pairing"in s&&(s.pairing=Br(s.pairing,["status","joinToken","expiresAt"]));const r=n.connectionPath&&"object"==typeof n.connectionPath&&!Array.isArray(n.connectionPath)?"control-plane-proxy"===n.connectionPath.kind?Br(n.connectionPath,["kind","proxyId","proxyBindingId","targetNodeId"]):Br(n.connectionPath,["kind"]):{kind:"direct"},o=n.proxyState&&"object"==typeof n.proxyState&&!Array.isArray(n.proxyState)?Br(n.proxyState,["reachability","bindingStatus","bindingRevision","streamId","revision","observedAt","target","lastError","updatedAt"]):n.proxyState;if(o&&"object"==typeof o){const e=o;e.target=Br(e.target,["id","name","status","health","lastSeenAt","capabilities"]),e.lastError=Br(e.lastError,["code","message","retryable","details"])}return{...Object.fromEntries(Object.entries(n).filter(([e])=>i.has(e))),auth:s,connectionPath:r,proxyState:o}}(e,e=>this.logWarn(e,"unknown stored node field was ignored"))}),this.pendingPairingRevokes=new yo(e.pendingPairingRevokesDir,i(kc)),this.proxyLifecycle=new Jd({nodes:this.nodes,privateStore:this.proxyPrivateStore,fetchImpl:this.fetchImpl,requireNode:e=>this.requireNode(e),deleteNode:e=>this.deleteNode(e)}),this.nodeConnectionManager=new Tc({nodes:this.nodes,pendingPairingRevokes:this.pendingPairingRevokes,fetchImpl:this.fetchImpl,localNodeLabel:np,builtinNodeLabel:ip,info:(e,t)=>this.logInfo(e,t),warn:(e,t)=>this.logWarn(e,t)}),this.chatSessions=new yo(e.chatSessionsDir,i(Hr)),this.chatBridges=new yo(e.chatBridgesDir,i(Fr)),this.triggers=new yo(e.triggersDir,i(dc)),this.nodeJoinService=new Dc({nodes:this.nodes}),this.configSyncPreferences=new yo(t.join(e.dataDir,"config-sync-preferences"),{...i(Yl),sanitize:Ql}),this.marketCatalogService=new dl,this.catalogService=new sl({projects:this.projects,images:this.images,market:this.marketCatalogService,settings:this.settings,defaultNodeId:()=>this.defaultNodeId()}),this.controlledInstanceCreator=new Xc({gateway:this.nodeAgentGateway,defaultNodeId:()=>this.defaultNodeId(),requireProject:e=>this.requireProject(e),requireNode:e=>this.requireNode(e),requireRuntime:(e,t)=>this.requireNodeRuntimeOnNode(e,t),requireLocalFolder:(e,t)=>this.requireNodeLocalFolder(e,t),resolveImageSelection:e=>this.catalogService.resolveImageSelection(e),prepareModels:(e,t)=>this.modelService.prepareAssignment(e,t)}),this.controlPlaneTriggerService=new tl({triggers:this.triggers,listInstances:()=>this.listNodeInstances(),requireInstance:async e=>this.requireControlledInstance(e,!0),instanceRequest:(e,t,n)=>this.instanceRequest(e,t,n)}),this.appAccessService=new ll({requireInstance:async e=>this.requireControlledInstance(e,!0),listAppSessions:()=>this.listAppSessions()}),this.chatBridgeService=new vl({chatBridges:this.chatBridges,chatSessions:this.chatSessions}),this.chatSessionService=new wl({chatSessions:this.chatSessions}),this.chatSessionRuntime=new Jl({upsertChatSession:e=>this.upsertChatSession(e),boardAsync:()=>this.boardAsync(),listAiSessions:e=>this.listAiSessions(e),listAppSessions:e=>this.listAppSessions(e),listNodeInstances:()=>this.listNodeInstances(),listPendingRoutes:()=>this.listPendingRoutes(),pendingDecisionCallbackData:(e,t)=>this.pendingDecisionCallbackData(e,t),createChatActionToken:e=>this.createChatActionToken(e),createAppAccessToken:e=>this.createAppAccessToken(e),controlPlanePublicBaseUrl:()=>this.getSettings().publicBaseUrl||process.env.TASK_HANDOFF_CONTROL_PLANE_URL||process.env.TASK_HANDOFF_PUBLIC_BASE||process.env.TASK_HANDOFF_CONTROL_PLANE_PUBLIC_URL,requireControlledInstance:(e,t)=>this.requireControlledInstance(e,t),requireProject:e=>this.requireProject(e),getProject:e=>this.catalogService.getProject(e),listProjects:()=>this.catalogService.listProjects(),resolveAiSessionApproval:(e,t,n)=>this.resolveAiSessionApproval(e,t,n),sendAiSessionMessage:(e,t,n,i,s)=>this.sendAiSessionMessage(e,t,n,i,s),interruptAiSession:(e,t)=>this.interruptAiSession(e,t),launchAppSession:(e,t,n)=>this.launchAppSession(e,t,n)})}logInfo(e,t){this.logger?.info?.(e,t)}logWarn(e,t){this.logger?.warn?.(e,t)}logError(e,t){this.logger?.error?.(e,t)}setNodeAgentTransport(e){this.nodeAgentTransportResolver.setTunnel(e)}resolveNodeAgentTransport(e){return this.nodeAgentTransportResolver.resolve(e)}setAiSessionSnapshotProvider(e){this.aiSessionSnapshotProvider=e}async listAiSessions(e={}){return this.aiSessionSnapshotProvider?this.aiSessionSnapshotProvider(e):this.bootstrapAiSessionsFromInstances()}setAppSessionSnapshotProvider(e){this.appSessionSnapshotProvider=e}async listAppSessions(e={}){return this.appSessionSnapshotProvider?this.appSessionSnapshotProvider(e):this.bootstrapAppSessionsFromInstances()}init(){this.runPersistenceMaintenance(),this.projects.init(),this.models.init(),this.images.init(),this.nodes.init(),this.pendingPairingRevokes.init(),this.chatSessions.init(),this.chatBridges.init(),this.triggers.init(),this.proxyPrivateStore.init(),this.proxyPrivateStore.gcNodeCredentials(e=>{const t=this.nodes.get(e.nodeId);return"control-plane-proxy"===t?.connectionMode&&"control-plane-proxy"===t.connectionPath.kind&&t.connectionPath.proxyBindingId===e.proxyBindingId&&t.connectionPath.targetNodeId===e.targetNodeId}),this.settings.init();const e=this.settings.put(this.settings.get());this.diagnosticLogsState=e.diagnosticLogs,this.migrateLegacyImageCatalog(),this.seedDefaults()}runPersistenceMaintenance(){try{return this.persistenceMaintenance.run()}catch(e){return this.logWarn({error:e instanceof Error?e.message:String(e)},"control-plane persistence maintenance failed"),[]}}migrateLegacyImageCatalog(){const e=Object.keys(Wi),i=[];for(const t of e){const e=this.images.filePath(t);if(n.existsSync(e))try{i.push({id:t,filePath:e,record:JSON.parse(n.readFileSync(e,"utf8"))})}catch(e){return this.writeMarketMigrationState("failed",{code:"LEGACY_IMAGE_BACKUP_READ_FAILED",legacyId:t,error:Wd(e)}),void this.logWarn({legacyId:t,error:Wd(e)},"legacy embedded image migration was not applied")}}if(!i.length)return;const s=n.readdirSync(this.paths.projectsDir).filter(e=>e.endsWith(".json")).sort().map(e=>t.join(this.paths.projectsDir,e)),r=[];for(const e of s)try{const t=JSON.parse(n.readFileSync(e,"utf8")),i=Rs.parse(Vi(t));r.push({filePath:e,raw:t,migrated:i})}catch(t){return this.writeMarketMigrationState("failed",{code:"PROJECT_REFERENCE_VALIDATION_FAILED",filePath:e,error:Wd(t)}),void this.logWarn({filePath:e,error:Wd(t)},"legacy embedded image migration was not applied")}const o=r.find(({migrated:t})=>{const n=t.defaultImageSelection?.imageId;return!!n&&e.includes(n)});if(o)this.writeMarketMigrationState("failed",{code:"PROJECT_REFERENCE_MIGRATION_INCOMPLETE",filePath:o.filePath});else{n.mkdirSync(this.paths.marketDir,{recursive:!0}),c.sync(this.paths.marketMigrationBackupPath,`${JSON.stringify({version:li,createdAt:Ud(),images:i.map(({id:e,record:t})=>({id:e,record:t})),projects:r.map(({filePath:e,raw:n})=>({file:t.basename(e),record:n}))},null,2)}\n`,{encoding:"utf8"});for(const{migrated:e}of r)this.projects.put(e);for(const{id:e}of i)this.images.delete(e),this.logWarn({legacyId:e,marketId:Wi[e]},"embedded image profile migrated to Market");this.writeMarketMigrationState("complete",{code:"LEGACY_IMAGE_MIGRATION_COMPLETE",migratedImageIds:i.map(({id:e})=>e),backupPath:this.paths.marketMigrationBackupPath})}}writeMarketMigrationState(e,t){n.mkdirSync(this.paths.marketDir,{recursive:!0}),c.sync(this.paths.marketStatePath,`${JSON.stringify({status:e,updatedAt:Ud(),...t},null,2)}\n`,{encoding:"utf8"})}getSettings(){return this.catalogService.getSettings()}diagnosticLogsEnabled(){return this.diagnosticLogsState}updateSettings(e){const t=this.catalogService.updateSettings(e);return this.diagnosticLogsState=t.diagnosticLogs,t}seedDefaults(){return this.catalogService.seedDefaults()}listProjects(){return this.catalogService.listProjects()}defaultNodeId(){return this.nodes.list().find(sp)?.id||this.nodes.list()[0]?.id}async syncLocalNodeConnection(){const e=await this.nodeConnectionManager.syncLocal();return this.nodeConnectionRuntime?.observedReachable(e),this.projectNodeConnection(e)}recoverPendingPairingRevokes(){return this.nodeConnectionManager.recoverPendingPairingRevokes()}listModels(){return this.modelService.list()}listFederatedModels(e){return this.modelService.listFederated(e)}createModel(e){return this.modelService.create(e)}updateModel(e,t){return this.modelService.update(e,t)}deleteModel(e){return this.modelService.delete(e)}reorderModels(e){return this.modelService.reorder(e)}createNodeModel(e,t){return this.modelService.createOnNode(e,t)}updateNodeModel(e,t,n){return this.modelService.updateOnNode(e,t,n)}deleteNodeModel(e,t){return this.modelService.deleteOnNode(e,t)}discoverModels(e){return this.modelService.discover(e)}testModel(e){return this.modelService.test(e)}discoverNodeModels(e,t){return this.modelService.discoverOnNode(e,t)}testNodeModel(e,t){return this.modelService.testOnNode(e,t)}createProject(e){return this.catalogService.createProject(e)}updateProject(e,t){return this.catalogService.updateProject(e,t)}deleteProject(e){return this.catalogService.deleteProject(e)}listImages(){return this.catalogService.listImages()}getMarketCatalog(){return this.catalogService.getMarketCatalog()}async refreshMarketCatalog(){return await this.marketCatalogService.refresh(new al),this.getMarketCatalog()}listImageOptions(){return this.catalogService.listImageOptions()}createImage(e){return this.catalogService.createImage(e)}async listNodeDockerImages(e){const t=this.requireNode(e);return this.nodeAgentGateway.listDockerImages(t)}async listNodeImageAvailability(e){const t=this.requireNode(e),n=t.capabilities.agent&&"object"==typeof t.capabilities.agent?t.capabilities.agent:{},i={os:"string"==typeof n.platform?n.platform:void 0,architecture:"string"==typeof n.arch?"x64"===n.arch?"amd64":n.arch:void 0},s=this.catalogService.listImageOptions(i);try{const e=await this.nodeAgentGateway.listDockerImages(t);return s.map(t=>{const n=e.find(e=>e.reference===t.reference||!!t.digest&&e.repoDigests.some(e=>e.endsWith(`@${t.digest}`))||e.repoDigests.includes(t.reference));return xr.parse({image:t,status:n?"available":"pull-required",localImage:n,localSizeBytes:n?.sizeBytes,downloadSizeBytes:n?void 0:t.downloadSizeBytes,unpackedSizeBytes:n?void 0:t.unpackedSizeBytes})})}catch(e){const t=e instanceof Error?e.message:String(e);return s.map(e=>xr.parse({image:e,status:"unknown",error:t}))}}async listNodeLocalFolders(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.listLocalFolders(n,{signal:t})}async listNodeFolderTree(e,t={}){const n=this.requireNode(e);return this.nodeAgentGateway.listFolderTree(n,t)}async listNodeFolderPlaces(e){const t=this.requireNode(e);if(n=t.capabilities?.agent&&"object"==typeof t.capabilities.agent?t.capabilities.agent.capabilities:void 0,!0!==Ir.safeParse(n).data?.folderPlaces)return(await this.nodeAgentGateway.listFolderTree(t,{depth:0})).map(e=>Or.parse({kind:"root",name:e.name,path:e.path}));var n;try{return await this.nodeAgentGateway.listFolderPlaces(t)}catch(e){if(404!==(e&&"object"==typeof e?e.statusCode:void 0))throw e;return(await this.nodeAgentGateway.listFolderTree(t,{depth:0})).map(e=>Or.parse({kind:"root",name:e.name,path:e.path}))}}async createNodeLocalFolder(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.createLocalFolder(n,t)}async deleteNodeLocalFolder(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.deleteLocalFolder(n,t)}async checkNode(e){const t=this.requireNode(e);try{const e=await this.nodeAgentGateway.health(t),n=e&&"object"==typeof e?e:{},i="string"==typeof n.nodeId&&n.nodeId.trim()?n.nodeId.trim():t.id,s=mr.parse({...t,id:i,status:"online",health:"ok",capabilities:"object"==typeof e&&e?{...t.capabilities,agent:Md(e)}:t.capabilities,lastSeenAt:Ud(),updatedAt:Ud()});return i!==t.id&&this.nodes.delete(t.id),this.nodes.put(s),this.nodeConnectionRuntime?.observedReachable(s),{id:s.id,status:"online",checkedAt:Ud(),agent:e}}catch(e){const n=mr.parse({...t,status:"offline",health:"failed",updatedAt:Ud()});return this.nodes.put(n),this.nodeConnectionRuntime?.observedFailure(n,Wd(e)),{id:t.id,status:"offline",checkedAt:Ud(),error:e instanceof Error?e.message:String(e)}}}async checkNodeUpdate(e,t){return this.nodeAgentGateway.checkUpdate(this.requireNode(e),t)}async applyNodeUpdate(e,t){return this.nodeAgentGateway.applyUpdate(this.requireNode(e),t)}async listNodeUpdateJobs(e){return this.nodeAgentGateway.listUpdateJobs(this.requireNode(e))}async getLocalNodeExternalListener(e){return this.nodeAgentGateway.getExternalListener(this.requireLocalListenerNode(e))}async updateLocalNodeExternalListener(e,t){return this.nodeAgentGateway.updateExternalListener(this.requireLocalListenerNode(e),t)}async createNodePairingInvite(e,t={}){const n=this.requireNode(e);return this.nodeAgentGateway.createPairingInvite(n,t)}requireLocalListenerNode(e){const t=this.requireNode(e);if(!rp(t)||!sp(t)){const e=new Error("Node agent TCP listener settings are available only for the built-in local node.");throw Object.assign(e,{statusCode:403,code:"LOCAL_NODE_LISTENER_ONLY"}),e}return t}createNodeJoinInvite(e={}){return this.nodeJoinService.createInvite(e)}completeNodeJoin(e){return this.nodeJoinService.complete(e)}async connectNodeToControlPlane(e,t){const n=this.requireNode(e),i=Ac.parse(t);return this.nodeAgentGateway.createControlPlaneConnection(n,i)}async listNodeControlPlanePairings(e){const t=this.requireNode(e);return this.nodeAgentGateway.listControlPlanePairings(t)}async deleteNodeControlPlanePairing(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.deleteControlPlanePairing(n,t)}async listNodeControlPlaneConnections(e){const t=this.requireNode(e);return this.nodeAgentGateway.listControlPlaneConnections(t)}async deleteNodeControlPlaneConnection(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.deleteControlPlaneConnection(n,t)}updateImage(e,t){return this.catalogService.updateImage(e,t)}async deleteImage(e){this.catalogService.requireImage(e);const t=this.listProjects().find(t=>t.defaultImageSelection?.imageId===e);if(t)throw Object.assign(new Error(`Image ${e} is the default for project ${t.name}.`),{statusCode:409,code:"IMAGE_IN_USE"});const n=(await Promise.all(this.listNodes().map(e=>this.nodeAgentGateway.listLocalFolders(e)))).flat().find(t=>t.defaultImageSelection?.imageId===e);if(n)throw Object.assign(new Error(`Image ${e} is the default for local folder ${n.name}.`),{statusCode:409,code:"IMAGE_IN_USE"});const i=(await this.listNodeInstances()).find(t=>t.imageSelection?.imageId===e);if(i)throw Object.assign(new Error(`Image ${e} is used by instance ${i.name}.`),{statusCode:409,code:"IMAGE_IN_USE"});return this.catalogService.deleteImage(e)}listNodes(){return this.nodes.list()}listPublicNodes(){return this.listNodes().map(e=>Ld(this.projectNodeConnection(e)))}projectNodeConnection(e){return this.nodeConnectionRuntime?.project(e)||e}createNode(e){return this.nodeConnectionManager.create(e)}listPendingProxyClaims(){return this.proxyLifecycle.listPendingClaims()}claimProxyNode(e){return this.proxyLifecycle.claimNode(e)}resumeProxyClaim(e){return this.proxyLifecycle.resumeClaim(e)}cancelProxyClaim(e,t=!1){return this.proxyLifecycle.cancelClaim(e,t)}applyProxyTargetSnapshot(e,t){return this.proxyLifecycle.applyTargetSnapshot(e,t)}applyProxyTargetEvent(e,t){return this.proxyLifecycle.applyTargetEvent(e,t)}markProxyUnavailable(e,t){return this.proxyLifecycle.markUnavailable(e,t)}markProxyBindingRevoked(e,t){return this.proxyLifecycle.markBindingRevoked(e,t)}updateNode(e,t){const n=Sc.parse(t),i=this.requireNode(e);this.proxyLifecycle.assertIdentityPatch(i,n);const s=mr.parse({...i,...n,id:e,createdAt:i.createdAt,updatedAt:Ud()});return this.nodes.put(s)}deleteNode(e){if(rp(this.requireNode(e))){const e=new Error("The built-in local node connection cannot be deleted.");throw Object.assign(e,{statusCode:400,code:"LOCAL_NODE_CANNOT_BE_DELETED"}),e}return this.nodes.delete(e)}async deleteNodeWithProxyLifecycle(e,t=!1){return this.proxyLifecycle.deleteNode(this.requireNode(e),t)}async listNodeRuntimes(e,t){const n=e?[this.requireNode(e)]:this.listNodes();return e?this.nodeAgentGateway.listRuntimes(n[0],{signal:t}):(await this.nodeAgentGateway.listFleetRuntimes(n,{signal:t})).items}async listNodeRuntimesWithDiagnostics(e){return this.nodeAgentGateway.listFleetRuntimes(this.listNodes().map(e=>this.projectNodeConnection(e)),{signal:e})}async createNodeRuntime(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.createRuntime(n,t)}async updateNodeRuntime(e,t,n){const i=this.requireNode(e);return this.nodeAgentGateway.updateRuntime(i,t,n)}async deleteNodeRuntime(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.deleteRuntime(n,t)}async checkNodeRuntime(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.checkRuntime(n,t)}async listControlledInstances(){return(await this.listNodeInstances()).map($d)}async listControlledInstancesWithDiagnostics(){const e=await this.listNodeInstancesWithDiagnostics();return{items:e.items.map($d),nodeErrors:e.nodeErrors}}async instanceResourceMetrics(e){const t=await this.requireNodeInstance(e);return this.nodeAgentGateway.instanceResourceMetrics(this.requireNode(t.nodeId),t.id)}async nodeOwnsInstance(e,t){const n=this.requireNode(e);return(await this.nodeAgentGateway.listInstances(n)).some(n=>n.id===t&&n.nodeId===e)}createControlledInstance(e){return this.controlledInstanceCreator.create(e)}async updateControlledInstance(e,t){const n=yc.parse(t),i=await this.requireNodeInstance(e),s=this.requireNode(i.nodeId);void 0!==n.config?.aiSessionHistoryLimit&&function(e,t){const n=e.capabilities.agent,i=n&&"object"==typeof n&&!Array.isArray(n)?n.capabilities:void 0;if(!Boolean(i&&"object"==typeof i&&!Array.isArray(i)&&!0===i.aiSessionHistoryLimit)||!Ii(t.capabilities).features.aiSessionPersistenceSettings)throw Object.assign(new Error("This instance does not support managed AI session history retention settings."),{statusCode:409,code:"AI_SESSION_HISTORY_LIMIT_UNSUPPORTED"})}(s,i);const{modelSelection:r,...o}=n;let a=Object.keys(o).length?await this.nodeAgentGateway.updateInstance(s,e,o):i;if(r){const t=await this.modelService.prepareAssignment(s,r);a=(await this.nodeAgentGateway.assignInstanceModels(s,e,t)).instance}return $d(a)}async deleteControlledInstance(e,t){const n=Ui.parse(t),i=await this.requireNodeInstance(e),s=this.requireNode(i.nodeId),r=await this.nodeAgentGateway.deleteInstance(s,e,n);return r.completed&&this.configSyncPreferences.delete(e),r}listEnvironmentTemplates(e){return this.nodeAgentGateway.listEnvironmentTemplates(this.requireNode(e))}getEnvironmentTemplate(e,t){return this.nodeAgentGateway.getEnvironmentTemplate(this.requireNode(e),t)}async createEnvironmentTemplate(e,t){const n=await this.requireNodeInstance(e);return this.nodeAgentGateway.createEnvironmentTemplate(this.requireNode(n.nodeId),e,t)}deleteEnvironmentTemplate(e,t){return this.nodeAgentGateway.deleteEnvironmentTemplate(this.requireNode(e),t)}async startControlledInstance(e){const t=await this.requireNodeInstance(e),n=this.requireNode(t.nodeId);return await this.modelService.ensureInstanceAssignment(t),$d(await this.nodeAgentGateway.startInstance(n,e))}async stopControlledInstance(e){const t=await this.requireNodeInstance(e),n=this.requireNode(t.nodeId);return $d(await this.nodeAgentGateway.stopInstance(n,e))}async restartControlledInstance(e){const t=await this.requireNodeInstance(e),n=this.requireNode(t.nodeId);return await this.modelService.ensureInstanceAssignment(t),$d(await this.nodeAgentGateway.restartInstance(n,e))}async retryControlledInstanceImageProvisioning(e){const t=await this.requireNodeInstance(e);return $d(await this.nodeAgentGateway.retryInstanceImageProvisioning(this.requireNode(t.nodeId),e))}async boardAsync(){return(await this.boardWithDiagnostics()).items}async boardWithDiagnostics(e){const[t,n]=await Promise.all([this.listNodeRuntimesWithDiagnostics(e),this.listNodeInstancesWithDiagnostics(e)]);return this.instanceBoardReader.read({projects:this.listProjects(),images:this.listImageOptions(),nodes:this.nodes.list().map(e=>this.projectNodeConnection(e)),runtimes:t.items,instances:n.items,nodeErrors:[...t.nodeErrors,...n.nodeErrors]})}async bootstrapAiSessionsFromInstances(){const e=await this.listNodeInstances(),t=await Promise.all(e.map(async e=>{if(!Vr(e)||!e.target.web||"online"!==e.connectionStatus&&"online"!==e.agentStatus)return{streamId:`bootstrap:${e.id}:ai.sessions`,revision:0,lastEventAt:e.aiSessions.updatedAt,snapshot:e.aiSessions};try{return Bo(et,await this.instanceRequest(e,"/ai-sessions/state"))}catch(t){return this.logWarn({instanceId:e.id,error:Wd(t),errorCode:"AI_SESSION_LIVE_REFRESH_FAILED"},"control plane failed to refresh live AI sessions"),{streamId:`bootstrap:${e.id}:ai.sessions`,revision:0,lastEventAt:e.aiSessions.updatedAt,snapshot:e.aiSessions}}}));return{updatedAt:(new Date).toISOString(),instances:e.map((e,n)=>({instanceId:e.id,streamId:t[n].streamId,aiSessions:t[n].snapshot,revision:t[n].revision,lastEventAt:t[n].lastEventAt}))}}async bootstrapAppSessionsFromInstances(){const e=await this.listNodeInstances(),t=await Promise.all(e.map(async e=>{if(!Vr(e)||!e.target.web||"online"!==e.connectionStatus&&"online"!==e.agentStatus){const t=Ft();return{streamId:`bootstrap:${e.id}:app.sessions`,revision:0,lastEventAt:t.updatedAt,snapshot:t}}try{return Bo(zt,await this.instanceRequest(e,"/apps/sessions/state"))}catch(t){this.logWarn({instanceId:e.id,error:Wd(t),errorCode:"APP_SESSION_LIVE_REFRESH_FAILED"},"control plane failed to refresh live app sessions");const n=Ft();return{streamId:`bootstrap:${e.id}:app.sessions`,revision:0,lastEventAt:n.updatedAt,snapshot:n}}}));return{updatedAt:(new Date).toISOString(),instances:e.map((e,n)=>({instanceId:e.id,streamId:t[n].streamId,appSessions:t[n].snapshot,revision:t[n].revision,lastEventAt:t[n].lastEventAt}))}}async recoverAiSessionDelta(e,t,n){const i=await this.requireControlledInstance(e,!0),s=new URLSearchParams({streamId:t,sinceRevision:String(n)});return Bo(lt,await this.instanceRequest(i,`/ai-sessions?${s}`))}async recoverAiSessionSnapshot(e){const t=await this.requireControlledInstance(e,!0);return Bo(et,await this.instanceRequest(t,"/ai-sessions/state"))}async recoverAppSessionDelta(e,t,n){const i=await this.requireControlledInstance(e,!0),s=new URLSearchParams({streamId:t,sinceRevision:String(n)});return Bo(Nt,await this.instanceRequest(i,`/apps/sessions?${s}`))}async recoverAppSessionSnapshot(e){const t=await this.requireControlledInstance(e,!0);return Bo(zt,await this.instanceRequest(t,"/apps/sessions/state"))}async listTriggers(){return this.controlPlaneTriggerService.listTriggers()}createTrigger(e){return this.controlPlaneTriggerService.createTrigger(e)}async updateTrigger(e,t){return this.controlPlaneTriggerService.updateTrigger(e,t)}async deleteTrigger(e){return this.controlPlaneTriggerService.deleteTrigger(e)}async applyTrigger(e,t){return this.controlPlaneTriggerService.applyTrigger(e,t)}async listInstanceTriggers(e){return this.controlPlaneTriggerService.listInstanceTriggers(e)}async bindAiSessionTrigger(e,t,n){return this.controlPlaneTriggerService.bindAiSessionTrigger(e,t,n)}async unbindAiSessionTrigger(e,t,n){return this.controlPlaneTriggerService.unbindAiSessionTrigger(e,t,n)}async runInstanceTrigger(e,t,n={}){return this.controlPlaneTriggerService.runInstanceTrigger(e,t,n)}listChatSessions(){return this.chatSessionService.list()}createAppAccessToken(e){return this.appAccessService.createToken(e)}createAppSessionAccessToken(e){return this.appAccessService.createSessionToken(e)}revokeAppSessionAccessToken(e,t){this.appAccessService.revokeToken(e,t)}resolveAppAccessToken(e,t){return this.appAccessService.resolveToken(e,t)}createChatActionToken(e){return this.chatActionTokenService.create(e)}resolveChatActionToken(e,t){return this.chatActionTokenService.resolve(e,t)}pendingDecisionCallbackData(e,t){return this.chatActionTokenService.pendingDecisionCallbackData(e,t)}async appAccessProxyTarget(e,t,n=""){return this.appAccessService.proxyTarget(e,t,n)}listChatBridges(){return this.chatBridgeService.list()}requireChatBridge(e){return this.chatBridgeService.require(e)}createChatBridge(e){return this.chatBridgeService.create(e)}updateChatBridge(e,t){return this.chatBridgeService.update(e,t)}deleteChatBridge(e){return this.chatBridgeService.delete(e)}requireChatSession(e){return this.chatSessionService.require(e)}upsertChatSession(e){return this.chatSessionService.upsert(e)}async handleChatGatewayMessage(e){return this.chatSessionRuntime.handleChatGatewayMessage(e)}async handleChatGatewayAction(e){return this.chatSessionRuntime.handleChatGatewayAction(e)}async handleChatCommand(e,t){return this.chatSessionRuntime.handleChatCommand(e,t)}async listPendingRoutes(){const e=Ud(),t=[],n=await this.listAiSessions(),i=new Map(n.instances.map(e=>[e.instanceId,e.aiSessions])),s=await this.nodeAgentGateway.listFleetInstances(this.listNodes());for(const n of s.items){if("online"!==n.connectionStatus&&"online"!==n.agentStatus||!n.target.web)continue;const s=n.projectId?this.catalogService.getProject(n.projectId):void 0;for(const r of i.get(n.id)?.sessions||[]){if("waiting"!==r.status)continue;const i=Gr.parse({id:`${n.id}:ai:${r.id}`,instanceId:n.id,projectId:n.projectId,aiSessionId:r.id,providerSessionId:r.providerSessionId,result:r.summary||r.currentTool?.inputPreview||r.lastMessage||`${r.agent} is waiting for approval`,source:r.agent,kind:"approval",status:"pending",lastSeenAt:e});t.push({...i,project:s,instance:$d(n)})}}return t}async listAiSessionInstanceNames(){return(await this.nodeAgentGateway.listFleetInstances(this.listNodes())).items.map(e=>({id:e.id,name:e.name}))}resolveAiSessionApproval(e,t,n){return this.aiSessionActionService.resolveApproval(e,t,n)}listAiSessionHistory(e){return this.aiSessionActionService.listHistory(e)}getAiSessionHistoryDetail(e,t){return this.aiSessionActionService.historyDetail(e,t)}getAiSessionTimeline(e,t){return this.aiSessionActionService.timeline(e,t)}getAiSessionTurnTimeline(e,t,n){return this.aiSessionActionService.turnTimeline(e,t,n)}resumeAiSession(e,t){return this.aiSessionActionService.resume(e,t)}async createAiSession(e,t){const n=await this.requireControlledInstance(e,!0),{cwdFolderId:i,...s}=t,r={type:"runtime-path",path:await this.aiSessionRuntimeCwd(n,t.cwdFolderId)};return this.aiSessionActionService.create(e,{...s,cwd:r,...t.cwdFolderId?{cwdFolderId:t.cwdFolderId}:{}})}async inspectAiSessionWorkspace(e,t){const n=await this.requireControlledInstance(e,!0),i={type:"runtime-path",path:await this.aiSessionRuntimeCwd(n,t)};return this.aiSessionActionService.inspectWorkspace(e,i)}forkAiSession(e,t,n){return this.aiSessionActionService.fork(e,t,n)}openAiSessionApp(e,t,n){return this.aiSessionActionService.openApp(e,t,n)}closeAiSession(e,t,n){return this.aiSessionActionService.close(e,t,n)}aiSessionActionDiagnostics(){return this.aiSessionActionService.diagnostics()}async launchAppSession(e,t="terminal-tty",n={}){const i=await this.requireControlledInstance(e,!0);if("online"!==i.connectionStatus&&"online"!==i.agentStatus){const e=new Error(`Instance ${i.name} is still starting. Wait for it to connect before launching apps.`);throw Object.assign(e,{statusCode:409,code:"INSTANCE_NOT_CONNECTED"}),e}const s=await this.resolveAppLaunchOptions(i,n),r=await this.instanceRequest(i,"/apps/sessions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({appId:t,...s})});return await this.listAppSessions({refresh:!0}),r}async stopAppSession(e,t){const n=await this.requireControlledInstance(e,!0),i=await this.instanceRequest(n,`/apps/sessions/${encodeURIComponent(t)}/stop`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({})});return await this.listAppSessions({refresh:!0}),i}async instanceAppManagement(e){const t=await this.requireControlledInstance(e,!0);try{return function(e){try{return Bo(ps,e)}catch(e){if(e instanceof a.z.ZodError){const e=new Error("This controlled instance does not support managed app operations.");throw Object.assign(e,{statusCode:409,code:"INSTANCE_APP_MANAGEMENT_UNSUPPORTED"}),e}throw e}}(await this.instanceRequest(t,"/apps/management"))}catch(e){const t=e&&"object"==typeof e?e:{};if(e instanceof a.z.ZodError||404===t.statusCode){const e=new Error("This controlled instance does not support managed app operations.");throw Object.assign(e,{statusCode:409,code:"INSTANCE_APP_MANAGEMENT_UNSUPPORTED"}),e}throw e}}async requestInstanceAppOperation(e,t,n,i={}){const s=await this.requireControlledInstance(e,!0);return Bo(gs,await this.instanceRequest(s,`/apps/${encodeURIComponent(t)}/${n}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i)}))}async instanceAppManagementJob(e,t){const n=await this.requireControlledInstance(e,!0);return Bo(gs,await this.instanceRequest(n,`/apps/jobs/${encodeURIComponent(t)}`))}async renameAppSession(e,t,n){const i=await this.requireControlledInstance(e,!0),s=await this.instanceRequest(i,`/apps/sessions/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({title:n})});return await this.listAppSessions({refresh:!0}),s}sendAiSessionMessage(e,t,n,i,s=[],r=[],o){return this.aiSessionActionService.sendMessage(e,t,n,i,s,r,o)}aiSessionMentionCatalog(e,t){return this.aiSessionActionService.mentionCatalog(e,t)}searchAiSessionMentionFiles(e,t,n){return this.aiSessionActionService.searchMentionFiles(e,t,n)}executeAiSessionCommand(e,t,n){return this.aiSessionActionService.executeCommand(e,t,n)}aiSessionQueue(e,t){return this.aiSessionActionService.queue(e,t)}steerAiSessionQueuedMessage(e,t,n){return this.aiSessionActionService.steerQueuedMessage(e,t,n)}retryAiSessionQueuedMessage(e,t,n){return this.aiSessionActionService.retryQueuedMessage(e,t,n)}removeAiSessionQueuedMessage(e,t,n){return this.aiSessionActionService.removeQueuedMessage(e,t,n)}editAiSessionQueuedMessage(e,t,n,i){return this.aiSessionActionService.editQueuedMessage(e,t,n,i)}reorderAiSessionQueuedMessages(e,t,n){return this.aiSessionActionService.reorderQueuedMessages(e,t,n)}interruptAiSession(e,t){return this.aiSessionActionService.interrupt(e,t)}async proxyInstanceHttp(e,t,n={}){const i=await this.requireControlledInstance(e,!0);return this.controlledInstanceGateway.proxyHttp(i,t,n)}async proxyInstanceWebSocket(e,t,n,i,s={}){const r=await this.requireControlledInstance(e,!0);this.controlledInstanceGateway.proxyWebSocket(r,t,n,i,s)}async instanceConfigSyncState(e){const t=await this.requireControlledInstance(e,!0),n=a.z.array(Vo).parse(await this.instanceRequest(t,"/config-sync/programs"));return Yo.parse({programs:n,preferences:this.configSyncPreferences.get(e)?.preferences||Xl()})}async listInstanceConfigSyncFolders(e,t={}){const n=await this.requireControlledInstance(e,!0),i=new URLSearchParams;return t.path&&i.set("path",t.path),void 0!==t.depth&&i.set("depth",String(t.depth)),a.z.array(Nr).parse(await this.instanceRequest(n,"/config-sync/folders"+(i.size?`?${i}`:"")))}async syncInstanceConfigs(e,t){const n=Ko.parse(t),i=await this.requireControlledInstance(e,!0);if("export"===n.direction&&"local-folder"!==i.source.type){const e=new Error("Exporting instance config is only available for local folder projects.");throw Object.assign(e,{statusCode:400,code:"CONFIG_SYNC_EXPORT_REQUIRES_LOCAL_PROJECT"}),e}const s=function(e){const t=function(e){const t=[];for(const n of e.split("/"))if(n&&"."!==n)if(".."===n){if(!t.length)return"..";t.pop()}else t.push(n);return t.join("/")||"."}(e.trim().replace(/\\/g,"/")||".");if(t.startsWith("/")||".."===t||t.startsWith("../")){const e=new Error("Config sync folder must stay inside the instance workspace.");throw Object.assign(e,{statusCode:400,code:"CONFIG_SYNC_FOLDER_INVALID"}),e}return t||"."}(n.workspaceFolder),r={...n,workspaceFolder:s},o=Bo(Zo,await this.instanceRequest(i,"/config-sync",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(r)})),a=Ud(),d=this.configSyncPreferences.get(e);return this.configSyncPreferences.put({id:e,preferences:{...d?.preferences||Xl(),[n.direction]:s},createdAt:d?.createdAt||a,updatedAt:a}),o}async instanceRequest(e,t,n={}){return this.controlledInstanceGateway.request(e,t,n)}async reportInstanceHeartbeat(e,t){await this.controlledInstanceGateway.reportHeartbeat(e,t)}async nodeAgentFetch(e,t,n={}){const i="reverse-wss"!==e.connectionMode&&"control-plane-proxy"!==e.connectionMode;try{const s=await this.nodeAgentTransportResolver.resolve(e).request(e,t,n);return i&&this.nodeConnectionRuntime?.observedReachable(e),s}catch(t){throw!i||n.signal?.aborted||function(e){return e instanceof Error&&("AbortError"===e.name||"ABORT_ERR"===e.code)}(t)||this.nodeConnectionRuntime?.observedFailure(e,Wd(t)),t}}async listNodeInstances(){return(await this.listNodeInstancesWithDiagnostics()).items}async listNodeInstancesWithDiagnostics(e){return this.nodeAgentGateway.listFleetInstances(this.listNodes().map(e=>this.projectNodeConnection(e)),{signal:e})}async requireNodeInstance(e){for(const t of this.listNodes())try{const n=(await this.nodeAgentGateway.listInstances(t)).find(t=>t.id===e);if(n)return n}catch{}Gd("CONTROLLED_INSTANCE_NOT_FOUND",`Controlled instance ${e} was not found.`)}async requireNodeRuntimeOnNode(e,t){const n=(await this.listNodeRuntimes(e)).find(e=>e.id===t);return n||Gd("NODE_RUNTIME_NOT_FOUND",`Runtime ${t} was not found on node ${e}.`),n}async requireNodeLocalFolder(e,t){return this.nodeAgentGateway.requireLocalFolder(e,t)}async resolveAppLaunchOptions(e,t){const n="string"==typeof t.cwdFolderId?t.cwdFolderId.trim():"",i={...t};return delete i.cwdFolderId,n?{...i,cwd:await this.runtimeCwdForFolderId(e,n)}:i}async runtimeCwdForFolderId(e,t){const n=this.requireNode(e.nodeId),i=await this.requireNodeLocalFolder(n,t);if(i.nodeId!==e.nodeId){const t=new Error(`Local folder ${i.id} belongs to node ${i.nodeId}, not ${e.nodeId}.`);throw Object.assign(t,{statusCode:400,code:"LOCAL_FOLDER_REQUIRES_INSTANCE_NODE"}),t}const s=await this.requireNodeRuntimeOnNode(e.nodeId,e.runtimeId);return this.appLaunchCwdForFolder(e,i,s)}async aiSessionRuntimeCwd(e,t){return t?this.runtimeCwdForFolderId(e,t):e.runtime.workspacePath||e.workspace.path||qd(e.source).path||"/workspace"}appLaunchCwdForFolder(e,n,i){const s=function(e,n,i){if("local"===i.type)return ep(s=n).resolve(s);var s;if("local-folder"!==e.source.type)return;const r=function(e,t){if(Zl(e)!==Zl(t))return;const n=ep(e),i=n.resolve(e),s=n.resolve(t),r=n.relative(i,s);return r?".."===r||r.startsWith(`..${n.sep}`)||n.isAbsolute(r)?void 0:r.split(n.sep).filter(Boolean):[]}(e.source.path,n);if(!r)return;const o=e.runtime.workspacePath||e.workspace.path||qd(e.source).path||"/workspace";return r.length?t.posix.join(o,...r):o}(e,n.path,i);if(s)return s;if("local-folder"!==e.source.type){const e=new Error("App cwd folder selection is only supported for local-folder instances.");throw Object.assign(e,{statusCode:400,code:"APP_CWD_REQUIRES_LOCAL_FOLDER_SOURCE"}),e}const r=new Error(`Local folder ${n.path} is outside the instance workspace ${e.source.path}.`);throw Object.assign(r,{statusCode:400,code:"APP_CWD_OUTSIDE_WORKSPACE"}),r}requireProject(e){return this.catalogService.requireProject(e)}requireModel(e,t=!1){return this.modelService.require(e,t)}requireImage(e){return this.catalogService.requireImage(e)}requireNode(e){const t=this.nodes.get(e);return t||Gd("NODE_NOT_FOUND",`Node ${e} was not found.`),t}requirePublicNode(e){return Ld(this.projectNodeConnection(this.requireNode(e)))}async requireControlledInstance(e,t=!1){const n=await this.requireNodeInstance(e);return t?n:$d(n)}}function ap(e){return h(String(e),"escape").replace(/\n+$/,"")}function dp(e){const[t,...n]=String(e).split("\n");return[`*${ap(t)}*`,...n.map(ap)].join("\n")}function cp(e,t=4e3){const n=String(e),i=dp(n);if(i.length<=t)return i;const[s,...r]=n.split("\n"),o=r.join("\n"),a="...\n";let d=s;for(;dp(`${d}\n${a}`).length>t&&d.length>0;)d=d.slice(0,Math.floor(.8*d.length));let c=0,l=o.length,p=0,u=dp(`${d}\n${a}`);for(;c<=l;){const e=Math.floor((c+l)/2),n=dp(`${d}\n${a}${o.slice(-e)}`);n.length<=t?(u=n,p=e,c=e+1):l=e-1}const g=o.slice(-p),h=g.indexOf("\n");return h>=0&&h<200&&(u=dp(`${d}\n${a}${g.slice(h+1)}`)),u}function lp(e){return String(e).replace(/\\([_*\[\]()~`>#+\-=|{}.!\\])/g,"$1")}async function pp(e,t,n,i,s={}){if(!t.token)return;const r=n=>e(`https://api.telegram.org/bot${t.token}/sendMessage`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)}),o=function(e,t={}){const n=String(e),i=t.rawMarkdownV2?e=>e:ap;if(i(n).length<=4e3)return[n];const s=[];let r=n;for(;r;){let e=1,t=r.length,n=1;for(;e<=t;){const s=Math.floor((e+t)/2);i(r.slice(0,s)).length<=4e3?(n=s,e=s+1):t=s-1}if(n<r.length){const e=r.slice(0,n),t=Math.max(e.lastIndexOf("\n"),e.lastIndexOf(" "));t>=Math.floor(.6*n)&&(n=t+1)}s.push(r.slice(0,n).trimEnd()),r=r.slice(n).trimStart()}return s.filter(Boolean)}(i,s);let a;for(const[e,t]of o.entries())a=await gp(r,"sendMessage",t,{chat_id:n,...0===e&&s.replyToMessageId?{reply_to_message_id:s.replyToMessageId,allow_sending_without_reply:!0}:{},...e===o.length-1&&s.replyMarkup?{reply_markup:s.replyMarkup}:{}},s);return a}async function up(e,t,n){if(!t.token||!n)throw new Error("Telegram file id is required.");const i=await e(`https://api.telegram.org/bot${t.token}/getFile`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({file_id:n})}),s=await i.json().catch(()=>({}));if(!i.ok||!1===s.ok||!s.result?.file_path)throw new Error(s.description||`Telegram getFile failed with HTTP ${i.status}`);return`https://api.telegram.org/file/bot${t.token}/${s.result.file_path}`}async function gp(e,t,n,i,s){const r=s.parseMode||"MarkdownV2",o=s.rawMarkdownV2?String(n):ap(n),a=await e({...i,text:o,disable_web_page_preview:!0,parse_mode:r}),d=await a.json().catch(()=>({}));if(a.ok&&!1!==d.ok)return d.result;if("editMessageText"===t&&hp(d.description))return;if(s.rawMarkdownV2&&"MarkdownV2"===r){const s=await e({...i,text:lp(n),disable_web_page_preview:!0,parse_mode:"Markdown"}),r=await s.json().catch(()=>({}));if(s.ok&&!1!==r.ok)return r.result;if("editMessageText"===t&&hp(r.description))return}const c=await e({...i,text:s.rawMarkdownV2?lp(n):String(n),disable_web_page_preview:!0}),l=await c.json().catch(()=>({}));if(c.ok&&!1!==l.ok)return l.result;if("editMessageText"!==t||!hp(l.description))throw new Error(l.description||d.description||`Telegram ${t} failed with HTTP ${c.status}`)}function hp(e){return"string"==typeof e&&e.toLowerCase().includes("message is not modified")}function mp(e,t){if("string"==typeof e&&e.trim())return e.trim();fp(`Chat action token is missing ${t}.`)}function yp(e){if("allow"===e||"deny"===e||"skip"===e)return e;fp("Chat action token has an invalid decision.")}function fp(e){const t=new Error(e);throw Object.assign(t,{statusCode:400,code:"CHAT_ACTION_TOKEN_INVALID"}),t}function Ip(e){return Buffer.from(e,"base64url").toString("utf8")}function bp(e){return String(e||"").split(/\r?\n/,1)[0].replace(/^#+\s*/,"").trim().slice(0,20)||"消息通知"}function vp(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,"string"==typeof t?t:JSON.stringify(t)]))}function wp(e){return`dtv1.card//IM_GROUP.${e}`}function Sp(e){return`dtv1.card//IM_ROBOT.${e}`}function Ap(e,t){return Lp(t.biz_conversation_id).trim()||Lp(e.spaceId).replace(/^dtv1\.card\/\/(?:IM_GROUP|IM_SINGLE|IM_ROBOT)\./,"")}function zp(e,t={}){const n=Lp(e).trim().toUpperCase();return"2"===n||"IM_GROUP"===n?"IM_GROUP":"1"===n||"IM_SINGLE"===n?t.robotMessage?"IM_ROBOT":"IM_SINGLE":"IM_ROBOT"===n?"IM_ROBOT":void 0}function kp(e){if(e.startsWith("task_handoff:"))return e;if(!e.startsWith("th_cb_"))return"";try{return Buffer.from(e.slice(6),"base64url").toString("utf8")}catch{return""}}function Tp(e,t,n,i,s){const r=Ap(i,s);return{cardUpdateOptions:{updateCardDataByKey:!0,updatePrivateDataByKey:!1},cardData:{cardParamMap:vp({type:"actions",title:"TaskHandoff",description:e,list:kl(t),biz_out_track_id:i.outTrackId||s.biz_out_track_id||"",biz_conversation_id:r,biz_sender_id:s.biz_sender_id||i.userId||"",biz_session_webhook:s.biz_session_webhook||"",biz_conversation_type:s.biz_conversation_type||"",biz_step:n,error_msg:""})}}}function Ep(e,t,n){const i=[];return Cp(i,n),Cp(i,t),Cp(i,e),i.find(e=>kp(e))||""}function Cp(e,t){for(const n of["actionIdList","actionIds"]){const i=t[n];Array.isArray(i)&&e.push(...i.map(e=>Lp(e)).filter(Boolean))}for(const n of["actionId","action_id","id","actionValue"]){const i=Lp(t[n]);i&&e.push(i)}}async function xp(e,t,n,i){i?.("info",{target:"sessionWebhook",hasSessionWebhook:Boolean(t),textPreview:jp(n)},"dingding webhook send requested");const s=await e(t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({msgtype:"markdown",markdown:{title:bp(n),text:n}})}),r=await s.json().catch(()=>{});if(i?.(s.ok?"info":"warn",{target:"sessionWebhook",status:s.status,response:Pp(r)},"dingding webhook send completed"),!s.ok)throw new Error(`DingDing webhook failed with HTTP ${s.status}`)}async function Np(e){const t=kl(e.replyMarkup);if(!t.length&&!e.forceCard)return e.sessionWebhook&&await xp(e.fetchImpl,e.sessionWebhook,e.text,e.runtime.onLog),e.sessionWebhook?{delivered:!0}:void 0;const n=e.bridge.settings||{},i=Lp(n.robotCode),s=Lp(n.cardTemplateId)||"13fc6717-12e4-43ed-8533-111a310d4995.schema",r=Lp(n.cardCallbackRouteKey)||"task_handoff_message",o=e.senderId||e.runtime.senderIds.get(e.chatId)||Lp(n.senderId),a=(d=e.runtime,c=e.chatId,d.conversationTypes?.get(c)||"IM_GROUP");var d,c;if(!i||!s||!o){if(e.sessionWebhook&&!e.forceCard)return await xp(e.fetchImpl,e.sessionWebhook,e.text,e.runtime.onLog),{delivered:!0};throw new Error("DingDing card target is incomplete.")}const l=`task_handoff_cp_${Date.now()}_${Math.random().toString(16).slice(2)}`,p=vp({type:"actions",title:e.title||bp(e.text),description:e.text,list:t,biz_out_track_id:l,biz_step:e.step||"task_handoff_actions",biz_conversation_id:e.chatId,biz_sender_id:o,biz_session_webhook:e.sessionWebhook||e.runtime.chatWebhooks.get(e.chatId)||"",biz_conversation_type:a,error_msg:""}),u=function(e,t,n,i){return"IM_SINGLE"===e?{openSpaceId:(s=t,`dtv1.card//IM_SINGLE.${s}`),imSingleOpenSpaceModel:{},imSingleOpenDeliverModel:{extension:{}}}:"IM_ROBOT"===e?{openSpaceId:Sp(n),imRobotOpenSpaceModel:{supportForward:!1},imRobotOpenDeliverModel:{extension:{},robotCode:i,spaceType:"IM_ROBOT"}}:{openSpaceId:wp(t),imGroupOpenSpaceModel:{supportForward:!1},imGroupOpenDeliverModel:{extension:{},robotCode:i}};var s}(a,e.chatId,o,i);return e.runtime.onLog?.("info",{target:"card",chatId:e.chatId,senderId:o,conversationType:a,openSpaceId:u.openSpaceId,hasSessionWebhook:Boolean(e.sessionWebhook||e.runtime.chatWebhooks.get(e.chatId)),hasReplyMarkup:Boolean(e.replyMarkup),actionCount:t.length,textPreview:jp(e.text)},"dingding card send requested"),await Op(e.fetchImpl,e.bridge,e.runtime,"POST","/v1.0/card/instances/createAndDeliver",{userId:o,cardTemplateId:s,outTrackId:l,callbackType:"STREAM",callbackRouteKey:r,cardData:{cardParamMap:p},userIdType:Number(n.cardUserIdType||1),...u}),{delivered:!0,outTrackId:l}}async function Op(e,t,n,i,s,r){const o=await async function(e,t,n){if(n.accessToken&&n.accessToken.expiresAt>Date.now()+6e4)return n.accessToken.value;const i=Lp(t.settings.clientSecret);if(!t.token||!i)throw new Error("DingDing client id/secret is not configured.");const s=await e("https://api.dingtalk.com/v1.0/oauth2/accessToken",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({appKey:t.token,appSecret:i})}),r=await s.json().catch(()=>({}));if(!s.ok||!r.accessToken)throw new Error(`DingDing access token failed with HTTP ${s.status}`);const o=Number(r.expireIn||7200);return n.accessToken={value:r.accessToken,expiresAt:Date.now()+1e3*Math.max(60,o-120)},n.accessToken.value}(e,t,n);n.onLog?.("info",{method:i,path:s,body:_p(r)},"dingding api request");const a=await e(`https://api.dingtalk.com${s}`,{method:i,headers:{"content-type":"application/json","x-acs-dingtalk-access-token":o},body:JSON.stringify(r)}),d=await a.json().catch(()=>{});if(n.onLog?.(a.ok?"info":"warn",{method:i,path:s,status:a.status,response:Pp(d)},"dingding api response"),!a.ok)throw new Error(`DingDing API failed with HTTP ${a.status}`);const c=Dp(d),l=c.code??c.errcode,p=c.success;if(void 0!==l&&"0"!==String(l)||!1===p)throw new Error(Lp(c.message||c.errmsg)||`DingDing API returned ${String(l||"failure")}`);const u=function(e){const t=Dp(Dp(e).result).deliverResults;if(!Array.isArray(t))return"";const n=t.find(e=>!1===Dp(e).success);if(!n)return"";const i=Dp(n),s=Lp(i.spaceId),r=Lp(i.errorMsg||i.message||i.errmsg)||"delivery failed";return s?`DingDing card delivery failed for ${s}: ${r}`:`DingDing card delivery failed: ${r}`}(d);if(u)throw new Error(u);return a}function _p(e){const t=Dp(e),n=Dp(t.cardData),i=Dp(n.cardParamMap);return{openSpaceId:Lp(t.openSpaceId),outTrackId:Lp(t.outTrackId),userId:Lp(t.userId),userIdType:t.userIdType,callbackType:Lp(t.callbackType),callbackRouteKey:Lp(t.callbackRouteKey),hasImGroupTarget:Boolean(t.imGroupOpenSpaceModel||t.imGroupOpenDeliverModel),hasImSingleTarget:Boolean(t.imSingleOpenSpaceModel||t.imSingleOpenDeliverModel),hasImRobotTarget:Boolean(t.imRobotOpenSpaceModel||t.imRobotOpenDeliverModel),imGroupOpenDeliverModel:Rp(t.imGroupOpenDeliverModel),imSingleOpenDeliverModel:Rp(t.imSingleOpenDeliverModel),imRobotOpenDeliverModel:Rp(t.imRobotOpenDeliverModel),bizConversationId:Lp(i.biz_conversation_id),bizConversationType:Lp(i.biz_conversation_type),bizSenderId:Lp(i.biz_sender_id),hasBizSessionWebhook:Boolean(Lp(i.biz_session_webhook))}}function Rp(e){const t=Dp(e);if(Object.keys(t).length)return{hasExtension:Boolean(t.extension),hasRobotCode:Boolean(Lp(t.robotCode)),spaceType:Lp(t.spaceType),recipients:Array.isArray(t.recipients)?t.recipients.length:void 0,atUserIds:t.atUserIds&&"object"==typeof t.atUserIds?Object.keys(t.atUserIds).length:void 0}}function Pp(e){const t=Dp(e),n=Dp(t.result);return{code:t.code??t.errcode,message:jp(t.message||t.errmsg,240),success:t.success,requestId:t.requestId,result:Object.keys(n).length?n:void 0}}function jp(e,t=160){const n=String(e||"").replace(/\s+/g," ").trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-3))}...`}function Dp(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function Mp(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:"string"==typeof e&&e.trim()?qp(e):{}}function Lp(e){return"string"==typeof e?e:""}function qp(e){try{return Dp(JSON.parse(String(e||"{}")))}catch{return{}}}function $p(e){return JSON.stringify(kl(e))}const Bp="task_handoff_action_id";function Up(e,t){const n=kl(t);return{schema:"2.0",config:{summary:{content:Wp(e)}},body:{elements:[{tag:"markdown",content:e},...n.map(e=>({tag:"button",text:{tag:"plain_text",content:e.text},type:Gp(e.text),width:"fill",size:"medium",behaviors:[{type:"callback",value:{[Bp]:e.id}}]}))]}}}function Fp(e){const t=function(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}(e);return function(e){const t=String(e||"");return t.startsWith("th_cb_")?function(e){try{return Buffer.from(e,"base64url").toString("utf8")}catch{return""}}(t.slice(6)):""}(t[Bp]||t.action_id||t.actionId||t.id||e)}function Hp(e){return JSON.stringify(kl(e))}function Wp(e){const t=e.replace(/\s+/g," ").trim();return t.length<=50?t:`${t.slice(0,47)}...`}function Gp(e){const t=e.trim().toLowerCase();return["deny","cancel","delete","remove"].some(e=>t.includes(e))?"danger":["allow","approve","launch","open"].some(e=>t.includes(e))?"primary":"default"}function Vp(e){return e instanceof Error?e.message:String(e)}function Kp(e){const t=Number(function(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}(e).message_id);return Number.isInteger(t)&&t>0?t:void 0}function Jp(e){return Array.isArray(e?.actionRows)?e.actionRows:(Array.isArray(e?.actions)?e.actions:[]).map(e=>[e])}function Yp(e,t){const n=Jp(e),i=Jp(t);return n.length===i.length&&n.every((e,t)=>{const n=i[t];return e.length===n.length&&e.every((e,t)=>{const i=n[t];return e.text===i?.text&&e.callbackData===i.callbackData})})}class Qp{entries;updateIntervalMs;send;edit;deleteMessage;messageIdFromResult;retryAfterMs;isMessageTooLong;onLog;constructor(e){this.entries=e.entries||new Map,this.updateIntervalMs=e.updateIntervalMs||1e3,this.send=e.send,this.edit=e.edit,this.deleteMessage=e.delete,this.messageIdFromResult=e.messageIdFromResult||Kp,this.retryAfterMs=e.retryAfterMs,this.isMessageTooLong=e.isMessageTooLong,this.onLog=e.onLog}remember(e,t,n,i,s,r){const o=this.entries.get(e);return o&&(clearTimeout(o.timer),o.timer=void 0,o.pendingText=void 0),this.entries.set(e,{lastText:n,lastUpdateAt:Date.now(),messageId:t,route:i,options:s,lastOptions:s,renderOptions:r}),o}rekey(e,t){if(e===t)return this.entries.has(e);const n=this.entries.get(e);if(!n||this.entries.has(t))return!1;if(clearTimeout(n.timer),n.timer=void 0,this.entries.delete(e),this.entries.set(t,n),n.pendingText){const e=n.rateLimitedUntil?Math.max(0,n.rateLimitedUntil-Date.now()):Math.max(0,this.updateIntervalMs-(Date.now()-n.lastUpdateAt));this.scheduleFlush(t,e)}return!0}scheduleFlush(e,t){const n=this.entries.get(e);n&&!n.timer&&(n.timer=setTimeout(()=>{n.timer=void 0;const t=n.pendingText;n.pendingText=void 0,t&&this.applyUpdate(e,t,n.route,n.options)},t))}markRateLimited(e,t,n,i){const s=this.entries.get(e);s&&(s.rateLimitedUntil=Date.now()+n,s.pendingText=t,s.route=i||s.route,this.scheduleFlush(e,n))}async applyUpdate(e,t,n,i){let s=this.entries.get(e);const r=s,o=n||s?.route,a=i||s?.options;try{if(s&&(s.route=o,s.options=a),s?.pending&&await s.pending,s=this.entries.get(e),r&&s!==r)return!1;if(s?.messageId){if(s.lastText===t&&Yp(s.lastOptions,a))return!0;const n=Date.now()-(s.lastUpdateAt||0);return n<this.updateIntervalMs?(s.pendingText=t,s.route=o||s.route,s.options=a||s.options,this.scheduleFlush(e,this.updateIntervalMs-n),!0):(await this.edit(s.messageId,t,o||s.route,a),s.lastText=t,s.lastOptions=a,s.lastUpdateAt=Date.now(),s.rateLimitedUntil=void 0,!0)}const n={lastText:t,lastUpdateAt:Date.now(),route:o,options:a,lastOptions:a};return n.pending=this.send(t,o,a).then(e=>{const t=this.messageIdFromResult(e);t&&(n.messageId=t)}).finally(()=>{n.pending=void 0}),this.entries.set(e,n),await n.pending,this.entries.get(e)===n&&(n.rateLimitedUntil=void 0,Boolean(n.messageId))}catch(n){const i=this.retryAfterMs?.(n);return i&&this.markRateLimited(e,t,i,o),this.onLog?.(`Telegram progress update skipped: ${Vp(n)}`),!1}}update(e,t,n,i){const s=String(t||"").trim();if(!s)return;const r=this.entries.get(e);if(r&&(r.route=n||r.route,r.options=i||r.options),r?.lastText===s&&Yp(r.lastOptions,i||r.options)&&!r.pending&&!r.pendingText)return;const o=Date.now();if(r?.rateLimitedUntil){if(r.rateLimitedUntil>o)return r.pendingText=s,void this.scheduleFlush(e,r.rateLimitedUntil-o);r.rateLimitedUntil=void 0}if(r?.pending&&!r.messageId)return r.pendingText=s,void this.scheduleFlush(e,this.updateIntervalMs);if(!r||!r.messageId)return void this.applyUpdate(e,s,n,i);const a=Date.now()-(r.lastUpdateAt||0);if(a>=this.updateIntervalMs)return clearTimeout(r.timer),r.timer=void 0,r.pendingText=void 0,void this.applyUpdate(e,s,n||r.route,i||r.options);r.pendingText=s,this.scheduleFlush(e,this.updateIntervalMs-a)}async finish(e,t,n,i,s){const r=this.entries.get(e);if(!r)return!1;try{if(clearTimeout(r.timer),r.timer=void 0,r.pendingText=void 0,r.pending&&await r.pending,this.entries.delete(e),!r.messageId)return!1;const o=i||r.options;return r.lastText===t&&Yp(r.lastOptions,o)||await this.edit(r.messageId,t,n||r.route,o,s||r.renderOptions),!0}catch(t){return this.entries.delete(e),this.isMessageTooLong?.(t)?this.onLog?.("Telegram progress finish too long; sending result as multiple messages"):this.onLog?.(`Telegram progress finish skipped: ${Vp(t)}`),!1}}async delete(e,t){const n=this.entries.get(e);if(!n)return!1;try{return clearTimeout(n.timer),n.timer=void 0,n.pendingText=void 0,n.pending&&await n.pending,this.entries.delete(e),!(!this.deleteMessage||!n.messageId)&&(await this.deleteMessage(n.messageId,t||n.route),!0)}catch(t){return this.entries.delete(e),this.onLog?.(`Telegram progress delete skipped: ${Vp(t)}`),!1}}async flush(e){const t=this.entries.get(e);if(t?.pending&&await t.pending,t?.timer){clearTimeout(t.timer),t.timer=void 0;const n=t.pendingText;t.pendingText=void 0,n&&await this.applyUpdate(e,n,t.route,t.options)}}async wait(e){await function(e){return new Promise(t=>setTimeout(t,e))}(e)}}const Xp=20971520;function Zp(e){const t=[],n=[...e.photo||[]].filter(e=>e.file_id).sort((e,t)=>Number(t.file_size||t.width||0)-Number(e.file_size||e.width||0))[0];return n?.file_id&&t.push({fileId:n.file_id,fileName:"telegram-photo.jpg",fileSize:n.file_size}),e.document?.file_id&&String(e.document.mime_type||"").startsWith("image/")&&t.push({fileId:e.document.file_id,fileName:e.document.file_name,fileSize:e.document.file_size}),t}async function eu(e,n,i="telegram-image",s){if(s&&s>Xp)throw new Error(`image is too large: ${s} bytes`);const r=await e.getFileLink(n),o=String(r),a=await(e.fetchFile||fetch)(o);if(!a.ok)throw new Error(`download failed with HTTP ${a.status}`);const d=Number(a.headers.get("content-length")||0);if(d>Xp)throw new Error(`image is too large: ${d} bytes`);const c=t.extname(i)||".jpg";let l=c;try{l=t.extname(new URL(o).pathname)||c}catch{l=c}const p=t.join(y.tmpdir(),"task-handoff-images");await m.mkdir(p,{recursive:!0});const u=l.replace(/[^.\w-]/g,"")||".jpg",g=t.join(p,`telegram-${Date.now()}-${Math.random().toString(16).slice(2)}${u}`),h=Buffer.from(await a.arrayBuffer());if(h.length>Xp)throw new Error(`image is too large: ${h.length} bytes`);return await m.writeFile(g,h),g}class tu{store;constructor(e){this.store=new Qp({updateIntervalMs:e.updateIntervalMs,send:(t,n,i)=>e.send(e.requireBridge(n?.bridgeId||""),n?.chatId||"",cp(t),{rawMarkdownV2:!0,replyMarkup:au(i)}),edit:(t,n,i,s)=>e.edit(e.requireBridge(i?.bridgeId||""),i?.chatId||"",t,cp(n),{rawMarkdownV2:!0,replyMarkup:au(s)}),delete:(t,n)=>e.deleteMessage(e.requireBridge(n?.bridgeId||""),n?.chatId||"",t),onLog:e.onLog})}get entries(){return this.store.entries}remember(e,t,n,i){return this.store.remember(e,t,n,i)}rekey(e,t){return this.store.rekey(e,t)}delete(e){return this.store.delete(e)}async applyUpdate(e){return this.store.applyUpdate(e.key,e.text,{bridgeId:e.bridge.id,chatId:e.chatId},{actionRows:e.actionRows})}}async function nu(e){return(await async function(e,t,n,i){const s=[];for(const r of Zp(n))try{const n=await eu({getFileLink:n=>up(e,t,n),fetchFile:e},r.fileId,r.fileName,r.fileSize);s.push(n)}catch(e){i?.({fileId:r.fileId,fileName:r.fileName,error:e})}return s}(e.fetchImpl,e.bridge,e.message,e.onImageDownloadError)).map((e,s)=>{const r=n.readFileSync(e);return{id:`tg_${i.randomUUID().replace(/-/g,"").slice(0,24)}`,kind:"image",name:t.basename(e)||`telegram-image-${s+1}`,mime:iu(e),size:r.length,source:{type:"inline",encoding:"base64",data:r.toString("base64")}}})}function iu(e){const n=t.extname(e).toLowerCase();return".png"===n?"image/png":".webp"===n?"image/webp":".gif"===n?"image/gif":".bmp"===n?"image/bmp":"image/jpeg"}function su(e){const t=Number(e?.message_id);return Number.isInteger(t)?t:void 0}function ru(e){return e&&"object"==typeof e?e:{}}function ou(e){return"string"==typeof e?e:""}function au(e){const t=Array.isArray(e?.actionRows)?e.actionRows:void 0;return Sl(t||(Array.isArray(e?.actions)?e.actions:[]).map(e=>[e]))}function du(e){const t=Array.isArray(e.item_list)?e.item_list:[];for(const e of t){const t=cu(e);if(1!==t.type)continue;const n=lu(cu(t.text_item).text).trim();if(n)return n}return""}function cu(e){return e&&"object"==typeof e?e:{}}function lu(e){return"string"==typeof e?e:""}function pu(e){const{fetchImpl:t,bridge:n,dingdingRuntime:s,larkRuntime:r}=e;return"telegram"===n.channel?function(e,t){return{bridge:t,send:async(n,i,s={})=>{const r=await pp(e,t,n,i,{replyMarkup:s.replyMarkup,replyToMessageId:s.replyToMessageId,rawMarkdownV2:s.rawMarkdownV2,parseMode:s.parseMode});return{provider:"telegram",raw:r,messageId:Number(ru(r).message_id)||void 0}}}}(t,n):"dingding"===n.channel?function(e,t,n){return{bridge:t,send:async(i,s,r={})=>{const o=r.sessionWebhook||n?.chatWebhooks.get(i)||Lp(t.settings.sessionWebhook);if(r.replyMarkup&&n){const a=await Np({fetchImpl:e,bridge:t,runtime:n,chatId:i,text:s,replyMarkup:r.replyMarkup,sessionWebhook:o,senderId:r.senderId||n.senderIds.get(i)||Lp(t.settings.senderId)});if(a?.delivered)return{provider:"dingding",interactionId:a.outTrackId}}if(o)return await xp(e,o,s,n?.onLog),{provider:"dingding"}}}}(t,n,s):"lark"===n.channel?function(e,t){return{bridge:e,send:async(e,n,i={})=>{if(!t)return;const s=await t.channel.send(e,i.replyMarkup?{card:Up(n,i.replyMarkup)}:{markdown:n});return{provider:"lark",interactionId:s.messageId,raw:s}}}}(n,r):"wechat"===n.channel?function(e,t){return{bridge:t,send:async(n,s,r={})=>{const o=r.contextToken||lu(t.settings.contextToken);if(o)return await async function(e,t,n,s,r){const o=lu(t.settings.baseUrl)||"https://ilinkai.weixin.qq.com",a=await e(`${o}/ilink/bot/sendmessage`,{method:"POST",headers:{"content-type":"application/json",AuthorizationType:"ilink_bot_token",Authorization:`Bearer ${t.token}`,"X-WECHAT-UIN":String(Math.floor(Math.random()*2**31))},body:JSON.stringify({msg:{from_user_id:"",to_user_id:n,client_id:i.randomUUID(),message_type:2,message_state:2,context_token:s,item_list:[{type:1,text_item:{text:r}}]},base_info:{channel_version:"1.0.2"}})}),d=await a.json().catch(()=>({}));if(!a.ok||d.errcode)throw new Error(lu(d.errmsg)||`WeChat send failed with HTTP ${a.status}`)}(e,t,n,o,s),{provider:"wechat"}}}}(t,n):{bridge:n,send:async()=>{}}}class uu{entries=new Map;fetchImpl;generations=new Map;constructor(e){this.fetchImpl=e}clear(){for(const e of new Set([...this.generations.keys(),...[...this.entries.values()].map(e=>e.bridgeId)]))this.clearBridge(e)}clearBridge(e){this.generations.set(e,this.generation(e)+1),this.clearEntries(t=>t.bridgeId===e)}generation(e){return this.generations.get(e)||0}isCurrent(e,t){return this.generation(e)===t}clearEntries(e){for(const[t,n]of this.entries)e(n)&&(n.timer&&clearTimeout(n.timer),n.cancelPending?.(new Error("DingDing progress update was cancelled.")),this.entries.delete(t))}async applyUpdate(e,t){const n=this.generation(e.bridge.id),i=$p(e.replyMarkup);let s=this.entries.get(e.key);if(s?.pending&&await s.pending,!this.isCurrent(e.bridge.id,n))return!1;if(s=this.entries.get(e.key),s?.outTrackId){if(s.lastText===e.text&&s.lastActionsFingerprint===i)return!0;const r=Date.now()-(s.lastUpdateAt||0);return r<1e3?(s.pendingText=e.text,s.pendingReplyMarkup=e.replyMarkup,s.timer||(s.pending=new Promise((i,o)=>{s.cancelPending=o,s.timer=setTimeout(()=>{s.timer=void 0,s.cancelPending=void 0;const r=s.pendingText,a=s.pendingReplyMarkup;if(s.pendingText=void 0,s.pendingReplyMarkup=void 0,!r)return i(void 0);this.updateExistingEntry(e,t,s,r,a,$p(a),n).then(i,o)},1e3-r)}).finally(()=>{s.pending=void 0,s.timer=void 0,s.cancelPending=void 0})),await s.pending,this.isCurrent(e.bridge.id,n)&&this.entries.has(e.key)):(await this.updateExistingEntry(e,t,s,e.text,e.replyMarkup,i,n),this.isCurrent(e.bridge.id,n))}const r={bridgeId:e.bridge.id,lastText:e.text,lastActionsFingerprint:i,lastUpdateAt:Date.now()};return r.pending=Np({fetchImpl:this.fetchImpl,bridge:e.bridge,runtime:t,chatId:e.chatId,text:e.text,replyMarkup:e.replyMarkup,sessionWebhook:t.chatWebhooks.get(e.chatId)||gu(e.bridge.settings.sessionWebhook),senderId:t.senderIds.get(e.chatId)||gu(e.bridge.settings.senderId),title:"TaskHandoff 执行中",step:"progress",forceCard:!0}).then(t=>{this.isCurrent(e.bridge.id,n)&&(t?.outTrackId&&(r.outTrackId=t.outTrackId),t?.delivered&&(r.delivered=!0,r.lastUpdateAt=Date.now()))}).catch(t=>{throw this.isCurrent(e.bridge.id,n)&&this.entries.delete(e.key),t}).finally(()=>{r.pending=void 0}),this.entries.set(e.key,r),await r.pending,this.isCurrent(e.bridge.id,n)&&Boolean(r.delivered)}async updateExistingEntry(e,t,n,i,s,r,o){n.outTrackId&&(await async function(e){await Op(e.fetchImpl,e.bridge,e.runtime,"PUT","/v1.0/card/instances",{outTrackId:e.outTrackId,cardData:{cardParamMap:vp({type:"actions",title:e.title,description:e.text,list:kl(e.replyMarkup),biz_step:e.step,error_msg:""})},cardUpdateOptions:{updateCardDataByKey:!0,updatePrivateDataByKey:!1},userIdType:Number(e.bridge.settings.cardUserIdType||1)})}({fetchImpl:this.fetchImpl,bridge:e.bridge,runtime:t,outTrackId:n.outTrackId,text:i,replyMarkup:s,title:"TaskHandoff 执行中",step:"progress"}),this.isCurrent(e.bridge.id,o)&&(n.lastText=i,n.lastActionsFingerprint=r,n.lastUpdateAt=Date.now()))}}function gu(e){return"string"==typeof e?e:""}function hu(e){const t=new f.DWClient({clientId:e.clientId,clientSecret:e.clientSecret,ua:"task-handoff-control-plane",keepAlive:!1,autoReconnect:!1});let n,i=!1;return{async connect(){i=!1,await t.getEndpoint(),await t._connect();const e=t.socket;e?.once("close",()=>{i||n?.(new Error("DingDing stream connection closed."))})},disconnect(){i=!0,t.disconnect()},onDisconnect(e){n=e},getConfig:()=>t.getConfig(),registerCallbackListener(e,n){t.registerCallbackListener(e,n)},socketCallBackResponse(e,n){t.socketCallBackResponse(e,n)}}}class mu{runtimes=new Map;connected=new Set;reconnectTimers=new Map;progress;options;createClient;constructor(e){this.options=e,this.createClient=e.createClient||hu,this.progress=new uu(e.fetchImpl)}has(e){return this.runtimes.has(e)}isRunning(e){return this.connected.has(e)}get(e){return this.runtimes.get(e)}ids(){return this.runtimes.keys()}start(e){const t=(n=e.settings?.clientSecret,"string"==typeof n?n:"");var n;if(!e.token||!t)return this.options.onError(e.id,"DingDing client id/secret is not configured."),!1;const i={client:this.createClient({clientId:e.token,clientSecret:t}),chatWebhooks:new Map,senderIds:new Map,conversationTypes:new Map,onLog:(t,n,i)=>{this.options.logger["warn"===t?"warn":"info"]({bridgeId:e.id,...n},i)}};return i.client.onDisconnect?.(t=>{this.runtimes.get(e.id)===i&&this.handleConnectionFailure(e,i,t)}),i.client.registerCallbackListener(f.TOPIC_ROBOT,t=>{this.options.onRobotMessage(e,i,t).catch(t=>{this.options.onError(e.id,t)})}),i.client.registerCallbackListener(f.TOPIC_CARD,t=>{const n=t;this.options.onCardCallback(e,i,n).then(e=>i.client.socketCallBackResponse(n.headers.messageId,e||{})).catch(t=>{this.options.onError(e.id,t),i.client.socketCallBackResponse(n.headers.messageId,{})})}),this.options.clearError(e.id),this.runtimes.set(e.id,i),this.connect(e,i),!0}connect(e,t){this.reconnectTimers.delete(e.id),this.connected.add(e.id),t.client.connect().then(()=>{this.runtimes.get(e.id)===t&&(this.connected.add(e.id),this.options.clearError(e.id))}).catch(n=>{this.runtimes.get(e.id)===t&&this.handleConnectionFailure(e,t,n)})}handleConnectionFailure(e,t,n){if(this.connected.delete(e.id),this.progress.clearBridge(e.id),this.options.onError(e.id,n||"DingDing stream connection failed."),this.reconnectTimers.has(e.id))return;const i=setTimeout(()=>{this.runtimes.get(e.id)===t&&this.connect(e,t)},this.options.reconnectDelayMs??1e3);i.unref?.(),this.reconnectTimers.set(e.id,i)}stop(e){const t=this.reconnectTimers.get(e);t&&clearTimeout(t),this.reconnectTimers.delete(e),this.connected.delete(e);const n=this.runtimes.get(e);if(n){try{n.client.disconnect()}catch{}this.runtimes.delete(e)}this.progress.clearBridge(e)}stopAll(){for(const e of[...this.runtimes.keys()])this.stop(e);this.progress.clear()}applyUpdate(e){const t=this.runtimes.get(e.bridge.id);return t?this.progress.applyUpdate(e,t):Promise.resolve(!1)}applyProgressUpdate(e){return this.applyUpdate(e)}}class yu{entries=new Map;generations=new Map;updateIntervalMs;constructor(e=1e3){this.updateIntervalMs=e}clear(){for(const e of new Set([...this.generations.keys(),...[...this.entries.values()].map(e=>e.bridgeId)]))this.clearBridge(e)}clearBridge(e){this.generations.set(e,this.generation(e)+1);for(const[t,n]of this.entries)n.bridgeId===e&&(n.timer&&clearTimeout(n.timer),n.cancelPending?.(new Error("Lark progress update was cancelled.")),this.entries.delete(t))}generation(e){return this.generations.get(e)||0}isCurrent(e,t){return this.generation(e)===t}async applyUpdate(e,t){const n=this.generation(e.bridge.id),i=Hp(e.replyMarkup);let s=this.entries.get(e.key);if(s?.pending&&await s.pending,!this.isCurrent(e.bridge.id,n))return!1;if(s=this.entries.get(e.key),s?.messageId){if(s.lastText===e.text&&s.lastActionsFingerprint===i)return!0;const r=Date.now()-s.lastUpdateAt;return r<this.updateIntervalMs?(s.pendingText=e.text,s.pendingReplyMarkup=e.replyMarkup,s.timer||(s.pending=new Promise((i,o)=>{s.cancelPending=o,s.timer=setTimeout(()=>{s.timer=void 0,s.cancelPending=void 0;const r=s.pendingText,a=s.pendingReplyMarkup;if(s.pendingText=void 0,s.pendingReplyMarkup=void 0,!r)return i(void 0);this.updateExistingEntry(e,t,s,r,a,Hp(a),n).then(i,o)},this.updateIntervalMs-r)}).finally(()=>{s.pending=void 0,s.timer=void 0,s.cancelPending=void 0})),await s.pending,this.isCurrent(e.bridge.id,n)&&this.entries.has(e.key)):(await this.updateExistingEntry(e,t,s,e.text,e.replyMarkup,i,n),this.isCurrent(e.bridge.id,n))}const r={bridgeId:e.bridge.id,lastText:e.text,lastActionsFingerprint:i,lastUpdateAt:Date.now()};return r.pending=t.channel.send(e.chatId,{card:Up(e.text,e.replyMarkup)}).then(t=>{this.isCurrent(e.bridge.id,n)&&(r.messageId=t.messageId,r.delivered=!0,r.lastUpdateAt=Date.now())}).catch(t=>{throw this.isCurrent(e.bridge.id,n)&&this.entries.delete(e.key),t}).finally(()=>{r.pending=void 0}),this.entries.set(e.key,r),await r.pending,this.isCurrent(e.bridge.id,n)&&Boolean(r.delivered)}async updateExistingEntry(e,t,n,i,s,r,o){n.messageId&&(await t.channel.updateCard(n.messageId,Up(i,s)),this.isCurrent(e.bridge.id,o)&&(n.lastText=i,n.lastActionsFingerprint=r,n.lastUpdateAt=Date.now()))}}function fu(e){const t={appId:e.appId,appSecret:e.appSecret,domain:e.domain,transport:"websocket",source:"task-handoff-control-plane",handshakeTimeoutMs:15e3,policy:{requireMention:!0,dmMode:"open",respondToMentionAll:!1}};return I.createLarkChannel(t)}class Iu{runtimes=new Map;connected=new Set;unsubscribe=new Map;reconnectTimers=new Map;options;createChannel;progress;constructor(e){this.options=e,this.createChannel=e.createChannel||fu,this.progress=new yu(e.progressUpdateIntervalMs)}has(e){return this.runtimes.has(e)}isRunning(e){return this.connected.has(e)}get(e){return this.runtimes.get(e)}ids(){return this.runtimes.keys()}start(e){const t=(n=e.settings?.appSecret,"string"==typeof n?n.trim():"");var n;if(!e.token||!t)return this.options.onError(e.id,"Lark app id/secret is not configured."),!1;const i={channel:this.createChannel({appId:e.token,appSecret:t,domain:bu(e.settings?.domain)})},s=i.channel.on({message:t=>{this.options.onMessage(e,i,t).catch(t=>{this.options.onError(e.id,t)})},cardAction:t=>{this.options.onCardAction(e,i,t).catch(t=>{this.options.onError(e.id,t)})},error:t=>{this.options.onError(e.id,t),this.options.logger.warn({bridgeId:e.id,error:t.message},"lark channel error")},reconnecting:()=>{this.connected.delete(e.id),this.options.onError(e.id,"Lark WebSocket is reconnecting."),this.options.logger.info({bridgeId:e.id},"lark channel reconnecting")},reconnected:()=>{this.runtimes.get(e.id)===i&&(this.connected.add(e.id),this.options.clearError(e.id),this.options.logger.info({bridgeId:e.id},"lark channel reconnected"))}});return this.options.clearError(e.id),this.runtimes.set(e.id,i),this.unsubscribe.set(e.id,s),this.connect(e,i),!0}connect(e,t){this.reconnectTimers.delete(e.id),t.channel.connect().then(()=>{this.runtimes.get(e.id)===t&&(this.connected.add(e.id),this.options.clearError(e.id),this.options.logger.info({bridgeId:e.id},"lark channel connected"))}).catch(n=>{if(this.runtimes.get(e.id)!==t)return;if(this.connected.delete(e.id),this.options.onError(e.id,n),t.channel.rawWsClient||this.reconnectTimers.has(e.id))return;const i=setTimeout(()=>{this.runtimes.get(e.id)===t&&this.connect(e,t)},this.options.reconnectDelayMs??1e3);i.unref?.(),this.reconnectTimers.set(e.id,i)})}stop(e){const t=this.reconnectTimers.get(e);t&&clearTimeout(t),this.reconnectTimers.delete(e),this.unsubscribe.get(e)?.(),this.unsubscribe.delete(e),this.connected.delete(e);const n=this.runtimes.get(e);if(this.runtimes.delete(e),this.progress.clearBridge(e),n){try{n.channel.rawWsClient?.close({force:!0})}catch{}n.channel.disconnect().catch(()=>{})}}stopAll(){for(const e of[...this.runtimes.keys()])this.stop(e);this.progress.clear()}applyUpdate(e){const t=this.runtimes.get(e.bridge.id);return t?this.progress.applyUpdate(e,t):Promise.resolve(!1)}applyProgressUpdate(e){return this.applyUpdate(e)}}function bu(e){return"lark"===String(e||"").trim().toLowerCase()?I.Domain.Lark:I.Domain.Feishu}class vu{ttlMs;load;now;cached;pending;generation=0;constructor(e,t,n={}){this.ttlMs=e,this.load=t,this.now=n.now||Date.now}get(){if(this.cached&&this.cached.expiresAt>this.now())return Promise.resolve(this.cached.value);if(this.pending)return this.pending;const e=this.generation,t=this.load().then(t=>(this.generation===e&&(this.cached={expiresAt:this.now()+this.ttlMs,value:t}),t)).finally(()=>{this.pending===t&&(this.pending=void 0)});return this.pending=t,t}invalidate(){this.generation+=1,this.cached=void 0,this.pending=void 0}}class wu{aggregates=new Map;endTokens=new Map;options;delayMs;constructor(e){this.options=e,this.delayMs=e.delayMs??1e3}async handleIncoming(e,t,n,i,s=[],r={},o={}){const a=i.trim(),d=a.split(/\s+/,1)[0]?.toLowerCase()||"",c=Su(e.id,t,n),l=this.aggregates.get(c);return o.autoBegin&&!l?(this.start(c,e,t,n,r),this.enqueue(c,e,t,n,i,s,r,!0),void await this.sendCollectionStarted(e,t,c,r.sourceMessageId,"Image received. Continue sending messages, then send /end when done.")):"/begin"===d?(this.start(c,e,t,n,r),void await this.sendCollectionStarted(e,t,c,r.sourceMessageId,"Started collecting messages. Send /end when done.")):void("/end"!==d?l?.explicit?this.enqueue(c,e,t,n,i,s,r,!0):a.startsWith("/")?await this.options.dispatch(e,t,n,i,s,r):this.enqueue(c,e,t,n,i,s,r,!1):await this.flush(c,"manual"))}async handleEndCallback(e,t,n,i,s){const r=this.endTokens.get(i)||"";if(r!==Su(e.id,t,s))return void await this.options.answerCallback(e,n,"This collection is not active here");const o=await this.flush(r,"callback");await this.options.answerCallback(e,n,o?"Collected message sent":"No messages collected")}stop(){for(const e of this.aggregates.values())e.timer&&clearTimeout(e.timer);this.aggregates.clear(),this.endTokens.clear()}stopBridge(e){for(const[t,n]of this.aggregates)n.bridgeId===e&&(n.timer&&clearTimeout(n.timer),this.aggregates.delete(t));for(const[t,n]of this.endTokens)n.startsWith(`${e}:`)&&this.endTokens.delete(t)}start(e,t,n,i,s){const r=this.aggregates.get(e);r?.timer&&clearTimeout(r.timer),this.aggregates.set(e,{bridgeId:t.id,chatId:n,userId:i,texts:[],attachments:[],context:s,explicit:!0})}enqueue(e,t,n,i,s,r,o,a){const d=this.aggregates.get(e);d?.timer&&clearTimeout(d.timer);const c=d||{bridgeId:t.id,chatId:n,userId:i,texts:[],attachments:[],context:o,explicit:a};var l,p;c.bridgeId=t.id,c.chatId=n,c.userId=i,c.context=(l=c.context,p=o,{sourceMessageId:l?.sourceMessageId??p.sourceMessageId,replyToMessageId:l?.replyToMessageId??p.replyToMessageId,quoteText:l?.quoteText||p.quoteText}),c.explicit=c.explicit||a,s.trim()&&c.texts.push(s),c.attachments.push(...r),c.timer=c.explicit?void 0:setTimeout(()=>{this.flush(e,"timer").catch(e=>this.options.onError?.(c.bridgeId,e))},this.delayMs),this.aggregates.set(e,c)}async flush(e,t){const n=this.aggregates.get(e);if(!n)return!1;n.timer&&clearTimeout(n.timer),this.aggregates.delete(e);const i=this.options.requireBridge(n.bridgeId),s=n.texts.join("\n\n").trim();return s||n.attachments.length?(await this.options.dispatch(i,n.chatId,n.userId,s,n.attachments,n.context||{}),!0):("timer"!==t&&await this.options.send(i,n.chatId,"No messages collected.",{replyToMessageId:n.context?.sourceMessageId}),!1)}sendCollectionStarted(e,t,n,i,s){return this.options.send(e,t,s,{replyToMessageId:i,replyMarkup:Sl([[{text:"/end",callbackData:this.endCallbackData(n)}]])})}endCallbackData(e){const t=i.createHash("sha256").update(e).digest("base64url").slice(0,16);return this.endTokens.set(t,e),`task_handoff:cp_msg_end:${t}`}}function Su(e,t,n){return[e,t,n||""].join(":")}class Au{cancelTokens=new Map;queueActionTokens=new Map;options;constructor(e){this.options=e}cancelCallbackData(e,t){this.pruneExpired();const n=ku([e,t]);return this.cancelTokens.set(n,this.expiring({instanceId:e,sessionId:t})),`task_handoff:cp_ai_cancel:${n}`}queueSteerCallbackData(e,t,n){return`task_handoff:cp_ai_steer:${this.queueActionToken({type:"steer",instanceId:e,sessionId:t,queueId:n})}`}queueDeleteMenuCallbackData(e,t){return`task_handoff:cp_ai_qdel_menu:${this.queueActionToken({type:"delete-menu",instanceId:e,sessionId:t})}`}async tryHandle(e,t){this.pruneExpired();const n=zu(e,"task_handoff:cp_ai_cancel:");if(void 0!==n){const e=this.cancelTokens.get(n)?.value;return e?(await this.cancel(t,e.instanceId,e.sessionId),!0):this.expired(t)}const i=zu(e,"task_handoff:cp_ai_steer:");if(void 0!==i){const e=this.queueActionTokens.get(i)?.value;return e&&"steer"===e.type?(await this.steer(t,e),!0):this.expired(t)}const s=zu(e,"task_handoff:cp_ai_qdel_menu:");if(void 0!==s){const e=this.queueActionTokens.get(s)?.value;return e&&"delete-menu"===e.type?(await this.deleteMenu(t,e),!0):this.expired(t)}const r=zu(e,"task_handoff:cp_ai_qdel:");if(void 0!==r){const e=this.queueActionTokens.get(r)?.value;return e&&"delete-item"===e.type?(await this.deleteItem(t,e),!0):this.expired(t)}return!1}async cancel(e,t,n){await this.requireAllowed(e,t,n)&&await this.run(e,{instanceId:t,sessionId:n,successText:"Interrupt sent",failurePrefix:"Interrupt failed",logMessage:"chat ai session cancel sent",operation:()=>this.options.interrupt(t,n)})}async steer(e,t){await this.requireAllowed(e,t.instanceId,t.sessionId)&&await this.run(e,{...t,successText:"Steered queued message",failurePrefix:"Steer failed",logMessage:"chat ai session queued message steered",operation:()=>this.options.steer(t.instanceId,t.sessionId,t.queueId)})}async deleteMenu(e,t){if(await this.requireAllowed(e,t.instanceId,t.sessionId))try{const n=Eu(await this.options.queue(t.instanceId,t.sessionId)),i=(Array.isArray(n.items)?n.items:[]).map(Eu).filter(e=>"queued"===Cu(e.status)&&Cu(e.id));if(!i.length)return void await this.answer(e,"Queue is empty");const s=i.slice(0,5).map((e,n)=>[{text:Tu(Cu(e.message),n),callbackData:this.queueDeleteItemCallbackData(t.instanceId,t.sessionId,Cu(e.id))}]);await this.send(e,"Delete queued message",{replyMarkup:Sl(s)}),await this.answer(e,"Select a queued message"),this.options.info(this.logData(e,t,{itemCount:i.length}),"chat ai session queue delete menu sent")}catch(t){await this.fail(e,t,"Queue menu failed")}}async deleteItem(e,t){if(await this.requireAllowed(e,t.instanceId,t.sessionId))try{await this.options.remove(t.instanceId,t.sessionId,t.queueId),await this.answer(e,"Queued message deleted"),(e.deleteMessage||Number.isInteger(e.messageId))&&await this.deleteMessage(e).catch(n=>{this.options.warn(this.logData(e,t,{messageId:e.messageId,error:xu(n)}),"chat ai session queue delete menu message delete failed")}),this.options.info(this.logData(e,t),"chat ai session queued message deleted")}catch(t){await this.fail(e,t,"Delete failed")}}async run(e,t){try{await t.operation(),await this.answer(e,t.successText),this.options.info(this.logData(e,t),t.logMessage)}catch(n){await this.fail(e,n,t.failurePrefix)}}async requireAllowed(e,t,n){return!!(e.actionAllowed?e.actionAllowed(t,n):this.options.actionAllowed(e.bridge,e.chatId,t,n,Number.isInteger(e.messageId)?e.messageId:void 0))||(await this.answer(e,"This chat is not bound to that AI session"),!1)}async fail(e,t,n){const i=xu(t);this.options.setBridgeError(e.bridge.id,i),await this.answer(e,`${n}: ${function(e){const t=e.replace(/\s+/g," ").trim();return t.length<=120?t:`${t.slice(0,Math.max(0,119))}…`}(i)}`)}async expired(e){return await this.answer(e,"This AI session action expired"),!0}answer(e,t){return e.answer?e.answer(t):this.options.answer(e.bridge,e.callbackQueryId,t)}send(e,t,n){return e.send?e.send(t,n):this.options.send(e.bridge,e.chatId,t,n)}deleteMessage(e){return e.deleteMessage?e.deleteMessage():Number.isInteger(e.messageId)?this.options.deleteMessage(e.bridge,e.chatId,e.messageId):Promise.resolve(void 0)}queueDeleteItemCallbackData(e,t,n){return`task_handoff:cp_ai_qdel:${this.queueActionToken({type:"delete-item",instanceId:e,sessionId:t,queueId:n})}`}queueActionToken(e){this.pruneExpired();const t=ku([e.type,e.instanceId,e.sessionId,"queueId"in e?e.queueId:""]);return this.queueActionTokens.set(t,this.expiring(e)),t}clear(){this.cancelTokens.clear(),this.queueActionTokens.clear()}expiring(e){return{value:e,expiresAt:(this.options.now||Date.now)()+(this.options.tokenTtlMs??864e5)}}pruneExpired(){const e=(this.options.now||Date.now)();for(const[t,n]of this.cancelTokens)n.expiresAt<=e&&this.cancelTokens.delete(t);for(const[t,n]of this.queueActionTokens)n.expiresAt<=e&&this.queueActionTokens.delete(t)}logData(e,t,n={}){return{bridgeId:e.bridge.id,chatId:e.chatId,instanceId:t.instanceId,sessionId:t.sessionId,...t.queueId?{queueId:t.queueId}:{},userId:e.userId,...n}}}function zu(e,t){if(!e.startsWith(t))return;const n=e.slice(t.length);return n&&!n.includes(":")?n:void 0}function ku(e){return i.createHash("sha256").update(e.join("\0")).digest("base64url").slice(0,16)}function Tu(e,t){const n=`${t+1}. `,i=Cu(e).replace(/\s+/g," ").trim()||"Queued message",s=Math.max(8,48-n.length),r=Array.from(i);return`${n}${r.length>s?`${r.slice(0,Math.max(1,s-3)).join("")}...`:i}`}function Eu(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function Cu(e){return"string"==typeof e?e.trim():""}function xu(e){return e instanceof Error?e.message:String(e)}class Nu{announced=new Set;options;constructor(e){this.options=e}async poll(){const e=await this.options.listRoutes().catch(()=>[]);for(const t of e){if(this.announced.has(t.id))continue;const e=Ou(t,this.options.callbackData),n=t.aiSessionId?this.options.listBindings().filter(e=>e.activeInstanceId===t.instanceId&&e.activeAiSessionId===t.aiSessionId):[];(await this.sendToBindings(n,e)||await this.sendToDefaults(e))&&this.announced.add(t.id)}}async sendToBindings(e,t){let n=!1;for(const i of e){if(!i.bridgeId)continue;const e=this.options.requireBridge(i.bridgeId);if(!e.enabled)continue;const s=await this.send(e,i.chatSessionId,t);n||=s}return n}async sendToDefaults(e){let t=!1;for(const n of this.options.listBridges()){if(!n.enabled||!n.defaultChatId)continue;let i=!1;await this.options.send(n,n.defaultChatId,e).catch(e=>(this.options.setBridgeError(n.id,_u(e)),i=!0,!1))?t=!0:i||this.options.setBridgeError(n.id,"Chat bridge message was not delivered.")}return t}async send(e,t,n){return this.options.send(e,t,n).then(Boolean).catch(t=>(this.options.setBridgeError(e.id,_u(t)),!1))}}function Ou(e,t){const n=`${e.project?.name||e.projectId} / ${e.instance?.name||e.instanceId}`,i="approval"===e.kind?`/approve ${e.id}\n/deny ${e.id}\n/skip ${e.id}`:`/reply ${e.id} <message>`,s=`[${n}]\n${e.result}\n\n${i}`;return"approval"!==e.kind?{text:s}:{text:s,replyMarkup:Sl([[{text:"Allow",callbackData:t(e.id,"allow")},{text:"Skip",callbackData:t(e.id,"skip")},{text:"Deny",callbackData:t(e.id,"deny")}]])}}function _u(e){return e instanceof Error?e.message:String(e)}function Ru(){return e=process.env.TASK_HANDOFF_DIAGNOSTIC_LOGS,["1","true","yes","on"].includes(String(e||"").trim().toLowerCase());var e}class Pu{service;fetchImpl;logger;diagnosticLogsEnabled;bridgeTimers=new Map;bridgePollingGenerations=new Map;bridgePolls=new Map;dingdingBridges;larkBridges;bridgeErrors=new Map;telegramOffsets=new Map;seenTelegramUpdates=new Set;wechatCursors=new Map;pendingRouteNotifier;deliveredAiSessionFingerprints=new Map;telegramAiSessionCallbacks;telegramMessageAggregator;telegramProgressMessageTargets=new Map;aiSessionInstanceNamesCache;aiSessionPendingRoutesCache;telegramProgress;stopAiSessionListener;constructor(e,t=fetch,n={}){this.service=e,this.fetchImpl=t,this.logger=n.logger,this.diagnosticLogsEnabled=n.diagnosticLogsEnabled||Ru,this.aiSessionInstanceNamesCache=new vu(3e4,async()=>{const e=await(this.service.listAiSessionInstanceNames?.()||this.service.boardAsync()).catch(()=>[]);return new Map(e.map(e=>[e.id,e.name||e.id]))}),this.aiSessionPendingRoutesCache=new vu(1e3,()=>this.service.listPendingRoutes().catch(()=>[])),this.telegramMessageAggregator=new wu({requireBridge:e=>this.service.requireChatBridge(e),send:(e,t,n,i={})=>this.sendTelegramMessage(e,t,n,i),answerCallback:(e,t,n)=>this.answerTelegramCallback(e,t,n),dispatch:(e,t,n,i,s,r)=>this.dispatchTelegramGatewayMessage(e,t,n,i,s,r),onError:(e,t)=>this.bridgeErrors.set(e,Fu(t))}),this.telegramAiSessionCallbacks=new Au({interrupt:(e,t)=>this.service.interruptAiSession(e,t),queue:(e,t)=>this.service.aiSessionQueue(e,t),steer:(e,t,n)=>this.service.steerAiSessionQueuedMessage(e,t,n),remove:(e,t,n)=>this.service.removeAiSessionQueuedMessage(e,t,n),actionAllowed:(e,t,n,i,s)=>this.telegramAiSessionActionAllowed(e,t,n,i,s),answer:(e,t,n)=>this.answerTelegramCallback(e,t,n),send:(e,t,n,i={})=>this.sendTelegramMessage(e,t,n,i),deleteMessage:(e,t,n)=>this.deleteTelegramMessage(e,t,n),setBridgeError:(e,t)=>this.bridgeErrors.set(e,t),info:(e,t)=>this.logInfo(e,t),warn:(e,t)=>this.logWarn(e,t)}),this.pendingRouteNotifier=new Nu({listRoutes:()=>this.service.listPendingRoutes(),listBindings:()=>this.service.listChatSessions(),listBridges:()=>this.service.listChatBridges(),requireBridge:e=>this.service.requireChatBridge(e),callbackData:(e,t)=>this.service.pendingDecisionCallbackData(e,t),send:(e,t,n)=>this.sendViaBridge(e,t,n),setBridgeError:(e,t)=>this.bridgeErrors.set(e,t)}),this.telegramProgress=new tu({updateIntervalMs:n.telegramProgressUpdateIntervalMs,requireBridge:e=>this.service.requireChatBridge(e),send:(e,t,n,i={})=>this.sendTelegramMessage(e,t,n,i),edit:(e,t,n,i,s={})=>this.editTelegramMessage(e,t,n,i,s),deleteMessage:(e,t,n)=>this.deleteTelegramMessage(e,t,n),onLog:e=>this.logWarn({message:e},"telegram progress store warning")}),this.dingdingBridges=new mu({fetchImpl:this.fetchImpl,createClient:n.createDingdingClient,logger:{info:(e,t)=>this.logInfo(e,t),warn:(e,t)=>this.logWarn(e,t)},onRobotMessage:(e,t,n)=>this.handleDingdingRobotMessage(e,t,n),onCardCallback:(e,t,n)=>this.handleDingdingCardCallback(e,t,n),onError:(e,t)=>this.bridgeErrors.set(e,Fu(t)),clearError:e=>this.bridgeErrors.delete(e)}),this.larkBridges=new Iu({createChannel:n.createLarkChannel,progressUpdateIntervalMs:n.larkProgressUpdateIntervalMs,logger:{info:(e,t)=>this.logInfo(e,t),warn:(e,t)=>this.logWarn(e,t)},onMessage:(e,t,n)=>this.handleLarkMessage(e,t,n),onCardAction:(e,t,n)=>this.handleLarkCardAction(e,t,n),onError:(e,t)=>this.bridgeErrors.set(e,Fu(t)),clearError:e=>this.bridgeErrors.delete(e)}),this.stopAiSessionListener=n.aiSessions?.onSnapshot(e=>{this.deliverAiSessionSnapshot(e.instanceId,e.aiSessions).catch(t=>{this.logWarn({instanceId:e.instanceId,snapshotRevision:e.revision,error:Fu(t)},"chat ai session snapshot delivery failed")})})}logInfo(e,t){this.diagnosticLogsEnabled()&&this.logger?.info?.({component:"control-plane-chat-gateway",...e},t)}logWarn(e,t){this.diagnosticLogsEnabled()&&this.logger?.warn?.({component:"control-plane-chat-gateway",...e},t)}updateChatBridge(e,t){this.service.updateChatBridge?.(e,t)}startEnabled(){this.logAiSessionDelivery({stage:"runtime-start-enabled",bridgeCount:this.service.listChatBridges().length,enabledBridgeCount:this.service.listChatBridges().filter(e=>e.enabled).length});for(const e of this.service.listChatBridges())e.enabled&&this.startBridge(e.id)}startBridge(e){if(this.bridgeTimers.has(e)||this.dingdingBridges.has(e)||this.larkBridges.has(e))return this.logAiSessionDelivery({stage:"bridge-start-skipped-running",bridgeId:e}),this.status();const t=this.service.requireChatBridge(e);return this.logAiSessionDelivery({stage:"bridge-start",bridgeId:t.id,channel:t.channel,enabled:t.enabled,hasToken:Boolean(t.token)}),"wechat"===t.channel?this.startPollingBridge(t,(e,t)=>this.pollWechat(e,t)):"dingding"===t.channel?this.startDingdingBridge(t):"lark"===t.channel?this.startLarkBridge(t):"telegram"!==t.channel?(this.bridgeErrors.set(e,`${t.channel} bridge is not supported in the control plane.`),this.status()):t.token?this.startPollingBridge(t,(e,t)=>this.pollTelegram(e,t)):(this.bridgeErrors.set(e,"Telegram token is not configured."),this.status())}stopBridge(e){this.advanceBridgePollingGeneration(e);const t=`:${e}:`;for(const e of this.deliveredAiSessionFingerprints.keys())e.includes(t)&&this.deliveredAiSessionFingerprints.delete(e);const n=this.bridgeTimers.get(e);return n&&(clearInterval(n),this.bridgeTimers.delete(e)),this.dingdingBridges.stop(e),this.larkBridges.stop(e),this.telegramMessageAggregator.stopBridge(e),this.status()}stopAll(){const e=new Set([...this.service.listChatBridges().map(e=>e.id),...this.bridgePollingGenerations.keys(),...this.bridgeTimers.keys(),...this.bridgePolls.keys(),...this.dingdingBridges.ids(),...this.larkBridges.ids()]);for(const t of e)this.stopBridge(t);this.dingdingBridges.stopAll(),this.larkBridges.stopAll(),this.telegramMessageAggregator.stop(),this.telegramAiSessionCallbacks.clear(),this.stopAiSessionListener?.(),this.stopAiSessionListener=void 0}async pollBridgeNow(e){const t=this.service.requireChatBridge(e),n=this.bridgePollingGeneration(e);return"telegram"===t.channel?(await this.runBridgePoll(t,n,(e,t)=>this.pollTelegram(e,t)),this.status()):"wechat"===t.channel?(await this.runBridgePoll(t,n,(e,t)=>this.pollWechat(e,t)),this.status()):("dingding"===t.channel||"lark"===t.channel||this.bridgeErrors.set(e,`${t.channel} bridge is not supported in the control plane.`),this.status())}async pollAiSessionsNow(){return await this.pollAiSessionUpdates(),this.status()}status(){const e=this.service.listChatBridges().map(e=>({id:e.id,channel:e.channel,name:e.name,running:this.bridgeTimers.has(e.id)||this.dingdingBridges.isRunning(e.id)||this.larkBridges.isRunning(e.id),tokenSet:Boolean(e.tokenSet),defaultChatId:e.defaultChatId,lastUpdateId:this.telegramOffsets.get(e.id),error:this.bridgeErrors.get(e.id)}));return{running:e.some(e=>e.running),bridges:e}}startPollingBridge(e,t){if(!e.token)return this.bridgeErrors.set(e.id,`${e.channel} token is not configured.`),this.status();this.bridgeErrors.delete(e.id);const n=this.advanceBridgePollingGeneration(e.id),i=()=>this.bridgePollingGeneration(e.id)===n,s=s=>{i()&&this.runBridgePoll(s,n,t).catch(t=>{i()&&this.bridgeErrors.set(e.id,t instanceof Error?t.message:String(t))})},r=setInterval(()=>{if(!i())return;const t=this.service.requireChatBridge(e.id);t.enabled?s(t):this.stopBridge(e.id)},e.pollIntervalMs);if(this.bridgeTimers.set(e.id,r),this.logAiSessionDelivery({stage:"bridge-poll-started",bridgeId:e.id,channel:e.channel,intervalMs:e.pollIntervalMs}),e.enabled){const t=this.service.requireChatBridge(e.id);s(t)}return this.status()}runBridgePoll(e,t,n){const i=this.bridgePolls.get(e.id);if(i?.generation===t)return i.promise;const s=(async()=>{const i=()=>this.bridgePollingGeneration(e.id)===t;i()&&await n(e,i)})();this.bridgePolls.set(e.id,{generation:t,promise:s});const r=()=>{this.bridgePolls.get(e.id)?.promise===s&&this.bridgePolls.delete(e.id)};return s.then(r,r),s}bridgePollingGeneration(e){return this.bridgePollingGenerations.get(e)||0}advanceBridgePollingGeneration(e){const t=this.bridgePollingGeneration(e)+1;return this.bridgePollingGenerations.set(e,t),t}startDingdingBridge(e){return this.dingdingBridges.start(e),this.status()}startLarkBridge(e){return this.larkBridges.start(e),this.status()}async handleLarkMessage(e,t,n){const i=this.larkAllowed(e,n.senderId),s=String(n.content||"").trim();if(!i||!s)return void this.logWarn({bridgeId:e.id,chatId:n.chatId,senderId:n.senderId,allowed:i,hasText:Boolean(s)},"lark message ignored");let r;e.defaultChatId||this.updateChatBridge(e.id,{defaultChatId:n.chatId}),this.logInfo({bridgeId:e.id,chatId:n.chatId,senderId:n.senderId,chatType:n.chatType,messageId:n.messageId,textPreview:Wu(s)},"lark chat gateway message received");try{r=await this.service.handleChatGatewayMessage({source:{type:"chat-gateway",channel:"lark",bridgeId:e.id,chatSessionId:n.chatId,userId:n.senderId},message:{text:s,attachments:[]}})}catch(e){return void await t.channel.send(n.chatId,{markdown:`Failed to handle message: ${Fu(e)}`})}const o=ju(r);if(!o)return;const a=Mu(r);if(await this.sendLarkRoutedAiSessionProgress(r,e,n.chatId,o,a))return;const d=pu({fetchImpl:this.fetchImpl,bridge:e,larkRuntime:t}),c=await d.send(n.chatId,o,{replyMarkup:a});c&&this.logInfo({bridgeId:e.id,chatId:n.chatId,senderId:n.senderId,provider:c.provider,interactionId:c.interactionId,routed:!0===Ku(r).routed,replyPreview:Wu(o)},"lark chat gateway reply sent")}async sendLarkRoutedAiSessionProgress(e,t,n,i,s){if(!0!==e.routed)return!1;const r=Qu(e),{instanceId:o,sessionId:a,turnId:d}=r;if(!o||!a||!d)return this.logWarn({bridgeId:t.id,chatId:n,instanceId:o,sessionId:a,turnId:d,turnIdSources:r.sources,routed:e.routed},"lark ai session progress message not started"),!1;const c=ig(o,a,d,t.id,n);return!!await this.larkBridges.applyProgressUpdate({bridge:t,key:c,chatId:n,text:i,replyMarkup:s})&&(this.deliveredAiSessionFingerprints.delete(c),this.logInfo({bridgeId:t.id,chatId:n,instanceId:o,sessionId:a,turnId:d,key:c,textPreview:Wu(i)},"lark ai session progress message started"),!0)}async handleLarkCardAction(e,t,n){const i=n.operator.openId||n.operator.userId;if(!this.larkAllowed(e,i))return void this.logWarn({bridgeId:e.id,chatId:n.chatId,messageId:n.messageId,userId:i},"lark card action ignored");const s=Fp(n.action.value),r=(e,i)=>t.channel.updateCard(n.messageId,Up(e||"Updated",i));if(!s)return void await r("Unsupported action");if(await this.telegramAiSessionCallbacks.tryHandle(s,{bridge:e,chatId:n.chatId,callbackQueryId:n.messageId,userId:i,messageId:n.messageId,actionAllowed:(t,i)=>this.chatAiSessionBindingActive(e,n.chatId,t,i),answer:e=>r(e),send:(e,i)=>t.channel.send(n.chatId,{card:Up(e,i?.replyMarkup)})}))return;let o;try{o=await this.parseChatGatewayCallbackAction(s)}catch(e){if(Hu(e,"CHAT_PENDING_ACTION_STALE"))return void await r(Fu(e));throw e}if(!o)return void await r("Unsupported action");const a=await this.service.handleChatGatewayAction({source:{channel:"lark",bridgeId:e.id,chatSessionId:n.chatId,userId:i},action:o});if("pending-decision"===o.type&&Du(a))return void await r(`${o.decision} sent`);const d=ju(a)||Uu(a.message)||"Updated";await r(d,Mu(a))}async handleDingdingRobotMessage(e,t,n){const i=function(e){const t=qp(e),n=Lp(t.conversationId),i=Lp(Dp(t.text).content).trim();if(!n||!i)return;const s=Lp(t.senderStaffId||t.senderId);return{chatId:n,userId:s||void 0,senderId:s||void 0,sessionWebhook:Lp(t.sessionWebhook)||void 0,conversationType:zp(t.conversationType,{robotMessage:!0}),text:i,raw:t}}(n.data);if(t.client.socketCallBackResponse(n.headers.messageId,{}),!i||!this.dingdingAllowed(e,i.senderId))return void this.logWarn({bridgeId:e.id,hasEvent:Boolean(i),senderId:i?.senderId,allowed:i?this.dingdingAllowed(e,i.senderId):void 0},"dingding robot message ignored");const{chatId:s,text:r,senderId:o,sessionWebhook:a}=i;a&&t.chatWebhooks.set(s,a),i.conversationType&&t.conversationTypes.set(s,i.conversationType);const d=a||t.chatWebhooks.get(s)||Uu(e.settings.sessionWebhook);let c;o&&t.senderIds.set(s,o),e.defaultChatId||this.updateChatBridge(e.id,{defaultChatId:s}),this.logInfo({bridgeId:e.id,chatId:s,senderId:o,conversationType:i.conversationType,hasSessionWebhook:Boolean(a),hasCachedSessionWebhook:Boolean(t.chatWebhooks.get(s)),hasResolvedSessionWebhook:Boolean(d),textPreview:Wu(r)},"dingding chat gateway message received");try{c=await this.service.handleChatGatewayMessage({source:{type:"chat-gateway",channel:"dingding",bridgeId:e.id,chatSessionId:s,userId:o||void 0},message:{text:r,attachments:[]}})}catch(e){if(d)return void await xp(this.fetchImpl,d,`Failed to handle message: ${Fu(e)}`,t.onLog);throw e}const l=ju(c);if(l){const n=Mu(c);if(await this.sendDingdingRoutedAiSessionProgress(c,e,t,s,l,{replyMarkup:n,sessionWebhook:d,senderId:o,sourcePrompt:r}))return;const i=pu({fetchImpl:this.fetchImpl,bridge:e,dingdingRuntime:t}),a=await i.send(s,l,{replyMarkup:n,sessionWebhook:d,senderId:o});if(a)return void this.logInfo({bridgeId:e.id,chatId:s,senderId:o,provider:a.provider,interactionId:a.interactionId,routed:!0===Ku(c).routed,hasReplyMarkup:Boolean(n),replyPreview:Wu(l)},"dingding chat gateway reply sent");this.logWarn({bridgeId:e.id,chatId:s,senderId:o,hasReplyMarkup:Boolean(n),hasSessionWebhook:Boolean(d),hasRobotCode:Boolean(Uu(e.settings.robotCode)),replyPreview:Wu(l)},"dingding chat gateway reply skipped")}}async sendDingdingRoutedAiSessionProgress(e,t,n,i,s,r={}){if(!0!==e.routed)return!1;const o=Qu(e),{instanceId:a,sessionId:d,turnId:c}=o;if(!a||!d||!c)return this.logWarn({bridgeId:t.id,chatId:i,instanceId:a,sessionId:d,turnId:c,turnIdSources:o.sources,routed:e.routed},"dingding ai session progress card not started"),!1;const l=ig(a,d,c,t.id,i);return!!await this.dingdingBridges.applyProgressUpdate({bridge:t,key:l,chatId:i,text:s,replyMarkup:r.replyMarkup})&&(this.deliveredAiSessionFingerprints.delete(l),this.logInfo({bridgeId:t.id,chatId:i,instanceId:a,sessionId:d,turnId:c,key:l,hasSessionWebhook:Boolean(r.sessionWebhook),hasSenderId:Boolean(r.senderId),sourcePrompt:Wu(r.sourcePrompt,80),textPreview:Wu(s)},"dingding ai session progress card started"),!0)}async handleDingdingCardCallback(e,t,n){const i=function(e){const t=qp(e),n=Mp(t.cardActionData||t.content),i=Mp(n.cardPrivateData||t.cardPrivateData||t.content),s=Mp(i.params||n.params||t.params),r=Lp(t.userId),o=Lp(s.biz_sender_id);return{userId:r||void 0,chatId:Ap(t,s),senderId:r||void 0,deliverySenderId:o||void 0,sessionWebhook:Lp(s.biz_session_webhook)||void 0,conversationType:zp(s.biz_conversation_type||t.conversationType||t.conversation_type),callbackData:kp(Ep(t,n,i)),body:t,params:s}}(n.data);if(!this.dingdingAllowed(e,i.userId))return Tp("not authorized",void 0,"unauthorized",i.body,i.params);const s=i.chatId||Uu(e.defaultChatId),r=i.deliverySenderId||i.senderId,o=i.sessionWebhook;let a;s&&o&&t.chatWebhooks.set(s,o),s&&i.conversationType&&t.conversationTypes.set(s,i.conversationType),s&&r&&t.senderIds.set(s,r);try{a=await this.parseChatGatewayCallbackAction(i.callbackData)}catch(e){if(Hu(e,"CHAT_PENDING_ACTION_STALE"))return Tp(Fu(e),void 0,"approval_stale",i.body,i.params);throw e}if(!a)return this.logWarn({bridgeId:e.id,chatId:s,userId:i.userId,senderId:r,...Gu(i)},"dingding card callback action unsupported"),Tp("Unsupported action",void 0,"unsupported",i.body,i.params);this.logInfo({bridgeId:e.id,chatId:s,userId:i.userId,senderId:r,actionType:a.type,...Gu(i)},"dingding card callback action parsed");const d=await this.service.handleChatGatewayAction({source:{channel:"dingding",bridgeId:e.id,chatSessionId:s,userId:i.userId||void 0},action:a});return"pending-decision"===a.type&&Du(d)?Tp(`${a.decision} sent`,void 0,"approval_done",i.body,i.params):Tp(ju(d)||Uu(d.message)||"updated",Mu(d),"updated",i.body,i.params)}async pollWechat(e,t=()=>!0){if(!e.token)return;const n=e.settings||{},i=this.wechatCursors.get(e.id)||Uu(n.updatesBuf),s=await async function(e){const t=lu((e.bridge.settings||{}).baseUrl)||"https://ilinkai.weixin.qq.com",n=await e.fetchImpl(`${t}/ilink/bot/getupdates`,{method:"POST",headers:{"content-type":"application/json",AuthorizationType:"ilink_bot_token",Authorization:`Bearer ${e.bridge.token}`,"X-WECHAT-UIN":String(Math.floor(Math.random()*2**31))},body:JSON.stringify({get_updates_buf:e.cursor,base_info:{channel_version:"1.0.2"}})}),i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(`HTTP ${n.status}`);const s=Number(i.errcode??i.ret??0);if(0!==s)throw new Error(lu(i.errmsg||i.msg)||`chat bridge API returned ${s}`);const r=[];for(const e of Array.isArray(i.msgs)?i.msgs:[]){const t=cu(e);if(1!==t.message_type)continue;const n=lu(t.from_user_id),i=du(t);n&&i&&r.push({chatId:n,text:i,contextToken:lu(t.context_token)})}return{cursor:lu(i.get_updates_buf),messages:r}}({fetchImpl:this.fetchImpl,bridge:e,cursor:i});if(t()){s.cursor&&(this.wechatCursors.set(e.id,s.cursor),this.updateChatBridge(e.id,{settings:{updatesBuf:s.cursor}}));for(const i of s.messages){if(!t())return;const{chatId:s,contextToken:r,text:o}=i;if(e.defaultChatId||this.updateChatBridge(e.id,{defaultChatId:s,settings:{contextToken:r}}),e.defaultChatId&&e.defaultChatId!==s)continue;const a=await this.service.handleChatGatewayMessage({source:{type:"chat-gateway",channel:"wechat",bridgeId:e.id,chatSessionId:s},message:{text:o,attachments:[]}});if(!t())return;const d=ju(a);if(d){const t=pu({fetchImpl:this.fetchImpl,bridge:e});await t.send(s,d,{contextToken:r||Uu(n.contextToken)})}}}}pollPendingRoutes(){return this.pendingRouteNotifier.poll()}async sendToChatBinding(e,t){if(!e.bridgeId)return!1;const n=this.service.requireChatBridge(e.bridgeId);if(!n.enabled)return!1;const i=await this.sendViaBridge(n,e.chatSessionId,t).catch(e=>{this.bridgeErrors.set(n.id,e instanceof Error?e.message:String(e))});return Boolean(i)}async sendViaBridge(e,t,n){const i="string"==typeof n?n:n.text,s="string"==typeof n?void 0:n.replyMarkup;return pu({fetchImpl:this.fetchImpl,bridge:e,dingdingRuntime:this.dingdingBridges.get(e.id),larkRuntime:this.larkBridges.get(e.id)}).send(t,i,{replyMarkup:s})}async pollTelegram(e,t=()=>!0){if(!e.token)return;const n=Number(e.settings?.telegramLastUpdateId),i=this.telegramOffsets.get(e.id)||(Number.isInteger(n)?n:void 0),s=await async function(e){const t=new URLSearchParams({timeout:"0",...e.offset?{offset:String(e.offset+1)}:{}}),n=await e.fetchImpl(`https://api.telegram.org/bot${e.bridge.token}/getUpdates?${t.toString()}`),i=await n.json().catch(()=>({}));if(!n.ok||!1===i.ok){if(409===n.status||/terminated by other getUpdates request/i.test(String(i.description||"")))return{updates:[],conflict:i.description||"Telegram getUpdates conflict: another bot instance is polling this token."};throw new Error(i.description||`Telegram getUpdates failed with HTTP ${n.status}`)}const s=[];for(const t of i.result||[]){const n=Number(t.update_id),i=Number.isInteger(n)?n:void 0,r=ru(t.callback_query);if(Object.keys(r).length>0){s.push({updateId:i,callbackQuery:r});continue}const o=ru(t.message||t.edited_message);if(0===Object.keys(o).length)continue;const a=ru(o.chat),d=ru(o.from),c=void 0!==a.id?String(a.id):e.bridge.defaultChatId,l=void 0!==d.id?String(d.id):void 0;if(!c)continue;const p=ou(o.text??o.caption),u=Zp(o);(p||0!==u.length)&&s.push({updateId:i,chatId:c,userId:l,text:p,rawText:p,message:o,messageId:su(o),replyToMessageId:su(ru(o.reply_to_message)),quoteText:ou(ru(o.quote).text),autoBegin:1===u.length&&!p.trim(),hasSingleImageWithoutText:1===u.length&&!p.trim()})}return{updates:s}}({fetchImpl:this.fetchImpl,bridge:e,offset:i});if(t())if(s.conflict)this.bridgeErrors.set(e.id,s.conflict);else for(const n of s.updates){if(!t())return;if(void 0!==n.updateId){const t=`${e.id}:${n.updateId}`;if(this.seenTelegramUpdates.has(t)||n.updateId<=(this.telegramOffsets.get(e.id)||0))continue;this.seenTelegramUpdates.add(t),this.telegramOffsets.set(e.id,n.updateId),this.updateChatBridge(e.id,{settings:{...e.settings,telegramLastUpdateId:n.updateId}})}if("callbackQuery"in n){const t=n.callbackQuery;await this.handleTelegramCallback(e,t).catch(async n=>{const i=Ku(t.message),s=Ku(i.chat),r=void 0!==s.id?String(s.id):e.defaultChatId;this.bridgeErrors.set(e.id,Fu(n)),r&&await this.sendTelegramMessage(e,r,`Action failed: ${Fu(n)}`).catch(t=>{this.bridgeErrors.set(e.id,Fu(t))})});continue}if(!this.telegramAllowed(e,n.userId))continue;const i=await nu({fetchImpl:this.fetchImpl,bridge:e,message:n.message,onImageDownloadError:({fileId:t,fileName:n,error:i})=>{this.logWarn({bridgeId:e.id,fileId:t,fileName:n,error:Fu(i)},"telegram image download skipped")}});if(!t())return;const s=n.rawText.trim();(s||i.length)&&(this.logInfo({bridgeId:e.id,chatId:n.chatId,messageId:n.messageId,replyToMessageId:n.replyToMessageId,hasQuote:Boolean(n.quoteText),textPreview:Wu(s)},"telegram chat gateway message received"),await this.telegramMessageAggregator.handleIncoming(e,n.chatId,n.userId,s,i,{sourceMessageId:n.messageId,replyToMessageId:n.replyToMessageId,quoteText:n.quoteText},{autoBegin:n.autoBegin}))}}async dispatchTelegramGatewayMessage(e,t,n,i,s=[],r={}){try{const o=void 0!==r.replyToMessageId?this.telegramReplyAiSessionTarget(e.id,t,r.replyToMessageId):void 0,a=function(e,t){const n=String(t||"").trim(),i=e.trim();return n?[`引用:${n}`,i].filter(Boolean).join("\n"):i}(i,r.quoteText),d=await this.service.handleChatGatewayMessage({source:{type:"chat-gateway",channel:"telegram",bridgeId:e.id,chatSessionId:t,userId:n},message:{text:a,attachments:s},...o?{target:{instanceId:o.instanceId,aiSessionId:o.sessionId}}:{}}),c=ju(d),l=Mu(d);if(c){const n=await this.sendTelegramMessage(e,t,c,{replyMarkup:l,replyToMessageId:r.sourceMessageId});this.logInfo({bridgeId:e.id,chatId:t,sourceMessageId:r.sourceMessageId,replyToMessageId:r.replyToMessageId,replyTargetInstanceId:o?.instanceId,replyTargetSessionId:o?.sessionId,sentMessageId:Number(Ku(n).message_id)||void 0,routed:!0===Ku(d).routed,replyPreview:Wu(c)},"telegram chat gateway reply sent"),await this.rememberTelegramProgressMessage(d,e,t,n,c)}}catch(n){this.bridgeErrors.set(e.id,Fu(n)),await this.sendTelegramMessage(e,t,`Failed to handle message: ${Fu(n)}`,{replyToMessageId:r.sourceMessageId}).catch(t=>{this.bridgeErrors.set(e.id,Fu(t))})}}async handleTelegramCallback(e,t){const n=Uu(t.data),i=Ku(t.from),s=Ku(t.message),r=Ku(s.chat),o=void 0!==r.id?String(r.id):e.defaultChatId,a=void 0!==i.id?String(i.id):void 0;if(!o||!this.telegramAllowed(e,a))return;if(await this.telegramAiSessionCallbacks.tryHandle(n,{bridge:e,chatId:o,callbackQueryId:Uu(t.id),userId:a,messageId:qu(s)}))return;const d=n.match(/^task_handoff:cp_msg_end:([^:]+)$/);if(d)return void await this.telegramMessageAggregator.handleEndCallback(e,o,Uu(t.id),d[1],a);let c;try{c=await this.parseChatGatewayCallbackAction(n)}catch(n){if(Hu(n,"CHAT_PENDING_ACTION_STALE")){await this.answerTelegramCallback(e,Uu(t.id),Fu(n));const i=qu(s);return void(void 0!==i&&await this.deleteTelegramStandaloneApprovalMessage(e,o,i))}throw n}if(!c)return void await this.answerTelegramCallback(e,Uu(t.id),"Unsupported action");const l=await this.service.handleChatGatewayAction({source:{channel:"telegram",bridgeId:e.id,chatSessionId:o,userId:a},action:c});if("pending-decision"===c.type&&Du(l)){await this.answerTelegramCallback(e,Uu(t.id),"");const n=qu(s);return void(void 0!==n&&await this.deleteTelegramStandaloneApprovalMessage(e,o,n))}await this.answerTelegramCallback(e,Uu(t.id),Uu(l.message)||"updated");const p=ju(l),u=Mu(l),g=s.message_id;p&&"number"==typeof g?await this.editTelegramMessage(e,o,g,p,{replyMarkup:u}):p&&await this.sendTelegramMessage(e,o,p,{replyMarkup:u})}async deleteTelegramStandaloneApprovalMessage(e,t,n){[...this.telegramProgress.entries.values()].find(i=>i.messageId===n&&i.route?.bridgeId===e.id&&i.route?.chatId===t)||await this.deleteTelegramMessage(e,t,n).catch(i=>{this.logWarn({bridgeId:e.id,chatId:t,messageId:n,error:Fu(i)},"telegram callback message delete failed")})}chatAiSessionBindingActive(e,t,n,i){return this.service.listChatSessions().some(s=>s.bridgeId===e.id&&s.chatSessionId===t&&s.activeInstanceId===n&&s.activeAiSessionId===i)}telegramAiSessionActionAllowed(e,t,n,i,s){if(this.chatAiSessionBindingActive(e,t,n,i))return!0;if(!Number.isInteger(s))return!1;const r=this.telegramReplyAiSessionTarget(e.id,t,s);return Boolean(r&&r.instanceId===n&&r.sessionId===i)}async parseChatGatewayCallbackAction(e){const t=function(e){const t=e.match(/^task_handoff:cp_p:v1:([ads]):([A-Za-z0-9_-]{16})$/);if(!t)return;const n=Object.entries(hl).find(([,e])=>e===t[1])?.[0];return"allow"===n||"deny"===n||"skip"===n?{routeFingerprint:t[2],decision:n}:void 0}(e);if(t){const e=(await this.service.listPendingRoutes()).filter(e=>"approval"===e.kind&&"pending"===e.status&&ml(e.id)===t.routeFingerprint);if(1!==e.length){const e=new Error("This approval is no longer pending.");throw Object.assign(e,{statusCode:409,code:"CHAT_PENDING_ACTION_STALE"}),e}return{type:"pending-decision",routeId:e[0].id,decision:t.decision}}return function(e,t){const n=e.match(/^task_handoff:cp_session:(\d+)$/);if(n)return{type:"ai-session",index:Number(n[1])};const i=e.match(/^task_handoff:cp_i:([^:]+)$/)||e.match(/^task_handoff:cp_instance_apps:([^:]+)$/);if(i)return i[0].startsWith("task_handoff:cp_i:")?{type:"instance-app-menu",instanceId:mp(t(i[1],"instance-app-menu").instanceId,"instanceId")}:{type:"instance-app-menu",instanceId:Ip(i[1])};const s=e.match(/^task_handoff:cp_a:([^:]+)$/)||e.match(/^task_handoff:cp_launch_app:([^:]+):([^:]+)$/);if(s){if(s[0].startsWith("task_handoff:cp_a:")){const e=t(s[1],"launch-app");return{type:"launch-app",instanceId:mp(e.instanceId,"instanceId"),appId:mp(e.appId,"appId")}}return{type:"launch-app",instanceId:Ip(s[1]),appId:Ip(s[2])}}const r=e.match(/^task_handoff:cp_p:([^:]+)$/);if(r){const e=t(r[1],"pending-decision");return{type:"pending-decision",routeId:mp(e.routeId,"routeId"),decision:yp(e.decision)}}const o=e.match(/^task_handoff:approval:([^:]+:ai:[^:]+):(allow|deny|skip)$/);return o?{type:"pending-decision",routeId:o[1],decision:o[2]}:void 0}(e,(e,t)=>this.service.resolveChatActionToken(e,t))}dingdingAllowed(e,t){const n=String(t||"").trim();return!!n&&(0===e.allowedUserIds.length?(e.allowedUserIds=[n],this.updateChatBridge(e.id,{allowedUserIds:e.allowedUserIds}),this.logInfo({bridgeId:e.id,userId:n},"dingding user bound"),!0):e.allowedUserIds.includes(n))}larkAllowed(e,t){const n=String(t||"").trim();return!!n&&(0===e.allowedUserIds.length?(e.allowedUserIds=[n],this.updateChatBridge(e.id,{allowedUserIds:e.allowedUserIds}),this.logInfo({bridgeId:e.id,userId:n},"lark user bound"),!0):e.allowedUserIds.includes(n))}telegramAllowed(e,t){const n=String(t||"").trim();return!!n&&(0===e.allowedUserIds.length?(e.allowedUserIds=[n],this.updateChatBridge(e.id,{allowedUserIds:e.allowedUserIds}),this.logInfo({bridgeId:e.id,userId:n},"telegram user bound"),!0):e.allowedUserIds.includes(n))}async answerTelegramCallback(e,t,n){return async function(e,t,n,i){t.token&&n&&await e(`https://api.telegram.org/bot${t.token}/answerCallbackQuery`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({callback_query_id:n,text:i.slice(0,200)})})}(this.fetchImpl,e,t,n)}async editTelegramMessage(e,t,n,i,s={}){return async function(e,t,n,i,s,r={}){if(t.token)return gp(n=>e(`https://api.telegram.org/bot${t.token}/editMessageText`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)}),"editMessageText",s,{chat_id:n,message_id:i,...r.replyMarkup?{reply_markup:r.replyMarkup}:{}},r)}(this.fetchImpl,e,t,n,i,s)}async sendTelegramMessage(e,t,n,i={}){return pp(this.fetchImpl,e,t,n,i)}async deleteTelegramMessage(e,t,n){return async function(e,t,n,i){if(!t.token||!Number.isInteger(i))return;const s=await e(`https://api.telegram.org/bot${t.token}/deleteMessage`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({chat_id:n,message_id:i})}),r=await s.json().catch(()=>({}));if(!s.ok||!1===r.ok)throw new Error(r.description||`Telegram deleteMessage failed with HTTP ${s.status}`)}(this.fetchImpl,e,t,n)}async rememberTelegramProgressMessage(e,t,n,i,s){if(!0!==e.routed)return;const r=Qu(e),{instanceId:o,sessionId:a,turnId:d}=r,c=Number(Ku(i).message_id);if(!(o&&a&&d&&Number.isInteger(c)))return void this.logWarn({bridgeId:t.id,chatId:n,instanceId:o,sessionId:a,turnId:d,turnIdSources:r.sources,messageId:Number.isInteger(c)?c:void 0,routed:e.routed},"telegram ai session progress message not remembered");const l=ig(o,a,d,t.id,n),p=this.telegramProgress.remember(l,c,s,{bridgeId:t.id,chatId:n});this.telegramProgressMessageTargets.set($u(t.id,n,c),{instanceId:o,sessionId:a,turnId:d,messageId:c}),this.deliveredAiSessionFingerprints.delete(l),this.logInfo({bridgeId:t.id,chatId:n,instanceId:o,sessionId:a,turnId:d,turnIdSources:r.sources,key:l,messageId:c,progressKeys:this.telegramProgressKeysFor(o,a,t.id,n),textPreview:Wu(s)},"telegram ai session progress message remembered"),"queue"===function(e){return e.aiSession&&"action"in e.aiSession?e.aiSession.action:void 0}(e)&&p?.messageId&&p.messageId!==c&&(this.telegramProgressMessageTargets.delete($u(t.id,n,p.messageId)),await this.deleteTelegramMessage(t,n,p.messageId).catch(e=>{this.logWarn({bridgeId:t.id,chatId:n,instanceId:o,sessionId:a,turnId:d,replacedMessageId:p.messageId,replacementMessageId:c,error:Fu(e)},"telegram queued progress message replacement cleanup failed")}))}telegramReplyAiSessionTarget(e,t,n){const i=this.telegramProgressMessageTargets.get($u(e,t,n));if(i)return i;for(const[i,s]of this.telegramProgress.entries)if(s.messageId===n&&s.route?.bridgeId===e&&s.route?.chatId===t){const s=Bu(i,e,t);if(s){const i={...s,messageId:n};return this.telegramProgressMessageTargets.set($u(e,t,n),i),i}}}async pollAiSessionUpdates(){this.logAiSessionDelivery({stage:"poll-tick"});const e=await this.service.listAiSessions({refresh:!0}).catch(()=>{});if(!e)return void this.logAiSessionDelivery({stage:"poll-no-snapshot"});const t=new Map(e.instances.map(e=>[e.instanceId,e.aiSessions]));this.logAiSessionDelivery({stage:"poll-snapshot",instanceCount:t.size,instances:[...t.entries()].map(([e,t])=>({instanceId:e,sessionCount:t.sessions?.length||0,runningCount:t.runningCount,waitingCount:t.waitingCount,updatedAt:t.updatedAt}))});const n=await this.aiSessionInstanceNames();for(const[e,i]of t)await this.deliverAiSessionSnapshot(e,i,n)}async deliverAiSessionSnapshot(e,t,n){const i=Array.isArray(t.sessions)?t.sessions:[];if(this.pruneAiSessionDeliveryState(e,new Set(i.map(e=>e.id))),0===i.length)return;const s=n||await this.aiSessionInstanceNames(),r=await this.aiSessionPendingApprovalRoutes(e);await this.deliverOwnedTelegramProgress(e,i,s,r),await this.deliverActiveBindingTelegramProgress(e,i,s,r)}pruneAiSessionDeliveryState(e,t){for(const[n,i]of this.telegramProgress.entries){const s=i.route?.bridgeId&&i.route.chatId?this.telegramProgressMessageTargets.get($u(i.route.bridgeId,i.route.chatId,i.messageId||0))||Bu(n,i.route.bridgeId,i.route.chatId):void 0;s&&s.instanceId===e&&!t.has(s.sessionId)&&(i.timer&&clearTimeout(i.timer),this.telegramProgress.entries.delete(n),this.deliveredAiSessionFingerprints.delete(n),i.route?.bridgeId&&i.route.chatId&&i.messageId&&this.telegramProgressMessageTargets.delete($u(i.route.bridgeId,i.route.chatId,i.messageId)))}}async deliverActiveBindingTelegramProgress(e,t,n,i){for(const s of this.service.listChatSessions()){if(!s.bridgeId||s.activeInstanceId!==e||!s.activeAiSessionId)continue;const r=t.find(e=>e.id===s.activeAiSessionId);if(!r)continue;const o=dg(n.get(e)||e,r),a=ag(r,o);if(!a){this.logAiSessionDelivery({stage:"skip-empty-text",instanceId:e,sessionId:r.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,status:r.status,phase:r.phase,activeTurnId:r.activeTurnId,latestTurn:Vu(lg(r))});continue}const d=sg(r);if(!d){this.logAiSessionDelivery({stage:"skip-empty-turn-id",instanceId:e,sessionId:r.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,status:r.status,phase:r.phase,activeTurnId:r.activeTurnId,latestTurn:Vu(lg(r))});continue}if(this.listTelegramOwnedProgressEntries(e).some(e=>e.route.bridgeId===s.bridgeId&&e.route.chatId===s.chatSessionId&&e.owner.sessionId===r.id&&e.owner.turnId===d))continue;const c=ig(e,r.id,d,s.bridgeId||"",s.chatSessionId),l=rg(r,o);if(!l||this.deliveredAiSessionFingerprints.get(c)===l){this.logAiSessionDelivery({stage:"skip-duplicate-fingerprint",instanceId:e,sessionId:r.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:d,key:c,hasFingerprint:Boolean(l),fingerprintMatched:this.deliveredAiSessionFingerprints.get(c)===l,latestTurn:Vu(lg(r)),textPreview:Wu(a)});continue}const p=eg({cancelCallbackData:this.telegramAiSessionCallbacks.cancelCallbackData(e,r.id),queueSteerCallbackData:t=>this.telegramAiSessionCallbacks.queueSteerCallbackData(e,r.id,t),queueDeleteMenuCallbackData:()=>this.telegramAiSessionCallbacks.queueDeleteMenuCallbackData(e,r.id),permissionCallbackData:(e,t)=>this.service.pendingDecisionCallbackData(e,t),pendingApproval:i.get(r.id)||tg(e,r),session:r});if(this.logAiSessionDelivery({stage:"attempt",instanceId:e,sessionId:r.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:d,key:c,relatedProgressKeys:this.telegramProgressKeysFor(e,r.id,s.bridgeId||"",s.chatSessionId),hasProgressEntry:this.telegramProgress.entries.has(c),status:r.status,phase:r.phase,activeTurnId:r.activeTurnId,latestTurn:Vu(lg(r)),textPreview:Wu(a)}),await this.updateChatAiSessionProgress(s,a,c,p).catch(t=>(this.bridgeErrors.set(s.bridgeId||"",t instanceof Error?t.message:String(t)),this.logWarn({bridgeId:s.bridgeId,chatId:s.chatSessionId,instanceId:e,sessionId:r.id,turnId:d,key:c,error:Fu(t)},"chat ai session progress update failed"),!1)))this.logAiSessionDelivery({stage:"delivered",instanceId:e,sessionId:r.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:d,key:c,textPreview:Wu(a)}),this.deliveredAiSessionFingerprints.set(c,l);else{if("telegram"===this.service.requireChatBridge(s.bridgeId).channel){const t=this.telegramProgress.entries.get(c),n=this.service.requireChatBridge(s.bridgeId);this.logAiSessionDelivery({stage:t?"telegram-update-not-delivered":"telegram-no-progress-entry",instanceId:e,sessionId:r.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:d,key:c,relatedProgressKeys:this.telegramProgressKeysFor(e,r.id,s.bridgeId||"",s.chatSessionId),bridgeEnabled:n.enabled,bridgeChannel:n.channel,progressMessageId:t?.messageId,progressLastText:Wu(t?.lastText),progressHasPending:Boolean(t?.pending),latestTurn:Vu(lg(r)),textPreview:Wu(a)});continue}await this.sendToChatBinding(s,{text:a}).catch(e=>(this.bridgeErrors.set(s.bridgeId||"",e instanceof Error?e.message:String(e)),!1))&&(this.logAiSessionDelivery({stage:"fallback-sent",instanceId:e,sessionId:r.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:d,key:c,textPreview:Wu(a)}),this.deliveredAiSessionFingerprints.set(c,l))}}}async deliverOwnedTelegramProgress(e,t,n,i){for(const s of this.listTelegramOwnedProgressEntries(e)){const r=this.service.requireChatBridge(s.route.bridgeId);if("telegram"!==r.channel||!r.enabled)continue;const o=this.matchTelegramOwnedProgressSession(s,t);if(!o)continue;const a={bridgeId:s.route.bridgeId,chatSessionId:s.route.chatId},d=dg(n.get(e)||e,o),c=ag(o,d),l=sg(o);if(!c||!l){this.logAiSessionDelivery({stage:"remembered-skip-turn-or-text",key:s.key,parsedTurnId:s.owner.turnId,currentTurnId:l,hasText:Boolean(c),instanceId:e,sessionId:o.id,bridgeId:s.route.bridgeId,chatId:s.route.chatId});continue}if(s.owner.turnId&&l!==s.owner.turnId){this.logAiSessionDelivery({stage:"remembered-skip-different-active-turn",key:s.key,ownerTurnId:s.owner.turnId,currentTurnId:l,instanceId:e,sessionId:o.id,bridgeId:s.route.bridgeId,chatId:s.route.chatId});continue}const p=l===s.owner.turnId?s.key:ig(e,o.id,l,s.route.bridgeId,s.route.chatId);if(p!==s.key&&this.telegramProgress.entries.has(p))continue;if(p!==s.key&&!this.rekeyTelegramOwnedProgress(s,p,{instanceId:e,sessionId:o.id,turnId:l}))continue;const u=rg(o,d);if(!u||this.deliveredAiSessionFingerprints.get(p)===u){this.logAiSessionDelivery({stage:"remembered-skip-fingerprint",key:s.key,hasFingerprint:Boolean(u),fingerprintMatched:this.deliveredAiSessionFingerprints.get(p)===u,instanceId:e,sessionId:o.id,bridgeId:s.route.bridgeId,chatId:s.route.chatId});continue}const g=eg({cancelCallbackData:this.telegramAiSessionCallbacks.cancelCallbackData(e,o.id),queueSteerCallbackData:t=>this.telegramAiSessionCallbacks.queueSteerCallbackData(e,o.id,t),queueDeleteMenuCallbackData:()=>this.telegramAiSessionCallbacks.queueDeleteMenuCallbackData(e,o.id),permissionCallbackData:(e,t)=>this.service.pendingDecisionCallbackData(e,t),pendingApproval:i.get(o.id)||tg(e,o),session:o}),h=await this.updateChatAiSessionProgress(a,c,p,g).catch(e=>(this.bridgeErrors.set(a.bridgeId||"",e instanceof Error?e.message:String(e)),!1));this.logAiSessionDelivery({stage:h?"remembered-delivered":"remembered-not-delivered",key:p,instanceId:e,sessionId:o.id,bridgeId:s.route.bridgeId,chatId:s.route.chatId,textPreview:Wu(c)}),h&&(this.telegramProgressMessageTargets.set($u(s.route.bridgeId,s.route.chatId,s.messageId),{instanceId:e,sessionId:o.id,turnId:l,messageId:s.messageId}),this.deliveredAiSessionFingerprints.set(p,u))}}rekeyTelegramOwnedProgress(e,t,n){return!!this.telegramProgress.rekey(e.key,t)&&(this.deliveredAiSessionFingerprints.delete(e.key),this.telegramProgressMessageTargets.set($u(e.route.bridgeId,e.route.chatId,e.messageId),{...n,messageId:e.messageId}),!0)}logAiSessionDelivery(e){this.logInfo(e,"telegram ai session delivery flow")}telegramProgressKeysFor(e,t,n,i){const s=`${e}:${t}:`,r=`:${n}:${i}`;return[...this.telegramProgress.entries.keys()].filter(e=>e.startsWith(s)&&e.endsWith(r))}listTelegramOwnedProgressEntries(e){const t=[];for(const[n,i]of this.telegramProgress.entries){if(!i.route?.bridgeId||!i.route.chatId||!Number.isInteger(i.messageId))continue;const s=this.telegramProgressMessageTargets.get($u(i.route.bridgeId,i.route.chatId,i.messageId))||Bu(n,i.route.bridgeId,i.route.chatId);s&&s.instanceId===e&&t.push({key:n,route:{bridgeId:i.route.bridgeId,chatId:i.route.chatId},messageId:i.messageId,owner:{...s,messageId:i.messageId}})}return t}matchTelegramOwnedProgressSession(e,t){const n=t.find(t=>t.id===e.owner.sessionId);if(n)return n;if(e.owner.turnId){const n=t.find(t=>t.activeTurnId===e.owner.turnId||lg(t)?.id===e.owner.turnId||lg(t)?.providerTurnId===e.owner.turnId);if(n)return n}}async updateChatAiSessionProgress(e,t,n,i){if(!e.bridgeId)return this.logAiSessionDelivery({stage:"chat-update-skip-missing-bridge",chatId:e.chatSessionId,key:n}),!1;const s=this.service.requireChatBridge(e.bridgeId);if(!s.enabled)return this.logAiSessionDelivery({stage:"chat-update-skip-bridge-state",bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,bridgeEnabled:s.enabled,bridgeChannel:s.channel}),!1;if("dingding"===s.channel){if(!this.dingdingBridges.get(s.id))return!1;const r=await this.dingdingBridges.applyProgressUpdate({bridge:s,key:n,chatId:e.chatSessionId,text:t,replyMarkup:Lu({actionRows:i})});return r&&this.logInfo({bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,textPreview:Wu(t)},"dingding ai session progress updated"),r}if("lark"===s.channel){const r=await this.larkBridges.applyProgressUpdate({bridge:s,key:n,chatId:e.chatSessionId,text:t,replyMarkup:Lu({actionRows:i})});return r&&this.logInfo({bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,textPreview:Wu(t)},"lark ai session progress updated"),r}if("telegram"!==s.channel)return!1;const r=this.telegramProgress.entries.get(n);if(!await this.telegramProgress.applyUpdate({bridge:s,key:n,chatId:e.chatSessionId,text:t,actionRows:i})){const t=this.telegramProgress.entries.get(n);return this.logAiSessionDelivery({stage:"telegram-update-returned-false",bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,progressMessageId:r?.messageId||t?.messageId,progressLastText:Wu(r?.lastText||t?.lastText),progressHasPending:Boolean(r?.pending||t?.pending)}),!1}return this.logInfo({bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,messageId:r?.messageId||this.telegramProgress.entries.get(n)?.messageId,textPreview:Wu(t)},r?"telegram ai session progress edited":"telegram ai session progress sent"),!0}async aiSessionInstanceNames(){return this.aiSessionInstanceNamesCache.get()}async aiSessionPendingApprovalRoutes(e){const t=await this.aiSessionPendingRoutesCache.get();return new Map(t.filter(t=>t.instanceId===e&&t.aiSessionId&&"approval"===t.kind).map(e=>[e.aiSessionId||"",e]))}}function ju(e){return"object"==typeof e&&e&&"reply"in e?String(e.reply||""):""}function Du(e){return"object"==typeof e&&null!==e&&!0===e.accepted}function Mu(e){const t="object"==typeof e&&e&&"replyMarkup"in e?e.replyMarkup:void 0;if(t&&"object"==typeof t&&!Array.isArray(t))return t}function Lu(e){const t=Array.isArray(e?.actionRows)?e.actionRows:void 0;return Sl(t||(Array.isArray(e?.actions)?e.actions:[]).map(e=>[e]))}function qu(e){const t=Number(e?.message_id);return Number.isInteger(t)?t:void 0}function $u(e,t,n){return[e,t,String(n)].join(":")}function Bu(e,t,n){const i=`:${t}:${n}`;if(!e.endsWith(i))return;const s=e.slice(0,-i.length).split(":"),r=s[0]||"",o=s[1]||"",a=s.slice(2).join(":")||void 0;return r&&o?{instanceId:r,sessionId:o,turnId:a}:void 0}function Uu(e){return"string"==typeof e?e:""}function Fu(e){return e instanceof Error?e.message:String(e)}function Hu(e,t){return Boolean(e&&"object"==typeof e&&"code"in e&&e.code===t)}function Wu(e,t=160){const n=String(e||"").replace(/\s+/g," ").trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-3))}...`}function Gu(e){const t=Ju(e.body.cardActionData||e.body.content),n=Ju(t.cardPrivateData||e.body.cardPrivateData||e.body.content);return{outTrackId:Uu(e.body.outTrackId),spaceId:Uu(e.body.spaceId),conversationType:e.conversationType,hasCallbackData:Boolean(e.callbackData),callbackDataPreview:Wu(e.callbackData,120),actionIds:[...Yu(n.actionIdList),...Yu(t.actionIdList),Uu(n.actionId),Uu(t.actionId),Uu(e.body.actionId)].filter(Boolean).slice(0,5),cardActionDataKeys:Object.keys(t).sort(),privateDataKeys:Object.keys(n).sort(),paramKeys:Object.keys(e.params).sort(),hasSessionWebhook:Boolean(e.sessionWebhook)}}function Vu(e){if(e)return{id:e.id,providerTurnId:e.providerTurnId,source:e.source,status:e.status,phase:e.phase,revision:e.revision,userPrompt:Wu(e.userPrompt,80),hasResponse:Boolean(e.lastMessage?.trim()||e.summary?.trim()),responsePreview:Wu(e.lastMessage||e.summary,80),updatedAt:e.updatedAt,observedAt:e.observedAt}}function Ku(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function Ju(e){if(e&&"object"==typeof e&&!Array.isArray(e))return e;if("string"==typeof e&&e.trim())try{return Ku(JSON.parse(e))}catch{return{}}return{}}function Yu(e){return Array.isArray(e)?e.map(e=>Uu(e)).filter(Boolean):[]}function Qu(e){const t=e.aiSession&&"session"in e.aiSession?e.aiSession:void 0,n=t?.session||(e.aiSession&&"id"in e.aiSession?e.aiSession:void 0);return{instanceId:e.instanceId||e.instance?.id||"",sessionId:e.aiSessionId||n?.id||e.binding?.activeAiSessionId||"",turnId:e.turnId||e.providerTurnId||t?.turnId||t?.providerTurnId||(n?sg(n):""),sources:{resultTurnId:e.turnId,resultProviderTurnId:e.providerTurnId,actionTurnId:t?.turnId,actionProviderTurnId:t?.providerTurnId,sessionActiveTurnId:n?.activeTurnId,latestTurnId:n?lg(n)?.id:void 0}}}const Xu=5,Zu=48;function eg(e){const{cancelCallbackData:t,queueSteerCallbackData:n,queueDeleteMenuCallbackData:i,permissionCallbackData:s,pendingApproval:r,session:o}=e,a="approval"===r?.kind?[[{text:"Allow",callbackData:s(r.id,"allow")},{text:"Skip",callbackData:s(r.id,"skip")},{text:"Deny",callbackData:s(r.id,"deny")}]]:[];if("running"!==o.status)return a;const d=(o.queue?.items||[]).filter(e=>"queued"===e.status).slice(0,Xu);return[...d.map((e,t)=>[{text:ng(e.message,t),callbackData:n(e.id)}]),d.length?[{text:"Delete Queue",callbackData:i()},{text:"Cancel",callbackData:t}]:[{text:"Cancel",callbackData:t}]]}function tg(e,t){if("approval"===t.phase)return{id:`${e}:ai:${t.id}`,kind:"approval"}}function ng(e,t){const n=`${t+1}. `,i=e.replace(/\s+/g," ").trim()||"Queued message",s=Math.max(8,Zu-n.length),r=Array.from(i);return`${n}${r.length>s?`${r.slice(0,Math.max(1,s-3)).join("")}...`:i}`}function ig(e,t,...n){return[e,t,...n].join(":")}function sg(e){const t=lg(e);return t?.id?t.id:Uu(e.activeTurnId)}function rg(e,t=""){const n=lg(e);return[t,n?.id||"",n?.status||e.status||"",n?.phase||e.phase||"",n?.lastMessage||"",n?.summary||"",n?.userPrompt||"",e.error||"",e.currentTool?.id||"",e.currentTool?.name||"",e.currentTool?.inputPreview||"",String(e.toolCallsSinceLastMessage??0),og(e)].join("\0")}function og(e){return(e.queue?.items||[]).map(e=>[e.id,e.status,e.message].join(":")).join("|")}function ag(e,t){const n=function(e,t){let n="";t?"waiting"===t.status&&"approval"===t.phase&&t.summary?.trim()?n=t.summary.trim():t.lastMessage?.trim()?n=t.lastMessage.trim():t.summary?.trim()&&(n=t.summary.trim()):"waiting"===e.status&&"approval"===e.phase&&e.summary?.trim()?n=e.summary.trim():e.lastMessage?.trim()?n=e.lastMessage.trim():e.summary?.trim()?n=e.summary.trim():e.error?.trim()&&(n="failed"===e.status?`${e.agent} session failed:\n${e.error.trim()}`:e.error.trim());const i=function(e){if(e.currentTool?.name)return`Thinking... · ${e.currentTool.name}${e.currentTool.inputPreview?` · ${e.currentTool.inputPreview}`:""}`;const t=e.toolCallsSinceLastMessage??0;return t>0?`Thinking... · ${t} ${1===t?"tool":"tools"} completed`:""}(e);return[n,i&&!cg(n,e)?i:""].filter(Boolean).join("\n\n")}(e,lg(e));return n?`${t}\n${n}`:""}function dg(e,t){const n=["idle"===t.status?"completed":t.status,t.phase&&"unknown"!==t.phase?t.phase:void 0].filter(Boolean).join("/");return`${e} · ${t.agent||"ai"} ${n||"unknown"}`}function cg(e,t){if("waiting"!==t.status||"approval"!==t.phase)return!1;const n=t.currentTool?.inputPreview?.trim();return Boolean(n&&e.includes(n))}function lg(e){return(e.turns||[]).filter(e=>e.id||e.userPrompt?.trim()||e.lastMessage?.trim()||e.summary?.trim()).at(-1)}class pg{clients=new Set;listeners=new Set;seq=0;connect(e,t={}){e.topics=new Set(["*"]),e.instanceIds=t.instanceIds?.length?new Set(t.instanceIds):void 0,this.clients.add(e),e.on("close",()=>{this.clients.delete(e)}),e.on("message",t=>{const n=function(e){try{const t=JSON.parse(String(e||"{}"));if(!t||"object"!=typeof t)return;const n=t;return{type:n.type,topics:Array.isArray(n.topics)?n.topics.map(String).filter(Boolean):void 0,instanceIds:Array.isArray(n.instanceIds)?n.instanceIds.map(String).map(e=>e.trim()).filter(Boolean):void 0}}catch{return}}(t);"subscribe"===n?.type&&(e.topics=new Set(n.topics?.length?n.topics:["*"]),e.instanceIds=n.instanceIds?.length?new Set(n.instanceIds):void 0)})}publish(e,t,n={}){const i=this.createEvent(e,t,n),s=i.topic,r=JSON.stringify(i);for(const e of this.listeners)try{e(i)}catch{this.listeners.delete(e)}for(const t of this.clients)if(t.readyState===t.OPEN&&ug(t.topics,s,e)&&gg(t.instanceIds,i.scope))try{t.send(r)}catch{this.clients.delete(t)}return i}on(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}send(e,t,n,i={}){const s=this.createEvent(t,n,i);return e.send(JSON.stringify(s)),s}createEvent(e,t,n={}){return{v:1,id:`evt_${Date.now().toString(36)}_${Math.random().toString(16).slice(2)}`,seq:++this.seq,type:e,topic:n.topic||Qr(e),createdAt:(new Date).toISOString(),payload:t,scope:n.scope}}}function ug(e,t,n){return!e||e.has("*")||e.has(t)||e.has(n)}function gg(e,t){return!e||!t?.instanceId||e.has(t.instanceId)}const hg={"image/bmp":".bmp","image/gif":".gif","image/jpeg":".jpg","image/png":".png","image/webp":".webp"},mg=a.z.object({instanceId:a.z.string().trim().min(1).max(120),sessionId:a.z.string().trim().min(1).max(120),kind:a.z.enum(["image","file"]),name:a.z.string().trim().min(1).max(240),mime:a.z.string().trim().min(1).max(120),data:a.z.string().min(1).max(31457280)}).strict();function yg(){return t.join(y.tmpdir(),"task-handoff-ai-session-attachments")}class fg{items=new Map;ttlMs;constructor(e=864e5){this.ttlMs=e,this.pruneOrphanFiles()}upload(e){this.pruneExpired();const s=mg.parse(e),r=function(e,t){const n=/^data:([^;,]+);base64,(.+)$/i.exec(e.trim()),i=n?.[1]||t,s=n?.[2]||e;return{mime:i,buffer:Buffer.from(s,"base64")}}(s.data,s.mime),o=r.mime.toLowerCase(),a=hg[o]||"";if("image"===s.kind&&!a)throw new Error(`Unsupported image type: ${o}`);const d="image"===s.kind?r.buffer.length>E:r.buffer.length>=C;if(!r.buffer.length||d)throw new Error("image"===s.kind?"Image must be between 1 byte and 20971520 bytes.":"File must be smaller than 512000 bytes.");const c=`att_${i.randomUUID().replace(/-/g,"").slice(0,24)}`,l=new Date,p=new Date(l.getTime()+this.ttlMs),u=yg();n.mkdirSync(u,{recursive:!0});const g=function(e){return t.basename(e).replace(/[^\w.\- ()\u4e00-\u9fff]/g,"_").slice(0,160)||"attachment"}(s.name),h=t.join(u,`${c}-${g.endsWith(a)?g:`${g}${a}`}`);n.writeFileSync(h,r.buffer);const m={id:c,instanceId:s.instanceId,sessionId:s.sessionId,kind:s.kind,name:g,mime:o,size:r.buffer.length,source:{type:"inline",encoding:"base64",data:r.buffer.toString("base64")},path:h,createdAt:l.toISOString(),expiresAt:p.toISOString()};return this.items.set(c,m),this.publicAttachment(m)}resolveRefs(e,t,n){this.pruneExpired();const i=a.z.array(oe).max(6).default([]).parse(e),s=i.map(e=>"runtime-path"===e.source.type?se.parse(e):this.requireAttachment(e,t,n));if(s.reduce((e,t)=>e+("inline"===t.source.type?t.size:0),0)>x)throw new Error("Inline attachments must be 41943040 bytes or less in total.");for(const e of i)"upload-ref"===e.source.type&&this.consumeAttachment(e.id);return s}dispose(){for(const e of[...this.items.keys()])this.consumeAttachment(e)}requireAttachment(e,t,n){const i=this.items.get(e.id);if(!i)throw new Error(`AI session attachment not found or expired: ${e.id}`);if(e.kind&&e.kind!==i.kind)throw new Error(`AI session attachment kind mismatch: ${e.id}`);if(i.instanceId!==t||i.sessionId!==n)throw new Error(`AI session attachment scope mismatch: ${e.id}`);return se.parse({id:i.id,kind:i.kind,name:i.name,mime:i.mime,size:i.size,source:i.source})}consumeAttachment(e){const t=this.items.get(e);if(t){this.items.delete(e);try{n.unlinkSync(t.path)}catch{}}}publicAttachment(e){return{id:e.id,kind:e.kind,name:e.name,mime:e.mime,size:e.size,expiresAt:e.expiresAt}}pruneExpired(){const e=Date.now();for(const[t,i]of this.items)if(!(Date.parse(i.expiresAt)>e)){this.items.delete(t);try{n.unlinkSync(i.path)}catch{}}this.pruneOrphanFiles()}pruneOrphanFiles(){const e=yg();let i;try{i=n.readdirSync(e)}catch{return}const s=Date.now()-Math.max(this.ttlMs,864e5);for(const r of i){const i=t.join(e,r);try{n.statSync(i).isFile()&&n.statSync(i).mtimeMs<=s&&n.unlinkSync(i)}catch{}}}}const Ig={controlPlaneAuthBoundary:"public"},bg={controlPlaneAuthBoundary:"public-ui"},vg={controlPlaneAuthBoundary:"proxy-binding"},wg={controlPlaneAuthBoundary:"node-tunnel"};function Sg(e,t=Math.random){const n=Math.max(1,Math.floor(e));if(1===n)return 0;if(2===n)return 250;const i=Math.min(6e4,250*2**(n-2));return Math.min(6e4,Math.round(i*(.75+.5*t())))}class Ag{retryNumber=0;random;constructor(e=Math.random){this.random=e}get attempts(){return this.retryNumber}next(){return this.retryNumber+=1,{attempt:this.retryNumber,delay:Sg(this.retryNumber,this.random)}}reset(){this.retryNumber=0}}class zg{backoff;timer;constructor(e=Math.random){this.backoff=new Ag(e)}get pending(){return Boolean(this.timer)}get attempts(){return this.backoff.attempts}schedule(e,t={}){if(this.timer)return;const n=this.backoff.next(),i=t.setTimeoutFn||setTimeout;return this.timer=i(()=>{this.timer=void 0,e()},n.delay),n}reset(e=clearTimeout){this.timer&&e(this.timer),this.timer=void 0,this.backoff.reset()}cancel(e=clearTimeout){this.timer&&e(this.timer),this.timer=void 0}}class kg extends zg{}function Tg(e,t){return Number.isFinite(e)&&Number(e)>0?Number(e):t}function Eg(e){if(!e.length)return;const t=[...e].sort((e,t)=>e-t);return t[Math.ceil(.95*t.length)-1]}function Cg(e){return e.unref?.(),e}class xg{connectTimeoutMs;handshakeTimeoutMs;heartbeatIntervalMs;heartbeatTimeoutMs;stableThresholdMs;now;setTimeoutFn;clearTimeoutFn;ping;onTimeout;onStable;onPhase;connectTimer;handshakeTimer;heartbeatTimer;stableTimer;awaitingPongSince;stable=!1;stopped=!1;currentPhase="connecting";lastActivityAt;lastPongAt;pingRttMs;recentPingRttMs=[];constructor(e){this.connectTimeoutMs=Tg(e.connectTimeoutMs,1e4),this.handshakeTimeoutMs=Tg(e.handshakeTimeoutMs,1e4),this.heartbeatIntervalMs=Tg(e.heartbeatIntervalMs,25e3),this.heartbeatTimeoutMs=Tg(e.heartbeatTimeoutMs,1e4),this.stableThresholdMs=Tg(e.stableThresholdMs,6e4),this.now=e.now||Date.now,this.setTimeoutFn=e.setTimeoutFn||setTimeout,this.clearTimeoutFn=e.clearTimeoutFn||clearTimeout,this.ping=e.ping,this.onTimeout=e.onTimeout,this.onStable=e.onStable,this.onPhase=e.onPhase}get phase(){return this.currentPhase}start(){this.stopped=!1,this.setPhase("connecting"),this.clearTimer("connectTimer"),this.connectTimer=Cg(this.setTimeoutFn(()=>this.timeout("connect"),this.connectTimeoutMs))}opened(){this.stopped||(this.clearTimer("connectTimer"),this.setPhase("handshaking"),this.handshakeTimer=Cg(this.setTimeoutFn(()=>this.timeout("handshake"),this.handshakeTimeoutMs)),this.scheduleHeartbeat(this.heartbeatIntervalMs))}healthy(){this.stopped||(this.clearTimer("handshakeTimer"),this.activity(),this.setPhase("healthy"),this.stable||this.stableTimer||(this.stableTimer=Cg(this.setTimeoutFn(()=>{this.stableTimer=void 0,this.stopped||"healthy"!==this.currentPhase||(this.stable=!0,this.onStable?.())},this.stableThresholdMs))))}activity(){this.stopped||(this.lastActivityAt=this.now())}pong(){if(this.stopped)return;const e=this.now();void 0!==this.awaitingPongSince&&(this.pingRttMs=Math.max(0,e-this.awaitingPongSince),this.recentPingRttMs.push(this.pingRttMs),this.recentPingRttMs.length>20&&this.recentPingRttMs.shift()),this.awaitingPongSince=void 0,this.lastPongAt=e,this.lastActivityAt=e,this.scheduleHeartbeat(this.heartbeatIntervalMs)}close(){this.stopped||(this.stopped=!0,this.clearTimers(),this.awaitingPongSince=void 0,this.setPhase("closed"))}diagnostics(){return{phase:this.currentPhase,stable:this.stable,...void 0===this.pingRttMs?{}:{pingRttMs:this.pingRttMs},...this.recentPingRttMs.length?{pingRttP95Ms:Eg(this.recentPingRttMs)}:{},...void 0===this.lastActivityAt?{}:{lastActivityAt:new Date(this.lastActivityAt).toISOString()},...void 0===this.lastPongAt?{}:{lastPongAt:new Date(this.lastPongAt).toISOString()}}}scheduleHeartbeat(e){this.stopped||(this.clearTimer("heartbeatTimer"),this.heartbeatTimer=Cg(this.setTimeoutFn(()=>{if(this.heartbeatTimer=void 0,!this.stopped){if(void 0!==this.awaitingPongSince){const e=Math.max(0,this.now()-this.awaitingPongSince);return e>=this.heartbeatTimeoutMs?void this.timeout("heartbeat"):void this.scheduleHeartbeat(this.heartbeatTimeoutMs-e)}this.awaitingPongSince=this.now();try{this.ping()}catch{return void this.timeout("heartbeat")}this.scheduleHeartbeat(this.heartbeatTimeoutMs)}},e)))}timeout(e){this.stopped||(this.clearTimers(),this.setPhase("failed"),this.onTimeout(e))}setPhase(e){this.currentPhase!==e&&(this.currentPhase=e,this.onPhase?.(e))}clearTimers(){this.clearTimer("connectTimer"),this.clearTimer("handshakeTimer"),this.clearTimer("heartbeatTimer"),this.clearTimer("stableTimer")}clearTimer(e){const t=this[e];t&&this.clearTimeoutFn(t),this[e]=void 0}}class Ng{transport;constructor(e){this.transport=e}attachMain(e,t){this.transport.attach(e,t),t.send(JSON.stringify({type:"control-plane.hello",protocolVersion:"2026-08-01",nodeId:e,serverTime:(new Date).toISOString(),capabilities:{reverseTunnel:"request-response",auxiliaryChannels:!0,httpResponseStreaming:!0,lifecycleCommands:!0,instanceApiProxy:!0}})),t.on("message",n=>this.handleMainMessage(e,t,n))}attachAuxiliary(e,t,n){return this.transport.attachAuxiliary(e,t,n)}handleMainMessage(e,t,n){if(!this.transport.isCurrentSocket(e,t))return;let i;try{i=JSON.parse(String(n))}catch{return void t.send(JSON.stringify({type:"control-plane.error",code:"INVALID_JSON"}))}const s=i&&"object"==typeof i?i:{},r=this.transport.handleSocketMessage(e,t,s);if(void 0!==r&&!r){if("node-agent.ping"!==s.type)return"node-agent.identify"===s.type?(this.transport.markHealthy(e,t),void t.send(JSON.stringify({type:"control-plane.identified",nodeId:e,serverTime:(new Date).toISOString()}))):void t.send(JSON.stringify({type:"control-plane.error",code:"UNSUPPORTED_MESSAGE"}));t.send(JSON.stringify({type:"control-plane.pong",nodeId:e,serverTime:(new Date).toISOString()}))}}}const Og={[N]:rt,[O]:ot,[_]:at,[R]:dt,[P]:ct,[mt]:Et,[yt]:Ct,[ft]:xt},_g=new Set(Object.keys(Og));class Rg{options;validatedScopes=new Map;validatingScopes=new Map;eventQueues=new Map;scopeEpochs=new Map;constructor(e={}){this.options=e}handle(e,t){const n="string"==typeof t.type?t.type:"";if("node-agent.streams.hello"===n){const n="string"==typeof t.instanceId?t.instanceId:"",i=$o(eo,t.payload);return n&&i.success&&this.enqueue(e,n,()=>this.options.onStreamsHello?.(n,i.data)),!0}if(!n.startsWith("node-agent.event."))return!1;const i=Pg(t.event),s="string"==typeof i?.type?i.type:"";if(!s)return!0;const r="payload"in i?i.payload:{},o=Pg(i.scope)||{},a="string"==typeof t.instanceId?t.instanceId:void 0,d=function(...e){return e.find(e=>"string"==typeof e)}(o.instanceId,i.instanceId,a);if("instance.metrics.snapshot"===s){const t=$o(fr,r);return!t.success||t.data.instanceId!==d||(this.enqueue(e,t.data.instanceId,()=>{this.options.events?.publish(s,t.data,{topic:"instances",scope:{...o,nodeId:e,instanceId:t.data.instanceId}})}),!0)}if(s===Mr){const t=$o(Lr,r);return!t.success||t.data.instanceId!==d||(this.enqueue(e,t.data.instanceId,()=>{this.options.events?.publish(s,t.data,{topic:"instances",scope:{...o,nodeId:e,instanceId:t.data.instanceId}})}),!0)}if(s===or||s===ar){const t=$o(s===or?cr:lr,r);return!t.success||t.data.instanceId!==d||(this.enqueue(e,t.data.instanceId,()=>{this.options.events?.publish(s,t.data,{topic:"instances",scope:{...o,nodeId:e,instanceId:t.data.instanceId}})}),!0)}if(_g.has(s)){const t=function(e,t){const n=Og[e];if(!n)return;const i=$o(n,t);if(!i.success)return;const s=i.data;return{instanceId:"meta"in s?s.meta.instanceId:s.instanceId,payload:s}}(s,r);return!t||([o.instanceId,i.instanceId,a].filter(e=>"string"==typeof e&&Boolean(e)).some(e=>e!==t.instanceId)||this.enqueue(e,t.instanceId,()=>{const n={...o,nodeId:e,instanceId:t.instanceId},r={v:1,id:"string"==typeof i.id?i.id:`forwarded_${Date.now().toString(36)}`,seq:"number"==typeof i.seq?i.seq:0,type:s,topic:"string"==typeof i.topic?i.topic:s.startsWith("app-session.")?"app.sessions":"ai.sessions",createdAt:"string"==typeof i.createdAt?i.createdAt:(new Date).toISOString(),payload:t.payload,scope:n};this.options.onSessionEvent&&!this.options.onSessionEvent(r)||this.options.events?.publish(s,t.payload,{topic:r.topic,scope:n})}),!0)}const c=()=>{this.options.events?.publish(s,r,{topic:"string"==typeof i.topic?i.topic:void 0,scope:{...o,nodeId:e,...d?{instanceId:d}:{}}})};return d?this.enqueue(e,d,c):c(),!0}invalidate(e={}){const t=new Set;for(const[n,i]of this.validatedScopes)e.nodeId&&i.nodeId!==e.nodeId||e.instanceId&&i.instanceId!==e.instanceId||t.add(n);for(const n of new Set([...this.validatingScopes.keys(),...this.eventQueues.keys()])){const[i,s]=Dg(n);e.nodeId&&i!==e.nodeId||e.instanceId&&s!==e.instanceId||t.add(n)}for(const e of t)this.scopeEpochs.delete(e),this.validatedScopes.delete(e),this.validatingScopes.delete(e),this.eventQueues.delete(e)}diagnostics(){return{validatedScopes:this.validatedScopes.size,validatingScopes:this.validatingScopes.size,queuedScopes:this.eventQueues.size,scopeEpochs:this.scopeEpochs.size}}enqueue(e,t,n){const i=jg(e,t),s=this.scopeEpoch(i),r=(this.eventQueues.get(i)||Promise.resolve()).catch(()=>{}).then(async()=>{this.scopeEpochs.get(i)===s&&await this.isScopeValid(e,t,s)&&this.scopeEpochs.get(i)===s&&await n()});this.eventQueues.set(i,r);const o=()=>{this.eventQueues.get(i)===r&&this.eventQueues.delete(i),this.scopeEpochs.get(i)!==s||this.eventQueues.has(i)||this.validatingScopes.has(i)||this.scopeEpochs.delete(i)};r.then(o,o)}async isScopeValid(e,t,n){const i=jg(e,t);if((this.validatedScopes.get(i)?.expiresAt||0)>Date.now())return!0;const s=this.validatingScopes.get(i);if(s)return s;const r=Promise.resolve(this.options.validateInstanceScope?.(e,t)).then(Boolean).catch(()=>!1).then(s=>(s&&this.scopeEpochs.get(i)===n&&this.validatedScopes.set(i,{nodeId:e,instanceId:t,expiresAt:Date.now()+(this.options.scopeTtlMs??3e4)}),s));return this.validatingScopes.set(i,r),r.finally(()=>{this.validatingScopes.get(i)===r&&this.validatingScopes.delete(i)})}scopeEpoch(e){const t=this.scopeEpochs.get(e);if(t)return t;const n={};return this.scopeEpochs.set(e,n),n}}function Pg(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:void 0}function jg(e,t){return JSON.stringify([e,t])}function Dg(e){const t=JSON.parse(e);return Array.isArray(t)&&2===t.length?[String(t[0]),String(t[1])]:["",""]}const Mg=a.z.object({nodeId:a.z.string().trim().min(1).max(120)}).strict();class Lg{OPEN=1;readyState=this.OPEN;listeners=new Map;pingUpstream;on(e,t){const n=this.listeners.get(e)||new Set;n.add(t),this.listeners.set(e,n)}send(e){this.readyState===this.OPEN&&this.emit("message",e,!1)}ping(){this.readyState===this.OPEN&&this.pingUpstream?.()}control(e,t){this.pingUpstream=e,t?.(()=>this.emit("pong"))}opened(){this.readyState===this.OPEN&&this.emit("open")}terminate(){this.close(1006)}close(e=1e3,t=""){this.readyState===this.OPEN&&(this.readyState=3,this.emit("close",e,Buffer.from(t)))}emit(e,...t){for(const n of this.listeners.get(e)||[])n(...t)}}function qg(){return`req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}const $g=new Map;function Bg(e,t){if("paired-hmac"!==e.auth.mode||!e.auth.keyId||!e.auth.secret){const e=new Error("Reverse tunnel requires paired-HMAC node auth.");throw Object.assign(e,{statusCode:401,code:"NODE_AGENT_TUNNEL_REQUIRES_PAIRED_HMAC"}),e}const n=function(e){const t=new Map;for(const[n,i]of Object.entries(e)){const e=Array.isArray(i)?i.join(","):"string"==typeof i?i:void 0===i?"":String(i);t.set(n.toLowerCase(),e)}return{nodeId:t.get("x-taskhandoff-node-id")||"",keyId:t.get("x-taskhandoff-key-id")||"",timestamp:t.get("x-taskhandoff-timestamp")||"",nonce:t.get("x-taskhandoff-nonce")||"",bodySha256:t.get("x-taskhandoff-body-sha256")||"",signature:t.get("x-taskhandoff-signature")||""}}(t.headers);if(n.nodeId!==e.id)throw Object.assign(new Error("Invalid reverse tunnel node id."),{statusCode:401,code:"NODE_AGENT_TUNNEL_NODE_MISMATCH"});if(n.keyId!==e.auth.keyId)throw Object.assign(new Error("Invalid reverse tunnel key id."),{statusCode:401,code:"NODE_AGENT_TUNNEL_KEY_INVALID"});const s=Date.parse(n.timestamp);if(!Number.isFinite(s)||Math.abs(Date.now()-s)>td)throw Object.assign(new Error("Reverse tunnel timestamp is outside the allowed window."),{statusCode:401,code:"NODE_AGENT_TUNNEL_TIMESTAMP_INVALID"});const r=Date.now()-td;for(const[e,t]of $g)t<=r&&$g.delete(e);const o=`${e.id}:${n.keyId}:${n.nonce}`;if(!n.nonce||$g.has(o))throw Object.assign(new Error("Reverse tunnel nonce is invalid."),{statusCode:401,code:"NODE_AGENT_TUNNEL_NONCE_INVALID"});const a=sd("");if(n.bodySha256!==a)throw Object.assign(new Error("Reverse tunnel body hash is invalid."),{statusCode:401,code:"NODE_AGENT_TUNNEL_BODY_HASH_INVALID"});const d=t.url||`${nd}?nodeId=${encodeURIComponent(e.id)}`,c=rd(e.auth.secret,{keyId:n.keyId,method:"GET",pathWithQuery:d,timestamp:n.timestamp,nonce:n.nonce,bodySha256:a});if(!function(e,t){const n=Buffer.from(e,"hex"),s=Buffer.from(t,"hex");return n.length===s.length&&i.timingSafeEqual(n,s)}(n.signature,c))throw Object.assign(new Error("Reverse tunnel signature is invalid."),{statusCode:401,code:"NODE_AGENT_TUNNEL_SIGNATURE_INVALID"});$g.set(o,Date.now()+td)}function Ug(e){return e?e instanceof Headers?Object.fromEntries(e.entries()):Array.isArray(e)?Object.fromEntries(e.map(([e,t])=>[e,t])):Object.fromEntries(Object.entries(e).map(([e,t])=>[e,String(t)])):{}}class Fg{sockets=new Map;eventRouter;httpStreamHeaderTimeoutMs;requestTimeoutMs;auxiliaryAttachTimeoutMs;connectionRuntime;connectionOptions;constructor(e,t={}){this.eventRouter=new Rg({events:e,onStreamsHello:t.onStreamsHello,onSessionEvent:t.onSessionEvent,validateInstanceScope:t.validateInstanceScope}),this.httpStreamHeaderTimeoutMs=t.httpStreamHeaderTimeoutMs??3e4,this.requestTimeoutMs=t.requestTimeoutMs??3e4,this.auxiliaryAttachTimeoutMs=t.auxiliaryAttachTimeoutMs??3e4,this.connectionRuntime=t.connectionRuntime,this.connectionOptions=t}attach(e,t){const n=this.sockets.get(e);if(n?.socket===t)return;n&&this.invalidateInstanceScope({nodeId:e});const i=new Map,s={socket:t,runtimeGeneration:this.connectionRuntime?.begin(e,"reverse-wss","handshaking"),pending:i,streams:new Map,httpStreams:new Map,pendingChannels:new Map},r=new xg({...this.connectionOptions,ping:()=>t.ping?.(),onTimeout:n=>{this.sockets.get(e)===s&&(void 0!==s.runtimeGeneration&&this.connectionRuntime?.update(e,s.runtimeGeneration,{phase:"suspect",error:`Reverse tunnel ${n} timeout.`}),t.terminate?t.terminate():t.close?.(1011,`Reverse tunnel ${n} timeout.`))},onStable:()=>{void 0!==s.runtimeGeneration&&this.connectionRuntime?.stable(e,s.runtimeGeneration)}});s.supervisor=r,this.sockets.set(e,s),r.start(),r.opened(),t.on?.("pong",()=>{this.sockets.get(e)===s&&(r.pong(),void 0!==s.runtimeGeneration&&this.connectionRuntime?.pong(e,s.runtimeGeneration))}),t.on?.("close",()=>this.detach(e,t)),t.on?.("error",()=>this.detach(e,t)),n&&n.socket!==t&&this.finalizeConnection(n,new Error(`Reverse tunnel for node ${e} was replaced.`),"Reverse tunnel was replaced.",!0)}detach(e,t){const n=this.sockets.get(e);!n||t&&n.socket!==t||(this.sockets.delete(e),n.supervisor?.close(),void 0!==n.runtimeGeneration&&this.connectionRuntime?.disconnected(e,n.runtimeGeneration,{error:"Reverse tunnel disconnected."}),this.invalidateInstanceScope({nodeId:e}),this.finalizeConnection(n,new Error(`Reverse tunnel for node ${e} disconnected.`),"Reverse tunnel disconnected.",!0))}disconnect(e,t="Node connection disabled locally."){const n=this.sockets.get(e);return!!n&&(this.detach(e,n.socket),n.socket.close?.(1e3,t),!0)}connected(e){return this.sockets.has(e)}markHealthy(e,t){const n=this.sockets.get(e);return!(!n||n.socket!==t||void 0===n.runtimeGeneration)&&(n.supervisor?.healthy(),this.connectionRuntime?.connected(e,n.runtimeGeneration)??!0)}finalizeConnection(e,t,n,i){e.supervisor?.close();for(const n of[...e.pending.keys()])this.cancelPendingRequest(e,n,t,!1);for(const[t,i]of e.streams)e.streams.delete(t),i.downstream.close(1011,n);for(const i of[...e.httpStreams.keys()])this.cancelHttpStream(e,i,t,n,!1);for(const t of e.pendingChannels.values())clearTimeout(t.timer);if(e.pendingChannels.clear(),i&&e.socket.close&&3!==e.socket.readyState)try{e.socket.close(1e3,n)}catch{}}isCurrentSocket(e,t){return this.sockets.get(e)?.socket===t}handleSocketMessage(e,t,n){if(this.isCurrentSocket(e,t))return this.handleMessage(e,n)}handleMessage(e,t){if(this.eventRouter.handle(e,t))return!0;if(this.handleWebSocketMessage(e,t))return!0;if("node-agent.response"!==t.type)return!1;const n="string"==typeof t.requestId?t.requestId:"",i=this.sockets.get(e),s=i?.pending.get(n);if(!s||!i)return!0;i.pending.delete(n),clearTimeout(s.timer),s.signal&&s.onAbort&&s.signal.removeEventListener("abort",s.onAbort);const r=Number(t.status)||502,o=t.headers&&"object"==typeof t.headers?t.headers:{},a="string"==typeof t.body?t.body:"";if(t.error&&"object"==typeof t.error){const e=t.error,n=new Error("string"==typeof e.message?e.message:`Reverse tunnel request failed with HTTP ${r}`);return Object.assign(n,{statusCode:r,code:"string"==typeof e.code?e.code:"NODE_AGENT_REVERSE_REQUEST_FAILED"}),s.reject(n),!0}return s.resolve(new Response(a,{status:r,headers:o})),!0}invalidateInstanceScope(e={}){this.eventRouter.invalidate(e)}instanceScopeDiagnostics(){return this.eventRouter.diagnostics()}async request(e,t,n={}){const i=this.sockets.get(e.id);if(!i){const t=new Error(`Reverse tunnel for node ${e.id} is not connected.`);throw Object.assign(t,{statusCode:503,code:"NODE_AGENT_REVERSE_TUNNEL_OFFLINE"}),t}const s=qg(),r=zi(n.body),o={type:"control-plane.request",requestId:s,route:t,init:{method:n.method||"GET",headers:Ug(n.headers),body:r}};return new Promise((r,a)=>{let d;if(d={resolve:r,reject:a,timer:setTimeout(()=>{const n=new Error(`Reverse tunnel request to ${e.id}${t} timed out.`);Object.assign(n,{statusCode:504,code:"NODE_AGENT_REVERSE_REQUEST_TIMEOUT"}),this.cancelPendingRequest(i,s,n)},this.requestTimeoutMs),signal:n.signal||void 0},n.signal&&(d.onAbort=()=>{this.cancelPendingRequest(i,s,Object.assign(new Error("Reverse tunnel request was aborted."),{name:"AbortError",code:"ABORT_ERR"}))},n.signal.addEventListener("abort",d.onAbort,{once:!0})),i.pending.set(s,d),n.signal?.aborted)d.onAbort?.();else try{i.socket.send(JSON.stringify(o))}catch(e){this.cancelPendingRequest(i,s,e instanceof Error?e:new Error(String(e)),!1)}})}cancelPendingRequest(e,t,n,i=!0){const s=e.pending.get(t);if(!s)return!1;if(e.pending.delete(t),clearTimeout(s.timer),s.signal&&s.onAbort&&s.signal.removeEventListener("abort",s.onAbort),s.reject(n),i)try{e.socket.send(JSON.stringify({type:"control-plane.request.cancel",requestId:t}))}catch{}return!0}async requestStream(e,t,n={}){const i=this.sockets.get(e.id);if(!i)throw Object.assign(new Error(`Reverse tunnel for node ${e.id} is not connected.`),{statusCode:503,code:"NODE_AGENT_REVERSE_TUNNEL_OFFLINE"});const s=qg(),r=zi(n.body);return new Promise((o,a)=>{const d={resolve:o,reject:a,timer:setTimeout(()=>{this.cancelHttpStream(i,s,Object.assign(new Error(`Reverse tunnel stream to ${e.id}${t} timed out.`),{statusCode:504,code:"NODE_AGENT_REVERSE_STREAM_TIMEOUT"}),"Reverse HTTP stream header timeout.")},this.httpStreamHeaderTimeoutMs),settled:!1,finalized:!1,signal:n.signal||void 0};if(i.httpStreams.set(s,d),this.registerPendingChannel(i,{id:s,attach:t=>this.attachHttpStreamChannel(e.id,s,t),cancel:(e,t)=>{this.cancelHttpStream(i,s,e,t)}},"Reverse HTTP channel attach timed out."),n.signal&&(d.onAbort=()=>this.cancelHttpStream(i,s,Object.assign(new Error("Reverse HTTP stream consumer disconnected."),{name:"AbortError",code:"ABORT_ERR"}),"HTTP consumer disconnected."),n.signal.addEventListener("abort",d.onAbort,{once:!0}),n.signal.aborted))d.onAbort();else try{i.socket.send(JSON.stringify({type:"control-plane.http.open",streamId:s,route:t,init:{method:n.method||"GET",headers:Ug(n.headers),body:r}}))}catch(e){this.cancelHttpStream(i,s,e instanceof Error?e:new Error(String(e)),"Reverse tunnel send failed.",!1)}})}cancelHttpStream(e,t,n,i,s=!0){const r=e.httpStreams.get(t);if(!r||r.finalized)return!1;if(r.finalized=!0,e.httpStreams.delete(t),this.removePendingChannel(e,t),clearTimeout(r.timer),r.signal&&r.onAbort&&r.signal.removeEventListener("abort",r.onAbort),r.settled?r.body?.destroy(n):(r.settled=!0,r.reject(n)),1===r.socket?.readyState&&r.socket.close(1e3,i),s)try{e.socket.send(JSON.stringify({type:"control-plane.http.cancel",streamId:t,reason:i}))}catch{}return!0}completeHttpStream(e,t){const n=e.httpStreams.get(t);return!(!n||n.finalized||(n.finalized=!0,e.httpStreams.delete(t),this.removePendingChannel(e,t),clearTimeout(n.timer),n.signal&&n.onAbort&&n.signal.removeEventListener("abort",n.onAbort),n.body?.end(),0))}attachAuxiliary(e,t,n){const i=this.sockets.get(e),s=i?.pendingChannels.get(t);return i&&s?(this.removePendingChannel(i,t),s.attach(n)):(n.close(1008,"Unknown reverse tunnel channel."),!1)}registerPendingChannel(e,t,n){this.removePendingChannel(e,t.id),t.timer=setTimeout(()=>{e.pendingChannels.get(t.id)===t&&(e.pendingChannels.delete(t.id),t.cancel(Object.assign(new Error(n),{code:"NODE_AGENT_REVERSE_CHANNEL_ATTACH_TIMEOUT"}),n))},this.auxiliaryAttachTimeoutMs),t.timer.unref?.(),e.pendingChannels.set(t.id,t)}removePendingChannel(e,t){const n=e.pendingChannels.get(t);return n?.timer&&clearTimeout(n.timer),e.pendingChannels.delete(t),n}attachHttpStream(e,t,n){return this.attachAuxiliary(e,t,n)}attachHttpStreamChannel(e,t,n){const i=this.sockets.get(e),s=i?.httpStreams.get(t);if(!i||!s)return n.close(1008,"Unknown reverse HTTP stream."),!1;s.socket=n;const r=e=>{this.cancelHttpStream(i,t,e,"Reverse HTTP stream failed.")};return n.on("message",(e,o)=>{if(s.finalized||i.httpStreams.get(t)!==s)return;if(o)return s.body?void(s.body.write(Buffer.isBuffer(e)?e:Buffer.from(e))||(n.pause?.(),s.body.once("drain",()=>n.resume?.()))):r(new Error("Reverse HTTP stream received data before response headers."));let a;try{a=JSON.parse(String(e))}catch{return void r(new Error("Reverse HTTP stream sent invalid JSON control data."))}if("node-agent.http.head"===a.type){if(s.settled)return;clearTimeout(s.timer);const e=Number(a.status)||502,n=a.headers&&"object"==typeof a.headers?a.headers:{},r=new g.PassThrough({highWaterMark:65536});return s.body=r,s.settled=!0,r.once("close",()=>{this.cancelHttpStream(i,t,new Error("Reverse HTTP stream consumer closed."),"HTTP consumer closed.")}),void s.resolve(new Response(g.Readable.toWeb(r),{status:e,headers:n}))}"node-agent.http.end"!==a.type?"node-agent.http.error"===a.type&&r(new Error("string"==typeof a.message?a.message:"Reverse HTTP stream failed.")):s.settled?this.completeHttpStream(i,t):r(new Error("Reverse HTTP stream ended before response headers."))}),n.on("close",()=>{r(new Error("Reverse HTTP stream disconnected."))}),n.on("error",()=>r(new Error("Reverse HTTP stream failed."))),!0}proxyWebSocket(e,t,n,i,s={}){const r=e.id,o=this.sockets.get(r);if(!o)return void t.close(1011,"Reverse tunnel is not connected.");const a=qg(),d=e=>{try{o.socket.send(JSON.stringify(e))}catch{this.removePendingChannel(o,a),o.streams.delete(a),t.close(1011,"Reverse tunnel send failed.")}},c={downstream:t,pendingFrames:[]};o.streams.set(a,c),this.registerPendingChannel(o,{id:a,attach:e=>this.attachWebSocketStreamChannel(r,a,e),cancel:(e,n)=>{this.removePendingChannel(o,a),o.streams.delete(a),t.close(1011,n)}},"Reverse websocket channel attach timed out."),d({type:"control-plane.websocket.open",streamId:a,route:n,protocols:Array.isArray(i)?i:i?[i]:[],headers:s}),t.on("message",(e,n)=>{const i=o.streams.get(a);if(i&&!i.upstream)return i.pendingFrames.length>=256?(this.removePendingChannel(o,a),o.streams.delete(a),t.close(1011,"Reverse websocket stream pending frame limit exceeded."),void d({type:"control-plane.websocket.close",streamId:a,code:1011,reason:"Reverse websocket stream pending frame limit exceeded."})):void i.pendingFrames.push({data:e,isBinary:Boolean(n)})}),t.on("close",(e,t)=>{const n=o.streams.get(a);if(n){this.removePendingChannel(o,a),o.streams.delete(a);const i=Ya(e),s=Ja(t);n.upstream&&Qa(n.upstream,i,s),d({type:"control-plane.websocket.close",streamId:a,...void 0===i?{}:{code:i},...s?{reason:s}:{}})}}),t.on("error",()=>{const e=o.streams.get(a);e&&(this.removePendingChannel(o,a),o.streams.delete(a),e.upstream?.close(1011,"Downstream websocket failed."),d({type:"control-plane.websocket.close",streamId:a,code:1011,reason:"Downstream websocket failed."}))})}attachWebSocketStream(e,t,n){return this.attachAuxiliary(e,t,n)}attachWebSocketStreamChannel(e,t,n){const i=this.sockets.get(e),s=i?.streams.get(t);if(!i||!s)return n.close(1008,"Unknown reverse websocket stream."),!1;s.upstream=n;for(const e of s.pendingFrames.splice(0))n.send(e.data,{binary:e.isBinary});return Za(s.downstream,n,{pendingFrameLimit:256,onClientClose:()=>{this.removePendingChannel(i,t),i.streams.delete(t)},onClientError:()=>{this.removePendingChannel(i,t),i.streams.delete(t)},onUpstreamClose:()=>{this.removePendingChannel(i,t),i.streams.delete(t)},onUpstreamError:()=>{this.removePendingChannel(i,t),i.streams.delete(t)}}),!0}handleWebSocketMessage(e,t){const n="string"==typeof t.type?t.type:"";if(!n.startsWith("node-agent.websocket."))return!1;const i=this.sockets.get(e),s="string"==typeof t.streamId?t.streamId:"",r=i?.streams.get(s);return!r||("node-agent.websocket.close"===n?(i&&this.removePendingChannel(i,s),i?.streams.delete(s),Qa(r.downstream,t.code,t.reason),!0):"node-agent.websocket.error"!==n||(i&&this.removePendingChannel(i,s),i?.streams.delete(s),r.downstream.close(1011,"string"==typeof t.message?t.message:"Reverse websocket proxy failed."),!0))}}class Hg{sockets=new Map;connectionKeys=new Map;retries=new Map;supervisors=new Map;runtimeGenerations=new Map;service;tunnel;safetyIntervalMs;logger;connectionRuntime;connectionOptions;reconnectAttempts=0;safetyReconciliations=0;timer;running=!1;constructor(e,t,n={}){var i;this.service=e,this.tunnel=t,this.safetyIntervalMs=(i=n.safetyIntervalMs,Math.min(6e4,Math.max(3e4,i??45e3))),this.logger=n.logger,this.connectionRuntime=n.connectionRuntime,this.connectionOptions=n}start(){this.running||(this.running=!0,this.sync(),this.timer=setInterval(()=>{this.safetyReconciliations+=1,this.sync()},this.safetyIntervalMs))}stop(){this.running=!1,this.timer&&(clearInterval(this.timer),this.timer=void 0);for(const e of this.sockets.values())e.close();for(const e of this.supervisors.values())e.close();this.sockets.clear(),this.connectionKeys.clear(),this.supervisors.clear(),this.runtimeGenerations.clear();for(const e of this.retries.values())e.timer.cancel();this.retries.clear()}syncNow(){this.sync()}diagnostics(){return{reconnectAttempts:this.reconnectAttempts,safetyReconciliations:this.safetyReconciliations,activeConnections:this.sockets.size,pendingRetries:[...this.retries.values()].filter(e=>e.timer.pending).length,safetyIntervalMs:this.safetyIntervalMs,connections:[...this.supervisors.entries()].map(([e,t])=>({nodeId:e,...t.diagnostics()}))}}sync(){const e=new Set;for(const t of this.service.listNodes()){const n=this.nodeEventConnectionKey(t);if(!n)continue;e.add(t.id);const i=this.retries.get(t.id);if(i?.timer.pending&&i.connectionKey!==n&&(i.timer.cancel(),this.retries.delete(t.id)),this.connectionKeys.get(t.id)!==n&&this.sockets.has(t.id)){const e=this.sockets.get(t.id),n=this.runtimeGenerations.get(t.id);this.supervisors.get(t.id)?.close(),this.sockets.delete(t.id),this.connectionKeys.delete(t.id),this.supervisors.delete(t.id),this.runtimeGenerations.delete(t.id),void 0!==n&&this.connectionRuntime?.disconnected(t.id,n,{error:"Direct event endpoint changed."}),e?.close()}this.sockets.has(t.id)||this.retries.get(t.id)?.timer.pending||this.connect(t,n)}for(const[t,n]of this.sockets)if(!e.has(t)){const e=this.runtimeGenerations.get(t);this.supervisors.get(t)?.close(),this.sockets.delete(t),this.connectionKeys.delete(t),this.supervisors.delete(t),this.runtimeGenerations.delete(t),void 0!==e&&this.connectionRuntime?.disconnected(t,e,{error:"Direct event connection is no longer configured."}),n.close();const i=this.retries.get(t);i?.timer.cancel(),this.retries.delete(t)}for(const[t,n]of this.retries)e.has(t)||(n.timer.cancel(),this.retries.delete(t),this.connectionKeys.delete(t))}connect(e,t){const n=new Lg,i="control-plane-proxy"!==e.connectionMode?this.connectionRuntime?.begin(e.id,"direct-http","connecting"):void 0;void 0!==i&&this.runtimeGenerations.set(e.id,i);const s=this.retries.get(e.id)?.timer||new kg;this.retries.set(e.id,{timer:s,connectionKey:t});const r=new xg({...this.connectionOptions,ping:()=>n.ping(),onTimeout:t=>{this.sockets.get(e.id)===n&&(void 0!==i&&this.connectionRuntime?.update(e.id,i,{phase:"suspect",error:`Direct event WebSocket ${t} timeout.`}),n.terminate())},onStable:()=>{s.reset(),void 0!==i&&this.connectionRuntime?.stable(e.id,i)}});this.sockets.set(e.id,n),this.connectionKeys.set(e.id,t),this.supervisors.set(e.id,r),r.start(),n.on("open",()=>{this.sockets.get(e.id)===n&&(r.opened(),void 0!==i&&this.connectionRuntime?.update(e.id,i,{phase:"handshaking"}))}),n.on("message",t=>{if(this.sockets.get(e.id)!==n)return;let s;try{s=JSON.parse(String(t))}catch{return}if(s&&"object"==typeof s&&!Array.isArray(s)){r.activity(),"healthy"!==r.phase&&(r.healthy(),void 0!==i&&this.connectionRuntime?.connected(e.id,i));const t=s,n="string"==typeof t.type&&t.type.startsWith("node-agent.")?t:{type:"node-agent.event.forwarded",event:t};this.tunnel.handleMessage(e.id,n)}}),n.on("pong",()=>{this.sockets.get(e.id)===n&&(r.pong(),void 0!==i&&this.connectionRuntime?.pong(e.id,i))}),n.on("close",(t,s)=>{this.sockets.get(e.id)===n&&(r.close(),this.sockets.delete(e.id),this.connectionKeys.delete(e.id),this.supervisors.delete(e.id),this.runtimeGenerations.delete(e.id),this.scheduleReconnect(e.id,{generation:i,closeCode:"number"==typeof t?t:void 0,error:Buffer.isBuffer(s)?s.toString("utf8"):String(s||"Direct event WebSocket disconnected.")}))}),n.on("error",()=>{this.sockets.get(e.id)===n&&n.terminate()});try{n.opened();const t=this.service.resolveNodeAgentTransport(e).proxyWebSocket(e,n,"/events");n.control(t&&t.ping,t&&t.onPong)}catch{n.close(1011,"Node event transport failed.")}}scheduleReconnect(e,t={}){const n=this.service.listNodes().find(t=>t.id===e),i=n&&this.nodeEventConnectionKey(n);if(!this.running||!n||!i)return void(void 0!==t.generation&&this.connectionRuntime?.disconnected(e,t.generation,t));const s=this.retries.get(e)??{timer:new kg};if(s.timer.pending)return;s.connectionKey=i;const r=s.timer.schedule(()=>{this.running&&!this.sockets.has(e)&&this.connect(n,i)});r&&(this.reconnectAttempts+=1,void 0!==t.generation&&this.connectionRuntime?.disconnected(e,t.generation,{...t,nextRetryAt:new Date(Date.now()+r.delay).toISOString()}),this.logger?.info?.({nodeId:e,attempt:r.attempt,delay:r.delay,reconnectAttempts:this.reconnectAttempts},"session-stream.node-connection.reconnect-scheduled")),this.retries.set(e,s)}nodeEventConnectionKey(e){if(!1===e.connectionEnabled)return;if("reverse-wss"===e.connectionMode)return;const t="control-plane-proxy"===e.connectionMode?e.connectionPath:{endpoint:e.controlEndpoint||e.endpoint,auth:e.auth};return`transport:${e.connectionMode}:${sd(JSON.stringify(t))}`}}function Wg(e=function(){return process.env.TASK_HANDOFF_CONTROL_PLANE_DATA_DIR||t.join(y.homedir(),".config","task-handoff","control-plane")}()){const n=t.resolve(e);return{dataDir:n,settingsPath:t.join(n,"control-plane-settings.json"),projectsDir:t.join(n,"projects"),modelsDir:t.join(n,"models"),imagesDir:t.join(n,"images"),marketDir:t.join(n,"market"),marketCachePath:t.join(n,"market","catalog-cache.json"),marketStatePath:t.join(n,"market","catalog-state.json"),marketMigrationBackupPath:t.join(n,"market","legacy-image-migration-backup.json"),nodesDir:t.join(n,"nodes"),pendingPairingRevokesDir:t.join(n,"pending-pairing-revokes"),chatSessionsDir:t.join(n,"chat-sessions"),chatBridgesDir:t.join(n,"chat-bridges"),triggersDir:t.join(n,"triggers"),proxyAuthorityPath:t.join(n,"control-plane-proxy","authority.json"),identitySigningPath:t.join(n,"control-plane-identity-signing.json"),cloudConnectivityPath:t.join(n,"cloud-connectivity.json"),authUsersDir:t.join(n,"auth-users"),authSessionsDir:t.join(n,"auth-sessions"),aiSessionUnreadDir:t.join(n,"ai-session-unread"),logsDir:t.join(n,"logs")}}class Gg extends Error{code;lockPath;owner;constructor(e,t,n={}){const i=t?.pid?` pid ${t.pid}`:"";super(`${n.label||"Process"} is already running${i}. Lock: ${e}`),this.name="ProcessSingletonError",this.code=n.code||"PROCESS_ALREADY_RUNNING",this.lockPath=e,this.owner=t}}function Vg(e){return t.join(e,"owner.json")}function Kg(e){return t.join(e,"initializing.json")}function Jg(e){return t.join(e,"recovering.json")}function Yg(e){return Number.isInteger(e)&&Number(e)>0}function Qg(e,t=process.platform){if(Yg(e)){if("linux"===t)try{const t=n.readFileSync(`/proc/${e}/stat`,"utf8"),i=t.lastIndexOf(")");if(i<0)return;const s=t.slice(i+2).trim().split(/\s+/)[19];return s?`linux:${s}`:void 0}catch{return}if(["darwin","freebsd","openbsd","aix","sunos"].includes(t)){const n=b.spawnSync("ps",["-o","lstart=","-p",String(e)],{encoding:"utf8",timeout:1e3}),i=0===n.status?n.stdout.trim().replace(/\s+/g," "):"";return i?`${t}:${i}`:void 0}if("win32"===t){const t=`(Get-Process -Id ${e} -ErrorAction Stop).StartTime.ToUniversalTime().Ticks`,n=b.spawnSync("powershell.exe",["-NoProfile","-NonInteractive","-Command",t],{encoding:"utf8",timeout:2e3}),i=0===n.status?n.stdout.trim():"";return/^\d+$/.test(i)?`win32:${i}`:void 0}}}const Xg=function(e){try{const t=JSON.parse(n.readFileSync(Vg(e),"utf8"));if(Yg(t.pid)&&"string"==typeof t.startTime){const e=t;return{pid:e.pid,hostname:"string"==typeof e.hostname&&e.hostname?e.hostname:y.hostname(),component:e.component||"server-update",command:"string"==typeof e.command?e.command:"",acquiredAt:"string"==typeof e.createdAt&&Number.isFinite(Date.parse(e.createdAt))?e.createdAt:new Date(0).toISOString(),token:"string"==typeof e.token&&e.token?e.token:`legacy:${e.pid}:${e.startTime}`,startIdentity:e.startTime.startsWith("linux:")?e.startTime:`linux:${e.startTime}`}}if(!(Yg(t.pid)&&"string"==typeof t.hostname&&t.hostname&&"string"==typeof t.command&&"string"==typeof t.acquiredAt&&Number.isFinite(Date.parse(t.acquiredAt))&&"string"==typeof t.token&&t.token))return;return t}catch{return}};function Zg(e){if(!Yg(e))return!1;try{return process.kill(Number(e),0),!0}catch(e){return"EPERM"===e.code}}function eh(e){if(!e||!Zg(e.pid))return!1;if(!e.startIdentity)return!0;const t=Qg(e.pid);return void 0===t||t===e.startIdentity}function th(e,i){const s=t.join(e,`.owner-${i.token}.tmp`);n.writeFileSync(s,`${JSON.stringify(i,null,2)}\n`,{encoding:"utf8",mode:384,flag:"wx"});const r=ih(e);if(r?.token!==i.token)throw rh(s),new Error(`Process lock initialization was superseded: ${e}`);n.renameSync(s,Vg(e)),rh(Kg(e))}function nh(e,s,r){const o=Xg(e);if(o?.token!==s.token)return!1;const a={...s};for(const[e,t]of Object.entries(r))void 0===t?delete a[e]:Object.assign(a,{[e]:t});const d=t.join(e,`.owner-update-${s.token}-${i.randomUUID()}.tmp`);try{if(n.writeFileSync(d,`${JSON.stringify(a,null,2)}\n`,{encoding:"utf8",mode:384,flag:"wx"}),Xg(e)?.token!==s.token)return!1;n.renameSync(d,Vg(e));for(const e of Object.keys(s))delete s[e];return Object.assign(s,a),!0}catch(e){if("ENOENT"===e.code)return!1;throw e}finally{rh(d)}}function ih(e){try{return JSON.parse(n.readFileSync(Kg(e),"utf8"))}catch{return}}function sh(e){const t=ih(e);return Yg(t?.pid)&&eh({pid:t.pid,startIdentity:t.startIdentity})}function rh(e){try{n.unlinkSync(e)}catch(e){if("ENOENT"!==e.code)throw e}}function oh(){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,20)}function ah(e){try{const t=ih(e),i=Date.parse(t?.startedAt||"");return Number.isFinite(i)?Math.max(0,Date.now()-i):Math.max(0,Date.now()-n.statSync(e).mtimeMs)}catch{return 0}}function dh(e,s){try{return n.writeFileSync(Jg(e),`${JSON.stringify({token:s,pid:process.pid,startedAt:(new Date).toISOString()})}\n`,{encoding:"utf8",mode:384,flag:"wx"}),!0}catch(r){if("EEXIST"===r.code)return!!function(e){const s=Jg(e),r=ch(s),o=Date.parse(r?.startedAt||"");if(Zg(r?.pid)||Number.isFinite(o)&&Date.now()-o<2e3)return!1;const a=t.join(e,`.recovering-${i.randomUUID()}.stale`);try{n.renameSync(s,a)}catch(e){if(["ENOENT","EEXIST"].includes(e.code||""))return!1;throw e}const d=ch(a);if(d?.token===r?.token)return rh(a),!0;try{n.linkSync(a,s)}catch(e){if("EEXIST"!==e.code)throw e}finally{rh(a)}return!1}(e)&&dh(e,s);if("ENOENT"===r.code)return!1;throw r}}function ch(e){try{return JSON.parse(n.readFileSync(e,"utf8"))}catch{return}}function lh(e,t){return ch(Jg(e))?.token===t}function ph(){const e=process.env.TASK_HANDOFF_CONTROL_PLANE_LOCK_PATH?.trim();return e?t.resolve(e):t.join(y.tmpdir(),`task-handoff-control-plane-${process.getuid?.()??"user"}.lock`)}function uh(e,s={}){return function(e,s={}){n.mkdirSync(t.dirname(e),{recursive:!0});const r=Qg(process.pid),o={pid:process.pid,hostname:y.hostname(),command:process.argv.join(" "),acquiredAt:(new Date).toISOString(),token:i.randomUUID(),...void 0!==s.component?{component:s.component}:{},...r?{startIdentity:r}:{},...void 0!==s.dataDir?{dataDir:s.dataDir}:{},...void 0!==s.host?{host:s.host}:{},...void 0!==s.port?{port:s.port}:{},...void 0!==s.instanceId?{instanceId:s.instanceId}:{}};for(let t=0;t<5;t+=1)try{return n.mkdirSync(e),n.writeFileSync(Kg(e),`${JSON.stringify({token:o.token,pid:o.pid,startIdentity:o.startIdentity,startedAt:(new Date).toISOString()})}\n`,{encoding:"utf8",mode:384,flag:"wx"}),th(e,o),{lockPath:e,owner:o,updateDetails:t=>nh(e,o,t),release(){const t=Xg(e);t?.token===o.token&&n.rmSync(e,{recursive:!0,force:!0})}}}catch(r){if("EEXIST"!==r.code)throw r;const o=Xg(e);if(eh(o))throw new Gg(e,o,s.error);if(!o&&(sh(e)||ah(e)<(s.incompleteLockStaleMs??2e3))){if(t+1<5){oh();continue}throw new Gg(e,void 0,s.error)}const a=i.randomUUID();if(!dh(e,a)){if(t+1<5){oh();continue}throw new Gg(e,Xg(e),s.error)}const d=Xg(e);if(eh(d))throw rh(Jg(e)),new Gg(e,d,s.error);if(o?.token&&d?.token!==o.token){rh(Jg(e));continue}if(!lh(e,a))continue;n.rmSync(e,{recursive:!0,force:!0})}const a=Xg(e);throw new Gg(e,a,s.error)}(e,{...s,component:"control-plane",error:{label:"Control plane",code:"CONTROL_PLANE_ALREADY_RUNNING"}})}function gh(e,t,n){if(function(e,t,n){return"system"===e.type||("chat-bridge"===e.type?function(e,t){return"ai-session"===t.type?["read","send-message","approve","interrupt"].includes(e):"instance"===t.type?["read","start","stop","restart"].includes(e):"read"===e}(t,n):"cloud-account"===e.type?function(e,t){return!["control-plane-settings","secret","chat-bridge"].includes(t.type)&&("node"===t.type?"read"===e:hh(e,t))}(t,n):"admin"===e.role||("viewer"===e.role?"read"===t:"operator"===e.role&&hh(t,n)))}(e,t,n))return;const i=new Error(`Actor is not allowed to ${t} ${n.type}${n.id?` ${n.id}`:""}.`);throw Object.assign(i,{statusCode:403,code:"CONTROL_PLANE_FORBIDDEN"}),i}function hh(e,t){return"read"===e||("instance"===t.type?["create","update","delete","start","stop","restart","proxy"].includes(e):"ai-session"===t.type?["send-message","approve","interrupt"].includes(e):("trigger"===t.type||"runtime"===t.type)&&["create","update","delete"].includes(e))}const mh=a.z.string().trim().min(1),yh=a.z.object({id:mh}).strict(),fh=a.z.object({id:mh,keyId:mh}).strict(),Ih=a.z.object({id:mh,connectionId:mh}).strict(),bh=a.z.object({id:mh,runtimeId:mh}).strict(),vh=a.z.object({id:mh,folderId:mh}).strict(),wh=a.z.object({id:mh,sessionId:mh}).strict(),Sh=a.z.object({id:mh,sessionId:mh,turnId:mh}).strict(),Ah=a.z.object({id:mh,sessionId:mh,queueId:mh}).strict(),zh=a.z.object({configHash:mh}).strict(),kh=a.z.object({id:mh,configHash:mh}).strict(),Th=a.z.object({id:mh,sessionId:mh,configHash:mh}).strict(),Eh=a.z.object({path:a.z.string().optional(),depth:a.z.coerce.number().int().min(0).max(32).optional()}).strict();async function Ch(e,t,n){const i=new AbortController,s=()=>i.abort(),r=()=>{t.raw.writableEnded||s()};e.raw.once("aborted",s),t.raw.once("close",r);try{return await n(i.signal)}finally{e.raw.off("aborted",s),t.raw.off("close",r)}}const xh=a.z.object({ids:a.z.array(a.z.string().trim().min(1).max(120)).default([])}).strict(),Nh=a.z.object({nodeId:a.z.string().trim().min(1).max(120),modelId:a.z.string().trim().min(1).max(120).optional()}).strict(),Oh=a.z.object({source:a.z.object({channel:Ur,bridgeId:a.z.string().trim().min(1).max(120).optional(),chatSessionId:a.z.string().trim().min(1).max(240),userId:a.z.string().trim().max(240).optional()}).strict(),action:a.z.discriminatedUnion("type",[a.z.object({type:a.z.literal("ai-session"),index:a.z.number().int().nonnegative()}).strict(),a.z.object({type:a.z.literal("instance-app-menu"),instanceId:a.z.string().trim().min(1).max(120)}).strict(),a.z.object({type:a.z.literal("launch-app"),instanceId:a.z.string().trim().min(1).max(120),appId:a.z.string().trim().min(1).max(120)}).strict(),a.z.object({type:a.z.literal("pending-decision"),routeId:a.z.string().trim().min(1).max(120),decision:a.z.enum(["allow","deny","skip"])}).strict()])}).strict();function _h(e){const t=Oh.parse(e);if(!t.action)throw new Error("Chat gateway action is required.");return{source:t.source,action:t.action}}const Rh=a.z.object({path:a.z.string().trim().max(1e3).optional(),depth:a.z.coerce.number().int().min(0).max(2).optional()}).strict(),Ph=a.z.object({id:a.z.string().trim().min(1),appId:a.z.string().trim().min(1)}).strict(),jh=a.z.object({id:a.z.string().trim().min(1),jobId:a.z.string().trim().min(1)}).strict(),Dh=a.z.object({projection:a.z.literal("directory").optional(),instanceId:a.z.string().trim().min(1).max(120).optional()}).strict();const Mh=a.z.object({id:a.z.string().trim().min(1).max(120)}).strict(),Lh=a.z.object({nodeId:a.z.string().trim().min(1).max(120),templateId:a.z.string().trim().min(1).max(120)}).strict(),qh=a.z.object({force:a.z.enum(["true","false"]).optional()}).strict(),$h=a.z.object({projection:a.z.literal("directory").optional()}).strict();const Bh=a.z.object({cwdFolderId:a.z.string().trim().min(1).max(120).optional()}).strict(),Uh=a.z.object({appId:a.z.string().trim().min(1).max(120).default("terminal-tty"),cwdFolderId:a.z.string().trim().min(1).max(120).optional(),options:a.z.record(a.z.string(),a.z.unknown()).default({})}).strict().default({appId:"terminal-tty",options:{}}),Fh=a.z.object({title:a.z.string().trim().min(1).max(120)}).strict(),Hh=a.z.object({token:a.z.string().trim().min(1).max(512)}).strict(),Wh=a.z.object({}).strict();function Gh(e){const{app:t,service:n,events:i,appSessionAggregator:s,aiSessionAggregator:r,aiSessionUnread:o,chatGateway:d,aiSessionAttachments:c,nodeAgentTunnel:l,nodeEventSubscriber:p,errorPayload:u}=e;!function({app:e,service:t,events:n}){e.get("/api/projects",async()=>({data:t.listProjects()})),e.post("/api/projects",async(e,i)=>{const s=t.createProject(e.body);return n.publish("project.created",{projectId:s.id}),i.code(201).send({data:s})}),e.get("/api/projects/:id",async e=>({data:t.requireProject(yh.parse(e.params).id)})),e.patch("/api/projects/:id",async e=>{const i=t.updateProject(yh.parse(e.params).id,e.body);return n.publish("project.updated",{projectId:i.id}),{data:i}}),e.delete("/api/projects/:id",async e=>{const i=yh.parse(e.params).id,s=t.deleteProject(i);return n.publish("project.deleted",{projectId:i,deleted:s}),{data:{deleted:s}}}),e.get("/api/models",async(e,n)=>Ch(e,n,async e=>({data:await t.listFederatedModels(e)}))),e.post("/api/models",async(e,i)=>{const s=await t.createModel(e.body);return n.publish("model.created",{modelId:s.id}),i.code(201).send({data:s})}),e.post("/api/models/discover",async e=>({data:await t.discoverModels(e.body)})),e.post("/api/models/test",async e=>({data:await t.testModel(e.body)})),e.post("/api/models/reorder",async e=>{const i=xh.parse(e.body),s=await t.reorderModels(i.ids);return n.publish("model.reordered",{ids:i.ids}),{data:s}}),e.get("/api/models/:id",async e=>({data:t.requireModel(yh.parse(e.params).id)})),e.patch("/api/models/:id",async e=>{const i=await t.updateModel(yh.parse(e.params).id,e.body);return n.publish("model.updated",{modelId:i.id}),{data:i}}),e.delete("/api/models/:id",async e=>{const i=yh.parse(e.params).id,s=await t.deleteModel(i);return n.publish("model.deleted",{modelId:i,deleted:s}),{data:{deleted:s}}}),e.post("/api/nodes/:nodeId/models",async(e,i)=>{const{nodeId:s}=Nh.parse(e.params),r=await t.createNodeModel(s,e.body);return n.publish("model.created",{modelId:r.id,nodeId:s}),i.code(201).send({data:r})}),e.post("/api/nodes/:nodeId/models/discover",async e=>{const{nodeId:n}=Nh.parse(e.params);return{data:await t.discoverNodeModels(n,e.body)}}),e.post("/api/nodes/:nodeId/models/test",async e=>{const{nodeId:n}=Nh.parse(e.params);return{data:await t.testNodeModel(n,e.body)}}),e.patch("/api/nodes/:nodeId/models/:modelId",async e=>{const{nodeId:i,modelId:s}=Nh.parse(e.params),r=await t.updateNodeModel(i,s,e.body);return n.publish("model.updated",{modelId:s,nodeId:i}),{data:r}}),e.delete("/api/nodes/:nodeId/models/:modelId",async e=>{const{nodeId:i,modelId:s}=Nh.parse(e.params),r=await t.deleteNodeModel(i,s);return n.publish("model.deleted",{modelId:s,nodeId:i,deleted:r.deleted}),{data:r}}),e.get("/api/market/catalog",async()=>({data:t.getMarketCatalog()})),e.post("/api/market/refresh",async()=>{const e=await t.refreshMarketCatalog();return n.publish("market.catalog.updated",{revision:e.catalog.revision,source:e.catalog.source}),{data:e}}),e.get("/api/image-options",async()=>({data:t.listImageOptions()})),e.get("/api/images",async()=>({data:t.listImages()})),e.post("/api/images",async(e,i)=>{const s=t.createImage(e.body);return n.publish("image.created",{imageId:s.id}),i.code(201).send({data:s})}),e.get("/api/images/:id",async e=>({data:t.requireImage(yh.parse(e.params).id)})),e.patch("/api/images/:id",async e=>{const i=t.updateImage(yh.parse(e.params).id,e.body);return n.publish("image.updated",{imageId:i.id}),{data:i}}),e.delete("/api/images/:id",async e=>{const i=yh.parse(e.params).id,s=await t.deleteImage(i);return n.publish("image.deleted",{imageId:i,deleted:s}),{data:{deleted:s}}})}({app:t,service:n,events:i}),function({app:e,service:t,events:n,nodeAgentTunnel:i,nodeEventSubscriber:s,errorPayload:r}){const o=e=>{if(!e||"object"!=typeof e||Array.isArray(e)||!("target"in e))return;const t=e.target;if(!t||"object"!=typeof t||Array.isArray(t)||"controlled-instance"!==t.component)return;const n=new Error("Independent controlled-instance updates were retired; update the Node rollout instead.");throw Object.assign(n,{statusCode:404,code:"LEGACY_INSTANCE_UPDATE_RETIRED"}),n};e.get("/api/nodes",async e=>({data:"directory"===$h.parse(e.query).projection?t.listNodes().map(e=>function(e){const t=e.proxyState?.lastError;return Pd.parse({id:e.id,name:e.name,status:e.status,health:e.health,connectionMode:e.connectionMode,connectionPhase:e.connectionPhase,lastSeenAt:e.lastSeenAt,observedAt:e.updatedAt,capabilities:Object.keys(e.capabilities).sort(),error:t?{code:t.code,message:"Node connection failed. Use the desktop Control Plane for diagnostics."}:void 0})}(t.projectNodeConnection(e))):t.listPublicNodes()})),e.post("/api/nodes/local/sync",async()=>{const e=await t.syncLocalNodeConnection();return s.syncNow(),n.publish("node.local-synced",{nodeId:e.id}),{data:t.requirePublicNode(e.id)}}),e.post("/api/nodes",async(e,i)=>{const r=await t.createNode(e.body);return s.syncNow(),n.publish("node.created",{nodeId:r.id}),i.code(201).send({data:t.requirePublicNode(r.id)})}),e.post("/api/nodes/:id/check",async e=>{const i=await t.checkNode(yh.parse(e.params).id);return n.publish("node.checked",{nodeId:i.id},{topic:"node.state",scope:{nodeId:i.id}}),{data:i}}),e.get("/api/nodes/:id/updates/jobs",async e=>({data:await t.listNodeUpdateJobs(yh.parse(e.params).id)})),e.get("/api/nodes/:id/settings/external-listener",async e=>({data:await t.getLocalNodeExternalListener(yh.parse(e.params).id)})),e.patch("/api/nodes/:id/settings/external-listener",async e=>{const i=yh.parse(e.params).id,s=await t.updateLocalNodeExternalListener(i,e.body);return n.publish("node.external-listener.updated",{nodeId:i,bindScope:s.bindScope,port:s.port}),{data:s}}),e.post("/api/nodes/:id/updates/check",async e=>{o(e.body);const i=yh.parse(e.params).id,s=await t.checkNodeUpdate(i,Ss.parse(e.body));return n.publish("node.update.checked",{nodeId:i,availableVersion:s.availableVersion,impact:s.impact}),{data:s}}),e.post("/api/nodes/:id/updates/apply",async(e,i)=>{o(e.body);const s=yh.parse(e.params).id,r=await t.applyNodeUpdate(s,ks.parse(e.body));return n.publish("node.update.queued",{nodeId:s,updateJobId:r.id,desiredVersion:r.toVersion,impact:r.impact}),i.code(202).send({data:r})}),e.post("/api/nodes/:id/pairing/invites",async(e,i)=>{const s=yh.parse(e.params),r=await t.createNodePairingInvite(s.id,e.body);return n.publish("node.pairing-invite.created",{nodeId:s.id}),i.code(201).send({data:r})}),e.post("/api/nodes/:id/control-plane-connections",async e=>{const i=yh.parse(e.params),s=await t.connectNodeToControlPlane(i.id,e.body);return n.publish("node.remote-connect.requested",{nodeId:i.id}),{data:s}}),e.get("/api/nodes/:id/control-plane-pairings",async e=>{const n=yh.parse(e.params);return{data:await t.listNodeControlPlanePairings(n.id)}}),e.delete("/api/nodes/:id/control-plane-pairings/:keyId",async e=>{const i=fh.parse(e.params),s=await t.deleteNodeControlPlanePairing(i.id,i.keyId);return n.publish("node.control-plane-pairing.deleted",{nodeId:i.id,keyId:i.keyId}),{data:s}}),e.get("/api/nodes/:id/control-plane-connections",async e=>{const n=yh.parse(e.params);return{data:await t.listNodeControlPlaneConnections(n.id)}}),e.delete("/api/nodes/:id/control-plane-connections/:connectionId",async e=>{const i=Ih.parse(e.params),s=await t.deleteNodeControlPlaneConnection(i.id,i.connectionId);return n.publish("node.control-plane-connection.deleted",{nodeId:i.id,connectionId:i.connectionId}),{data:s}}),e.post("/api/node-join/invites",async(e,i)=>{const s=t.createNodeJoinInvite(e.body);return n.publish("node-join.invite.created",{inviteId:s.id}),i.code(201).send({data:s})}),e.post("/api/node-join/complete",{config:Ig},async(e,i)=>{const r=t.completeNodeJoin(e.body);return s.syncNow(),n.publish("node.joined",{nodeId:r.id}),i.code(201).send({data:t.requirePublicNode(r.id)})}),e.get("/api/nodes/:id/runtimes",async e=>({data:await t.listNodeRuntimes(yh.parse(e.params).id)})),e.post("/api/nodes/:id/runtimes",async(e,i)=>{const s=yh.parse(e.params),r=await t.createNodeRuntime(s.id,e.body);return n.publish("node.runtime.created",{nodeId:s.id,runtimeId:r.id}),i.code(201).send({data:r})}),e.patch("/api/nodes/:id/runtimes/:runtimeId",async e=>{const i=bh.parse(e.params),s=await t.updateNodeRuntime(i.id,i.runtimeId,e.body);return n.publish("node.runtime.updated",{nodeId:i.id,runtimeId:s.id}),{data:s}}),e.delete("/api/nodes/:id/runtimes/:runtimeId",async e=>{const i=bh.parse(e.params),s=await t.deleteNodeRuntime(i.id,i.runtimeId);return n.publish("node.runtime.deleted",{nodeId:i.id,runtimeId:i.runtimeId}),{data:s}}),e.post("/api/nodes/:id/runtimes/:runtimeId/check",async e=>{const i=bh.parse(e.params),s=await t.checkNodeRuntime(i.id,i.runtimeId);return n.publish("node.runtime.checked",{nodeId:i.id,runtimeId:s.id}),{data:s}}),e.get("/api/nodes/:id/docker/images",async e=>({data:await t.listNodeDockerImages(yh.parse(e.params).id)})),e.get("/api/nodes/:id/image-options",async e=>({data:await t.listNodeImageAvailability(yh.parse(e.params).id)})),e.get("/api/nodes/:id/local-folders",async(e,n)=>Ch(e,n,async n=>({data:await t.listNodeLocalFolders(yh.parse(e.params).id,n)}))),e.get("/api/nodes/:id/folders/places",async e=>({data:await t.listNodeFolderPlaces(yh.parse(e.params).id)})),e.get("/api/nodes/:id/folders/tree",async e=>{const n=yh.parse(e.params),i=Eh.parse(e.query);return{data:await t.listNodeFolderTree(n.id,{path:i.path,depth:i.depth})}}),e.post("/api/nodes/:id/local-folders",async(e,i)=>{const s=yh.parse(e.params),r=await t.createNodeLocalFolder(s.id,e.body);return n.publish("node.local-folder.created",{nodeId:s.id,folderId:r.id}),i.code(201).send({data:r})}),e.delete("/api/nodes/:id/local-folders/:folderId",async e=>{const i=vh.parse(e.params),s=await t.deleteNodeLocalFolder(i.id,i.folderId);return n.publish("node.local-folder.deleted",{nodeId:i.id,folderId:i.folderId}),{data:s}}),e.get("/api/nodes/:id",async e=>({data:t.requirePublicNode(yh.parse(e.params).id)})),e.patch("/api/nodes/:id",async e=>{const r=t.updateNode(yh.parse(e.params).id,e.body);return r.connectionEnabled||i.disconnect(r.id),s.syncNow(),n.publish("node.updated",{nodeId:r.id}),{data:t.requirePublicNode(r.id)}}),e.delete("/api/nodes/:id",async e=>{const i=yh.parse(e.params).id,r=qh.parse(e.query),o=await t.deleteNodeWithProxyLifecycle(i,"true"===r.force);return s.syncNow(),n.publish("node.deleted",{nodeId:i,deleted:o.deleted,revoke:o.revoke}),{data:o}}),e.get("/api/node-runtimes",async(e,n)=>Ch(e,n,async e=>{const n=await t.listNodeRuntimesWithDiagnostics(e);return{data:n.items,meta:{nodeErrors:n.nodeErrors}}})),function(e){const{app:t,service:n,nodeAgentTunnel:i,errorPayload:s}=e,r=new Ng(i),o=e=>{if(!1===e.connectionEnabled){const e=new Error("Node agent connection is disabled locally.");throw Object.assign(e,{statusCode:409,code:"NODE_AGENT_CONNECTION_DISABLED"}),e}};t.get(nd,{websocket:!0,config:wg},(e,t)=>{try{const i=Mg.parse(t.query),s=n.requireNode(i.nodeId);Bg(s,t),o(s),r.attachMain(s.id,e)}catch(t){const n=s(t);e.send(JSON.stringify({type:"control-plane.error",code:n.code,message:n.message})),e.close(1008,n.message)}}),t.get(`${nd}/streams/:streamId`,{websocket:!0,config:wg},(e,t)=>{try{const i=Mg.parse(t.query),s=n.requireNode(i.nodeId);Bg(s,t),o(s);const a=t.params.streamId;r.attachAuxiliary(s.id,a,e)}catch(t){const n=s(t);e.close(1008,n.message)}}),t.get(`${nd}/channels/:channelId`,{websocket:!0,config:wg},(e,t)=>{try{const i=Mg.parse(t.query),s=n.requireNode(i.nodeId);Bg(s,t),o(s);const a=t.params.channelId;r.attachAuxiliary(s.id,a,e)}catch(t){const n=s(t);e.close(1008,n.message)}}),t.get(`${nd}/http-streams/:streamId`,{websocket:!0,config:wg},(e,t)=>{try{const i=Mg.parse(t.query),s=n.requireNode(i.nodeId);Bg(s,t),o(s);const a=t.params.streamId;r.attachAuxiliary(s.id,a,e)}catch(t){const n=s(t);e.close(1008,n.message)}})}({app:e,service:t,nodeAgentTunnel:i,errorPayload:r})}({app:t,service:n,events:i,nodeAgentTunnel:l,nodeEventSubscriber:p,errorPayload:u}),function({app:e,service:t,events:n}){e.get("/api/controlled-instances",async()=>({data:await t.listControlledInstances()})),e.post("/api/controlled-instances",async(e,i)=>{const s=await t.createControlledInstance(e.body);return n.publish("instance.created",{instanceId:s.id}),i.code(201).send({data:s})}),e.get("/api/controlled-instances/:id",async e=>({data:await t.requireControlledInstance(yh.parse(e.params).id)})),e.get("/api/controlled-instances/:id/metrics",async e=>({data:await t.instanceResourceMetrics(yh.parse(e.params).id)})),e.get("/api/controlled-instances/:id/apps/management",async e=>({data:await t.instanceAppManagement(yh.parse(e.params).id)})),e.post("/api/controlled-instances/:id/apps/:appId/install",async e=>{const n=Ph.parse(e.params),i=us.parse(e.body||{});return{data:await t.requestInstanceAppOperation(n.id,n.appId,"install",i)}}),e.post("/api/controlled-instances/:id/apps/:appId/uninstall",async e=>{const n=Ph.parse(e.params),i=us.parse(e.body||{});return{data:await t.requestInstanceAppOperation(n.id,n.appId,"uninstall",i)}}),e.get("/api/controlled-instances/:id/apps/jobs/:jobId",async e=>{const n=jh.parse(e.params);return{data:await t.instanceAppManagementJob(n.id,n.jobId)}}),e.patch("/api/controlled-instances/:id",async e=>{const i=await t.updateControlledInstance(yh.parse(e.params).id,e.body);return n.publish("instance.updated",{instanceId:i.id}),{data:i}}),e.delete("/api/controlled-instances/:id",async e=>{const i=yh.parse(e.params).id,s=await t.deleteControlledInstance(i,Ui.parse(e.body));return s.completed&&n.publish("instance.deleted",{instanceId:i,result:s}),{data:s}}),e.post("/api/controlled-instances/:id/start",async e=>{const i=await t.startControlledInstance(yh.parse(e.params).id);return n.publish("instance.started",{instanceId:i.id}),{data:i}}),e.post("/api/controlled-instances/:id/stop",async e=>{const i=await t.stopControlledInstance(yh.parse(e.params).id);return n.publish("instance.stopped",{instanceId:i.id}),{data:i}}),e.post("/api/controlled-instances/:id/restart",async e=>{const i=await t.restartControlledInstance(yh.parse(e.params).id);return n.publish("instance.restarted",{instanceId:i.id}),{data:i}}),e.post("/api/controlled-instances/:id/image-provisioning/retry",async e=>{const i=await t.retryControlledInstanceImageProvisioning(yh.parse(e.params).id);return n.publish("instance.image-provisioning-retried",{instanceId:i.id}),{data:i}}),e.get("/api/controlled-instances/:id/config-sync",async e=>({data:await t.instanceConfigSyncState(yh.parse(e.params).id)})),e.get("/api/controlled-instances/:id/config-sync/folders",async e=>({data:await t.listInstanceConfigSyncFolders(yh.parse(e.params).id,Rh.parse(e.query))})),e.post("/api/controlled-instances/:id/config-sync",async e=>{const i=yh.parse(e.params).id,s=await t.syncInstanceConfigs(i,e.body);return n.publish("instance.config-synced",{instanceId:i}),{data:s}}),e.get("/api/instance-board",async(e,n)=>Ch(e,n,async n=>{const i=Dh.parse(e.query),s=await t.boardWithDiagnostics(n);return{data:(i.instanceId?s.items.filter(e=>e.id===i.instanceId):s.items).map(e=>"directory"===i.projection?function(e){const t=e.runtimeVersion?.error,n=e.imageProvisioning?.error,i=e.workspace.error,s=t?{code:t.code,message:"Instance runtime convergence failed. Use the desktop Control Plane for diagnostics."}:n?{code:"IMAGE_PROVISIONING_FAILED",message:"Instance image provisioning failed. Use the desktop Control Plane for diagnostics."}:i?{code:"WORKSPACE_FAILED",message:"Instance workspace preparation failed. Use the desktop Control Plane for diagnostics."}:void 0,r=e.node?.capabilities.agent,o=r&&"object"==typeof r&&!Array.isArray(r)?r:void 0,a="string"==typeof o?.protocolVersion?o.protocolVersion:void 0,d=!a||a===li,c=[e.protocolCompatible?void 0:`Instance protocol ${e.protocolVersion||"unknown"} differs from this Control Plane.`,d?void 0:`Node protocol ${a} differs from this Control Plane.`].filter(e=>Boolean(e)),l="running"===e.status||"online"===e.connectionStatus||"reachable"===e.access.status,p=!["failed","stopped","stopping","unhealthy"].includes(e.status)&&"online"!==e.connectionStatus&&["provisioning","starting","registering","registered"].includes(e.status),u=[l||["provisioning","starting","registering","registered","stopping"].includes(e.status)?void 0:"start",["failed","stopped","stopping","unhealthy"].includes(e.status)||!l&&!p?void 0:"stop",l?"restart":void 0,"failed"===e.status&&"failed"===e.imageProvisioning?.phase?"retry-image":void 0].filter(e=>Boolean(e));return Dd.parse({id:e.id,name:e.name,nodeId:e.nodeId,status:e.status,health:e.health,connectionStatus:e.connectionStatus,ready:e.ready,capabilities:{aiSessionTimeline:e.capabilities.features.aiSessionTimeline},config:{defaultCodexPermissionMode:e.config.defaultCodexPermissionMode},lastHeartbeatAt:e.lastHeartbeatAt,heartbeatAgeMs:e.heartbeatAgeMs,observedAt:e.updatedAt,runtime:{id:e.runtimeId,name:e.runtime?.name,type:e.runtime?.type},workspace:{status:e.workspace.status,path:e.workspace.path},protocol:{version:e.protocolVersion,compatible:e.protocolCompatible&&d,warning:c.length?c.join(" "):void 0},aiSessions:e.aiSessions,availableActions:u,availableApps:(e.appInventory?.items||[]).filter(e=>"available"===e.availability).map(e=>({id:e.id,name:e.name,kind:e.kind,supportsCwdSelection:e.capabilities.supportsCwdSelection})),availableAgents:(e.appInventory?.items||[]).filter(e=>"available"===e.availability&&("codex"===e.id||"claude"===e.id)).map(e=>({id:e.id,name:e.name,kind:e.kind,supportsCwdSelection:e.capabilities.supportsCwdSelection})),error:s})}(e):e),meta:{nodeErrors:s.nodeErrors}}}))}({app:t,service:n,events:i}),function(e,t,n){e.get("/api/nodes/:id/environment-templates",async e=>({data:await t.listEnvironmentTemplates(Mh.parse(e.params).id)})),e.get("/api/nodes/:nodeId/environment-templates/:templateId",async e=>{const n=Lh.parse(e.params);return{data:await t.getEnvironmentTemplate(n.nodeId,n.templateId)}}),e.post("/api/controlled-instances/:id/environment-templates",async(e,i)=>{const s=Mh.parse(e.params).id,r=await t.createEnvironmentTemplate(s,e.body);return n.publish("environment-template.updated",{templateId:r.id,nodeId:r.nodeId,status:r.status}),i.code(201).send({data:r})}),e.delete("/api/nodes/:nodeId/environment-templates/:templateId",async e=>{const i=Lh.parse(e.params),s=await t.deleteEnvironmentTemplate(i.nodeId,i.templateId);return n.publish("environment-template.deleted",s),{data:s}})}(t,n,i),function({app:e,service:t,events:n,appSessionAggregator:i,aiSessionAggregator:s,aiSessionUnread:r,aiSessionAttachments:o}){e.get("/api/app-sessions",async e=>{const t=a.z.object({refresh:a.z.string().optional(),instanceId:a.z.string().trim().min(1).optional(),streamId:a.z.string().trim().min(1).optional(),sinceRevision:a.z.string().optional()}).parse(e.query||{});if(void 0!==t.sinceRevision){const e=Number(t.sinceRevision);if(!Number.isInteger(e)||e<0){const e=new Error("sinceRevision must be a non-negative integer.");throw Object.assign(e,{statusCode:400,code:"APP_SESSION_DELTA_INVALID"}),e}if(!t.streamId){const e=new Error("streamId is required with sinceRevision.");throw Object.assign(e,{statusCode:400,code:"APP_SESSION_DELTA_INVALID"}),e}return{data:await i.delta({instanceId:t.instanceId,streamId:t.streamId,sinceRevision:e})}}const n=await i.list({refresh:"true"===t.refresh||"1"===t.refresh});return{data:t.instanceId?{...n,instances:n.instances.filter(e=>e.instanceId===t.instanceId)}:n}}),e.post("/api/controlled-instances/:id/apps/sessions",async e=>{const i=yh.parse(e.params),s=Uh.parse(e.body),r=await t.launchAppSession(i.id,s.appId,{...s.options,...s.cwdFolderId?{cwdFolderId:s.cwdFolderId}:{}});return n.publish("instance.app-session.launched",{instanceId:i.id,sessionId:"string"==typeof r.id?r.id:void 0,appId:s.appId}),{data:r}}),e.post("/api/controlled-instances/:id/apps/sessions/:sessionId/stop",async e=>{const i=wh.parse(e.params),s=await t.stopAppSession(i.id,i.sessionId);return n.publish("instance.app-session.stopped",{instanceId:i.id,sessionId:i.sessionId}),{data:s}}),e.patch("/api/controlled-instances/:id/apps/sessions/:sessionId",async e=>{const i=wh.parse(e.params),s=Fh.parse(e.body),r=await t.renameAppSession(i.id,i.sessionId,s.title);return n.publish("instance.app-session.renamed",{instanceId:i.id,sessionId:i.sessionId,title:s.title}),{data:r}}),e.post("/api/controlled-instances/:id/apps/sessions/:sessionId/access",async e=>{const n=wh.parse(e.params);Wh.parse(e.body||{});const i=await t.createAppSessionAccessToken({instanceId:n.id,sessionId:n.sessionId});return{data:{mode:i.mode,url:`/apps/access/${i.mode}?token=${encodeURIComponent(i.token)}`,token:i.token,expiresAt:i.expiresAt}}}),e.delete("/api/controlled-instances/:id/apps/sessions/:sessionId/access",async e=>{const n=wh.parse(e.params),i=Hh.parse(e.body||{});return t.revokeAppSessionAccessToken(i.token,{instanceId:n.id,sessionId:n.sessionId}),{data:{revoked:!0}}}),e.get("/api/controlled-instances/:id/app-sessions",async e=>{const t=yh.parse(e.params),n=(await i.list()).instances.find(e=>e.instanceId===t.id);return{data:n?.appSessions||{runningCount:0,problemCount:0,sessions:[],updatedAt:(new Date).toISOString()}}}),e.get("/api/controlled-instances/:id/ai-sessions/history",async e=>{const n=yh.parse(e.params);return{data:await t.listAiSessionHistory(n.id)}}),e.get("/api/controlled-instances/:id/ai-sessions/history/:sessionId",async e=>{const n=wh.parse(e.params);return{data:await t.getAiSessionHistoryDetail(n.id,n.sessionId)}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/timeline",async e=>{const n=wh.parse(e.params);return{data:await t.getAiSessionTimeline(n.id,n.sessionId)}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/turns/:turnId/timeline",async e=>{const n=Sh.parse(e.params);return{data:await t.getAiSessionTurnTimeline(n.id,n.sessionId,n.turnId)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/resume",async e=>{const i=wh.parse(e.params);Wh.parse(e.body||{});const s=await t.resumeAiSession(i.id,i.sessionId);return n.publish("instance.ai-session.resumed",{instanceId:i.id,sessionId:s.aiSessionId,providerSessionId:s.providerSessionId,appSessionId:s.appSessionId,disposition:s.disposition}),{data:s}}),e.get("/api/controlled-instances/:id/ai-sessions/workspace",async e=>{const n=yh.parse(e.params),i=Bh.parse(e.query||{});return{data:await t.inspectAiSessionWorkspace(n.id,i.cwdFolderId)}}),e.post("/api/controlled-instances/:id/ai-sessions",async e=>{const i=yh.parse(e.params),s=Ee.parse(e.body||{}),r=o.resolveRefs(s.attachments,i.id,s.clientRequestId),a=await t.createAiSession(i.id,{...s,attachments:r});return n.publish("instance.ai-session.created",{instanceId:i.id,sessionId:a.aiSessionId,providerSessionId:a.providerSessionId,clientRequestId:s.clientRequestId}),{data:a}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/open-app",async e=>{const i=wh.parse(e.params),s=_e.parse(e.body||{}),r=await t.openAiSessionApp(i.id,i.sessionId,s.clientRequestId);return n.publish("instance.ai-session.app-opened",{instanceId:i.id,sessionId:i.sessionId,appSessionId:r.appSessionId}),{data:r}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/fork",async e=>{const i=wh.parse(e.params),s=Ne.parse(e.body||{}),r=await t.forkAiSession(i.id,i.sessionId,s);return n.publish("instance.ai-session.forked",{instanceId:i.id,sourceSessionId:i.sessionId,sessionId:r.aiSessionId,providerSessionId:r.providerSessionId,clientRequestId:s.clientRequestId}),{data:r}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/close",async e=>{const i=wh.parse(e.params),s=Pe.parse(e.body||{}),r=await t.closeAiSession(i.id,i.sessionId,s.clientRequestId);return n.publish("instance.ai-session.closed",{instanceId:i.id,sessionId:i.sessionId,providerSessionId:r.providerSessionId}),{data:r}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/messages",async e=>{const i=wh.parse(e.params),s=Ae.parse(e.body||{}),r=o.resolveRefs(s.attachments,i.id,i.sessionId),a=await t.sendAiSessionMessage(i.id,i.sessionId,s.message,s.mode,r,s.references,s.permissionMode);return n.publish("instance.ai-session.message-sent",{instanceId:i.id,sessionId:i.sessionId}),{data:a}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/mentions",async e=>{const n=wh.parse(e.params);return{data:await t.aiSessionMentionCatalog(n.id,n.sessionId)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/mentions/files",async e=>{const n=wh.parse(e.params),i=be.parse(e.body||{});return{data:await t.searchAiSessionMentionFiles(n.id,n.sessionId,i.query)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/commands",async e=>{const i=wh.parse(e.params),s=le.parse(e.body||{}),r=await t.executeAiSessionCommand(i.id,i.sessionId,s);return n.publish("instance.ai-session.command-executed",{instanceId:i.id,sessionId:i.sessionId,command:s.command}),{data:r}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/queue",async e=>{const n=wh.parse(e.params);return{data:await t.aiSessionQueue(n.id,n.sessionId)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/:queueId/steer",async e=>{const i=Ah.parse(e.params),s=await t.steerAiSessionQueuedMessage(i.id,i.sessionId,i.queueId);return n.publish("instance.ai-session.message-sent",{instanceId:i.id,sessionId:i.sessionId}),{data:s}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/:queueId/retry",async e=>{const n=Ah.parse(e.params);return{data:await t.retryAiSessionQueuedMessage(n.id,n.sessionId,n.queueId)}}),e.delete("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/:queueId",async e=>{const n=Ah.parse(e.params);return{data:await t.removeAiSessionQueuedMessage(n.id,n.sessionId,n.queueId)}}),e.patch("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/:queueId",async e=>{const n=Ah.parse(e.params),i=Le.parse(e.body||{});return{data:await t.editAiSessionQueuedMessage(n.id,n.sessionId,n.queueId,i)}}),e.patch("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/reorder",async e=>{const n=wh.parse(e.params),i=Me.parse(e.body||{});return{data:await t.reorderAiSessionQueuedMessages(n.id,n.sessionId,i)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/interrupt",async e=>{const i=wh.parse(e.params),s=await t.interruptAiSession(i.id,i.sessionId);return n.publish("instance.ai-session.interrupted",{instanceId:i.id,sessionId:i.sessionId}),{data:s}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/approval",async e=>{const i=wh.parse(e.params),s=De.parse(e.body||{}),r=await t.resolveAiSessionApproval(i.id,i.sessionId,s.decision);return n.publish("instance.ai-session.approval-resolved",{instanceId:i.id,sessionId:i.sessionId,decision:s.decision}),{data:r}}),e.get("/api/ai-sessions",async(e,t)=>{const n=e.query;if(void 0!==n.sinceRevision){const e=Number(n.sinceRevision);if(!Number.isInteger(e)||e<0)return t.code(400).send({error:"invalid_since_revision"});try{return n.streamId?{data:await s.delta({instanceId:n.instanceId,streamId:n.streamId,sinceRevision:e})}:t.code(400).send({error:"stream_id_required"})}catch(e){if("AI_SESSION_DELTA_INSTANCE_ID_REQUIRED"===e.message)return t.code(400).send({error:"instance_id_required"});throw e}}const i=await s.list({refresh:"true"===n.refresh||"1"===n.refresh}),o=n.instanceId?{...i,instances:i.instances.filter(e=>e.instanceId===n.instanceId)}:i;for(const e of o.instances)r.reconcile(e.instanceId,e.aiSessions);return{data:{...o,instances:o.instances.map(e=>({...e,aiSessions:r.decorate(e.instanceId,e.aiSessions)}))}}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/read",async(e,t)=>{const i=wh.parse(e.params),o=a.z.object({sessionUpdatedAt:a.z.string().datetime()}).strict().parse(e.body||{}),d=(await s.list()).instances.find(e=>e.instanceId===i.id),c=d?.aiSessions.sessions.find(e=>e.id===i.sessionId);if(!d||!c)return t.code(404).send({error:{code:"AI_SESSION_NOT_FOUND",message:"AI session was not found."}});r.reconcile(i.id,d.aiSessions);const l=r.markRead(i.id,i.sessionId,o.sessionUpdatedAt);return l?(n.publish(j,l,{topic:"ai.sessions",scope:{instanceId:i.id,sessionId:i.sessionId}}),{data:l}):t.code(404).send({error:{code:"AI_SESSION_NOT_FOUND",message:"AI session was not found."}})})}({app:t,service:n,events:i,appSessionAggregator:s,aiSessionAggregator:r,aiSessionUnread:o,aiSessionAttachments:c}),function({app:e,service:t,events:n}){e.get("/api/triggers",async()=>({data:await t.listTriggers()})),e.post("/api/triggers",async(e,i)=>{const s=t.createTrigger(e.body);return n.publish("trigger.created",{configHash:s.configHash}),i.code(201).send({data:s})}),e.put("/api/triggers/:configHash",async e=>{const i=zh.parse(e.params),s=await t.updateTrigger(i.configHash,e.body);return n.publish("trigger.updated",{previousConfigHash:i.configHash,configHash:s.trigger.configHash}),{data:s}}),e.delete("/api/triggers/:configHash",async e=>{const i=zh.parse(e.params),s=await t.deleteTrigger(i.configHash);return n.publish("trigger.deleted",{configHash:i.configHash}),{data:s}}),e.post("/api/triggers/:configHash/apply",async e=>{const i=zh.parse(e.params),s=await t.applyTrigger(i.configHash,e.body||{});return n.publish("trigger.applied",{configHash:i.configHash}),{data:s}}),e.get("/api/controlled-instances/:id/triggers",async e=>{const n=yh.parse(e.params);return{data:await t.listInstanceTriggers(n.id)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/triggers",async e=>{const i=wh.parse(e.params),s=await t.bindAiSessionTrigger(i.id,i.sessionId,e.body||{});return n.publish("trigger.deployment.bound",{instanceId:i.id,sessionId:i.sessionId},{topic:"triggers",scope:{instanceId:i.id}}),{data:s}}),e.delete("/api/controlled-instances/:id/ai-sessions/:sessionId/triggers/:configHash",async e=>{const i=Th.parse(e.params),s=await t.unbindAiSessionTrigger(i.id,i.sessionId,i.configHash);return n.publish("trigger.deployment.unbound",{instanceId:i.id,sessionId:i.sessionId,configHash:i.configHash},{topic:"triggers",scope:{instanceId:i.id}}),{data:s}}),e.post("/api/controlled-instances/:id/triggers/:configHash/run",async e=>{const i=kh.parse(e.params),s=await t.runInstanceTrigger(i.id,i.configHash,e.body||{});return n.publish("trigger.run.requested",{instanceId:i.id,configHash:i.configHash},{topic:"triggers",scope:{instanceId:i.id}}),{data:s}})}({app:t,service:n,events:i}),function({app:e,service:t,chatGateway:n}){e.get("/api/chat/sessions",async()=>({data:t.listChatSessions()})),e.get("/api/chat/sessions/:id",async e=>({data:t.requireChatSession(yh.parse(e.params).id)})),e.get("/api/chat-gateway/status",async()=>({data:n.status()})),e.post("/api/chat-gateway/poll-ai-sessions",async()=>({data:await n.pollAiSessionsNow()})),e.get("/api/chat-gateway/bridges",async()=>({data:t.listChatBridges()})),e.post("/api/chat-gateway/bridges",async e=>({data:t.createChatBridge(e.body)})),e.patch("/api/chat-gateway/bridges/:id",async i=>{const s=yh.parse(i.params).id,r=t.requireChatBridge(s),o=oc.parse(i.body),a=t.updateChatBridge(s,i.body),d="boolean"==typeof o.enabled?o.enabled:void 0;return e.log.info({component:"control-plane-chat-gateway",action:"bridge-patch",bridgeId:s,hasEnabled:void 0!==d,requestedEnabled:d,previousEnabled:r.enabled,updatedEnabled:t.requireChatBridge(s).enabled},"chat gateway bridge state changed"),void 0!==d&&d!==r.enabled&&(d?n.startBridge(s):n.stopBridge(s)),{data:a}}),e.post("/api/chat-gateway/bridges/:id/start",async i=>{const s=yh.parse(i.params).id,r=t.requireChatBridge(s);return t.updateChatBridge(s,{enabled:!0}),e.log.info({component:"control-plane-chat-gateway",action:"bridge-start-request",bridgeId:s,previousEnabled:r.enabled,updatedEnabled:t.requireChatBridge(s).enabled},"chat gateway bridge state changed"),{data:n.startBridge(s)}}),e.post("/api/chat-gateway/bridges/:id/stop",async i=>{const s=yh.parse(i.params).id,r=t.requireChatBridge(s);return t.updateChatBridge(s,{enabled:!1}),e.log.info({component:"control-plane-chat-gateway",action:"bridge-stop-request",bridgeId:s,previousEnabled:r.enabled,updatedEnabled:t.requireChatBridge(s).enabled},"chat gateway bridge state changed"),{data:n.stopBridge(s)}}),e.delete("/api/chat-gateway/bridges/:id",async e=>{const i=yh.parse(e.params).id;return n.stopBridge(i),{data:{deleted:t.deleteChatBridge(i)}}}),e.post("/api/chat-gateway/messages",{bodyLimit:67108864},async e=>({data:await t.handleChatGatewayMessage(Wr.parse(e.body))})),e.post("/api/chat-gateway/actions",async e=>({data:await t.handleChatGatewayAction(_h(e.body))})),e.get("/api/pending-routes",async()=>({data:await t.listPendingRoutes()}))}({app:t,service:n,chatGateway:d})}const Vh=new Set(["connection","content-length","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade"]),Kh=new Set(["authorization"]),Jh=new Set(["content-encoding"]);function Yh(e){return Object.fromEntries(Object.entries(e).flatMap(([e,t])=>{const n=e.toLowerCase();if(Vh.has(n)||Kh.has(n)||void 0===t)return[];const i=Array.isArray(t)?t.join(", "):String(t);if("cookie"!==n)return[[e,i]];const s=function(e){return e.split(";").map(e=>e.trim()).filter(e=>e&&e.slice(0,e.indexOf("=")).trim()!==bo).join("; ")}(i);return s?[[e,s]]:[]}))}function Qh(e){return Object.fromEntries(Object.entries(Yh(e)).filter(([e])=>{const t=e.toLowerCase();return"host"!==t&&"cookie"!==t&&"authorization"!==t&&(!t.startsWith("sec-websocket-")||"sec-websocket-origin"===t)}))}function Xh(e){const t=e["sec-websocket-protocol"],n=(Array.isArray(t)?t.join(","):"string"==typeof t?t:"").split(",").map(e=>e.trim()).filter(Boolean);return n.length?n:void 0}function Zh(e,t,n,i,s={}){const r=new AbortController;return t.raw.once("close",()=>r.abort()),e.proxyInstanceHttp(n,i,{...s,signal:r.signal})}function em(e,t,n){for(const[n,i]of Object.entries(t.headers)){const t=n.toLowerCase();Vh.has(t)||Jh.has(t)||e.header(n,i)}if(!t.body)return e.code(t.status).send();const i=g.Readable.fromWeb(t.body);return e.raw.once("close",()=>i.destroy()),e.code(t.status).send(n?i.pipe(n):i)}function tm(e){return`/instances/${encodeURIComponent(e)}`}function nm(e,t,n,i){const s=function(e,t){const n=e.split("?",1)[0]||"/";return t.toLowerCase().includes("text/html")&&!n.startsWith("/api/")}(i,Object.entries(t.headers).find(([e])=>"content-type"===e.toLowerCase())?.[1]||"")?function(e){const t=[];let n=0,i=!1;const s=(s,r=!1)=>{if(i)return;const o=Buffer.concat(t,n).toString("utf8");!/<head(\s[^>]*)?>/i.exec(o)&&!r&&n<65536||(i=!0,s.push(function(e,t){if(e.includes("__TASK_HANDOFF_PUBLIC_BASE__"))return e;const n=`<script>window.__TASK_HANDOFF_PUBLIC_BASE__=${JSON.stringify(t)};<\/script>`;return/<head(\s[^>]*)?>/i.test(e)?e.replace(/<head(\s[^>]*)?>/i,e=>`${e}\n${n}`):`${n}\n${e}`}(o,e)),t.length=0,n=0)};return new g.Transform({transform(e,r,o){i?this.push(e):(t.push(Buffer.from(e)),n+=e.length,s(this)),o()},flush(e){s(this,!0),e()}})}(tm(n)):void 0;return em(e,t,s)}function im(e){return Buffer.isBuffer(e)?e:e instanceof Uint8Array?Buffer.from(e):e instanceof URLSearchParams?e.toString():"string"==typeof e?e:null==e?void 0:JSON.stringify(e)}function sm(e,t){if("string"!=typeof t||!e.hasContentTypeParser(t))try{e.addContentTypeParser(t,{parseAs:"buffer"},(e,t,n)=>n(null,t))}catch(e){if(e instanceof Error&&/Content type parser .* already present/i.test(e.message))return;throw e}}function rm(e){return new URL(e,"http://control-plane.local").searchParams.get("token")||""}function om(e,t,n){const i=encodeURIComponent(e),s=encodeURIComponent(t),r=`apps/access/vnc/${i}/proxy`,o=n.vnc&&"object"==typeof n.vnc?n.vnc:{};return"kasmvnc"===("string"==typeof o.backend?o.backend:"")?`/${r}/api/apps/sessions/${s}/web/`:`/${r}/api/novnc/vnc.html?path=${encodeURIComponent(`${r}/api/apps/sessions/${s}/vnc`)}&autoconnect=1&resize=scale`}class am{snapshots=new Map;history=new Map;advertisedStreams=new Map;recoveries=new Map;listeners=new Set;bootstrap;logger;recoverDelta;recoverSnapshot;onRecoveredEvent;recoveryCount=0;counters={streamResets:0,gaps:0,deltaRecoveries:0,snapshotRecoveries:0,recoveryFailures:0};constructor(e){this.bootstrap=e.bootstrap,this.logger=e.logger,this.recoverDelta=e.recoverDelta,this.recoverSnapshot=e.recoverSnapshot,this.onRecoveredEvent=e.onRecoveredEvent}handleEvent(e){if(e.type===R||e.type===P){const t=$o(e.type===R?dt:ct,e.payload);return!!t.success||(this.logger?.warn?.({eventType:e.type,issues:t.error.issues,errorCode:"AI_SESSION_TRANSIENT_EVENT_INVALID"},"ai-session.aggregator.transient-event.invalid"),!1)}const t=e.type===N?rt:e.type===O?ot:e.type===_?at:void 0;if(!t)return!1;const n=$o(t,e.payload);return n.success?e.type===N?this.applySnapshot(n.data):e.type===O?this.applyPatch(n.data):this.applyRemoved(n.data):(this.logger?.warn?.({eventType:e.type,issues:n.error.issues,errorCode:"AI_SESSION_EVENT_INVALID"},"ai-session.aggregator.event.invalid"),!1)}onSnapshot(e){return this.listeners.add(e),()=>this.listeners.delete(e)}applySnapshot(e){const t=this.advertisedStreams.get(e.meta.instanceId)?.streamId;return t&&t!==e.meta.streamId?(this.logger?.warn?.({instanceId:e.meta.instanceId,advertisedStreamId:t,streamId:e.meta.streamId,revision:e.meta.revision},"ai-session.aggregator.snapshot.obsolete-stream"),!1):this.apply({type:N,payload:e})}advertiseStream(e,t){return this.advertisedStreams.set(e,t),this.recoverStream(e,t.streamId,t.latestRevision).catch(n=>{this.counters.recoveryFailures+=1,this.logger?.warn?.({instanceId:e,streamId:t.streamId,error:n instanceof Error?n.message:String(n)},"ai-session.aggregator.recovery.failed")})}diagnostics(){return{...this.counters,recoveriesStarted:this.recoveryCount,activeRecoveries:this.recoveries.size}}removeInstance(e){this.snapshots.delete(e),this.history.delete(e),this.advertisedStreams.delete(e)}applyPatch(e){return this.apply({type:O,payload:e})}applyRemoved(e){return this.apply({type:_,payload:e})}async list(e={}){return(e.refresh||0===this.snapshots.size)&&await this.bootstrapFromInstances(),this.view()}async streamDescriptors(){return 0===this.snapshots.size&&await this.bootstrapFromInstances(),[...this.snapshots.entries()].map(([e,t])=>({topic:"ai.sessions",instanceId:e,streamId:t.streamId,latestRevision:t.revision,earliestRetainedRevision:this.history.get(e)?.[0]?.payload.meta.revision??t.revision+1}))}async delta(e){0===this.snapshots.size&&await this.bootstrapFromInstances();const t=this.resolveDeltaInstanceId(e.instanceId);this.pruneHistory(t);const n=this.snapshots.get(t)?.revision??0,i=this.snapshots.get(t)?.streamId||"unavailable",s=this.history.get(t)?.[0]?.payload.meta.revision??n+1;if(e.streamId!==i||e.sinceRevision>n)return lt.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:!0,events:[]});if(e.sinceRevision===n)return lt.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:!1,events:[]});const r=(this.history.get(t)??[]).filter(t=>t.payload.meta.revision>e.sinceRevision),o=!r.length||r[0].payload.meta.revision!==e.sinceRevision+1;return lt.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:o,events:o?[]:r.map(({type:e,payload:t})=>({type:e,payload:t}))})}apply(e,t=!1){const{meta:n}=e.payload,i=this.advertisedStreams.get(n.instanceId)?.streamId;if(i&&i!==n.streamId)return this.logger?.warn?.({instanceId:n.instanceId,advertisedStreamId:i,streamId:n.streamId,revision:n.revision},"ai-session.aggregator.event.obsolete-stream"),!1;const s=this.recoveries.get(n.instanceId);if(s&&!t)return s.streamId===n.streamId&&(s.highWater=Math.max(s.highWater,n.revision)),!1;const r=this.snapshots.get(n.instanceId);e.type===N&&r&&r.streamId!==n.streamId&&(this.counters.streamResets+=1,this.logger?.info?.({instanceId:n.instanceId,previousStreamId:r.streamId,streamId:n.streamId,previousRevision:r.revision,revision:n.revision,traceId:n.traceId,resetCount:this.counters.streamResets},"ai-session.aggregator.stream-reset"));const o=function(e,t){const{meta:n}=t.payload;if(t.type===N)return e?.streamId===n.streamId&&n.revision===e.revision?{kind:"duplicate",projection:e}:e?.streamId===n.streamId&&n.revision<e.revision?{kind:"stale",projection:e}:{kind:"applied",projection:et.parse({streamId:n.streamId,revision:n.revision,lastEventAt:n.generatedAt,snapshot:t.payload.snapshot})};if(!e||e.streamId!==n.streamId)return{kind:"snapshot-required",projection:e,streamId:n.streamId};if(n.revision===e.revision)return{kind:"duplicate",projection:e};if(n.revision<e.revision)return{kind:"stale",projection:e};if(n.revision!==e.revision+1||n.previousRevision!==e.revision)return{kind:"gap",projection:e,expectedRevision:e.revision+1,receivedRevision:n.revision};const i=new Map(e.snapshot.sessions.map(e=>[e.id,e]));if(t.type===O){for(const e of t.payload.upserted)i.set(e.id,e);for(const e of t.payload.removed)i.delete(e)}else for(const e of t.payload.sessionIds)i.delete(e);const s=[...i.values()],r=Ze.parse({runningCount:s.filter(e=>"running"===e.status).length,waitingCount:s.filter(e=>"waiting"===e.status).length,staleCount:e.snapshot.staleCount,sessions:s,updatedAt:n.generatedAt});return{kind:"applied",projection:et.parse({streamId:n.streamId,revision:n.revision,lastEventAt:n.generatedAt,snapshot:r})}}(r,e);if("applied"!==o.kind)return this.logger?.warn?.({traceId:n.traceId,streamId:n.streamId,instanceId:n.instanceId,currentRevision:r?.revision,revision:n.revision,outcome:o.kind},`ai-session.aggregator.event.${o.kind}`),"gap"!==o.kind&&"snapshot-required"!==o.kind||("gap"===o.kind&&(this.counters.gaps+=1),this.recoverStream(n.instanceId,n.streamId,n.revision).catch(e=>{this.logger?.warn?.({instanceId:n.instanceId,streamId:n.streamId,revision:n.revision,error:e instanceof Error?e.message:String(e)},"ai-session.aggregator.recovery.failed")})),!1;const a=o.projection;this.snapshots.set(n.instanceId,a),this.rememberEvent(n.instanceId,e);const d={instanceId:n.instanceId,streamId:a.streamId,aiSessions:a.snapshot,revision:a.revision,lastEventAt:a.lastEventAt};for(const e of this.listeners)try{e(d)}catch{this.listeners.delete(e)}return this.logger?.info?.({traceId:n.traceId,streamId:n.streamId,instanceId:n.instanceId,revision:n.revision,reason:n.reason,sessionCount:a.snapshot.sessions.length},"ai-session.aggregator.event.accepted"),!0}async bootstrapFromInstances(){this.logger?.info?.({},"ai-session.aggregator.bootstrap");const e=new Map(this.snapshots),t=await this.bootstrap(),n=new Set(t.instances.map(e=>e.instanceId));for(const[t,i]of e)n.has(t)||this.snapshots.get(t)!==i||(this.snapshots.delete(t),this.history.delete(t),this.advertisedStreams.delete(t));for(const n of t.instances){const t=this.snapshots.get(n.instanceId);if(t!==e.get(n.instanceId))continue;const i=this.advertisedStreams.get(n.instanceId)?.streamId;i&&i!==n.streamId||t?.streamId===n.streamId&&t.revision>=n.revision||(t?.streamId!==n.streamId&&this.history.delete(n.instanceId),this.snapshots.set(n.instanceId,{streamId:n.streamId,snapshot:n.aiSessions,revision:n.revision,lastEventAt:n.lastEventAt}))}}recoverStream(e,t,n){const i=this.recoveries.get(e);if(i)return i.streamId===t?i.highWater=Math.max(i.highWater,n):(i.streamId=t,i.highWater=n),i.promise;if(!this.recoverDelta||!this.recoverSnapshot)return Promise.resolve();const s={promise:Promise.resolve(),streamId:t,highWater:n},r=++this.recoveryCount;return this.logger?.info?.({instanceId:e,highWater:n,recoveryNumber:r},"ai-session.aggregator.recovery.started"),s.promise=(async()=>{for(;;){const t=this.advertisedStreams.get(e);if(!t)return;s.streamId!==t.streamId&&(s.streamId=t.streamId,s.highWater=t.latestRevision);const n=this.snapshots.get(e);if(n&&n.streamId===t.streamId){if(n.revision<Math.max(t.latestRevision,s.highWater)){const t=await this.recoverDelta(e,n.streamId,n.revision);if(this.advertisedStreams.get(e)?.streamId!==t.streamId||s.streamId!==t.streamId)continue;if(t.syncRequired){const t=await this.recoverSnapshot(e);if(this.advertisedStreams.get(e)?.streamId!==t.streamId)continue;const n={type:N,payload:{meta:{streamId:t.streamId,instanceId:e,revision:t.revision,traceId:`ais_recovery_${Date.now().toString(36)}`,generatedAt:t.lastEventAt,reason:"startup"},snapshot:t.snapshot}};this.apply(n,!0)&&this.onRecoveredEvent?.(n),this.counters.snapshotRecoveries+=1,this.logger?.info?.({instanceId:e,streamId:t.streamId,revision:t.revision,recoveryNumber:r,outcome:"snapshot-fallback"},"ai-session.aggregator.recovery.snapshot")}else{for(const e of t.events)this.apply(e,!0)&&this.onRecoveredEvent?.(e);this.counters.deltaRecoveries+=1,s.highWater=Math.max(s.highWater,t.latestRevision),this.logger?.info?.({instanceId:e,streamId:t.streamId,sinceRevision:t.sinceRevision,latestRevision:t.latestRevision,eventCount:t.events.length,recoveryNumber:r,outcome:"delta"},"ai-session.aggregator.recovery.delta")}}}else{const t=await this.recoverSnapshot(e);if(this.advertisedStreams.get(e)?.streamId!==t.streamId)continue;const n={type:N,payload:{meta:{streamId:t.streamId,instanceId:e,revision:t.revision,traceId:`ais_recovery_${Date.now().toString(36)}`,generatedAt:t.lastEventAt,reason:"startup"},snapshot:t.snapshot}};this.apply(n,!0)&&this.onRecoveredEvent?.(n),this.counters.snapshotRecoveries+=1,this.logger?.info?.({instanceId:e,streamId:t.streamId,revision:t.revision,recoveryNumber:r,outcome:"snapshot"},"ai-session.aggregator.recovery.snapshot")}const i=this.snapshots.get(e),o=this.advertisedStreams.get(e);if(i&&o&&i.streamId===o.streamId&&i.revision>=Math.max(o.latestRevision,s.highWater))return void this.logger?.info?.({instanceId:e,streamId:i.streamId,revision:i.revision,recoveryNumber:r,outcome:"success"},"ai-session.aggregator.recovery.completed")}})().finally(()=>this.recoveries.delete(e)),this.recoveries.set(e,s),s.promise}rememberEvent(e,t){const n=this.history.get(e)??[],i=n.length&&n[0].payload.meta.streamId!==t.payload.meta.streamId?[]:n;i.push({...t,createdAtMs:Date.now()}),this.history.set(e,i),this.pruneHistory(e)}pruneHistory(e){const t=this.history.get(e);if(!t?.length)return;const n=t.filter(e=>e.createdAtMs>=Date.now()-36e5);n.length?this.history.set(e,n):this.history.delete(e)}resolveDeltaInstanceId(e){if(e)return e;const t=[...this.snapshots.keys()];if(1===t.length)return t[0];throw new Error("AI_SESSION_DELTA_INSTANCE_ID_REQUIRED")}view(){return{updatedAt:(new Date).toISOString(),instances:[...this.snapshots.entries()].map(([e,t])=>({instanceId:e,streamId:t.streamId,aiSessions:t.snapshot,revision:t.revision,lastEventAt:t.lastEventAt}))}}}const dm=a.z.object({id:a.z.string().trim().min(1),instanceId:a.z.string().trim().min(1).max(160),sessionId:a.z.string().trim().min(1).max(120),unread:a.z.boolean(),lastStatus:a.z.enum(["running","waiting","idle","failed"]),sessionUpdatedAt:a.z.string().datetime(),createdAt:a.z.string().datetime(),updatedAt:a.z.string().datetime()}).strict();class cm{records;bySession=new Map;listener;constructor(e,t={}){this.records=new yo(e.aiSessionUnreadDir,{schema:dm}),this.listener=t.onChanged}init(){this.records.init(),this.bySession.clear();for(const e of this.records.list())this.bySession.set(pm(e.instanceId,e.sessionId),e)}reconcile(e,t){const n=new Set;for(const i of t.sessions)n.add(i.id),this.reconcileSession(e,i);for(const t of[...this.bySession.values()])t.instanceId!==e||n.has(t.sessionId)||this.deleteRecord(t)}decorate(e,t){return{...t,sessions:t.sessions.map(t=>({...t,unread:this.bySession.get(pm(e,t.id))?.unread||!1}))}}markRead(e,t,n){const i=this.bySession.get(pm(e,t));return i&&i.sessionUpdatedAt===n&&i.unread?lm(this.store({...i,unread:!1,updatedAt:(new Date).toISOString()},!1)):i?lm(i):void 0}removeInstance(e){for(const t of[...this.bySession.values()])t.instanceId===e&&this.deleteRecord(t)}reconcileSession(e,t){const n=pm(e,t.id),i=this.bySession.get(n),s=(new Date).toISOString();if(!i)return void this.store({id:um(e,t.id),instanceId:e,sessionId:t.id,unread:!1,lastStatus:t.status,sessionUpdatedAt:t.updatedAt,createdAt:s,updatedAt:s},!1);const r=function(e,t,n){return"running"!==n&&"waiting"!==n&&("running"===t||"waiting"===t||e)}(i.unread,i.lastStatus,t.status),o=r!==i.unread;(o||i.lastStatus!==t.status||i.sessionUpdatedAt!==t.updatedAt)&&this.store({...i,unread:r,lastStatus:t.status,sessionUpdatedAt:t.updatedAt,updatedAt:s},o)}store(e,t){const n=this.records.put(e);return this.bySession.set(pm(n.instanceId,n.sessionId),n),t&&this.listener?.(lm(n)),n}deleteRecord(e){this.records.delete(e.id),this.bySession.delete(pm(e.instanceId,e.sessionId))}}function lm(e){return q.parse({instanceId:e.instanceId,sessionId:e.sessionId,unread:e.unread,sessionUpdatedAt:e.sessionUpdatedAt,updatedAt:e.updatedAt})}function pm(e,t){return`${e}\0${t}`}function um(e,t){return`ais_unread_${i.createHash("sha256").update(pm(e,t)).digest("hex").slice(0,32)}`}class gm{snapshots=new Map;history=new Map;advertisedStreams=new Map;recoveries=new Map;bootstrap;logger;recoverDelta;recoverSnapshot;onRecoveredEvent;recoveryCount=0;counters={streamResets:0,gaps:0,deltaRecoveries:0,snapshotRecoveries:0,recoveryFailures:0};constructor(e){this.bootstrap=e.bootstrap,this.logger=e.logger,this.recoverDelta=e.recoverDelta,this.recoverSnapshot=e.recoverSnapshot,this.onRecoveredEvent=e.onRecoveredEvent}handleEvent(e){const t=e.type===mt?Et:e.type===yt?Ct:e.type===ft?xt:void 0;if(!t)return!1;const n=$o(t,e.payload);return n.success?e.type===mt?this.applySnapshot(n.data):e.type===yt?this.applyPatch(n.data):this.applyRemoved(n.data):(this.logger?.warn?.({eventType:e.type,issues:n.error.issues,errorCode:"APP_SESSION_EVENT_INVALID"},"app-session.aggregator.event.invalid"),!1)}applySnapshot(e){const t=this.advertisedStreams.get(e.meta.instanceId)?.streamId;return t&&t!==e.meta.streamId?(this.logger?.warn?.({instanceId:e.meta.instanceId,advertisedStreamId:t,streamId:e.meta.streamId,revision:e.meta.revision},"app-session.aggregator.snapshot.obsolete-stream"),!1):this.apply({type:mt,payload:e})}advertiseStream(e,t){return this.advertisedStreams.set(e,t),this.recoverStream(e,t.streamId,t.latestRevision).catch(n=>{this.counters.recoveryFailures+=1,this.logger?.warn?.({instanceId:e,streamId:t.streamId,error:n instanceof Error?n.message:String(n)},"app-session.aggregator.recovery.failed")})}diagnostics(){return{...this.counters,recoveriesStarted:this.recoveryCount,activeRecoveries:this.recoveries.size}}removeInstance(e){this.snapshots.delete(e),this.history.delete(e),this.advertisedStreams.delete(e)}applyPatch(e){return this.apply({type:yt,payload:e})}applyRemoved(e){return this.apply({type:ft,payload:e})}async list(e={}){return(e.refresh||0===this.snapshots.size)&&await this.bootstrapFromInstances(),this.view()}async streamDescriptors(){return 0===this.snapshots.size&&await this.bootstrapFromInstances(),[...this.snapshots.entries()].map(([e,t])=>({topic:"app.sessions",instanceId:e,streamId:t.streamId,latestRevision:t.revision,earliestRetainedRevision:this.history.get(e)?.[0]?.payload.meta.revision??t.revision+1}))}async delta(e){0===this.snapshots.size&&await this.bootstrapFromInstances();const t=this.resolveDeltaInstanceId(e.instanceId);this.pruneHistory(t);const n=this.snapshots.get(t)?.revision??0,i=this.snapshots.get(t)?.streamId||"unavailable",s=this.history.get(t)?.[0]?.payload.meta.revision??n+1;if(e.streamId!==i||e.sinceRevision>n)return Nt.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:!0,events:[]});if(e.sinceRevision===n)return Nt.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:!1,events:[]});const r=(this.history.get(t)??[]).filter(t=>t.payload.meta.revision>e.sinceRevision),o=!r.length||r[0].payload.meta.revision!==e.sinceRevision+1;return Nt.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:o,events:o?[]:r.map(({type:e,payload:t})=>({type:e,payload:t}))})}apply(e,t=!1){const{meta:n}=e.payload,i=this.advertisedStreams.get(n.instanceId)?.streamId;if(i&&i!==n.streamId)return this.logger?.warn?.({instanceId:n.instanceId,advertisedStreamId:i,streamId:n.streamId,revision:n.revision},"app-session.aggregator.event.obsolete-stream"),!1;const s=this.recoveries.get(n.instanceId);if(s&&!t)return s.streamId===n.streamId&&(s.highWater=Math.max(s.highWater,n.revision)),!1;const r=this.snapshots.get(n.instanceId);e.type===mt&&r&&r.streamId!==n.streamId&&(this.counters.streamResets+=1,this.logger?.info?.({instanceId:n.instanceId,previousStreamId:r.streamId,streamId:n.streamId,previousRevision:r.revision,revision:n.revision,traceId:n.traceId,resetCount:this.counters.streamResets},"app-session.aggregator.stream-reset"));const o=function(e,t){const{meta:n}=t.payload;if(t.type===mt)return e?.streamId===n.streamId&&n.revision===e.revision?{kind:"duplicate",projection:e}:e?.streamId===n.streamId&&n.revision<e.revision?{kind:"stale",projection:e}:{kind:"applied",projection:zt.parse({streamId:n.streamId,revision:n.revision,lastEventAt:n.generatedAt,snapshot:_t(t.payload.snapshot.sessions,t.payload.snapshot.updatedAt)})};if(!e||e.streamId!==n.streamId)return{kind:"snapshot-required",projection:e,streamId:n.streamId};if(n.revision===e.revision)return{kind:"duplicate",projection:e};if(n.revision<e.revision)return{kind:"stale",projection:e};if(n.revision!==e.revision+1||n.previousRevision!==e.revision)return{kind:"gap",projection:e,expectedRevision:e.revision+1,receivedRevision:n.revision};const i=[...e.snapshot.sessions];if(t.type===yt){const e=i.findIndex(e=>e.id===t.payload.session.id);jt(t.payload.session.status)?e<0?i.push(t.payload.session):i[e]=t.payload.session:e>=0&&i.splice(e,1)}else{const e=i.findIndex(e=>e.id===t.payload.sessionId);e>=0&&i.splice(e,1)}const s=Ot(i,n.generatedAt);return{kind:"applied",projection:zt.parse({streamId:n.streamId,revision:n.revision,lastEventAt:n.generatedAt,snapshot:s})}}(r,e);if("applied"!==o.kind)return this.logger?.warn?.({traceId:n.traceId,streamId:n.streamId,instanceId:n.instanceId,currentRevision:r?.revision,revision:n.revision,outcome:o.kind},`app-session.aggregator.event.${o.kind}`),"gap"!==o.kind&&"snapshot-required"!==o.kind||("gap"===o.kind&&(this.counters.gaps+=1),this.recoverStream(n.instanceId,n.streamId,n.revision).catch(e=>{this.logger?.warn?.({instanceId:n.instanceId,streamId:n.streamId,revision:n.revision,error:e instanceof Error?e.message:String(e)},"app-session.aggregator.recovery.failed")})),!1;const a=o.projection;return this.snapshots.set(n.instanceId,a),this.rememberEvent(n.instanceId,e),this.logger?.info?.({traceId:n.traceId,streamId:n.streamId,instanceId:n.instanceId,revision:n.revision,reason:n.reason,sessionCount:a.snapshot.sessions.length,runningCount:a.snapshot.runningCount,problemCount:a.snapshot.problemCount},"app-session.aggregator.event.accepted"),!0}async bootstrapFromInstances(){this.logger?.info?.({},"app-session.aggregator.bootstrap");const e=new Map(this.snapshots),t=await this.bootstrap(),n=new Set(t.instances.map(e=>e.instanceId));for(const[t,i]of e)n.has(t)||this.snapshots.get(t)!==i||(this.snapshots.delete(t),this.history.delete(t),this.advertisedStreams.delete(t));for(const n of t.instances){const t=this.snapshots.get(n.instanceId);if(t!==e.get(n.instanceId))continue;const i=this.advertisedStreams.get(n.instanceId)?.streamId;i&&i!==n.streamId||t?.streamId===n.streamId&&t.revision>=n.revision||(t?.streamId!==n.streamId&&this.history.delete(n.instanceId),this.snapshots.set(n.instanceId,{streamId:n.streamId,snapshot:_t(n.appSessions.sessions,n.appSessions.updatedAt),revision:n.revision,lastEventAt:n.lastEventAt}))}}recoverStream(e,t,n){const i=this.recoveries.get(e);if(i)return i.streamId===t?i.highWater=Math.max(i.highWater,n):(i.streamId=t,i.highWater=n),i.promise;if(!this.recoverDelta||!this.recoverSnapshot)return Promise.resolve();const s={promise:Promise.resolve(),streamId:t,highWater:n},r=++this.recoveryCount;return this.logger?.info?.({instanceId:e,highWater:n,recoveryNumber:r},"app-session.aggregator.recovery.started"),s.promise=(async()=>{for(;;){const t=this.advertisedStreams.get(e);if(!t)return;s.streamId!==t.streamId&&(s.streamId=t.streamId,s.highWater=t.latestRevision);const n=this.snapshots.get(e);if(n&&n.streamId===t.streamId){if(n.revision<Math.max(t.latestRevision,s.highWater)){const t=await this.recoverDelta(e,n.streamId,n.revision);if(this.advertisedStreams.get(e)?.streamId!==t.streamId||s.streamId!==t.streamId)continue;if(t.syncRequired){const t=await this.recoverSnapshot(e);if(this.advertisedStreams.get(e)?.streamId!==t.streamId)continue;const n={type:mt,payload:{meta:{streamId:t.streamId,instanceId:e,revision:t.revision,traceId:`aps_recovery_${Date.now().toString(36)}`,generatedAt:t.lastEventAt,reason:"startup"},snapshot:t.snapshot}};this.apply(n,!0)&&this.onRecoveredEvent?.(n),this.counters.snapshotRecoveries+=1,this.logger?.info?.({instanceId:e,streamId:t.streamId,revision:t.revision,recoveryNumber:r,outcome:"snapshot-fallback"},"app-session.aggregator.recovery.snapshot")}else{for(const e of t.events)this.apply(e,!0)&&this.onRecoveredEvent?.(e);this.counters.deltaRecoveries+=1,s.highWater=Math.max(s.highWater,t.latestRevision),this.logger?.info?.({instanceId:e,streamId:t.streamId,sinceRevision:t.sinceRevision,latestRevision:t.latestRevision,eventCount:t.events.length,recoveryNumber:r,outcome:"delta"},"app-session.aggregator.recovery.delta")}}}else{const t=await this.recoverSnapshot(e);if(this.advertisedStreams.get(e)?.streamId!==t.streamId)continue;const n={type:mt,payload:{meta:{streamId:t.streamId,instanceId:e,revision:t.revision,traceId:`aps_recovery_${Date.now().toString(36)}`,generatedAt:t.lastEventAt,reason:"startup"},snapshot:t.snapshot}};this.apply(n,!0)&&this.onRecoveredEvent?.(n),this.counters.snapshotRecoveries+=1,this.logger?.info?.({instanceId:e,streamId:t.streamId,revision:t.revision,recoveryNumber:r,outcome:"snapshot"},"app-session.aggregator.recovery.snapshot")}const i=this.snapshots.get(e),o=this.advertisedStreams.get(e);if(i&&o&&i.streamId===o.streamId&&i.revision>=Math.max(o.latestRevision,s.highWater))return void this.logger?.info?.({instanceId:e,streamId:i.streamId,revision:i.revision,recoveryNumber:r,outcome:"success"},"app-session.aggregator.recovery.completed")}})().finally(()=>this.recoveries.delete(e)),this.recoveries.set(e,s),s.promise}rememberEvent(e,t){const n=this.history.get(e)??[],i=n.length&&n[0].payload.meta.streamId!==t.payload.meta.streamId?[]:n;i.push({...t,createdAtMs:Date.now()}),this.history.set(e,i),this.pruneHistory(e)}pruneHistory(e){const t=this.history.get(e);if(!t?.length)return;const n=t.filter(e=>e.createdAtMs>=Date.now()-36e5);n.length?this.history.set(e,n):this.history.delete(e)}resolveDeltaInstanceId(e){if(e)return e;const t=[...this.snapshots.keys()];if(1===t.length)return t[0];throw new Error("APP_SESSION_DELTA_INSTANCE_ID_REQUIRED")}view(){return{updatedAt:(new Date).toISOString(),instances:[...this.snapshots.entries()].map(([e,t])=>({instanceId:e,streamId:t.streamId,appSessions:t.snapshot,revision:t.revision,lastEventAt:t.lastEventAt}))}}}function hm(e){return e.raw[0].replace(/\\\$\{/g,"${")}class mm{states=new Map;events;constructor(e){this.events=e}handle(e){if(e.type===Mr){const t=$o(Lr,e.payload);return void(t.success&&this.reconcileLifecycle(t.data))}if("instance.deleted"===e.type){const t=e.payload&&"object"==typeof e.payload&&"instanceId"in e.payload?String(e.payload.instanceId||""):"";return void(t&&this.deleteState(t))}if(e.type===or){const t=$o(cr,e.payload);return void(t.success&&this.applyOutput(t.data))}if(e.type===ar){const t=$o(lr,e.payload);t.success&&this.applyFinished(t.data)}}snapshots(){return[...this.states.values()].filter(e=>e.progress).map(e=>pr.parse({...e.progress,terminalTail:e.terminalTail,...e.terminalTruncated?{terminalTruncated:!0}:{}}))}close(){for(const e of this.states.values())e.timer&&clearTimeout(e.timer);this.states.clear()}deleteState(e){const t=this.states.get(e);t?.timer&&clearTimeout(t.timer),this.states.delete(e)}reconcileLifecycle(e){const t=this.states.get(e.instanceId),n=e.imageProvisioning;t&&(!n||n.generation>t.identity.generation||n.generation===t.identity.generation&&"ready"===n.phase)&&this.deleteState(e.instanceId)}applyOutput(e){const t=this.states.get(e.instanceId);if(t&&e.generation<t.identity.generation)return;if(t&&e.generation===t.identity.generation&&!e.replay&&e.sequence<=t.sequence)return;const n=this.requireState(e);e.replay&&(n.terminal=new bm,n.terminalTail="",n.layers.clear(),n.terminalTruncated=!1),n.sequence=Math.max(n.sequence,e.sequence),n.observedAt=e.observedAt,n.terminal.write(e.data);const i=`${n.terminalTail}${e.data}`;n.terminalTruncated||=i.length>262144,n.terminalTail=i.slice(-262144),function(e,t){for(const n of t.split("\n")){const t=n.trim().match(/^([a-f0-9]{6,64}):\s+(.+)$/i);if(!t)continue;const[,i,s]=t,r=s.toLowerCase(),o=["pull complete","already exists","download complete","pulling fs layer","waiting","downloading","extracting"].find(e=>r.startsWith(e));if(!o)continue;const a=e.get(i)||{status:o},d=fm(s);e.set(i,{...a,status:o,...d||{}})}}(n.layers,n.terminal.text()),n.progress=ym(n),this.schedule(n)}applyFinished(e){const t=this.states.get(e.instanceId);if(t&&e.generation<t.identity.generation)return;if(t&&e.generation===t.identity.generation&&e.sequence<=t.sequence)return;const n=this.requireState(e);n.sequence=Math.max(n.sequence,e.sequence),n.observedAt=e.observedAt,n.outcome=e.outcome,n.progress=ym(n),this.publish(n,!0)}requireState(e){const t=this.states.get(e.instanceId);if(t&&t.identity.generation===e.generation)return t;t?.timer&&clearTimeout(t.timer);const n={identity:{instanceId:e.instanceId,generation:e.generation,requestedReference:e.requestedReference},sequence:e.sequence,observedAt:e.observedAt,terminal:new bm,terminalTail:"",terminalTruncated:!1,layers:new Map};return this.states.set(e.instanceId,n),n}schedule(e){e.timer||(e.timer=setTimeout(()=>this.publish(e,!1),250),e.timer.unref?.())}publish(e,t){e.timer&&clearTimeout(e.timer),e.timer=void 0,e.progress&&(e.progress=ym(e),this.events.publish("image.pull.progress",e.progress,{topic:"instances",scope:{instanceId:e.identity.instanceId}}),t&&(e.progress=ym(e)))}}function ym(e){const t=[...e.layers.values()],n=t.filter(e=>["pull complete","already exists"].includes(e.status)).length,i=t.filter(e=>"download complete"===e.status).length,s=t.filter(e=>"downloading"===e.status).length,r=t.filter(e=>"extracting"===e.status).length;let o=0,a=0;for(const e of t)e.total&&(a+=e.total,o+=["pull complete","already exists","download complete"].includes(e.status)?e.total:Math.min(e.current||0,e.total));const d="failed"===e.outcome?"failed":"succeeded"===e.outcome?"complete":r>0?"extracting":t.length>0?"pulling":"connecting",c=t.filter(e=>"already exists"!==e.status),l=c.length>0&&c.every(e=>Boolean(e.total)),p=l&&a>0?Math.max(0,Math.min(100,o/a*100)):void 0,u="failed"===d?"Image pull failed":"complete"===d?"Image pull complete":t.length?`${n}/${t.length} layers ready${void 0===p?"":` · ${Math.round(p)}%`}`:"Connecting to image registry";return pr.parse({...e.identity,sequence:e.sequence,observedAt:e.observedAt,status:d,layers:{total:t.length,completed:n,downloaded:i,downloading:s,extracting:r},...l&&a>0?{bytes:{current:o,total:a},percent:p}:{},message:u})}function fm(e){const t=e.match(/([\d.]+)\s*([kmgt]?i?b)\s*\/\s*([\d.]+)\s*([kmgt]?i?b)/i);if(t)return{current:Im(t[1],t[2]),total:Im(t[3],t[4])}}function Im(e,t){return Number(e)*1024**({b:0,kb:1,kib:1,mb:2,mib:2,gb:3,gib:3,tb:4,tib:4}[t.toLowerCase()]||0)}class bm{lines=[[]];row=0;col=0;pending="";write(e){const t=`${this.pending}${e}`;this.pending="";for(let e=0;e<t.length;){const n=t[e];if(""===n&&"["===t[e+1]){let n=e+2;for(;n<t.length&&!/[\x40-\x7e]/.test(t[n]);)n+=1;if(n>=t.length){this.pending=t.slice(e);break}this.csi(t.slice(e+2,n),t[n]),e=n+1;continue}"\r"===n?this.col=0:"\n"===n?(this.row+=1,this.col=0,this.ensureLine()):"\b"===n?this.col=Math.max(0,this.col-1):n>=" "&&(this.ensureLine(),this.lines[this.row][this.col]=n,this.col+=1),e+=1}this.trim()}text(){return this.lines.map(e=>e.join("").trimEnd()).join("\n")}csi(e,t){const n=e.replace(/^\?/,"").split(";").map(e=>Number(e||1)),i=n[0]||1;"A"===t?this.row=Math.max(0,this.row-i):"B"===t?(this.row+=i,this.ensureLine()):"C"===t?this.col+=i:"D"===t?this.col=Math.max(0,this.col-i):"G"===t?this.col=Math.max(0,i-1):"H"===t||"f"===t?(this.row=Math.max(0,i-1),this.col=Math.max(0,(n[1]||1)-1),this.ensureLine()):"K"===t?(this.ensureLine(),2===(n[0]||0)?this.lines[this.row]=[]:this.lines[this.row].splice(this.col)):"J"===t&&2===(n[0]||0)&&(this.lines=[[]],this.row=0,this.col=0)}ensureLine(){for(;this.lines.length<=this.row;)this.lines.push([])}trim(){if(this.lines.length<=500)return;const e=this.lines.length-500;this.lines.splice(0,e),this.row=Math.max(0,this.row-e)}}const vm=Xn.extend({credentialHash:a.z.string().trim().min(32).max(256)}).strict(),wm=a.z.object({revision:a.z.number().int().nonnegative(),invites:a.z.array(a.z.unknown()).length(0).default([]),bindings:a.z.array(vm)}).strict(),Sm={binding:new Set(Object.keys(vm.shape))};function Am(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e;return Object.fromEntries([...t].filter(e=>e in n).map(e=>[e,n[e]]))}function zm(e){const{tokenHash:t,...n}=e;return Kn.parse(n)}function km(e){const{credentialHash:t,...n}=e;return Xn.parse(n)}class Tm{authority;constructor(e,t){this.authority=new fo(e,()=>({revision:0,invites:[],bindings:[]}),{schema:wm,sanitize:e=>function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e,i=new Set(["revision","invites","bindings"]),s=Object.keys(n).filter(e=>!i.has(e));return s.length>0&&t?.({kind:"authority",fields:s}),{...void 0===n.revision?{}:{revision:n.revision},invites:[],bindings:Array.isArray(n.bindings)?n.bindings.map(e=>function(e,t,n){if(!t||"object"!=typeof t||Array.isArray(t))return t;const i=t,s=Sm[e],r=Object.keys(i).filter(e=>!s.has(e));r.length>0&&n?.({kind:e,fields:r});const o=Am(i,s);return o.lastError&&(o.lastError=Am(o.lastError,Object.keys(Gn.shape))),o}("binding",e,t)).filter(e=>!e||"object"!=typeof e||"revoked"!==e.status):n.bindings}}(e,e=>t?.("unknown stored control-plane proxy fields were ignored",e)),logger:t,directoryMode:448,fileMode:384})}init(){this.authority.init();const e=this.authority.get();this.authority.put(e)}snapshot(){return this.authority.get()}transaction(e){const t=this.authority.get(),n=structuredClone(t),i=e(n);return JSON.stringify(n)!==JSON.stringify(t)&&this.authority.put({...n,revision:t.revision+1}),i}listBindings(){return this.snapshot().bindings}getBinding(e){return this.snapshot().bindings.find(t=>t.id===e)}}class Em extends Error{code;statusCode;retryable;details;constructor(e,t,n,i=!1,s={}){super(t),this.name="ControlPlaneProxyServiceError",this.code=e,this.statusCode=n,this.retryable=i,this.details=s}}const Cm=e=>i.createHash("sha256").update(e).digest("base64url"),xm=()=>i.randomBytes(32).toString("base64url");function Nm(e,t,n,i=!1,s={}){throw new Em(e,t,n,i,s)}class Om{store;targets;configuredProxyOrigin;proxyOriginProvider;now;createTokenValue;invites=new Pc;constructor(e,t,n){this.store=e,this.targets=t,this.configuredProxyOrigin=n.proxyOrigin,this.proxyOriginProvider=n.proxyOriginProvider,this.now=n.now??(()=>new Date),this.createTokenValue=n.createToken??xm}init(){this.store.init()}createInvite(e,t){const n=this.resolveProxyOrigin();n||Nm(Hn.Unavailable,"Configure an externally reachable HTTPS control-plane proxy origin before creating an invite.",409,!1);const i=Jn.parse(e);this.requireManageableTarget(i.targetNodeId);const s=this.createTokenValue(),r=this.nowIso(),o={id:ho("proxy_invite"),targetNodeId:i.targetNodeId,tokenHash:Cm(s),status:"active",createdBy:t,expiresAt:new Date(this.now().getTime()+Math.min(1e3*i.expiresInSeconds,6e5)).toISOString(),createdAt:r,updatedAt:r},a=Yn.parse({invite:zm(o),token:s,proxyOrigin:n,protocolVersion:Nn});return this.invites.put(o.tokenHash,o,this.now().getTime()),a}resolveProxyOrigin(){const e=this.configuredProxyOrigin??this.proxyOriginProvider?.();if(!e)return;const t=Dn.safeParse(e);return t.success?t.data:void 0}listInvites(){return this.invites.list(this.now().getTime()).map(zm)}revokeInvite(e){const t=this.listInviteRecords().find(t=>t.id===e);t||Nm(Hn.InviteInvalid,"Proxy invite is unknown.",404,!1,{inviteId:e});const n=this.nowIso(),i={...t,status:"revoked",revokedAt:n,updatedAt:n};return this.invites.delete(t.tokenHash,this.now().getTime()),zm(i)}claimInvite(e){const t=Zn.parse(e);this.requireCurrentProtocol(t.protocolVersion);const n=Cm(t.credential),i=this.store.listBindings().find(e=>e.claimId===t.claimId);if(i)return this.requireRecoveredIdentity(i,t,n),this.claimResult(i,this.requireKnownTarget(i.targetNodeId));t.inviteToken||Nm(Hn.InviteInvalid,"Proxy invite token is required for the first claim.",401);const s=Cm(t.inviteToken),r=this.invites.peek(s,this.now().getTime());r||Nm(Hn.InviteInvalid,"Proxy invite is invalid or expired.",401),t.targetNodeId&&t.targetNodeId!==r.targetNodeId&&Nm(Hn.TargetMismatch,"Proxy invite is bound to a different target.",409,!1,{inviteId:r.id,targetNodeId:t.targetNodeId});const o=this.requireManageableTarget(r.targetNodeId),a=this.store.transaction(e=>{const i=(s=r.id,`proxy_binding_${Cm(s).slice(0,32)}`);var s;const a=this.nowIso(),d={id:i,claimId:t.claimId,sourceControlPlaneId:t.sourceControlPlaneId,targetNodeId:r.targetNodeId,bindingKeyId:t.bindingKeyId,credentialHash:n,status:"active",revision:1,createdAt:a,updatedAt:a};return e.bindings.push(d),this.claimResult(d,o)});return this.invites.delete(s,this.now().getTime()),a}listBindings(){return this.store.listBindings().map(km)}authenticateBinding(e,t){const n=ei.parse(t),s=this.store.getBinding(e);return s||Nm(Hn.BindingUnknown,"Proxy binding is unknown.",404,!1,{bindingId:e}),"active"!==s.status&&Nm(Hn.BindingRevoked,"Proxy binding is revoked.",403,!1,{bindingId:e}),s.sourceControlPlaneId===n.sourceControlPlaneId&&s.bindingKeyId===n.bindingKeyId&&function(e,t){const n=Cm(t),s=Buffer.from(e),r=Buffer.from(n);return s.length===r.length&&i.timingSafeEqual(s,r)}(s.credentialHash,n.credential)||Nm(Hn.AuthenticationFailed,"Proxy binding authentication failed.",401,!1,{bindingId:e}),km(s)}revokeBinding(e){const t=this.requireBinding(e);if("revoked"===t.status)return km(t);const n=this.nowIso(),i={...t,status:"revoked",revision:t.revision+1,revokedAt:n,updatedAt:n};return this.store.transaction(t=>{t.bindings=t.bindings.filter(t=>t.id!==e)}),km(i)}revokeTarget(e){return this.store.transaction(t=>{const n=this.nowIso(),i=t.bindings.filter(t=>t.targetNodeId===e&&"active"===t.status).map(e=>km({...e,status:"revoked",revision:e.revision+1,revokedAt:n,updatedAt:n}));return t.bindings=t.bindings.filter(t=>t.targetNodeId!==e),{bindings:i,invites:this.revokeTargetInvites(e,n)}})}nowIso(){return this.now().toISOString()}requireCurrentProtocol(e){e!==Nn&&Nm(Hn.ProtocolUnsupported,"Control-plane proxy protocol version is unsupported.",426,!1,{requestedVersion:e,supportedVersion:Nn})}requireKnownTarget(e){const t=this.targets.get(e);return t||Nm(Hn.TargetUnavailable,"Proxy target no longer exists.",404,!1,{targetNodeId:e}),t}requireManageableTarget(e){const t=this.requireKnownTarget(e);return t.manageable&&"online"===t.status||Nm(Hn.TargetUnavailable,"Proxy target is not currently manageable.",503,!0,{targetNodeId:e}),t}requireBinding(e){const t=this.store.getBinding(e);return t||Nm(Hn.BindingUnknown,"Proxy binding is unknown.",404,!1,{bindingId:e}),t}requireRecoveredIdentity(e,t,n){(e.claimId!==t.claimId||e.sourceControlPlaneId!==t.sourceControlPlaneId||void 0!==t.targetNodeId&&e.targetNodeId!==t.targetNodeId||e.bindingKeyId!==t.bindingKeyId||e.credentialHash!==n)&&Nm(Hn.BindingIdentityConflict,"Proxy claim conflicts with an existing binding identity.",409,!1,{claimId:t.claimId})}claimResult(e,t){const{manageable:n,...i}=t;return ai.parse({protocolVersion:Nn,binding:km(e),target:i})}listInviteRecords(){return this.invites.list(this.now().getTime())}revokeTargetInvites(e,t){const n=this.listInviteRecords().filter(t=>t.targetNodeId===e);for(const e of n)this.invites.delete(e.tokenHash,this.now().getTime());return n.map(e=>zm({...e,status:"revoked",revokedAt:t,updatedAt:t}))}}class _m extends Error{statusCode=429;code=Hn.ResourceLimit;retryable=!0;details;constructor(e,t){super(e),this.name="NodeProxyRuntimeError",this.details=t}}class Rm{maxRequestBodyBytes;maxConcurrentHttpPerBinding;maxConcurrentStreamsPerBinding;maxHttpRequestsPerMinutePerBinding;maxConcurrentWebSocketsPerBinding;maxHttpResponseBytes;httpStreamIdleTimeoutMs;maxWebSocketFrameBytes;maxWebSocketBytes;webSocketIdleTimeoutMs;httpRequestWindowMs;bindings=new Map;requestWindows=new Map;requestWindowTimers=new Map;constructor(e={}){this.maxConcurrentHttpPerBinding=e.maxConcurrentHttpPerBinding??32,this.maxConcurrentStreamsPerBinding=e.maxConcurrentStreamsPerBinding??16,this.maxHttpRequestsPerMinutePerBinding=e.maxHttpRequestsPerMinutePerBinding??600,this.maxConcurrentWebSocketsPerBinding=e.maxConcurrentWebSocketsPerBinding??16,this.maxRequestBodyBytes=e.maxRequestBodyBytes??8388608,this.maxHttpResponseBytes=e.maxHttpResponseBytes??268435456,this.httpStreamIdleTimeoutMs=e.httpStreamIdleTimeoutMs??12e4,this.maxWebSocketFrameBytes=e.maxWebSocketFrameBytes??8388608,this.maxWebSocketBytes=e.maxWebSocketBytes??268435456,this.webSocketIdleTimeoutMs=e.webSocketIdleTimeoutMs??3e5,this.httpRequestWindowMs=e.httpRequestWindowMs??6e4}reserveHttp(e){this.consumeRequestRate(e);const t=this.activity(e);if(t.controllers.size>=this.maxConcurrentHttpPerBinding)throw this.deleteIfEmpty(e,t),this.limit("Proxy HTTP concurrency limit exceeded.",e,"http-concurrency",this.maxConcurrentHttpPerBinding);const n=new AbortController;t.controllers.add(n);let i,s=!1,r=!1,o=0;const a=()=>{r&&!s&&(i&&clearTimeout(i),i=setTimeout(()=>{n.abort(Object.assign(new Error("Proxy HTTP stream idle timeout."),{code:Hn.ResourceLimit}))},this.httpStreamIdleTimeoutMs),i.unref?.())};return{controller:n,acceptRequestBody:t=>{if(t>this.maxRequestBodyBytes)throw this.limit("Proxy request body limit exceeded.",e,"request-body",this.maxRequestBodyBytes)},beginResponseStream:()=>{if(!s&&!r){if(t.streams.size>=this.maxConcurrentStreamsPerBinding)throw this.limit("Proxy HTTP stream concurrency limit exceeded.",e,"stream-concurrency",this.maxConcurrentStreamsPerBinding);r=!0,t.streams.add(n),a()}},acceptResponseChunk:t=>{if(!s){if(o+=Pm(t),o>this.maxHttpResponseBytes){const t=this.limit("Proxy HTTP response byte limit exceeded.",e,"response-bytes",this.maxHttpResponseBytes);throw n.abort(t),t}a()}},release:()=>{s||(s=!0,i&&clearTimeout(i),t.controllers.delete(n),t.streams.delete(n),this.deleteIfEmpty(e,t))}}}openHttp(e,t){const n=this.reserveHttp(e);try{return n.acceptRequestBody(t),n}catch(e){throw n.release(),e}}openWebSocket(e,t,n){const i=this.activity(e);if(i.sockets.size>=this.maxConcurrentWebSocketsPerBinding)throw this.limit("Proxy WebSocket concurrency limit exceeded.",e,"websocket-concurrency",this.maxConcurrentWebSocketsPerBinding);let s,r=!1,o=0;const a=()=>{r||(r=!0,s&&clearTimeout(s),i.sockets.delete(p),this.deleteIfEmpty(e,i),n?.())},d=e=>{a(),t.close(1009,e)},c=()=>{s&&clearTimeout(s),s=setTimeout(()=>{a(),t.close(1001,"Proxy WebSocket idle timeout.")},this.webSocketIdleTimeoutMs),s.unref?.()},l=e=>{const t=Pm(e);return t>this.maxWebSocketFrameBytes?(d("Proxy WebSocket frame limit exceeded."),!1):(o+=t,o>this.maxWebSocketBytes?(d("Proxy WebSocket byte limit exceeded."),!1):(c(),!0))};c();const p={get readyState(){return t.readyState},send:e=>{!r&&l(e)&&t.send(e)},close:(e,n)=>{a(),t.close(e,n)},on:(e,n)=>{"message"!==e?"close"!==e&&"error"!==e?t.on(e,n):t.on(e,(...e)=>{a(),n(...e)}):t.on(e,(e,...t)=>{!r&&l(e)&&n(e,...t)})}};return i.sockets.add(p),p}closeBinding(e,t="Proxy binding was revoked."){const n=this.bindings.get(e);if(!n)return this.clearRequestWindow(e),{abortedRequests:0,closedSockets:0};const i=[...n.controllers],s=[...n.sockets],r=[...n.cleanup];this.bindings.delete(e);for(const e of i)e.abort(Object.assign(new Error(t),{code:Hn.BindingRevoked}));for(const e of r)e();for(const e of s)e.close(1008,t);return n.controllers.clear(),n.streams.clear(),n.sockets.clear(),n.cleanup.clear(),this.clearRequestWindow(e),{abortedRequests:i.length,closedSockets:s.length}}diagnostics(e){if(e){const t=this.bindings.get(e);return{bindingId:e,activeHttp:t?.controllers.size??0,activeStreams:t?.streams.size??0,activeWebSockets:t?.sockets.size??0}}return[...this.bindings].map(([e,t])=>({bindingId:e,activeHttp:t.controllers.size,activeStreams:t.streams.size,activeWebSockets:t.sockets.size}))}registerBindingCleanup(e,t){const n=this.activity(e);return n.cleanup.add(t),()=>{n.cleanup.delete(t),this.deleteIfEmpty(e,n)}}activity(e){const t=this.bindings.get(e);if(t)return t;const n={controllers:new Set,streams:new Set,sockets:new Set,cleanup:new Set};return this.bindings.set(e,n),n}deleteIfEmpty(e,t){0===t.controllers.size&&0===t.streams.size&&0===t.sockets.size&&0===t.cleanup.size&&this.bindings.get(e)===t&&this.bindings.delete(e)}limit(e,t,n,i){return new _m(e,{bindingId:t,resource:n,limit:i})}consumeRequestRate(e){const t=Date.now(),n=t-this.httpRequestWindowMs,i=(this.requestWindows.get(e)||[]).filter(e=>e>n);if(i.length>=this.maxHttpRequestsPerMinutePerBinding)throw this.limit("Proxy HTTP request rate limit exceeded.",e,"request-rate",this.maxHttpRequestsPerMinutePerBinding);i.push(t),this.requestWindows.set(e,i),this.scheduleRequestWindowCleanup(e)}scheduleRequestWindowCleanup(e){const t=this.requestWindowTimers.get(e);t&&clearTimeout(t);const n=this.requestWindows.get(e);if(!n?.length)return this.requestWindows.delete(e),void this.requestWindowTimers.delete(e);const i=Math.max(1,n[0]+this.httpRequestWindowMs-Date.now()+1),s=setTimeout(()=>{this.requestWindowTimers.delete(e);const t=Date.now()-this.httpRequestWindowMs,n=(this.requestWindows.get(e)||[]).filter(e=>e>t);n.length?(this.requestWindows.set(e,n),this.scheduleRequestWindowCleanup(e)):this.requestWindows.delete(e)},i);s.unref?.(),this.requestWindowTimers.set(e,s)}clearRequestWindow(e){this.requestWindows.delete(e);const t=this.requestWindowTimers.get(e);t&&clearTimeout(t),this.requestWindowTimers.delete(e)}}function Pm(e){return Buffer.isBuffer(e)||e instanceof ArrayBuffer||ArrayBuffer.isView(e)?e.byteLength:Buffer.byteLength("string"==typeof e?e:String(e),"utf8")}class jm{streams=new Map;historyLimit;maxEventBytes;maxHistoryBytes;createStreamId;projectTarget;unsubscribeBus;constructor(e,t){this.historyLimit=Math.max(1,t.historyLimit??256),this.maxEventBytes=Math.max(1024,t.maxEventBytes??524288),this.maxHistoryBytes=Math.max(this.maxEventBytes,t.maxHistoryBytes??16777216),this.createStreamId=t.createStreamId??(e=>`proxy_events_${e}_${i.randomUUID().replace(/-/g,"").slice(0,16)}`),this.projectTarget=t.projectTarget,this.unsubscribeBus=e.on(e=>this.accept(e))}stop(){this.unsubscribeBus();for(const e of this.streams.values())e.subscribers.clear();this.streams.clear()}cursor(e){const t=this.stream(e);return{streamId:t.streamId,revision:t.revision,earliestRetainedRevision:Dm(t)}}subscribe(e,t,n,i=()=>{}){const{bindingId:s,sourceControlPlaneId:r,targetNodeId:o}=e,a=this.stream(o),d=Dm(a);if(t>a.revision||t<d-1)return n(ri.parse({type:"control-plane-proxy.snapshot-required",protocolVersion:Nn,streamId:a.streamId,bindingId:s,sourceControlPlaneId:r,targetNodeId:o,sinceRevision:t,latestRevision:a.revision,earliestRetainedRevision:d,error:{code:Hn.SnapshotRequired,message:"Proxy target event history cannot continue from the requested revision; fetch a new snapshot.",retryable:!0,details:{targetNodeId:o}}})),{kind:"snapshot-required",close:()=>{}};n(si.parse({type:"control-plane-proxy.events.ready",protocolVersion:Nn,streamId:a.streamId,bindingId:s,sourceControlPlaneId:r,targetNodeId:o,latestRevision:a.revision,earliestRetainedRevision:d}));for(const e of a.history)e.event.revision>t&&n(Mm(e.event,s,r));const c={bindingId:s,sourceControlPlaneId:r,send:n,onDeliveryFailure:i};a.subscribers.add(c);let l=!1;return{kind:"subscribed",close:()=>{l||(l=!0,a.subscribers.delete(c))}}}diagnostics(e){const t=this.stream(e);return{targetNodeId:e,streamId:t.streamId,revision:t.revision,earliestRetainedRevision:Dm(t),historySize:t.history.length,historyBytes:t.historyBytes,subscribers:t.subscribers.size,subscriberBindings:[...t.subscribers].map(({bindingId:e,sourceControlPlaneId:t})=>({bindingId:e,sourceControlPlaneId:t}))}}accept(e){const t=e.scope?.nodeId;if("string"!=typeof t||!t)return;let n;try{n=this.projectTarget(t)}catch{return}if(!n)return;const i=this.stream(t),s=i.revision+1,r=ii.safeParse({type:"control-plane-proxy.event",protocolVersion:Nn,streamId:i.streamId,bindingId:"proxy_projection",sourceControlPlaneId:"proxy_projection",targetNodeId:t,revision:s,source:{id:e.id,seq:e.seq},target:n,event:{type:e.type,topic:e.topic,createdAt:e.createdAt}});if(!r.success)return;const{bindingId:o,sourceControlPlaneId:a,...d}=r.data,c=Lm(d);if(!(void 0===c||c>this.maxEventBytes-512)){for(i.revision=s,i.history.push({event:d,bytes:c}),i.historyBytes+=c;i.history.length>this.historyLimit||i.historyBytes>this.maxHistoryBytes;){const e=i.history.shift();e&&(i.historyBytes-=e.bytes)}for(const e of[...i.subscribers])try{const t=Mm(d,e.bindingId,e.sourceControlPlaneId),n=Lm(t);if(void 0===n||n>this.maxEventBytes)throw new Error("Proxy event byte limit exceeded.");e.send(t)}catch{i.subscribers.delete(e);try{e.onDeliveryFailure()}catch{}}}}stream(e){const t=this.streams.get(e);if(t)return t;const n={streamId:this.createStreamId(e),revision:0,history:[],historyBytes:0,subscribers:new Set};return this.streams.set(e,n),n}}function Dm(e){return e.history[0]?.event.revision??e.revision+1}function Mm(e,t,n){return ii.parse({...e,bindingId:t,sourceControlPlaneId:n})}function Lm(e){try{return Buffer.byteLength(JSON.stringify(e),"utf8")}catch{return}}function qm(e,t){const n=new WeakSet;let i=t,s=0;const r=e=>{if(i-=Buffer.byteLength(e,"utf8"),i<0)throw $m("Proxy target projection byte limit exceeded.",{resource:"target-projection-bytes",limit:t})},o=(e,t)=>{if(s+=1,s>16384||t>24)throw $m("Proxy target projection complexity limit exceeded.");if(null===e||"boolean"==typeof e)return e;if("string"==typeof e)return r(e),e;if("number"==typeof e)return Number.isFinite(e)?e:null;if("object"!=typeof e)return;if(n.has(e))throw $m("Proxy target projection contains a cycle.",void 0,!1);if(n.add(e),Array.isArray(e)){const i=e.map(e=>o(e,t+1)??null);return n.delete(e),i}const i={};for(const[n,s]of Object.entries(e)){if("__proto__"===n||"constructor"===n||"prototype"===n)continue;r(n);const e=o(s,t+1);void 0!==e&&(i[n]=e)}return n.delete(e),i};return o(e,0)}function $m(e,t,n=!0){return Object.assign(new Error(e),{code:"CONTROL_PLANE_PROXY_RESOURCE_LIMIT",statusCode:429,retryable:n,...t?{details:t}:{}})}function Bm(e){const{manageable:t,...n}=e;return n}const Um=a.z.object({bindingId:a.z.string().trim().min(1).max(160)}).passthrough(),Fm=a.z.object({route:Mn}).strict(),Hm=a.z.object({sinceRevision:a.z.coerce.number().int().nonnegative()}).strict(),Wm=new Set(["connection","cookie","host","keep-alive","proxy-authorization","te","trailer","transfer-encoding","upgrade"]),Gm=524288;function Vm(e,t,n){const i=ey(n.headers,$n);if(i!==Nn)throw Zm(Hn.ProtocolUnsupported,"Control-plane proxy protocol version is unsupported.",426,!1,{requestedVersion:i,supportedVersion:Nn});const s=ey(n.headers,Bn),r=ey(n.headers,Un),o=ey(n.headers,Fn);if(!s||!r||!o)throw Zm(Hn.AuthenticationFailed,"Proxy binding authentication headers are incomplete.",401);return e.authenticateBinding(t,{sourceControlPlaneId:s,bindingKeyId:r,credential:o})}function Km(e,t,n){const i=Vm(e,t.id,n);if(i.id!==t.id||i.revision!==t.revision||i.sourceControlPlaneId!==t.sourceControlPlaneId||i.targetNodeId!==t.targetNodeId||i.bindingKeyId!==t.bindingKeyId||"active"!==i.status)throw Zm(Hn.BindingIdentityConflict,"Proxy binding changed while the request was being established.",409,!0,{bindingId:t.id,expectedRevision:t.revision,actualRevision:i.revision})}function Jm(e,t){if(t.id!==e.targetNodeId)throw Zm(Hn.TargetMismatch,"Proxy target resolver returned another node.",409,!1,{bindingId:e.id,targetNodeId:e.targetNodeId})}function Ym(e){for(const t of Object.keys(e)){const e=t.toLowerCase();if(e.startsWith("x-taskhandoff-node-")||e.startsWith("x-task-handoff-node-"))throw Zm(Hn.HeaderInvalid,"Caller-supplied node transport authentication headers are forbidden.",400,!1,{header:e})}const t=Object.fromEntries([...Ln].flatMap(t=>{if(Wm.has(t))return[];const n=e[t];return void 0===n?[]:[[t,Array.isArray(n)?n.join(", "):String(n)]]}));if(void 0!==t["x-request-id"]){const e=jn.safeParse(t["x-request-id"]);if(!e.success)throw Zm(Hn.HeaderInvalid,"Proxy request correlation id is invalid.",400,!1,{header:"x-request-id"});t["x-request-id"]=e.data}return t}function Qm(e,t,n){const i=Xm(t),s=ty(n?.headers);return s&&e.header("x-request-id",s),e.code(i.statusCode).send({error:{code:i.code,message:i.message,retryable:i.retryable,...i.details?{details:i.details}:{}}})}function Xm(e){const t=e&&"object"==typeof e?e:{},n="number"==typeof t.statusCode?t.statusCode:502;return{statusCode:n,code:("string"==typeof t.code?t.code:void 0)||Hn.TransportFailed,message:e instanceof Error?e.message:"Control-plane proxy transport failed.",retryable:"boolean"==typeof t.retryable?t.retryable:n>=500,details:t.details&&"object"==typeof t.details&&!Array.isArray(t.details)?t.details:void 0}}function Zm(e,t,n,i=!1,s){return Object.assign(new Error(t),{code:e,statusCode:n,retryable:i,...s?{details:s}:{}})}function ey(e,t){const n=e[t];return Array.isArray(n)?n.join(","):"string"==typeof n?n:""}function ty(e){if(!e)return;const t=jn.safeParse(ey(e,"x-request-id"));return t.success?t.data:void 0}function ny(e){let t="";for(const n of e){if(Buffer.byteLength(t+n)>123)break;t+=n}return t}const iy=e=>Gn.parse({code:Hn.Unavailable,message:e,retryable:!0});class sy{service;subscriptions=new Map;fetchImpl;openWebSocket;onStateChanged;logger;running=!1;constructor(e,t={}){this.service=e,this.fetchImpl=t.fetchImpl??fetch,this.openWebSocket=t.openWebSocket??((e,t)=>new l.WebSocket(e,{headers:t})),this.onStateChanged=t.onStateChanged??(()=>{}),this.logger=t.logger}start(){this.running||(this.running=!0,this.syncNow())}syncNow(){if(!this.running)return;const e=new Map(this.service.listNodes().filter(e=>"control-plane-proxy"===e.connectionMode&&!1!==e.connectionEnabled).map(e=>[e.id,e]));for(const t of this.subscriptions.keys())e.has(t)||this.remove(t);for(const t of e.values()){const e=this.subscriptionIdentity(t),n=this.subscriptions.get(t.id);if(n?.identity===e)continue;n&&this.remove(t.id);const i={generation:1,identity:e,retry:new Ag};this.subscriptions.set(t.id,i),this.connect(t.id,i.generation)}}stop(){this.running=!1;for(const e of[...this.subscriptions.keys()])this.remove(e)}remove(e){const t=this.subscriptions.get(e);t&&(t.generation+=1,t.reconnect&&clearTimeout(t.reconnect),t.socket?.close(),this.subscriptions.delete(e))}async connect(e,t){if(!this.current(e,t))return;const n=this.service.proxyPrivateStore.nodeCredential(e);if(n)try{const i=await this.fetchImpl(function(e){return new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}/snapshot`,e.proxyOrigin)}(n),{headers:Id(n)});if(!this.current(e,t))return;const s=await i.json().catch(()=>{});if(!i.ok){const n=$o(Gn,s?.error),r=n.success?n.data:iy(`Proxy snapshot failed with HTTP ${i.status}.`);return r.code===Hn.BindingRevoked||r.code===Hn.BindingUnknown?void this.onStateChanged(this.service.markProxyBindingRevoked(e,r)):void this.fail(e,t,r,r.retryable)}const r=Bo(ni,s?.data);if(this.validateIdentity(n,r.binding.id,r.binding.targetNodeId),this.onStateChanged(this.service.applyProxyTargetSnapshot(e,r)),"revoked"===r.binding.status)return void this.onStateChanged(this.service.markProxyBindingRevoked(e,{code:Hn.BindingRevoked,message:"Control-plane proxy binding was revoked.",retryable:!1}));this.openEvents(e,t,n,r)}catch(n){if(!this.current(e,t))return;this.logger?.warn?.({nodeId:e,error:ry(n)},"control-plane proxy state bootstrap failed"),this.fail(e,t,iy("Trusted control-plane proxy is unavailable."),!0)}else this.fail(e,t,iy("Control-plane proxy credential is unavailable."),!1)}openEvents(e,t,n,i){const s=this.current(e,t);if(!s)return;const r=this.openWebSocket(function(e,t){const n=new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}/events`,e.proxyOrigin);return n.protocol="wss:",n.searchParams.set("sinceRevision",String(t)),n.toString()}(n,i.revision),Id(n));s.socket=r;let o=!1;const a=n=>{o||(o=!0,this.fail(e,t,iy(n),!0))};r.on("message",r=>{if(this.current(e,t))try{const o=Bo(oi,JSON.parse(String(r)));if(o.bindingId!==n.proxyBindingId||o.sourceControlPlaneId!==n.sourceControlPlaneId||o.targetNodeId!==n.targetNodeId||o.streamId!==i.streamId)throw new Error("Proxy event stream identity changed.");if("control-plane-proxy.snapshot-required"===o.type)return void this.restart(e,t);if("control-plane-proxy.events.ready"===o.type)return void s.retry.reset();this.onStateChanged(this.service.applyProxyTargetEvent(e,o))}catch(n){this.logger?.warn?.({nodeId:e,error:ry(n)},"control-plane proxy event requires a new snapshot"),this.restart(e,t)}}),r.on("error",()=>a("Control-plane proxy event stream failed.")),r.on("close",()=>a("Control-plane proxy event stream disconnected."))}restart(e,t){const n=this.current(e,t);n&&(n.generation+=1,n.socket?.close(),n.socket=void 0,this.connect(e,n.generation))}fail(e,t,n,i){const s=this.current(e,t);if(!s)return;if(this.onStateChanged(this.service.markProxyUnavailable(e,n)),!i)return s.generation+=1,s.socket?.close(),void this.subscriptions.delete(e);s.generation+=1,s.socket?.close(),s.socket=void 0;const r=s.retry.next();s.reconnect=setTimeout(()=>{s.reconnect=void 0,this.connect(e,s.generation)},r.delay),s.reconnect.unref?.()}current(e,t){const n=this.subscriptions.get(e);return this.running&&n?.generation===t?n:void 0}validateIdentity(e,t,n){if(t!==e.proxyBindingId||n!==e.targetNodeId){const e=new Error("Proxy snapshot identity does not match the private binding credential.");throw Object.assign(e,{code:Hn.BindingIdentityConflict}),e}}subscriptionIdentity(e){const t=this.service.proxyPrivateStore.nodeCredential(e.id);return JSON.stringify({connectionMode:e.connectionMode,connectionPath:e.connectionPath,credential:t&&{id:t.id,proxyOrigin:t.proxyOrigin,proxyBindingId:t.proxyBindingId,targetNodeId:t.targetNodeId,sourceControlPlaneId:t.sourceControlPlaneId,bindingKeyId:t.bindingKeyId,updatedAt:t.updatedAt}})}}function ry(e){const t=e&&"object"==typeof e?e:{};return{name:e instanceof Error?e.name:"Error",message:e instanceof Error?e.message:String(e),..."string"==typeof t.code?{code:t.code}:{}}}const oy=a.z.object({id:a.z.string().trim().min(1).max(160)}).strict(),ay=a.z.object({}).strict(),dy=a.z.object({force:a.z.enum(["true","false"]).optional()}).strict(),cy=a.z.object({algorithm:a.z.literal("Ed25519"),publicKey:a.z.string().regex(/^[A-Za-z0-9_-]{43}$/),privateKeyPkcs8:a.z.string().regex(/^[A-Za-z0-9_-]{64}$/)}).strip();function ly(){const{publicKey:e,privateKey:t}=i.generateKeyPairSync("ed25519"),n=e.export({format:"jwk"});if(!n.x)throw new Error("Generated Control Plane identity did not contain an Ed25519 public key.");return{algorithm:"Ed25519",publicKey:n.x,privateKeyPkcs8:t.export({format:"der",type:"pkcs8"}).toString("base64url")}}function py(e){return`sha256:${i.createHash("sha256").update(Buffer.from(e,"base64url")).digest("base64url")}`}function uy(e){return Array.isArray(e)?`[${e.map(uy).join(",")}]`:e&&"object"==typeof e?`{${Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${uy(t)}`).join(",")}}`:JSON.stringify(e)}class gy{identity;controlPlaneId;constructor(e,t,n){this.controlPlaneId=t,this.identity=new fo(e,ly,{schema:cy,logger:n,directoryMode:448,fileMode:384})}init(){this.identity.init(),this.privateKey()}publicDocument(e,t=Date.now()){const n=this.identity.get(),s={authentication:e,aiSessions:!0,nodes:!0,instanceBoard:!0,triggers:!0},r=no.parse({version:1,kind:"control-plane",controlPlaneId:this.controlPlaneId(),publicKey:{algorithm:"Ed25519",encoding:"base64url",value:n.publicKey,fingerprint:py(n.publicKey)},capabilities:s,protocolVersion:"2026-08-09",issuedAt:new Date(t).toISOString(),expiresAt:new Date(t+3e5).toISOString()}),o=i.sign(null,Buffer.from((a=r,JSON.stringify(no.parse(a)))),this.privateKey()).toString("base64url");var a;return io.parse({data:{payload:r,signature:o}})}publicIdentity(){const e=this.identity.get();return{controlPlaneId:this.controlPlaneId(),algorithm:e.algorithm,publicKey:e.publicKey,fingerprint:py(e.publicKey)}}signCloudBindingChallenge(e){return i.sign(null,Buffer.from(`task-handoff:cloud-binding-challenge:v1\n${uy(e)}`),this.privateKey()).toString("base64url")}signCloudOutboundRegistration(e){return i.sign(null,Buffer.from((t=e,`task-handoff:outbound-control-registration:v1\n${Jt(an.parse(t))}`)),this.privateKey()).toString("base64url");var t}acceptCloudAccessHandshake(e,t){return function(e){const t=dn.parse(e.ticket),n=pn.parse(e.clientHello);if(t.ticketId!==n.ticketId||t.deviceSessionId!==n.deviceSessionId||t.targetPublicKeyFingerprint!==e.controlPlaneFingerprint)throw un();const s=i.generateKeyPairSync("x25519"),r=function(e){const t=e.export({format:"jwk"}).x;if(!t)throw un();return t}(s.publicKey),o=function(e,t,n){return i.createHash("sha256").update(Jt({audience:e.audience,ticketId:e.ticketId,accountId:e.accountId,deviceSessionId:e.deviceSessionId,controlPlaneId:e.controlPlaneId,bindingId:e.bindingId,bindingRevision:e.bindingRevision,nonce:e.nonce,clientEphemeralPublicKey:t,serverEphemeralPublicKey:n})).digest("base64url")}(t,n.clientEphemeralPublicKey,r);var a;const d=function(e,t){return i.createHash("sha256").update(e).update(t).update("task-handoff:control-plane-access:e2e:v1").digest()}(i.diffieHellman({privateKey:s.privateKey,publicKey:(a=n.clientEphemeralPublicKey,i.createPublicKey({key:{kty:"OKP",crv:"X25519",x:a},format:"jwk"}))}),o);return{sessionKey:d,response:{serverEphemeralPublicKey:r,transcript:o,signature:i.sign(null,Buffer.from(o),e.controlPlanePrivateKey).toString("base64url")}}}({ticket:e,clientHello:t,controlPlaneFingerprint:this.publicIdentity().fingerprint,controlPlanePrivateKey:this.privateKey()})}privateKey(){const e=this.identity.get(),t=i.createPrivateKey({key:Buffer.from(e.privateKeyPkcs8,"base64url"),format:"der",type:"pkcs8"});if(i.createPublicKey(t).export({format:"jwk"}).x!==e.publicKey)throw new Error("Stored Control Plane signing identity public and private keys do not match.");return t}}class hy{observations=new Map;listeners=new Set;begin(e,t,n="connecting"){const i=this.observations.get(e),s={nodeId:e,transport:t,generation:(i?.generation||0)+1,phase:n,changedAt:(new Date).toISOString(),consecutiveFailures:i?.transport===t?i.consecutiveFailures:0,controlReachability:i?.transport===t?i.controlReachability:"unknown",controlChangedAt:i?.transport===t?i.controlChangedAt:void 0,controlError:i?.transport===t?i.controlError:void 0};return this.observations.set(e,s),this.publish(s),s.generation}update(e,t,n,i=!0){const s=this.observations.get(e);if(!s||s.generation!==t)return!1;const r={...s,...n,changedAt:(new Date).toISOString()};return this.observations.set(e,r),i&&this.publish(r),!0}connected(e,t){const n=(new Date).toISOString();return this.update(e,t,{phase:"healthy",connectedAt:n,lastSeenAt:n,nextRetryAt:void 0,error:void 0})}pong(e,t){const n=(new Date).toISOString();return this.update(e,t,{lastSeenAt:n,lastPongAt:n},!1)}stable(e,t){return this.update(e,t,{consecutiveFailures:0},!1)}observedReachable(e){if("control-plane-proxy"===e.connectionMode)return!1;const t="reverse-wss"===e.connectionMode?"reverse-wss":"direct-http",n=this.observations.get(e.id),i=n?.transport===t?n.generation:this.begin(e.id,t,"handshaking");if("direct-http"===t){const t=(new Date).toISOString();return"reachable"===n?.controlReachability?this.update(e.id,i,{lastSeenAt:t},!1):this.update(e.id,i,{controlReachability:"reachable",controlChangedAt:t,controlError:void 0,lastSeenAt:t})}return"healthy"===n?.phase?this.update(e.id,i,{lastSeenAt:(new Date).toISOString()},!1):this.connected(e.id,i)}observedFailure(e,t){if("control-plane-proxy"===e.connectionMode)return!1;const n="reverse-wss"===e.connectionMode?"reverse-wss":"direct-http",i=this.observations.get(e.id),s=i?.transport===n?i.generation:this.begin(e.id,n,"connecting");return"direct-http"===n?"unreachable"===i?.controlReachability?this.update(e.id,s,{controlError:t},!1):this.update(e.id,s,{controlReachability:"unreachable",controlChangedAt:(new Date).toISOString(),controlError:t}):this.disconnected(e.id,s,{error:t})}disconnected(e,t,n={}){const i=this.observations.get(e);return!(!i||i.generation!==t)&&this.update(e,t,{phase:n.nextRetryAt?"reconnecting":"offline",consecutiveFailures:i.consecutiveFailures+1,closeCode:n.closeCode,error:n.error,nextRetryAt:n.nextRetryAt})}observation(e){return this.observations.get(e)}onChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}project(e){if(!1===e.connectionEnabled)return{...e,status:"offline",health:"failed",connectionPhase:"offline"};if("direct-http"!==e.connectionMode&&"reverse-wss"!==e.connectionMode&&"local-ipc"!==e.connectionMode&&"local-loopback"!==e.connectionMode)return e;const t=this.observations.get(e.id),n="reverse-wss"===e.connectionMode?"reverse-wss":"direct-http";return t&&t.transport===n?"direct-http"===n?"reachable"===t.controlReachability?{...e,status:"online",health:"unknown"===e.health||"failed"===e.health?"ok":e.health,lastSeenAt:t.lastSeenAt||e.lastSeenAt,connectionPhase:"healthy"}:{...e,status:"unreachable"===t.controlReachability?"offline":"unknown",health:"unreachable"===t.controlReachability?"failed":"unknown",lastSeenAt:t.lastSeenAt,connectionPhase:"unreachable"===t.controlReachability?"offline":"connecting"}:"healthy"===t.phase?{...e,status:"online",health:"unknown"===e.health?"ok":e.health,lastSeenAt:t.lastSeenAt||t.connectedAt,connectionPhase:t.phase}:"connecting"===t.phase||"handshaking"===t.phase||"reconnecting"===t.phase||"suspect"===t.phase?{...e,status:"offline",health:"degraded",lastSeenAt:t.lastSeenAt,connectionPhase:t.phase}:{...e,status:"offline",health:"failed",lastSeenAt:t.lastSeenAt,connectionPhase:t.phase}:"direct-http"===n?{...e,status:"unknown",health:"unknown",connectionPhase:"connecting"}:e}diagnostics(){return[...this.observations.values()].map(e=>({...e}))}publish(e){for(const t of this.listeners)t({...e})}}function my(e,n){const i=t.extname(e);return`${i?e.slice(0,-i.length):e}.${n}${i}`}const yy=1048576,fy=52428800;function Iy(e){return e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:e}function by(e){const i=[],s=e=>{if(n.existsSync(e))for(const r of n.readdirSync(e,{withFileTypes:!0})){const n=t.join(e,r.name);r.isSymbolicLink()||(r.isDirectory()?s(n):r.isFile()&&(r.name.endsWith(".log")||r.name.endsWith(".jsonl"))&&i.push(n))}};return s(e),i.sort()}function vy(e,i,s){const r=n.statSync(e),o=Math.min(r.size,yy,s);if(o<=0)return 0;const a=Buffer.allocUnsafe(o),d=n.openSync(e,"r");try{n.readSync(d,a,0,o,Math.max(0,r.size-o))}finally{n.closeSync(d)}return n.mkdirSync(t.dirname(i),{recursive:!0,mode:448}),n.writeFileSync(i,a,{mode:384}),o}const wy=a.z.object({version:a.z.literal(1),serviceOrigin:a.z.string().url(),status:a.z.enum(["unbound","pending-claim","active","pending-revocation","clone-conflict"]),remoteAccessEnabled:a.z.boolean(),accountId:a.z.string().optional(),bindingId:a.z.string().optional(),bindingRevision:a.z.number().int().positive().optional(),backgroundCredential:a.z.string().min(32).optional(),updatedAt:a.z.string().datetime(),connectionEpoch:a.z.number().int().nonnegative().default(0)}).strip();class Sy{state;challenges=new Map;identity;serviceOrigin;clock;constructor(e){this.identity=e.identity,this.serviceOrigin=new URL(e.serviceOrigin).origin,this.clock=e.clock??Date.now,this.state=new fo(e.statePath,()=>({version:1,serviceOrigin:this.serviceOrigin,status:"unbound",remoteAccessEnabled:!0,updatedAt:new Date(this.clock()).toISOString(),connectionEpoch:0}),{schema:wy,directoryMode:448,fileMode:384})}init(){if(this.state.init(),this.state.get().serviceOrigin!==this.serviceOrigin)throw zy("CLOUD_SERVICE_ORIGIN_CHANGED","Cloud service origin does not match persisted binding authority.")}snapshot(){const{backgroundCredential:e,connectionEpoch:t,...n}=this.state.get();return{...n,identity:this.identity.publicIdentity(),hasBackgroundCredential:Boolean(e)}}createChallenge(){const e=this.state.get();if(["active","pending-revocation","clone-conflict"].includes(e.status))throw zy("active"===e.status?"CONTROL_PLANE_ALREADY_BOUND":"BINDING_STATE_CONFLICT","Existing cloud binding must be resolved first.");this.prune();const t=ho("binding_challenge"),n=i.randomBytes(32).toString("base64url"),s=this.challengePayload(t);return this.challenges.set(t,{digest:Ay(n),payload:s,expiresAtMs:Date.parse(s.expiresAt)}),this.state.put({...e,status:"pending-claim",updatedAt:new Date(this.clock()).toISOString()}),{challengeCode:`${t}.${n}`,authorizationUrl:`${this.serviceOrigin}/bindings/authorize`,payload:s,signature:this.identity.signCloudBindingChallenge(s)}}consumeChallenge(e){const t=e.challengeCode.indexOf("."),n=e.challengeCode.slice(0,t),s=e.challengeCode.slice(t+1),r=this.challenges.get(n);if(r&&this.challenges.delete(n),!r||r.expiresAtMs<=this.clock()||(o=r.digest,a=Ay(s),o.length!==a.length||!i.timingSafeEqual(o,a)))throw zy("BINDING_CHALLENGE_INVALID_OR_CONSUMED","Binding challenge is invalid, expired, or consumed.");var o,a;if(r.payload.controlPlaneId!==e.controlPlaneId||r.payload.publicKeyFingerprint!==e.fingerprint)throw zy("BINDING_IDENTITY_CONFLICT","Binding challenge identity does not match.");return r.payload}activate(e){const t=this.state.get();if("active"===t.status){if(t.accountId===e.accountId&&t.bindingId===e.bindingId&&t.bindingRevision===e.bindingRevision)return this.snapshot();throw zy("CONTROL_PLANE_ALREADY_BOUND","Control Plane is already bound to another account.")}if("pending-claim"!==t.status)throw zy("BINDING_STATE_CONFLICT","Control Plane has no pending binding claim.");return this.state.put({...t,status:"active",remoteAccessEnabled:!0,...e,updatedAt:new Date(this.clock()).toISOString()}),this.snapshot()}setRemoteAccess(e){const t=this.state.get();return this.state.put({...t,remoteAccessEnabled:e,updatedAt:new Date(this.clock()).toISOString()}),this.snapshot()}beginRevocation(){const e=this.state.get();return"unbound"===e.status||(this.challenges.clear(),this.state.put({...e,status:"pending-revocation",remoteAccessEnabled:!1,updatedAt:new Date(this.clock()).toISOString()})),this.snapshot()}confirmRevocation(){const e=this.state.get();return this.state.put({version:1,serviceOrigin:e.serviceOrigin,status:"unbound",remoteAccessEnabled:!1,updatedAt:new Date(this.clock()).toISOString(),connectionEpoch:e.connectionEpoch}),this.snapshot()}markCloneConflict(){const e=this.state.get();return this.challenges.clear(),this.state.put({...e,status:"clone-conflict",remoteAccessEnabled:!1,backgroundCredential:void 0,updatedAt:new Date(this.clock()).toISOString()}),this.snapshot()}backgroundCredential(){const e=this.state.get();return"active"===e.status&&e.remoteAccessEnabled?e.backgroundCredential:void 0}nextConnectionEpoch(){const e=this.state.get(),t=e.connectionEpoch+1;return this.state.put({...e,connectionEpoch:t,updatedAt:new Date(this.clock()).toISOString()}),t}challengePayload(e){const t=this.identity.publicIdentity(),n=this.clock();return{protocolVersion:"2026-08-10",audience:"task-handoff:binding",serviceOrigin:this.serviceOrigin,challengeId:e,controlPlaneId:t.controlPlaneId,publicKey:t.publicKey,publicKeyFingerprint:t.fingerprint,nonce:i.randomBytes(24).toString("base64url"),issuedAt:new Date(n).toISOString(),expiresAt:new Date(n+3e5).toISOString()}}prune(){const e=this.clock();for(const[t,n]of this.challenges)n.expiresAtMs<=e&&this.challenges.delete(t)}}function Ay(e){return i.createHash("sha256").update(e).digest()}function zy(e,t){return Object.assign(new Error(t),{code:e,statusCode:e.includes("CONFLICT")||e.includes("BOUND")?409:400})}class ky{revision=0;options;constructor(e){this.options=e}async apply(e){if(!Number.isSafeInteger(e.bindingRevision)||e.bindingRevision<this.revision)return{applied:!1,reason:"stale-revision"};if(this.revision=e.bindingRevision,"binding-revoked"===e.type||"account-disabled"===e.type||"background-credential-revoked"===e.type)this.options.state.beginRevocation(),await Promise.all([this.options.connections.stop(e.type),this.options.dataConnections.closeAll(e.type)]),this.options.state.confirmRevocation();else if("remote-access-changed"===e.type)this.options.state.setRemoteAccess(!0===e.enabled),e.enabled||await Promise.all([this.options.connections.stop("remote-access-disabled"),this.options.dataConnections.closeAll("remote-access-disabled")]);else{if("identity-clone-detected"!==e.type)return{applied:!1,reason:"unsupported-event"};this.options.state.markCloneConflict(),await Promise.all([this.options.connections.stop(e.type),this.options.dataConnections.closeAll(e.type)])}return{applied:!0}}}class Ty{connection;processInstanceId=`control_plane_process_${i.randomUUID().replaceAll("-","_")}`;backoff;options;constructor(e){this.options=e,this.backoff=e.backoff??new Ag}async connectOnce(){const e=this.options.state.backgroundCredential(),t=this.options.state.snapshot();if(!t.remoteAccessEnabled||!("pending-claim"===t.status||"active"===t.status&&Boolean(e)))return{status:"disabled"};if(this.connection)return{status:"connected",reused:!0};const n=this.options.state.nextConnectionEpoch(),i=this.connection;return this.connection=await this.options.connector.connect({serviceOrigin:t.serviceOrigin,credential:e,bindingId:t.bindingId,bindingRevision:t.bindingRevision,controlPlaneId:t.identity.controlPlaneId,processInstanceId:this.processInstanceId,epoch:n,onEvent:this.options.onEvent}),await(i?.close("replaced-by-new-epoch")),this.backoff.reset(),{status:"connected",epoch:n}}reconnectDelay(){return this.backoff.next().delay}disconnected(){this.connection=void 0}async stop(e){const t=this.connection;this.connection=void 0,await(t?.close(e))}}class Ey{connections=new Map;options;constructor(e){this.options=e}async attach(e){const t=await this.options.verifyAllocation(e),n=this.connections.get(t.allocationId);if(n&&t.epoch<=n.epoch)throw Object.assign(new Error("Cloud connection state is invalid."),{code:"STALE_CONNECTION_EPOCH"});const i=await this.options.connector.connect({relayUrl:t.relayUrl,allocation:e,epoch:t.epoch});return await(n?.connection.close("replaced-by-new-epoch")),this.connections.set(t.allocationId,{epoch:t.epoch,connection:i}),{status:"attached",allocationId:t.allocationId,epoch:t.epoch}}async closeAll(e){const t=[...this.connections.values()];this.connections.clear(),await Promise.allSettled(t.map(({connection:t})=>t.close(e)))}}class Cy{options;constructor(e){this.options=e}async disconnect(){const e=this.options.state.snapshot();if(!e.bindingId)return e;this.options.state.beginRevocation(),await this.options.connections.stop("binding-pending-revocation");try{if("revoked"===(await this.options.remote.revoke({bindingId:e.bindingId})).status)return this.options.state.confirmRevocation()}catch{}return this.options.state.snapshot()}async setRemoteAccess(e){const t=this.options.state.snapshot();if(this.options.state.setRemoteAccess(e),e||await this.options.connections.stop("remote-access-disabled"),t.bindingId)try{await this.options.remote.setRemoteAccess({bindingId:t.bindingId,enabled:e})}catch{return{...this.options.state.snapshot(),remoteResult:"unknown"}}return{...this.options.state.snapshot(),remoteResult:"confirmed"}}}class xy{options;constructor(e){this.options=e}async connect(e){const t=e.allocation,n=ln.parse(t.attach),i=dn.parse(t.ticket),s=new(this.options.webSocket??l)(e.relayUrl,{followRedirects:!1,handshakeTimeout:1e4,perMessageDeflate:!1});return await function(e){return new Promise((t,n)=>{e.once("open",t),e.once("error",n),e.once("close",()=>n(Ry("RELAY_SOCKET_CLOSED")))})}(s),s.send(JSON.stringify({type:"attach",capability:n})),async function(e,t,n,i,s){const r=await Oy(e,e=>"frame"===e?.type&&"handshake"===e.frame?.kind);if(r.frame.channelId!==t||0!==r.frame.sequence)throw Ry("RELAY_HANDSHAKE_SEQUENCE_INVALID");const o=JSON.parse(Buffer.from(r.frame.ciphertext,"base64url").toString("utf8")),a=i.acceptCloudAccessHandshake(n,o),d={...a.response,controlPlanePublicKey:i.publicIdentity().publicKey};e.send(JSON.stringify({type:"frame",frame:{protocolVersion:"2026-08-10",channelId:t,sequence:0,kind:"handshake",ciphertext:Buffer.from(JSON.stringify(d)).toString("base64url")}}));const c={type:"cloud-account",accountId:n.accountId,deviceSessionId:n.deviceSessionId,bindingId:n.bindingId,bindingRevision:n.bindingRevision},l=new Ny(e,t,a.sessionKey,c,s);return l.start(),{close:(e="normal")=>l.close(e)}}(s,(await Oy(s,e=>"attached"===e?.type)).channelId,i,this.options.identity,this.options.bridge)}}class Ny{receiveSequence=1;sendSequence=1;receiveCounter=0;sendCounter=0;unsubscribe;ttys=new Map;socket;channelId;key;actor;bridge;constructor(e,t,n,i,s){this.socket=e,this.channelId=t,this.key=n,this.actor=i,this.bridge=s}start(){this.socket.on("message",e=>{this.receive(e).catch(()=>this.socket.close(4400,"encrypted-protocol-error"))}),this.socket.once("close",()=>{this.unsubscribe?.();for(const e of this.ttys.values())e.close();this.ttys.clear()})}async close(e){this.unsubscribe?.();for(const e of this.ttys.values())e.close();this.ttys.clear(),this.socket.readyState<l.CLOSING&&this.socket.close(1e3,e.slice(0,120))}async receive(e){const t=JSON.parse(e.toString()),n=t?.frame;if("frame"!==t?.type||n?.channelId!==this.channelId||n.sequence!==this.receiveSequence++)throw Ry("RELAY_FRAME_SEQUENCE_INVALID");const i=w.secretbox.open(Buffer.from(n.ciphertext,"base64url"),_y(1,this.receiveCounter++),this.key);if(!i)throw Ry("RELAY_E2E_DECRYPT_FAILED");const s=JSON.parse(Buffer.from(i).toString("utf8"));await this.dispatch(s)}async dispatch(e){if("request"===e.type&&e.id){try{const t=await this.bridge.request(this.actor,e.body);this.send({type:"response",id:e.id,status:t.status,body:t.body})}catch(t){this.send({type:"response",id:e.id,status:Number(t?.statusCode)||500,body:{error:{code:t?.code??"CONTROL_PLANE_ERROR",message:"Control Plane request failed."}}})}return}if("event-subscribe"===e.type){this.unsubscribe?.();const t=Array.isArray(e.body?.topics)?e.body.topics.map(String):["*"];return void(this.unsubscribe=this.bridge.subscribe(this.actor,t,e=>this.send({type:"event",event:e})))}if("tty-open"===e.type&&e.streamId&&this.bridge.openTty){const t=e.streamId,n=await this.bridge.openTty(this.actor,e.body,e=>this.send({...e,streamId:t}));return this.ttys.set(t,n),void this.send({type:"tty-opened",streamId:t})}const t=e.streamId?this.ttys.get(e.streamId):void 0;if(t&&"tty-input"===e.type)return t.send(String(e.data??""));if(t&&"tty-resize"===e.type)return t.resize(Number(e.body?.cols),Number(e.body?.rows));if(t&&"tty-close"===e.type)return t.close(),this.ttys.delete(e.streamId),void this.send({type:"tty-closed",streamId:e.streamId});if("cancel"!==e.type)throw Ry("RELAY_ENVELOPE_UNSUPPORTED")}send(e){if(this.socket.readyState!==l.OPEN||this.socket.bufferedAmount>2097152)throw Ry("RELAY_BACKPRESSURE_LIMIT");const t=w.secretbox(Buffer.from(JSON.stringify(e)),_y(2,this.sendCounter++),this.key);this.socket.send(JSON.stringify({type:"frame",frame:{protocolVersion:"2026-08-10",channelId:this.channelId,sequence:this.sendSequence++,kind:"cancel"===e.type?"cancel":"data",ciphertext:Buffer.from(t).toString("base64url")}}))}}function Oy(e,t){return new Promise((n,i)=>{const s=e=>{try{const i=JSON.parse(e.toString());t(i)&&(o(),n(i))}catch(e){o(),i(e)}},r=()=>{o(),i(Ry("RELAY_SOCKET_CLOSED"))},o=()=>{e.off("message",s),e.off("close",r)};e.on("message",s),e.once("close",r)})}function _y(e,t){const n=new Uint8Array(24);return n[0]=e,new DataView(n.buffer).setBigUint64(16,BigInt(t),!1),n}function Ry(e){return Object.assign(new Error("Cloud Relay session is invalid."),{code:e,retryable:!0})}class Py{current;options;constructor(e){this.options=e}async connect(e){const t=this.options.identity.publicIdentity(),n=Date.now(),s={protocolVersion:"2026-08-10",audience:"task-handoff:coordinator-control",connectionId:`connection_${i.randomUUID().replaceAll("-","_")}`,processInstanceId:e.processInstanceId,controlPlaneId:t.controlPlaneId,publicKey:t.publicKey,publicKeyFingerprint:t.fingerprint,...e.bindingId?{bindingId:e.bindingId,bindingRevision:e.bindingRevision}:{},epoch:e.epoch,capabilities:["request","stream","websocket"],issuedAt:new Date(n).toISOString(),expiresAt:new Date(n+3e5).toISOString()},r=new URL("/api/v1/control-plane/connect",e.serviceOrigin);r.protocol="https:"===r.protocol?"wss:":"ws:";const o=new(this.options.webSocket??l)(r.href,{followRedirects:!1,handshakeTimeout:1e4});let a;return a=await function(e,t){return new Promise((n,s)=>{const r=new Map;let o,a=!1,d=!1;const c=e=>{for(const t of r.values())t.reject(e);r.clear(),a||s(e)},p={request(t,n){if(e.readyState!==l.OPEN)return Promise.reject(Dy("CLOUD_CONTROL_CONNECTION_UNAVAILABLE"));const s=`request_${i.randomUUID().replaceAll("-","_")}`;return e.send(JSON.stringify({type:"request",requestId:s,operation:t,payload:n})),new Promise((e,t)=>r.set(s,{resolve:e,reject:t}))},async close(t="normal"){d=!0,o&&clearInterval(o),e.close(1e3,t.slice(0,120))}};e.on("open",()=>e.send(JSON.stringify(t.register))),e.on("message",async i=>{let s;try{s=JSON.parse(i.toString())}catch{return e.close(1002,"invalid-json")}if("registered"===s.type)return a=!0,o=setInterval(()=>e.readyState===l.OPEN&&e.send(JSON.stringify({type:"heartbeat"})),1e4),o.unref(),n(p);if("event"===s.type)return t.onEvent(s.event);if("response"===s.type){const e=r.get(s.requestId);if(!e)return;return r.delete(s.requestId),s.error?e.reject(Object.assign(new Error(s.error.message),{code:s.error.code})):e.resolve(s.data)}if("request"===s.type&&t.onRequest)try{e.send(JSON.stringify({type:"response",requestId:s.requestId,data:await t.onRequest(s.operation,s.payload)}))}catch(t){e.send(JSON.stringify({type:"response",requestId:s.requestId,error:{code:t?.code??"REQUEST_FAILED",message:t instanceof Error?t.message:String(t)}}))}}),e.on("error",e=>c(e)),e.on("close",()=>{o&&clearInterval(o),c(Dy("CLOUD_CONTROL_CONNECTION_CLOSED")),d||t.onDisconnected()})})}(o,{register:{type:"register",registration:{...s,signature:this.options.identity.signCloudOutboundRegistration(s)},backgroundCredential:e.credential},onEvent:e.onEvent,onRequest:this.options.onRequest,onDisconnected:()=>{this.current===a&&(this.current=void 0),this.options.onDisconnected()}}),this.current=a,a}async request(e,t){if(!this.current)throw Dy("CLOUD_CONTROL_CONNECTION_UNAVAILABLE");return this.current.request(e,t)}}class jy{lifecycle;dataConnections;connector;control;events;timer;running=!1;connecting;options;constructor(e){this.options=e,this.connector=new Py({identity:e.identity,webSocket:e.webSocket,onDisconnected:()=>{this.control.disconnected(),this.schedule()},onRequest:(e,t)=>this.handleRequest(e,t)});const t=e.relayConnector??(e.relayBridge?new xy({identity:e.identity,bridge:e.relayBridge,webSocket:e.webSocket}):{async connect(){throw Dy("CLOUD_RELAY_CONNECTOR_UNAVAILABLE")}});this.dataConnections=new Ey({verifyAllocation:e.verifyAllocation??(t=>function(e,t){const n=e,i=ln.parse(n?.attach),s=dn.parse(n?.ticket),r=t.snapshot(),o=new URL(String(n?.relayUrl));if("relay-allocation"!==n?.type||n?.allocationId!==i.allocationId||"control-plane"!==i.role||i.ticketId!==s.ticketId||i.controlPlaneId!==s.controlPlaneId||i.accountId!==s.accountId||i.deviceSessionId!==s.deviceSessionId||i.bindingId!==s.bindingId||i.bindingRevision!==s.bindingRevision||"active"!==r.status||!r.remoteAccessEnabled||r.identity.controlPlaneId!==s.controlPlaneId||r.accountId!==s.accountId||r.bindingId!==s.bindingId||r.bindingRevision!==s.bindingRevision||s.targetPublicKeyFingerprint!==r.identity.fingerprint||Date.parse(i.expiresAt)<=Date.now())throw Ry("RELAY_ALLOCATION_AUTHORITY_INVALID");if(!function(e,t){if("wss:"!==e.protocol)return!1;if("relay.thandoff.com"===e.hostname||e.hostname.endsWith(".relay.thandoff.com"))return!0;const n=new URL(t);return"cloud.thandoff.com"!==n.hostname&&e.hostname===n.hostname}(o,r.serviceOrigin))throw Ry("UNTRUSTED_RELAY_URL");return{allocationId:i.allocationId,relayUrl:o.href,epoch:Date.parse(i.issuedAt),attach:i,ticket:s}}(t,e.state)),connector:t}),this.events=new ky({state:e.state,connections:{stop:e=>this.control.stop(e)},dataConnections:this.dataConnections}),this.control=new Ty({state:e.state,connector:this.connector,onEvent:async e=>{await this.events.apply(e)}}),this.lifecycle=new Cy({state:e.state,connections:this.control,remote:{revoke:async({bindingId:e})=>this.connector.request("revoke-binding",{bindingId:e}),setRemoteAccess:async({bindingId:e,enabled:t})=>{await this.connector.request("set-remote-access",{bindingId:e,enabled:t})}}})}start(){this.running=!0,"active"===this.options.state.snapshot().status&&this.schedule(0)}async stop(){this.running=!1,this.timer&&clearTimeout(this.timer),await Promise.all([this.control.stop("control-plane-stopping"),this.dataConnections.closeAll("control-plane-stopping")])}async publishBindingChallenge(e){await this.ensureConnected(),await this.connector.request("publish-binding-challenge",{payload:e.payload,signature:e.signature})}async request(e,t){return await this.ensureConnected(),this.connector.request(e,t)}async handleRequest(e,t){if("consume-binding-challenge"===e){const e=this.options.identity.publicIdentity();return this.options.state.consumeChallenge({challengeCode:t?.challengeCode,controlPlaneId:e.controlPlaneId,fingerprint:e.fingerprint})}if("deliver-binding-credential"===e)return this.options.state.activate(t);if("relay-allocation"===e)return this.dataConnections.attach(t);throw Dy("CLOUD_CONTROL_OPERATION_UNSUPPORTED")}async ensureConnected(){if(this.connecting||(this.connecting=this.control.connectOnce().finally(()=>{this.connecting=void 0})),"connected"!==(await this.connecting).status)throw Dy("CLOUD_CONTROL_CONNECTION_DISABLED")}schedule(e=this.control.reconnectDelay()){if(!this.running||this.timer)return;const t=this.options.state.snapshot();"active"===t.status&&t.remoteAccessEnabled&&(this.timer=setTimeout(()=>{this.timer=void 0,this.ensureConnected().catch(()=>this.schedule())},e),this.timer.unref())}}function Dy(e){return Object.assign(new Error("Cloud background connection is unavailable."),{code:e,retryable:!0})}const My="x-task-handoff-cloud-internal-actor",Ly=a.z.object({code:a.z.string().trim().min(1),message:a.z.string(),details:a.z.record(a.z.string(),a.z.unknown()).optional(),retryable:a.z.boolean().optional()}).strict(),qy=a.z.object({error:Ly}).strict(),$y="https://cloud.thandoff.com";function By(e,t={}){const n=new URL(e||$y).origin;if(n===$y)return n;if(t.production||!0!==t.allowNonProduction)throw Object.assign(new Error("Non-production cloud service origin is not trusted by this build."),{code:"UNTRUSTED_CLOUD_SERVICE_ORIGIN"});return n}function Uy(e){const t=process.env[e]?.trim();return t||void 0}const Fy=function(e,t=process.env,n=e){let i;return()=>{const s=t.TASK_HANDOFF_VERSION?.trim();return s||(i||=T(e,t,n),i)}}("@task-handoff/control-plane");function Hy(){return{component:"control-plane",packageName:"@task-handoff/control-plane",packageVersion:Fy(),protocolVersion:li,buildId:Uy("TASK_HANDOFF_BUILD_ID"),builtAt:Uy("TASK_HANDOFF_BUILT_AT"),gitCommit:Uy("TASK_HANDOFF_GIT_COMMIT"),imageRef:Uy("TASK_HANDOFF_IMAGE_REF"),imageDigest:Uy("TASK_HANDOFF_IMAGE_DIGEST")}}const Wy={".css":"text/css; charset=utf-8",".html":"text/html; charset=utf-8",".ico":"image/x-icon",".js":"text/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".map":"application/json; charset=utf-8",".png":"image/png",".svg":"image/svg+xml",".webp":"image/webp"};function Gy(e,i){const s=t.resolve(e),r=t.resolve(s,i);if(r===s||r.startsWith(`${s}${t.sep}`))return n.existsSync(r)&&n.statSync(r).isFile()?r:void 0}function Vy(e,i,s){const r=Gy(i,s);return r?(e.header("cache-control","no-store"),e.type(Wy[t.extname(r).toLowerCase()]||"application/octet-stream"),e.send(n.createReadStream(r))):e.code(404).send({error:{code:"STATIC_FILE_NOT_FOUND",message:`${s} was not found in the Control Plane UI static directory.`}})}function Ky(e){if(e instanceof a.z.ZodError)return{statusCode:400,code:"VALIDATION_ERROR",message:e.issues.map(e=>`${e.path.join(".")||"body"}: ${e.message}`).join("; ")};const t=e&&"object"==typeof e?e:{};return{statusCode:"number"==typeof t.statusCode?t.statusCode:500,code:"string"==typeof t.code?t.code:"CONTROL_PLANE_ERROR",message:e instanceof Error?e.message:String(e),...t.details&&"object"==typeof t.details&&!Array.isArray(t.details)?{details:t.details}:{},..."boolean"==typeof t.retryable?{retryable:t.retryable}:{},..."number"==typeof t.retryAfterSeconds?{retryAfterSeconds:t.retryAfterSeconds}:{}}}function Jy(e){const t=e.headers.authorization;if(void 0!==t){const e=/^Bearer ([^\s]+)$/.exec(t);return{token:e?.[1],clientType:"mobile"}}return{token:e.cookies[bo],clientType:"web"}}async function Yy(e,t){if(!e.enabled())return{type:"system",reason:"auth-disabled"};const n="mobile"===t.clientType?await e.userForMobileSessionToken(t.token):await e.userForSessionToken(t.token);return n?{type:"user",userId:n.id,role:n.role}:void 0}const Qy=new Set(["/api/auth/session","/api/auth/bootstrap-admin","/api/auth/login","/api/auth/logout","/api/auth/mobile/login","/api/control-plane/identity","/api/health","/api/events"]);function Xy(e,t){const n=t.split("?")[0]||"/";if(!n.startsWith("/api/"))return;if(Qy.has(n))return;const i=function(e){return"GET"===e||"HEAD"===e?"read":"POST"===e?"create":"PATCH"===e||"PUT"===e?"update":"DELETE"===e?"delete":"read"}(e);return"/api/control-plane/diagnostic-logs/export"===n?{action:"manage-settings",resource:{type:"control-plane-settings"}}:n.startsWith("/api/control-plane/settings")?{action:"GET"===e?"read":"manage-settings",resource:{type:"control-plane-settings"}}:"/api/auth/mobile/logout"===n||n.startsWith("/api/auth/mobile/sessions")||"/api/auth/password"===n?void 0:n.startsWith("/api/models")?{action:"GET"===e?"read":"manage-secrets",resource:{type:"model"}}:n.startsWith("/api/chat-gateway/bridges")?{action:"GET"===e?"read":"manage-secrets",resource:{type:"chat-bridge"}}:"/api/chat-gateway/messages"===n||"/api/chat-gateway/actions"===n?{action:"send-message",resource:{type:"ai-session"}}:"/api/chat-gateway/poll-ai-sessions"===n?{action:"manage-settings",resource:{type:"chat-bridge"}}:"/api/ai-session-attachments"===n?{action:"send-message",resource:{type:"ai-session"}}:"/api/node-join/invites"===n?{action:"manage-node-auth",resource:{type:"node"}}:n.startsWith("/api/control-plane-proxy")?{action:"GET"===e?"read":"manage-node-auth",resource:{type:"node"}}:n.startsWith("/api/nodes")?/\/(runtimes|local-folders)(\/|$)/.test(n)?{action:i,resource:{type:"runtime"}}:{action:"GET"===e?"read":"manage-node-auth",resource:{type:"node"}}:n.startsWith("/api/controlled-instances")?/\/apps\/sessions\/[^/]+\/access$/.test(n)?{action:"read",resource:{type:"instance"}}:n.includes("/ai-sessions")?n.includes("/triggers")?{action:i,resource:{type:"trigger"}}:"POST"===e&&/\/ai-sessions$/.test(n)?{action:"send-message",resource:{type:"ai-session"}}:n.endsWith("/approval")?{action:"approve",resource:{type:"ai-session"}}:n.endsWith("/interrupt")?{action:"interrupt",resource:{type:"ai-session"}}:n.endsWith("/resume")||n.endsWith("/fork")||n.endsWith("/commands")||n.includes("/messages")||n.includes("/queue/")?{action:"send-message",resource:{type:"ai-session"}}:n.endsWith("/read")||n.endsWith("/mentions/files")?{action:"read",resource:{type:"ai-session"}}:{action:i,resource:{type:"ai-session"}}:n.includes("/start")?{action:"start",resource:{type:"instance"}}:n.includes("/stop")?{action:"stop",resource:{type:"instance"}}:n.includes("/restart")?{action:"restart",resource:{type:"instance"}}:/\/config-sync(?:\/|$)/.test(n)?{action:"update",resource:{type:"instance"}}:{action:i,resource:{type:"instance"}}:n.startsWith("/api/projects")?{action:i,resource:{type:"project"}}:n.startsWith("/api/images")||n.startsWith("/api/image-options")||n.startsWith("/api/market")?{action:i,resource:{type:"runtime"}}:n.startsWith("/api/triggers")?{action:i,resource:{type:"trigger"}}:{action:i,resource:{type:"control-plane-settings"}}}async function Zy(e={}){const d=Wg(e.dataDir),c=s({logger:e.logger??!0}),l=new pg,p=e.cloudConnectivityEnabled??"0"!==process.env.TASK_HANDOFF_CLOUD_CONNECTIVITY_ENABLED;let u=(h=process.env.TASK_HANDOFF_DIAGNOSTIC_LOGS,["1","true","yes","on"].includes(String(h||"").trim().toLowerCase()));var h;const m=function(e,i,s,r={}){const o=(o,a,d)=>{if(i()){s[o]?.(a,d);try{!function(e,i,s=10485760,r=2){const o=Buffer.isBuffer(i)?i:Buffer.from(i),a=o.byteLength>s?o.subarray(o.byteLength-s):o;if(n.mkdirSync(t.dirname(e),{recursive:!0,mode:448}),n.existsSync(e)){const t=n.lstatSync(e);if(!t.isFile()||t.isSymbolicLink())throw new Error(`Managed log path must be a regular file: ${e}`);t.size+a.byteLength>s&&(function(e,t){if(!(t<=0)){n.rmSync(my(e,t),{force:!0});for(let i=t-1;i>=1;i-=1){const t=my(e,i);n.existsSync(t)&&n.renameSync(t,my(e,i+1))}}}(e,r),r>0?t.size>s?(n.writeFileSync(my(e,1),function(e,t){const i=n.statSync(e),s=Math.min(i.size,t),r=Buffer.allocUnsafe(s),o=n.openSync(e,"r");let a=0;try{for(;a<s;){const e=n.readSync(o,r,a,s-a,i.size-s+a);if(0===e)break;a+=e}}finally{n.closeSync(o)}return a===s?r:r.subarray(0,a)}(e,s),{mode:384}),n.rmSync(e,{force:!0})):n.renameSync(e,my(e,1)):n.rmSync(e,{force:!0}))}n.appendFileSync(e,a,{mode:384}),n.chmodSync(e,384)}(t.join(e,"control-plane.log"),`${JSON.stringify({time:(new Date).toISOString(),level:o,message:d,data:Iy(a)},(e,t)=>Iy(t))}\n`,r.maxBytes??10485760,r.backupCount??2)}catch{}}};return{info:(e,t)=>o("info",e,t),warn:(e,t)=>o("warn",e,t),error:(e,t)=>o("error",e,t)}}(d.logsDir,()=>u,c.log),f=new hy;f.onChange(e=>l.publish("node.connection.updated",e,{topic:"node.state",scope:{nodeId:e.nodeId}}));const I=new op(d,{...e.service,logger:m,nodeConnectionRuntime:f}),b=new qo(d,e.auth),v=new gy(d.identitySigningPath,()=>I.proxyPrivateStore.controlPlaneId(),(e,t)=>c.log.warn(t,e)),w=new Sy({statePath:d.cloudConnectivityPath,identity:v,serviceOrigin:By(e.cloudServiceOrigin||process.env.TASK_HANDOFF_CLOUD_SERVICE_ORIGIN,{production:"production"===process.env.NODE_ENV,allowNonProduction:!0===e.allowNonProductionCloudOrigin||"staging"===process.env.TASK_HANDOFF_CLOUD_ENV})}),S=new Map,z=new jy({state:w,identity:v,relayBridge:{async request(e,t){const n=String(t?.method||"GET").toUpperCase(),s=String(t?.path||""),r=Xy(n,s);if(!s.startsWith("/api/")||!r||Qy.has(s.split("?")[0]))throw Object.assign(new Error("Cloud access route is not available."),{code:"CLOUD_ROUTE_FORBIDDEN",statusCode:403});gh(e,r.action,r.resource);const o=i.randomBytes(32).toString("base64url");S.set(o,e);try{const e=Object.fromEntries(Object.entries(t.headers??{}).filter(([e])=>!["authorization","cookie","host","connection","upgrade",My].includes(e.toLowerCase())).map(([e,t])=>[e,String(t)])),i=await c.inject({method:n,url:s,headers:{...e,[My]:o},...void 0===t.body?{}:{payload:t.body}});let r;try{r=i.json()}catch{r=i.body}return{status:i.statusCode,body:r}}finally{S.delete(o)}},subscribe(e,t,n){if("cloud-account"!==e.type)throw Object.assign(new Error("Cloud account actor required."),{code:"CLOUD_ACTOR_REQUIRED"});const i=new Set(t.length?t:["*"]);return l.on(e=>{(i.has("*")||i.has(e.topic)||i.has(e.type))&&n(e)})},async openTty(e,t,n){const i=String(t?.instanceId||""),s=String(t?.sessionId||"");if(gh(e,"proxy",{type:"instance",id:i}),!i||!s)throw Object.assign(new Error("TTY target is required."),{code:"TTY_TARGET_REQUIRED",statusCode:400});const r=new Map,o=(e,...t)=>{for(const n of r.get(e)??[])n(...t)};let a=!1;const d={readyState:1,on(e,t){const n=r.get(e)??new Set;n.add(t),r.set(e,n)},send(e){try{const t=JSON.parse(String(e));if("snapshot"===t.type){const e=ht.parse(t);n(on.parse({type:"tty-snapshot",data:e.data,pendingEscape:e.pendingEscape,cols:e.cols,rows:e.rows}))}else"output"===t.type?n({type:"tty-output",data:t.data}):"resize"===t.type?n({type:"tty-resize",body:{cols:t.cols,rows:t.rows}}):"exit"===t.type?n({type:"tty-exit",code:t.code,signal:t.signal}):"error"===t.type&&n({type:"tty-error"})}catch{n({type:"tty-error"})}},close(){a||(a=!0,o("close"),n({type:"tty-closed"}))}};return await I.proxyInstanceWebSocket(i,d,`/api/apps/sessions/${encodeURIComponent(s)}/tty`,[],{}),{send(e){a||o("message",Buffer.from(JSON.stringify({type:"input",data:e})))},resize(e,t){!a&&Number.isInteger(e)&&Number.isInteger(t)&&e>0&&t>0&&o("message",Buffer.from(JSON.stringify({type:"resize",cols:e,rows:t})))},close(){d.close()}}}}}),k=e.cloudConnectivityLifecycle?.(w)??z.lifecycle,T=e.publishCloudBindingChallenge??(e=>z.publishBindingChallenge(e)),E=new mm(l),C=new cm(d,{onChanged:e=>queueMicrotask(()=>l.publish(j,e,{topic:"ai.sessions",scope:{instanceId:e.instanceId,sessionId:e.sessionId}}))});C.init();const x=new am({bootstrap:()=>I.bootstrapAiSessionsFromInstances(),logger:m,recoverDelta:(e,t,n)=>I.recoverAiSessionDelta(e,t,n),recoverSnapshot:e=>I.recoverAiSessionSnapshot(e),onRecoveredEvent:e=>l.publish(e.type,e.payload)});x.onSnapshot(e=>C.reconcile(e.instanceId,e.aiSessions));const N=new gm({bootstrap:()=>I.bootstrapAppSessionsFromInstances(),logger:m,recoverDelta:(e,t,n)=>I.recoverAppSessionDelta(e,t,n),recoverSnapshot:e=>I.recoverAppSessionSnapshot(e),onRecoveredEvent:e=>l.publish(e.type,e.payload)});I.setAppSessionSnapshotProvider(e=>N.list(e)),I.setAiSessionSnapshotProvider(e=>x.list(e)),l.on(e=>{if(E.handle(e),"instance.deleted"===e.type){const t=e.payload&&"object"==typeof e.payload&&"instanceId"in e.payload?String(e.payload.instanceId||""):"";t&&(N.removeInstance(t),x.removeInstance(t),C.removeInstance(t))}});const O=new fg;c.addHook("onClose",async()=>{O.dispose()});const _=new Fg(l,{connectionRuntime:f,validateInstanceScope:(e,t)=>I.nodeOwnsInstance(e,t),onStreamsHello:(e,t)=>{for(const n of t.streams)"ai.sessions"===n.topic&&x.advertiseStream(e,n),"app.sessions"===n.topic&&N.advertiseStream(e,n)},onSessionEvent:e=>e.type.startsWith("app-session.")?N.handleEvent(e):x.handleEvent(e)}),R=e.proxyOrigin||process.env.TASK_HANDOFF_CONTROL_PLANE_PROXY_ORIGIN,P=e=>{const t=I.nodes.get(e);return t?function(e,t){const n="reverse-wss"===e.connectionMode&&t,i=n?"online":e.status;return{id:e.id,name:e.name||e.id,status:i,health:e.health,...e.lastSeenAt?{lastSeenAt:e.lastSeenAt}:{},capabilities:qm(e.capabilities||{},262144),manageable:!1!==e.connectionEnabled&&(n||"online"===i)}}(t,_.connected(t.id)):void 0},D=new Om(new Tm(d.proxyAuthorityPath,(e,t)=>c.log.warn(t,e)),{get:P},{proxyOrigin:R,proxyOriginProvider:()=>I.getSettings().publicBaseUrl}),M=new Rm,L=new jm(l,{projectTarget:e=>{const t=P(e);return t?Bm(t):void 0}}),q=new sy(I,{fetchImpl:e.service?.fetchImpl,logger:m,onStateChanged:e=>l.publish("node.proxy-state.updated",{nodeId:e.id,proxyState:e.proxyState},{topic:"node.state",scope:{nodeId:e.id}})});let $,B,U;l.on(e=>{if("node.created"!==e.type&&"node.updated"!==e.type&&"node.deleted"!==e.type||q.syncNow(),"instance.created"===e.type||"instance.updated"===e.type||"instance.deleted"===e.type){const t=e.payload&&"object"==typeof e.payload&&"instanceId"in e.payload?String(e.payload.instanceId||""):"";t&&_.invalidateInstanceScope({instanceId:t})}if("node.deleted"===e.type){const t=e.payload&&"object"==typeof e.payload&&"nodeId"in e.payload?String(e.payload.nodeId||""):"";if(t){_.invalidateInstanceScope({nodeId:t});const e=D.revokeTarget(t);for(const n of e.bindings)M.closeBinding(n.id,"Proxy target was deleted."),l.publish("control-plane-proxy.binding.updated",{binding:n},{topic:"control-plane-proxy",scope:{nodeId:t}})}}}),I.setNodeAgentTransport(_),I.init(),u=I.diagnosticLogsEnabled(),v.init(),w.init(),p&&z.start();const F=()=>{if($)return $;const e=I.recoverPendingPairingRevokes().then(()=>{});return $=e,e.then(()=>{$===e&&($=void 0)},()=>{$===e&&($=void 0)}),e};await F().catch(e=>c.log.warn({error:e},"pending node pairing recovery failed")),D.init(),q.start(),await I.syncLocalNodeConnection().catch(()=>{}),b.init();const H=new Pu(I,e.service?.fetchImpl,{aiSessions:x,logger:m,diagnosticLogsEnabled:()=>u});H.startEnabled();const W=new Hg(I,_,{safetyIntervalMs:Number(process.env.TASK_HANDOFF_EVENT_CONNECTION_SAFETY_INTERVAL_MS)||void 0,logger:m,connectionRuntime:f});W.start(),await c.register(r),await c.register(o),c.addHook("onClose",async()=>{await z.stop(),B&&clearInterval(B),U&&clearInterval(U),await($?.catch(()=>{})),E.close(),L.stop(),q.stop(),W.stop(),H.stopAll()}),c.setErrorHandler((e,t,n)=>{const i=Ky(e);void 0!==i.retryAfterSeconds&&n.header("retry-after",String(i.retryAfterSeconds)),(u||i.statusCode>=500)&&(i.statusCode>=500?c.log.error.bind(c.log):c.log.warn.bind(c.log))({method:t.method,url:t.url,statusCode:i.statusCode,errorCode:i.code,error:i.message},"control plane request failed"),n.code(i.statusCode).send(qy.parse({error:{code:i.code,message:i.message,...i.details?{details:i.details}:{},...void 0!==i.retryable?{retryable:i.retryable}:{}}}))}),c.addHook("preHandler",async(e,t)=>{const n=e.routeOptions.url,i=n&&"*"!==n?n:e.url,s=e.routeOptions.config.controlPlaneAuthBoundary,r=e.headers[My],o="string"==typeof r?S.get(r):void 0;if(o){S.delete(r);const t=Xy(e.method,i);if(!t)throw Object.assign(new Error("Cloud access route is not authorized."),{code:"CLOUD_ROUTE_FORBIDDEN",statusCode:403});return void gh(o,t.action,t.resource)}if("proxy-binding"===s||"node-tunnel"===s)return;const a="public"===s||"public-ui"===s&&function(e){const t=e.split("?")[0]||"/";return!t.startsWith("/api/")&&"/api"!==t&&!t.startsWith("/instances/")&&"/instances"!==t}(e.url);if(!b.enabled()||a){const t=await Yy(b,Jy(e)),n=Xy(e.method,i);return void(n&&gh(t||{type:"system",reason:"auth-disabled"},n.action,n.resource))}const d=await Yy(b,Jy(e));if(!d)return t.code(401).send({error:{code:"CONTROL_PLANE_AUTH_REQUIRED",message:"Sign in to access the Control Plane."}});const c=Xy(e.method,i);c&&gh(d,c.action,c.resource)});const G=t.resolve(e.staticDir||process.env.TASK_HANDOFF_CONTROL_PLANE_STATIC_DIR||t.resolve(process.cwd(),"packages","control-plane-ui","dist"));n.existsSync(G)&&(c.get("/assets/*",{config:Ig},async(e,n)=>{const i=e.params["*"];return Vy(n,G,t.join("assets",i||""))}),c.get("/favicon.ico",{config:Ig},async(e,t)=>Gy(G,"favicon.ico")?Vy(t,G,"favicon.ico"):t.code(204).send())),c.get("/api/health",{config:Ig},async()=>ms.parse({data:{ok:!0,role:"control-plane",protocolVersion:li,build:Hy(),dataDir:d.dataDir,serverTime:(new Date).toISOString()}})),c.get("/api/control-plane/identity",{config:Ig},async()=>v.publicDocument(b.enabled()?"required":"disabled"));const V=async e=>{if(!p)throw Object.assign(new Error("Cloud connectivity is disabled by feature flag."),{code:"CLOUD_CONNECTIVITY_DISABLED",statusCode:503});gh(await Yy(b,Jy(e))||{type:"system",reason:"auth-disabled"},"manage-settings",{type:"control-plane-settings"})};return c.get("/api/cloud-connectivity",async e=>(await V(e),{data:w.snapshot()})),c.post("/api/cloud-connectivity/challenges",async(e,t)=>{await V(e),t.header("cache-control","no-store");const n=w.createChallenge();return await T(n),{data:n}}),c.post("/api/cloud-connectivity/remote-access",async e=>{await V(e);const t=a.z.object({enabled:a.z.boolean()}).strict().parse(e.body);return{data:k?await k.setRemoteAccess(t.enabled):w.setRemoteAccess(t.enabled)}}),c.post("/api/cloud-connectivity/disconnect",async e=>(await V(e),{data:k?await k.disconnect():w.beginRevocation()})),c.get("/api/session-streams/diagnostics",async()=>({data:{aiSessions:x.diagnostics(),aiSessionActions:I.aiSessionActionDiagnostics(),appSessions:N.diagnostics(),nodeConnections:{...W.diagnostics(),runtime:f.diagnostics()}}})),c.get("/install-node-agent.sh",{config:Ig},async(e,t)=>(t.header("cache-control","no-store"),t.type("text/x-shellscript; charset=utf-8"),hm`#!/bin/sh
1
+ "use strict";var e=require("commander"),t=require("node:path"),n=require("node:fs"),i=require("node:crypto"),s=require("fastify"),a=require("node:zlib"),o=require("node:util"),r=require("node:stream"),c=require("node:events"),d=require("node:string_decoder"),l=require("stream"),p=require("buffer"),u=require("events"),m=require("node:os"),h=require("@fastify/cookie"),g=require("@fastify/websocket"),f=require("zod"),y=require("write-file-atomic"),b=require("ws"),v=require("node:http"),I=require("node:net"),x=require("telegramify-markdown"),w=require("node:fs/promises"),S=require("dingtalk-stream"),A=require("@larksuiteoapi/node-sdk"),E=require("node:child_process"),_=require("tar"),T=require("tweetnacl"),z=require("drizzle-orm"),k=require("drizzle-orm/node-postgres"),N=require("pg"),C=require("drizzle-orm/pg-core"),R=require("node:sqlite"),O=require("drizzle-orm/node-sqlite"),j=require("drizzle-orm/sqlite-core");function P(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(n){if("default"!==n){var i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,i.get?i:{enumerable:!0,get:function(){return e[n]}})}}),t.default=e,Object.freeze(t)}var D=P(_);function L(e,t){try{const i=JSON.parse(n.readFileSync(e,"utf8"));if(t&&i.name!==t)return;return"string"==typeof i.version&&i.version.trim()?i.version.trim():void 0}catch{return}}function M(e){if(e)try{return t.dirname(n.realpathSync(e))}catch{return}}function q(e,n=process.env,i=e){const s=n.TASK_HANDOFF_VERSION?.trim();if(s)return s;const a=i.split("/").at(-1),o=process.argv[1]?t.resolve(process.argv[1]):void 0,r=o?t.dirname(o):void 0,c=[M(o),r,process.cwd()].filter(e=>Boolean(e));for(const n of new Set(c)){let i=n;for(;;){const n=L(t.join(i,"package.json"),e);if(n)return n;const s=t.dirname(i);if(s===i)break;i=s}}let d;for(const e of new Set(c)){let n=e;for(;;){if(a){const e=L(t.join(n,"packages",a,"package.json"),i);if(e)return e}d||=L(t.join(n,"package.json"));const e=t.dirname(n);if(e===n)break;n=e}}return d||"unknown"}var U="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function $(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function B(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if("function"==typeof t){var n=function e(){var n=!1;try{n=this instanceof e}catch{}return n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};n.prototype=t.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(e).forEach(function(t){var i=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,i.get?i:{enumerable:!0,get:function(){return e[t]}})}),n}var F,H,G,W,V={exports:{}},K={exports:{}},Y={exports:{}};function X(){if(F)return Y.exports;F=1;const e=/at\s(?:.*\.)?plugin\s.*\n\s*(.*)/,t=/(\w*(\.\w*)*)\..*/;function n(n){const i=n.match(e);return i?i[1].split(/[/\\]/).slice(-1)[0].match(t)[1]:"anonymous"}return Y.exports=function(e){if(e.name.length>0)return e.name;const t=Error.stackTraceLimit;Error.stackTraceLimit=10;try{throw new Error("anonymous function")}catch(e){return Error.stackTraceLimit=t,n(e.stack)}},Y.exports.extractPluginName=n,Y.exports}function J(){return G?H:(G=1,H=function(e){return"@"===e[0]&&(e=e.slice(1).replace("/","-")),e.replace(/-(.)/g,function(e,t){return t.toUpperCase()})})}var Q,Z={exports:{}};var ee,te,ne,ie={"application/1d-interleaved-parityfec":{source:"iana"},"application/3gpdash-qoe-report+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/3gpp-ims+xml":{source:"iana",compressible:!0},"application/3gpphal+json":{source:"iana",compressible:!0},"application/3gpphalforms+json":{source:"iana",compressible:!0},"application/a2l":{source:"iana"},"application/ace+cbor":{source:"iana"},"application/ace+json":{source:"iana",compressible:!0},"application/ace-groupcomm+cbor":{source:"iana"},"application/ace-trl+cbor":{source:"iana"},"application/activemessage":{source:"iana"},"application/activity+json":{source:"iana",compressible:!0},"application/aif+cbor":{source:"iana"},"application/aif+json":{source:"iana",compressible:!0},"application/alto-cdni+json":{source:"iana",compressible:!0},"application/alto-cdnifilter+json":{source:"iana",compressible:!0},"application/alto-costmap+json":{source:"iana",compressible:!0},"application/alto-costmapfilter+json":{source:"iana",compressible:!0},"application/alto-directory+json":{source:"iana",compressible:!0},"application/alto-endpointcost+json":{source:"iana",compressible:!0},"application/alto-endpointcostparams+json":{source:"iana",compressible:!0},"application/alto-endpointprop+json":{source:"iana",compressible:!0},"application/alto-endpointpropparams+json":{source:"iana",compressible:!0},"application/alto-error+json":{source:"iana",compressible:!0},"application/alto-networkmap+json":{source:"iana",compressible:!0},"application/alto-networkmapfilter+json":{source:"iana",compressible:!0},"application/alto-propmap+json":{source:"iana",compressible:!0},"application/alto-propmapparams+json":{source:"iana",compressible:!0},"application/alto-tips+json":{source:"iana",compressible:!0},"application/alto-tipsparams+json":{source:"iana",compressible:!0},"application/alto-updatestreamcontrol+json":{source:"iana",compressible:!0},"application/alto-updatestreamparams+json":{source:"iana",compressible:!0},"application/aml":{source:"iana"},"application/andrew-inset":{source:"iana",extensions:["ez"]},"application/appinstaller":{compressible:!1,extensions:["appinstaller"]},"application/applefile":{source:"iana"},"application/applixware":{source:"apache",extensions:["aw"]},"application/appx":{compressible:!1,extensions:["appx"]},"application/appxbundle":{compressible:!1,extensions:["appxbundle"]},"application/at+jwt":{source:"iana"},"application/atf":{source:"iana"},"application/atfx":{source:"iana"},"application/atom+xml":{source:"iana",compressible:!0,extensions:["atom"]},"application/atomcat+xml":{source:"iana",compressible:!0,extensions:["atomcat"]},"application/atomdeleted+xml":{source:"iana",compressible:!0,extensions:["atomdeleted"]},"application/atomicmail":{source:"iana"},"application/atomsvc+xml":{source:"iana",compressible:!0,extensions:["atomsvc"]},"application/atsc-dwd+xml":{source:"iana",compressible:!0,extensions:["dwd"]},"application/atsc-dynamic-event-message":{source:"iana"},"application/atsc-held+xml":{source:"iana",compressible:!0,extensions:["held"]},"application/atsc-rdt+json":{source:"iana",compressible:!0},"application/atsc-rsat+xml":{source:"iana",compressible:!0,extensions:["rsat"]},"application/atxml":{source:"iana"},"application/auth-policy+xml":{source:"iana",compressible:!0},"application/automationml-aml+xml":{source:"iana",compressible:!0,extensions:["aml"]},"application/automationml-amlx+zip":{source:"iana",compressible:!1,extensions:["amlx"]},"application/bacnet-xdd+zip":{source:"iana",compressible:!1},"application/batch-smtp":{source:"iana"},"application/bdoc":{compressible:!1,extensions:["bdoc"]},"application/beep+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/bufr":{source:"iana"},"application/c2pa":{source:"iana"},"application/calendar+json":{source:"iana",compressible:!0},"application/calendar+xml":{source:"iana",compressible:!0,extensions:["xcs"]},"application/call-completion":{source:"iana"},"application/cals-1840":{source:"iana"},"application/captive+json":{source:"iana",compressible:!0},"application/cbor":{source:"iana"},"application/cbor-seq":{source:"iana"},"application/cccex":{source:"iana"},"application/ccmp+xml":{source:"iana",compressible:!0},"application/ccxml+xml":{source:"iana",compressible:!0,extensions:["ccxml"]},"application/cda+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/cdfx+xml":{source:"iana",compressible:!0,extensions:["cdfx"]},"application/cdmi-capability":{source:"iana",extensions:["cdmia"]},"application/cdmi-container":{source:"iana",extensions:["cdmic"]},"application/cdmi-domain":{source:"iana",extensions:["cdmid"]},"application/cdmi-object":{source:"iana",extensions:["cdmio"]},"application/cdmi-queue":{source:"iana",extensions:["cdmiq"]},"application/cdni":{source:"iana"},"application/ce+cbor":{source:"iana"},"application/cea":{source:"iana"},"application/cea-2018+xml":{source:"iana",compressible:!0},"application/cellml+xml":{source:"iana",compressible:!0},"application/cfw":{source:"iana"},"application/cid-edhoc+cbor-seq":{source:"iana"},"application/city+json":{source:"iana",compressible:!0},"application/city+json-seq":{source:"iana"},"application/clr":{source:"iana"},"application/clue+xml":{source:"iana",compressible:!0},"application/clue_info+xml":{source:"iana",compressible:!0},"application/cms":{source:"iana"},"application/cnrp+xml":{source:"iana",compressible:!0},"application/coap-eap":{source:"iana"},"application/coap-group+json":{source:"iana",compressible:!0},"application/coap-payload":{source:"iana"},"application/commonground":{source:"iana"},"application/concise-problem-details+cbor":{source:"iana"},"application/conference-info+xml":{source:"iana",compressible:!0},"application/cose":{source:"iana"},"application/cose-key":{source:"iana"},"application/cose-key-set":{source:"iana"},"application/cose-x509":{source:"iana"},"application/cpl+xml":{source:"iana",compressible:!0,extensions:["cpl"]},"application/csrattrs":{source:"iana"},"application/csta+xml":{source:"iana",compressible:!0},"application/cstadata+xml":{source:"iana",compressible:!0},"application/csvm+json":{source:"iana",compressible:!0},"application/cu-seeme":{source:"apache",extensions:["cu"]},"application/cwl":{source:"iana",extensions:["cwl"]},"application/cwl+json":{source:"iana",compressible:!0},"application/cwl+yaml":{source:"iana"},"application/cwt":{source:"iana"},"application/cybercash":{source:"iana"},"application/dart":{compressible:!0},"application/dash+xml":{source:"iana",compressible:!0,extensions:["mpd"]},"application/dash-patch+xml":{source:"iana",compressible:!0,extensions:["mpp"]},"application/dashdelta":{source:"iana"},"application/davmount+xml":{source:"iana",compressible:!0,extensions:["davmount"]},"application/dca-rft":{source:"iana"},"application/dcd":{source:"iana"},"application/dec-dx":{source:"iana"},"application/dialog-info+xml":{source:"iana",compressible:!0},"application/dicom":{source:"iana",extensions:["dcm"]},"application/dicom+json":{source:"iana",compressible:!0},"application/dicom+xml":{source:"iana",compressible:!0},"application/dii":{source:"iana"},"application/dit":{source:"iana"},"application/dns":{source:"iana"},"application/dns+json":{source:"iana",compressible:!0},"application/dns-message":{source:"iana"},"application/docbook+xml":{source:"apache",compressible:!0,extensions:["dbk"]},"application/dots+cbor":{source:"iana"},"application/dpop+jwt":{source:"iana"},"application/dskpp+xml":{source:"iana",compressible:!0},"application/dssc+der":{source:"iana",extensions:["dssc"]},"application/dssc+xml":{source:"iana",compressible:!0,extensions:["xdssc"]},"application/dvcs":{source:"iana"},"application/eat+cwt":{source:"iana"},"application/eat+jwt":{source:"iana"},"application/eat-bun+cbor":{source:"iana"},"application/eat-bun+json":{source:"iana",compressible:!0},"application/eat-ucs+cbor":{source:"iana"},"application/eat-ucs+json":{source:"iana",compressible:!0},"application/ecmascript":{source:"apache",compressible:!0,extensions:["ecma"]},"application/edhoc+cbor-seq":{source:"iana"},"application/edi-consent":{source:"iana"},"application/edi-x12":{source:"iana",compressible:!1},"application/edifact":{source:"iana",compressible:!1},"application/efi":{source:"iana"},"application/elm+json":{source:"iana",charset:"UTF-8",compressible:!0},"application/elm+xml":{source:"iana",compressible:!0},"application/emergencycalldata.cap+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/emergencycalldata.comment+xml":{source:"iana",compressible:!0},"application/emergencycalldata.control+xml":{source:"iana",compressible:!0},"application/emergencycalldata.deviceinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.ecall.msd":{source:"iana"},"application/emergencycalldata.legacyesn+json":{source:"iana",compressible:!0},"application/emergencycalldata.providerinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.serviceinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.subscriberinfo+xml":{source:"iana",compressible:!0},"application/emergencycalldata.veds+xml":{source:"iana",compressible:!0},"application/emma+xml":{source:"iana",compressible:!0,extensions:["emma"]},"application/emotionml+xml":{source:"iana",compressible:!0,extensions:["emotionml"]},"application/encaprtp":{source:"iana"},"application/entity-statement+jwt":{source:"iana"},"application/epp+xml":{source:"iana",compressible:!0},"application/epub+zip":{source:"iana",compressible:!1,extensions:["epub"]},"application/eshop":{source:"iana"},"application/exi":{source:"iana",extensions:["exi"]},"application/expect-ct-report+json":{source:"iana",compressible:!0},"application/express":{source:"iana",extensions:["exp"]},"application/fastinfoset":{source:"iana"},"application/fastsoap":{source:"iana"},"application/fdf":{source:"iana",extensions:["fdf"]},"application/fdt+xml":{source:"iana",compressible:!0,extensions:["fdt"]},"application/fhir+json":{source:"iana",charset:"UTF-8",compressible:!0},"application/fhir+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/fido.trusted-apps+json":{compressible:!0},"application/fits":{source:"iana"},"application/flexfec":{source:"iana"},"application/font-sfnt":{source:"iana"},"application/font-tdpfr":{source:"iana",extensions:["pfr"]},"application/font-woff":{source:"iana",compressible:!1},"application/framework-attributes+xml":{source:"iana",compressible:!0},"application/geo+json":{source:"iana",compressible:!0,extensions:["geojson"]},"application/geo+json-seq":{source:"iana"},"application/geopackage+sqlite3":{source:"iana"},"application/geopose+json":{source:"iana",compressible:!0},"application/geoxacml+json":{source:"iana",compressible:!0},"application/geoxacml+xml":{source:"iana",compressible:!0},"application/gltf-buffer":{source:"iana"},"application/gml+xml":{source:"iana",compressible:!0,extensions:["gml"]},"application/gnap-binding-jws":{source:"iana"},"application/gnap-binding-jwsd":{source:"iana"},"application/gnap-binding-rotation-jws":{source:"iana"},"application/gnap-binding-rotation-jwsd":{source:"iana"},"application/gpx+xml":{source:"apache",compressible:!0,extensions:["gpx"]},"application/grib":{source:"iana"},"application/gxf":{source:"apache",extensions:["gxf"]},"application/gzip":{source:"iana",compressible:!1,extensions:["gz"]},"application/h224":{source:"iana"},"application/held+xml":{source:"iana",compressible:!0},"application/hjson":{extensions:["hjson"]},"application/hl7v2+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/http":{source:"iana"},"application/hyperstudio":{source:"iana",extensions:["stk"]},"application/ibe-key-request+xml":{source:"iana",compressible:!0},"application/ibe-pkg-reply+xml":{source:"iana",compressible:!0},"application/ibe-pp-data":{source:"iana"},"application/iges":{source:"iana"},"application/im-iscomposing+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/index":{source:"iana"},"application/index.cmd":{source:"iana"},"application/index.obj":{source:"iana"},"application/index.response":{source:"iana"},"application/index.vnd":{source:"iana"},"application/inkml+xml":{source:"iana",compressible:!0,extensions:["ink","inkml"]},"application/iotp":{source:"iana"},"application/ipfix":{source:"iana",extensions:["ipfix"]},"application/ipp":{source:"iana"},"application/isup":{source:"iana"},"application/its+xml":{source:"iana",compressible:!0,extensions:["its"]},"application/java-archive":{source:"iana",compressible:!1,extensions:["jar","war","ear"]},"application/java-serialized-object":{source:"apache",compressible:!1,extensions:["ser"]},"application/java-vm":{source:"apache",compressible:!1,extensions:["class"]},"application/javascript":{source:"apache",charset:"UTF-8",compressible:!0,extensions:["js"]},"application/jf2feed+json":{source:"iana",compressible:!0},"application/jose":{source:"iana"},"application/jose+json":{source:"iana",compressible:!0},"application/jrd+json":{source:"iana",compressible:!0},"application/jscalendar+json":{source:"iana",compressible:!0},"application/jscontact+json":{source:"iana",compressible:!0},"application/json":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["json","map"]},"application/json-patch+json":{source:"iana",compressible:!0},"application/json-seq":{source:"iana"},"application/json5":{extensions:["json5"]},"application/jsonml+json":{source:"apache",compressible:!0,extensions:["jsonml"]},"application/jsonpath":{source:"iana"},"application/jwk+json":{source:"iana",compressible:!0},"application/jwk-set+json":{source:"iana",compressible:!0},"application/jwk-set+jwt":{source:"iana"},"application/jwt":{source:"iana"},"application/kpml-request+xml":{source:"iana",compressible:!0},"application/kpml-response+xml":{source:"iana",compressible:!0},"application/ld+json":{source:"iana",compressible:!0,extensions:["jsonld"]},"application/lgr+xml":{source:"iana",compressible:!0,extensions:["lgr"]},"application/link-format":{source:"iana"},"application/linkset":{source:"iana"},"application/linkset+json":{source:"iana",compressible:!0},"application/load-control+xml":{source:"iana",compressible:!0},"application/logout+jwt":{source:"iana"},"application/lost+xml":{source:"iana",compressible:!0,extensions:["lostxml"]},"application/lostsync+xml":{source:"iana",compressible:!0},"application/lpf+zip":{source:"iana",compressible:!1},"application/lxf":{source:"iana"},"application/mac-binhex40":{source:"iana",extensions:["hqx"]},"application/mac-compactpro":{source:"apache",extensions:["cpt"]},"application/macwriteii":{source:"iana"},"application/mads+xml":{source:"iana",compressible:!0,extensions:["mads"]},"application/manifest+json":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["webmanifest"]},"application/marc":{source:"iana",extensions:["mrc"]},"application/marcxml+xml":{source:"iana",compressible:!0,extensions:["mrcx"]},"application/mathematica":{source:"iana",extensions:["ma","nb","mb"]},"application/mathml+xml":{source:"iana",compressible:!0,extensions:["mathml"]},"application/mathml-content+xml":{source:"iana",compressible:!0},"application/mathml-presentation+xml":{source:"iana",compressible:!0},"application/mbms-associated-procedure-description+xml":{source:"iana",compressible:!0},"application/mbms-deregister+xml":{source:"iana",compressible:!0},"application/mbms-envelope+xml":{source:"iana",compressible:!0},"application/mbms-msk+xml":{source:"iana",compressible:!0},"application/mbms-msk-response+xml":{source:"iana",compressible:!0},"application/mbms-protection-description+xml":{source:"iana",compressible:!0},"application/mbms-reception-report+xml":{source:"iana",compressible:!0},"application/mbms-register+xml":{source:"iana",compressible:!0},"application/mbms-register-response+xml":{source:"iana",compressible:!0},"application/mbms-schedule+xml":{source:"iana",compressible:!0},"application/mbms-user-service-description+xml":{source:"iana",compressible:!0},"application/mbox":{source:"iana",extensions:["mbox"]},"application/media-policy-dataset+xml":{source:"iana",compressible:!0,extensions:["mpf"]},"application/media_control+xml":{source:"iana",compressible:!0},"application/mediaservercontrol+xml":{source:"iana",compressible:!0,extensions:["mscml"]},"application/merge-patch+json":{source:"iana",compressible:!0},"application/metalink+xml":{source:"apache",compressible:!0,extensions:["metalink"]},"application/metalink4+xml":{source:"iana",compressible:!0,extensions:["meta4"]},"application/mets+xml":{source:"iana",compressible:!0,extensions:["mets"]},"application/mf4":{source:"iana"},"application/mikey":{source:"iana"},"application/mipc":{source:"iana"},"application/missing-blocks+cbor-seq":{source:"iana"},"application/mmt-aei+xml":{source:"iana",compressible:!0,extensions:["maei"]},"application/mmt-usd+xml":{source:"iana",compressible:!0,extensions:["musd"]},"application/mods+xml":{source:"iana",compressible:!0,extensions:["mods"]},"application/moss-keys":{source:"iana"},"application/moss-signature":{source:"iana"},"application/mosskey-data":{source:"iana"},"application/mosskey-request":{source:"iana"},"application/mp21":{source:"iana",extensions:["m21","mp21"]},"application/mp4":{source:"iana",extensions:["mp4","mpg4","mp4s","m4p"]},"application/mpeg4-generic":{source:"iana"},"application/mpeg4-iod":{source:"iana"},"application/mpeg4-iod-xmt":{source:"iana"},"application/mrb-consumer+xml":{source:"iana",compressible:!0},"application/mrb-publish+xml":{source:"iana",compressible:!0},"application/msc-ivr+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/msc-mixer+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/msix":{compressible:!1,extensions:["msix"]},"application/msixbundle":{compressible:!1,extensions:["msixbundle"]},"application/msword":{source:"iana",compressible:!1,extensions:["doc","dot"]},"application/mud+json":{source:"iana",compressible:!0},"application/multipart-core":{source:"iana"},"application/mxf":{source:"iana",extensions:["mxf"]},"application/n-quads":{source:"iana",extensions:["nq"]},"application/n-triples":{source:"iana",extensions:["nt"]},"application/nasdata":{source:"iana"},"application/news-checkgroups":{source:"iana",charset:"US-ASCII"},"application/news-groupinfo":{source:"iana",charset:"US-ASCII"},"application/news-transmission":{source:"iana"},"application/nlsml+xml":{source:"iana",compressible:!0},"application/node":{source:"iana",extensions:["cjs"]},"application/nss":{source:"iana"},"application/oauth-authz-req+jwt":{source:"iana"},"application/oblivious-dns-message":{source:"iana"},"application/ocsp-request":{source:"iana"},"application/ocsp-response":{source:"iana"},"application/octet-stream":{source:"iana",compressible:!0,extensions:["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"]},"application/oda":{source:"iana",extensions:["oda"]},"application/odm+xml":{source:"iana",compressible:!0},"application/odx":{source:"iana"},"application/oebps-package+xml":{source:"iana",compressible:!0,extensions:["opf"]},"application/ogg":{source:"iana",compressible:!1,extensions:["ogx"]},"application/ohttp-keys":{source:"iana"},"application/omdoc+xml":{source:"apache",compressible:!0,extensions:["omdoc"]},"application/onenote":{source:"apache",extensions:["onetoc","onetoc2","onetmp","onepkg","one","onea"]},"application/opc-nodeset+xml":{source:"iana",compressible:!0},"application/oscore":{source:"iana"},"application/oxps":{source:"iana",extensions:["oxps"]},"application/p21":{source:"iana"},"application/p21+zip":{source:"iana",compressible:!1},"application/p2p-overlay+xml":{source:"iana",compressible:!0,extensions:["relo"]},"application/parityfec":{source:"iana"},"application/passport":{source:"iana"},"application/patch-ops-error+xml":{source:"iana",compressible:!0,extensions:["xer"]},"application/pdf":{source:"iana",compressible:!1,extensions:["pdf"]},"application/pdx":{source:"iana"},"application/pem-certificate-chain":{source:"iana"},"application/pgp-encrypted":{source:"iana",compressible:!1,extensions:["pgp"]},"application/pgp-keys":{source:"iana",extensions:["asc"]},"application/pgp-signature":{source:"iana",extensions:["sig","asc"]},"application/pics-rules":{source:"apache",extensions:["prf"]},"application/pidf+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/pidf-diff+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/pkcs10":{source:"iana",extensions:["p10"]},"application/pkcs12":{source:"iana"},"application/pkcs7-mime":{source:"iana",extensions:["p7m","p7c"]},"application/pkcs7-signature":{source:"iana",extensions:["p7s"]},"application/pkcs8":{source:"iana",extensions:["p8"]},"application/pkcs8-encrypted":{source:"iana"},"application/pkix-attr-cert":{source:"iana",extensions:["ac"]},"application/pkix-cert":{source:"iana",extensions:["cer"]},"application/pkix-crl":{source:"iana",extensions:["crl"]},"application/pkix-pkipath":{source:"iana",extensions:["pkipath"]},"application/pkixcmp":{source:"iana",extensions:["pki"]},"application/pls+xml":{source:"iana",compressible:!0,extensions:["pls"]},"application/poc-settings+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/postscript":{source:"iana",compressible:!0,extensions:["ai","eps","ps"]},"application/ppsp-tracker+json":{source:"iana",compressible:!0},"application/private-token-issuer-directory":{source:"iana"},"application/private-token-request":{source:"iana"},"application/private-token-response":{source:"iana"},"application/problem+json":{source:"iana",compressible:!0},"application/problem+xml":{source:"iana",compressible:!0},"application/provenance+xml":{source:"iana",compressible:!0,extensions:["provx"]},"application/provided-claims+jwt":{source:"iana"},"application/prs.alvestrand.titrax-sheet":{source:"iana"},"application/prs.cww":{source:"iana",extensions:["cww"]},"application/prs.cyn":{source:"iana",charset:"7-BIT"},"application/prs.hpub+zip":{source:"iana",compressible:!1},"application/prs.implied-document+xml":{source:"iana",compressible:!0},"application/prs.implied-executable":{source:"iana"},"application/prs.implied-object+json":{source:"iana",compressible:!0},"application/prs.implied-object+json-seq":{source:"iana"},"application/prs.implied-object+yaml":{source:"iana"},"application/prs.implied-structure":{source:"iana"},"application/prs.mayfile":{source:"iana"},"application/prs.nprend":{source:"iana"},"application/prs.plucker":{source:"iana"},"application/prs.rdf-xml-crypt":{source:"iana"},"application/prs.vcfbzip2":{source:"iana"},"application/prs.xsf+xml":{source:"iana",compressible:!0,extensions:["xsf"]},"application/pskc+xml":{source:"iana",compressible:!0,extensions:["pskcxml"]},"application/pvd+json":{source:"iana",compressible:!0},"application/qsig":{source:"iana"},"application/raml+yaml":{compressible:!0,extensions:["raml"]},"application/raptorfec":{source:"iana"},"application/rdap+json":{source:"iana",compressible:!0},"application/rdf+xml":{source:"iana",compressible:!0,extensions:["rdf","owl"]},"application/reginfo+xml":{source:"iana",compressible:!0,extensions:["rif"]},"application/relax-ng-compact-syntax":{source:"iana",extensions:["rnc"]},"application/remote-printing":{source:"apache"},"application/reputon+json":{source:"iana",compressible:!0},"application/resolve-response+jwt":{source:"iana"},"application/resource-lists+xml":{source:"iana",compressible:!0,extensions:["rl"]},"application/resource-lists-diff+xml":{source:"iana",compressible:!0,extensions:["rld"]},"application/rfc+xml":{source:"iana",compressible:!0},"application/riscos":{source:"iana"},"application/rlmi+xml":{source:"iana",compressible:!0},"application/rls-services+xml":{source:"iana",compressible:!0,extensions:["rs"]},"application/route-apd+xml":{source:"iana",compressible:!0,extensions:["rapd"]},"application/route-s-tsid+xml":{source:"iana",compressible:!0,extensions:["sls"]},"application/route-usd+xml":{source:"iana",compressible:!0,extensions:["rusd"]},"application/rpki-checklist":{source:"iana"},"application/rpki-ghostbusters":{source:"iana",extensions:["gbr"]},"application/rpki-manifest":{source:"iana",extensions:["mft"]},"application/rpki-publication":{source:"iana"},"application/rpki-roa":{source:"iana",extensions:["roa"]},"application/rpki-signed-tal":{source:"iana"},"application/rpki-updown":{source:"iana"},"application/rsd+xml":{source:"apache",compressible:!0,extensions:["rsd"]},"application/rss+xml":{source:"apache",compressible:!0,extensions:["rss"]},"application/rtf":{source:"iana",compressible:!0,extensions:["rtf"]},"application/rtploopback":{source:"iana"},"application/rtx":{source:"iana"},"application/samlassertion+xml":{source:"iana",compressible:!0},"application/samlmetadata+xml":{source:"iana",compressible:!0},"application/sarif+json":{source:"iana",compressible:!0},"application/sarif-external-properties+json":{source:"iana",compressible:!0},"application/sbe":{source:"iana"},"application/sbml+xml":{source:"iana",compressible:!0,extensions:["sbml"]},"application/scaip+xml":{source:"iana",compressible:!0},"application/scim+json":{source:"iana",compressible:!0},"application/scvp-cv-request":{source:"iana",extensions:["scq"]},"application/scvp-cv-response":{source:"iana",extensions:["scs"]},"application/scvp-vp-request":{source:"iana",extensions:["spq"]},"application/scvp-vp-response":{source:"iana",extensions:["spp"]},"application/sdp":{source:"iana",extensions:["sdp"]},"application/secevent+jwt":{source:"iana"},"application/senml+cbor":{source:"iana"},"application/senml+json":{source:"iana",compressible:!0},"application/senml+xml":{source:"iana",compressible:!0,extensions:["senmlx"]},"application/senml-etch+cbor":{source:"iana"},"application/senml-etch+json":{source:"iana",compressible:!0},"application/senml-exi":{source:"iana"},"application/sensml+cbor":{source:"iana"},"application/sensml+json":{source:"iana",compressible:!0},"application/sensml+xml":{source:"iana",compressible:!0,extensions:["sensmlx"]},"application/sensml-exi":{source:"iana"},"application/sep+xml":{source:"iana",compressible:!0},"application/sep-exi":{source:"iana"},"application/session-info":{source:"iana"},"application/set-payment":{source:"iana"},"application/set-payment-initiation":{source:"iana",extensions:["setpay"]},"application/set-registration":{source:"iana"},"application/set-registration-initiation":{source:"iana",extensions:["setreg"]},"application/sgml":{source:"iana"},"application/sgml-open-catalog":{source:"iana"},"application/shf+xml":{source:"iana",compressible:!0,extensions:["shf"]},"application/sieve":{source:"iana",extensions:["siv","sieve"]},"application/simple-filter+xml":{source:"iana",compressible:!0},"application/simple-message-summary":{source:"iana"},"application/simplesymbolcontainer":{source:"iana"},"application/sipc":{source:"iana"},"application/slate":{source:"iana"},"application/smil":{source:"apache"},"application/smil+xml":{source:"iana",compressible:!0,extensions:["smi","smil"]},"application/smpte336m":{source:"iana"},"application/soap+fastinfoset":{source:"iana"},"application/soap+xml":{source:"iana",compressible:!0},"application/sparql-query":{source:"iana",extensions:["rq"]},"application/sparql-results+xml":{source:"iana",compressible:!0,extensions:["srx"]},"application/spdx+json":{source:"iana",compressible:!0},"application/spirits-event+xml":{source:"iana",compressible:!0},"application/sql":{source:"iana",extensions:["sql"]},"application/srgs":{source:"iana",extensions:["gram"]},"application/srgs+xml":{source:"iana",compressible:!0,extensions:["grxml"]},"application/sru+xml":{source:"iana",compressible:!0,extensions:["sru"]},"application/ssdl+xml":{source:"apache",compressible:!0,extensions:["ssdl"]},"application/sslkeylogfile":{source:"iana"},"application/ssml+xml":{source:"iana",compressible:!0,extensions:["ssml"]},"application/st2110-41":{source:"iana"},"application/stix+json":{source:"iana",compressible:!0},"application/stratum":{source:"iana"},"application/swid+cbor":{source:"iana"},"application/swid+xml":{source:"iana",compressible:!0,extensions:["swidtag"]},"application/tamp-apex-update":{source:"iana"},"application/tamp-apex-update-confirm":{source:"iana"},"application/tamp-community-update":{source:"iana"},"application/tamp-community-update-confirm":{source:"iana"},"application/tamp-error":{source:"iana"},"application/tamp-sequence-adjust":{source:"iana"},"application/tamp-sequence-adjust-confirm":{source:"iana"},"application/tamp-status-query":{source:"iana"},"application/tamp-status-response":{source:"iana"},"application/tamp-update":{source:"iana"},"application/tamp-update-confirm":{source:"iana"},"application/tar":{compressible:!0},"application/taxii+json":{source:"iana",compressible:!0},"application/td+json":{source:"iana",compressible:!0},"application/tei+xml":{source:"iana",compressible:!0,extensions:["tei","teicorpus"]},"application/tetra_isi":{source:"iana"},"application/thraud+xml":{source:"iana",compressible:!0,extensions:["tfi"]},"application/timestamp-query":{source:"iana"},"application/timestamp-reply":{source:"iana"},"application/timestamped-data":{source:"iana",extensions:["tsd"]},"application/tlsrpt+gzip":{source:"iana"},"application/tlsrpt+json":{source:"iana",compressible:!0},"application/tm+json":{source:"iana",compressible:!0},"application/tnauthlist":{source:"iana"},"application/toc+cbor":{source:"iana"},"application/token-introspection+jwt":{source:"iana"},"application/toml":{source:"iana",compressible:!0,extensions:["toml"]},"application/trickle-ice-sdpfrag":{source:"iana"},"application/trig":{source:"iana",extensions:["trig"]},"application/trust-chain+json":{source:"iana",compressible:!0},"application/trust-mark+jwt":{source:"iana"},"application/trust-mark-delegation+jwt":{source:"iana"},"application/ttml+xml":{source:"iana",compressible:!0,extensions:["ttml"]},"application/tve-trigger":{source:"iana"},"application/tzif":{source:"iana"},"application/tzif-leap":{source:"iana"},"application/ubjson":{compressible:!1,extensions:["ubj"]},"application/uccs+cbor":{source:"iana"},"application/ujcs+json":{source:"iana",compressible:!0},"application/ulpfec":{source:"iana"},"application/urc-grpsheet+xml":{source:"iana",compressible:!0},"application/urc-ressheet+xml":{source:"iana",compressible:!0,extensions:["rsheet"]},"application/urc-targetdesc+xml":{source:"iana",compressible:!0,extensions:["td"]},"application/urc-uisocketdesc+xml":{source:"iana",compressible:!0},"application/vc":{source:"iana"},"application/vc+cose":{source:"iana"},"application/vc+jwt":{source:"iana"},"application/vcard+json":{source:"iana",compressible:!0},"application/vcard+xml":{source:"iana",compressible:!0},"application/vemmi":{source:"iana"},"application/vividence.scriptfile":{source:"apache"},"application/vnd.1000minds.decision-model+xml":{source:"iana",compressible:!0,extensions:["1km"]},"application/vnd.1ob":{source:"iana"},"application/vnd.3gpp-prose+xml":{source:"iana",compressible:!0},"application/vnd.3gpp-prose-pc3a+xml":{source:"iana",compressible:!0},"application/vnd.3gpp-prose-pc3ach+xml":{source:"iana",compressible:!0},"application/vnd.3gpp-prose-pc3ch+xml":{source:"iana",compressible:!0},"application/vnd.3gpp-prose-pc8+xml":{source:"iana",compressible:!0},"application/vnd.3gpp-v2x-local-service-information":{source:"iana"},"application/vnd.3gpp.5gnas":{source:"iana"},"application/vnd.3gpp.5gsa2x":{source:"iana"},"application/vnd.3gpp.5gsa2x-local-service-information":{source:"iana"},"application/vnd.3gpp.5gsv2x":{source:"iana"},"application/vnd.3gpp.5gsv2x-local-service-information":{source:"iana"},"application/vnd.3gpp.access-transfer-events+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.bsf+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.crs+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.current-location-discovery+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.gmop+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.gtpc":{source:"iana"},"application/vnd.3gpp.interworking-data":{source:"iana"},"application/vnd.3gpp.lpp":{source:"iana"},"application/vnd.3gpp.mc-signalling-ear":{source:"iana"},"application/vnd.3gpp.mcdata-affiliation-command+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-msgstore-ctrl-request+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-payload":{source:"iana"},"application/vnd.3gpp.mcdata-regroup+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-service-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-signalling":{source:"iana"},"application/vnd.3gpp.mcdata-ue-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcdata-user-profile+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-affiliation-command+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-floor-request+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-location-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-mbms-usage-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-regroup+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-service-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-signed+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-ue-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-ue-init-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcptt-user-profile+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-affiliation-command+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-location-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-mbms-usage-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-regroup+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-service-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-transmission-request+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-ue-config+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mcvideo-user-profile+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.mid-call+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.ngap":{source:"iana"},"application/vnd.3gpp.pfcp":{source:"iana"},"application/vnd.3gpp.pic-bw-large":{source:"iana",extensions:["plb"]},"application/vnd.3gpp.pic-bw-small":{source:"iana",extensions:["psb"]},"application/vnd.3gpp.pic-bw-var":{source:"iana",extensions:["pvb"]},"application/vnd.3gpp.pinapp-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.s1ap":{source:"iana"},"application/vnd.3gpp.seal-group-doc+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.seal-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.seal-location-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.seal-mbms-usage-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.seal-network-qos-management-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.seal-ue-config-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.seal-unicast-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.seal-user-profile-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.sms":{source:"iana"},"application/vnd.3gpp.sms+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.srvcc-ext+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.srvcc-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.state-and-event-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.ussd+xml":{source:"iana",compressible:!0},"application/vnd.3gpp.v2x":{source:"iana"},"application/vnd.3gpp.vae-info+xml":{source:"iana",compressible:!0},"application/vnd.3gpp2.bcmcsinfo+xml":{source:"iana",compressible:!0},"application/vnd.3gpp2.sms":{source:"iana"},"application/vnd.3gpp2.tcap":{source:"iana",extensions:["tcap"]},"application/vnd.3lightssoftware.imagescal":{source:"iana"},"application/vnd.3m.post-it-notes":{source:"iana",extensions:["pwn"]},"application/vnd.accpac.simply.aso":{source:"iana",extensions:["aso"]},"application/vnd.accpac.simply.imp":{source:"iana",extensions:["imp"]},"application/vnd.acm.addressxfer+json":{source:"iana",compressible:!0},"application/vnd.acm.chatbot+json":{source:"iana",compressible:!0},"application/vnd.acucobol":{source:"iana",extensions:["acu"]},"application/vnd.acucorp":{source:"iana",extensions:["atc","acutc"]},"application/vnd.adobe.air-application-installer-package+zip":{source:"apache",compressible:!1,extensions:["air"]},"application/vnd.adobe.flash.movie":{source:"iana"},"application/vnd.adobe.formscentral.fcdt":{source:"iana",extensions:["fcdt"]},"application/vnd.adobe.fxp":{source:"iana",extensions:["fxp","fxpl"]},"application/vnd.adobe.partial-upload":{source:"iana"},"application/vnd.adobe.xdp+xml":{source:"iana",compressible:!0,extensions:["xdp"]},"application/vnd.adobe.xfdf":{source:"apache",extensions:["xfdf"]},"application/vnd.aether.imp":{source:"iana"},"application/vnd.afpc.afplinedata":{source:"iana"},"application/vnd.afpc.afplinedata-pagedef":{source:"iana"},"application/vnd.afpc.cmoca-cmresource":{source:"iana"},"application/vnd.afpc.foca-charset":{source:"iana"},"application/vnd.afpc.foca-codedfont":{source:"iana"},"application/vnd.afpc.foca-codepage":{source:"iana"},"application/vnd.afpc.modca":{source:"iana"},"application/vnd.afpc.modca-cmtable":{source:"iana"},"application/vnd.afpc.modca-formdef":{source:"iana"},"application/vnd.afpc.modca-mediummap":{source:"iana"},"application/vnd.afpc.modca-objectcontainer":{source:"iana"},"application/vnd.afpc.modca-overlay":{source:"iana"},"application/vnd.afpc.modca-pagesegment":{source:"iana"},"application/vnd.age":{source:"iana",extensions:["age"]},"application/vnd.ah-barcode":{source:"apache"},"application/vnd.ahead.space":{source:"iana",extensions:["ahead"]},"application/vnd.airzip.filesecure.azf":{source:"iana",extensions:["azf"]},"application/vnd.airzip.filesecure.azs":{source:"iana",extensions:["azs"]},"application/vnd.amadeus+json":{source:"iana",compressible:!0},"application/vnd.amazon.ebook":{source:"apache",extensions:["azw"]},"application/vnd.amazon.mobi8-ebook":{source:"iana"},"application/vnd.americandynamics.acc":{source:"iana",extensions:["acc"]},"application/vnd.amiga.ami":{source:"iana",extensions:["ami"]},"application/vnd.amundsen.maze+xml":{source:"iana",compressible:!0},"application/vnd.android.ota":{source:"iana"},"application/vnd.android.package-archive":{source:"apache",compressible:!1,extensions:["apk"]},"application/vnd.anki":{source:"iana"},"application/vnd.anser-web-certificate-issue-initiation":{source:"iana",extensions:["cii"]},"application/vnd.anser-web-funds-transfer-initiation":{source:"apache",extensions:["fti"]},"application/vnd.antix.game-component":{source:"iana",extensions:["atx"]},"application/vnd.apache.arrow.file":{source:"iana"},"application/vnd.apache.arrow.stream":{source:"iana"},"application/vnd.apache.parquet":{source:"iana"},"application/vnd.apache.thrift.binary":{source:"iana"},"application/vnd.apache.thrift.compact":{source:"iana"},"application/vnd.apache.thrift.json":{source:"iana"},"application/vnd.apexlang":{source:"iana"},"application/vnd.api+json":{source:"iana",compressible:!0},"application/vnd.aplextor.warrp+json":{source:"iana",compressible:!0},"application/vnd.apothekende.reservation+json":{source:"iana",compressible:!0},"application/vnd.apple.installer+xml":{source:"iana",compressible:!0,extensions:["mpkg"]},"application/vnd.apple.keynote":{source:"iana",extensions:["key"]},"application/vnd.apple.mpegurl":{source:"iana",extensions:["m3u8"]},"application/vnd.apple.numbers":{source:"iana",extensions:["numbers"]},"application/vnd.apple.pages":{source:"iana",extensions:["pages"]},"application/vnd.apple.pkpass":{compressible:!1,extensions:["pkpass"]},"application/vnd.arastra.swi":{source:"apache"},"application/vnd.aristanetworks.swi":{source:"iana",extensions:["swi"]},"application/vnd.artisan+json":{source:"iana",compressible:!0},"application/vnd.artsquare":{source:"iana"},"application/vnd.astraea-software.iota":{source:"iana",extensions:["iota"]},"application/vnd.audiograph":{source:"iana",extensions:["aep"]},"application/vnd.autodesk.fbx":{extensions:["fbx"]},"application/vnd.autopackage":{source:"iana"},"application/vnd.avalon+json":{source:"iana",compressible:!0},"application/vnd.avistar+xml":{source:"iana",compressible:!0},"application/vnd.balsamiq.bmml+xml":{source:"iana",compressible:!0,extensions:["bmml"]},"application/vnd.balsamiq.bmpr":{source:"iana"},"application/vnd.banana-accounting":{source:"iana"},"application/vnd.bbf.usp.error":{source:"iana"},"application/vnd.bbf.usp.msg":{source:"iana"},"application/vnd.bbf.usp.msg+json":{source:"iana",compressible:!0},"application/vnd.bekitzur-stech+json":{source:"iana",compressible:!0},"application/vnd.belightsoft.lhzd+zip":{source:"iana",compressible:!1},"application/vnd.belightsoft.lhzl+zip":{source:"iana",compressible:!1},"application/vnd.bint.med-content":{source:"iana"},"application/vnd.biopax.rdf+xml":{source:"iana",compressible:!0},"application/vnd.blink-idb-value-wrapper":{source:"iana"},"application/vnd.blueice.multipass":{source:"iana",extensions:["mpm"]},"application/vnd.bluetooth.ep.oob":{source:"iana"},"application/vnd.bluetooth.le.oob":{source:"iana"},"application/vnd.bmi":{source:"iana",extensions:["bmi"]},"application/vnd.bpf":{source:"iana"},"application/vnd.bpf3":{source:"iana"},"application/vnd.businessobjects":{source:"iana",extensions:["rep"]},"application/vnd.byu.uapi+json":{source:"iana",compressible:!0},"application/vnd.bzip3":{source:"iana"},"application/vnd.c3voc.schedule+xml":{source:"iana",compressible:!0},"application/vnd.cab-jscript":{source:"iana"},"application/vnd.canon-cpdl":{source:"iana"},"application/vnd.canon-lips":{source:"iana"},"application/vnd.capasystems-pg+json":{source:"iana",compressible:!0},"application/vnd.cendio.thinlinc.clientconf":{source:"iana"},"application/vnd.century-systems.tcp_stream":{source:"iana"},"application/vnd.chemdraw+xml":{source:"iana",compressible:!0,extensions:["cdxml"]},"application/vnd.chess-pgn":{source:"iana"},"application/vnd.chipnuts.karaoke-mmd":{source:"iana",extensions:["mmd"]},"application/vnd.ciedi":{source:"iana"},"application/vnd.cinderella":{source:"iana",extensions:["cdy"]},"application/vnd.cirpack.isdn-ext":{source:"iana"},"application/vnd.citationstyles.style+xml":{source:"iana",compressible:!0,extensions:["csl"]},"application/vnd.claymore":{source:"iana",extensions:["cla"]},"application/vnd.cloanto.rp9":{source:"iana",extensions:["rp9"]},"application/vnd.clonk.c4group":{source:"iana",extensions:["c4g","c4d","c4f","c4p","c4u"]},"application/vnd.cluetrust.cartomobile-config":{source:"iana",extensions:["c11amc"]},"application/vnd.cluetrust.cartomobile-config-pkg":{source:"iana",extensions:["c11amz"]},"application/vnd.cncf.helm.chart.content.v1.tar+gzip":{source:"iana"},"application/vnd.cncf.helm.chart.provenance.v1.prov":{source:"iana"},"application/vnd.cncf.helm.config.v1+json":{source:"iana",compressible:!0},"application/vnd.coffeescript":{source:"iana"},"application/vnd.collabio.xodocuments.document":{source:"iana"},"application/vnd.collabio.xodocuments.document-template":{source:"iana"},"application/vnd.collabio.xodocuments.presentation":{source:"iana"},"application/vnd.collabio.xodocuments.presentation-template":{source:"iana"},"application/vnd.collabio.xodocuments.spreadsheet":{source:"iana"},"application/vnd.collabio.xodocuments.spreadsheet-template":{source:"iana"},"application/vnd.collection+json":{source:"iana",compressible:!0},"application/vnd.collection.doc+json":{source:"iana",compressible:!0},"application/vnd.collection.next+json":{source:"iana",compressible:!0},"application/vnd.comicbook+zip":{source:"iana",compressible:!1},"application/vnd.comicbook-rar":{source:"iana"},"application/vnd.commerce-battelle":{source:"iana"},"application/vnd.commonspace":{source:"iana",extensions:["csp"]},"application/vnd.contact.cmsg":{source:"iana",extensions:["cdbcmsg"]},"application/vnd.coreos.ignition+json":{source:"iana",compressible:!0},"application/vnd.cosmocaller":{source:"iana",extensions:["cmc"]},"application/vnd.crick.clicker":{source:"iana",extensions:["clkx"]},"application/vnd.crick.clicker.keyboard":{source:"iana",extensions:["clkk"]},"application/vnd.crick.clicker.palette":{source:"iana",extensions:["clkp"]},"application/vnd.crick.clicker.template":{source:"iana",extensions:["clkt"]},"application/vnd.crick.clicker.wordbank":{source:"iana",extensions:["clkw"]},"application/vnd.criticaltools.wbs+xml":{source:"iana",compressible:!0,extensions:["wbs"]},"application/vnd.cryptii.pipe+json":{source:"iana",compressible:!0},"application/vnd.crypto-shade-file":{source:"iana"},"application/vnd.cryptomator.encrypted":{source:"iana"},"application/vnd.cryptomator.vault":{source:"iana"},"application/vnd.ctc-posml":{source:"iana",extensions:["pml"]},"application/vnd.ctct.ws+xml":{source:"iana",compressible:!0},"application/vnd.cups-pdf":{source:"iana"},"application/vnd.cups-postscript":{source:"iana"},"application/vnd.cups-ppd":{source:"iana",extensions:["ppd"]},"application/vnd.cups-raster":{source:"iana"},"application/vnd.cups-raw":{source:"iana"},"application/vnd.curl":{source:"iana"},"application/vnd.curl.car":{source:"apache",extensions:["car"]},"application/vnd.curl.pcurl":{source:"apache",extensions:["pcurl"]},"application/vnd.cyan.dean.root+xml":{source:"iana",compressible:!0},"application/vnd.cybank":{source:"iana"},"application/vnd.cyclonedx+json":{source:"iana",compressible:!0},"application/vnd.cyclonedx+xml":{source:"iana",compressible:!0},"application/vnd.d2l.coursepackage1p0+zip":{source:"iana",compressible:!1},"application/vnd.d3m-dataset":{source:"iana"},"application/vnd.d3m-problem":{source:"iana"},"application/vnd.dart":{source:"iana",compressible:!0,extensions:["dart"]},"application/vnd.data-vision.rdz":{source:"iana",extensions:["rdz"]},"application/vnd.datalog":{source:"iana"},"application/vnd.datapackage+json":{source:"iana",compressible:!0},"application/vnd.dataresource+json":{source:"iana",compressible:!0},"application/vnd.dbf":{source:"iana",extensions:["dbf"]},"application/vnd.dcmp+xml":{source:"iana",compressible:!0,extensions:["dcmp"]},"application/vnd.debian.binary-package":{source:"iana"},"application/vnd.dece.data":{source:"iana",extensions:["uvf","uvvf","uvd","uvvd"]},"application/vnd.dece.ttml+xml":{source:"iana",compressible:!0,extensions:["uvt","uvvt"]},"application/vnd.dece.unspecified":{source:"iana",extensions:["uvx","uvvx"]},"application/vnd.dece.zip":{source:"iana",extensions:["uvz","uvvz"]},"application/vnd.denovo.fcselayout-link":{source:"iana",extensions:["fe_launch"]},"application/vnd.desmume.movie":{source:"iana"},"application/vnd.dir-bi.plate-dl-nosuffix":{source:"iana"},"application/vnd.dm.delegation+xml":{source:"iana",compressible:!0},"application/vnd.dna":{source:"iana",extensions:["dna"]},"application/vnd.document+json":{source:"iana",compressible:!0},"application/vnd.dolby.mlp":{source:"apache",extensions:["mlp"]},"application/vnd.dolby.mobile.1":{source:"iana"},"application/vnd.dolby.mobile.2":{source:"iana"},"application/vnd.doremir.scorecloud-binary-document":{source:"iana"},"application/vnd.dpgraph":{source:"iana",extensions:["dpg"]},"application/vnd.dreamfactory":{source:"iana",extensions:["dfac"]},"application/vnd.drive+json":{source:"iana",compressible:!0},"application/vnd.ds-keypoint":{source:"apache",extensions:["kpxx"]},"application/vnd.dtg.local":{source:"iana"},"application/vnd.dtg.local.flash":{source:"iana"},"application/vnd.dtg.local.html":{source:"iana"},"application/vnd.dvb.ait":{source:"iana",extensions:["ait"]},"application/vnd.dvb.dvbisl+xml":{source:"iana",compressible:!0},"application/vnd.dvb.dvbj":{source:"iana"},"application/vnd.dvb.esgcontainer":{source:"iana"},"application/vnd.dvb.ipdcdftnotifaccess":{source:"iana"},"application/vnd.dvb.ipdcesgaccess":{source:"iana"},"application/vnd.dvb.ipdcesgaccess2":{source:"iana"},"application/vnd.dvb.ipdcesgpdd":{source:"iana"},"application/vnd.dvb.ipdcroaming":{source:"iana"},"application/vnd.dvb.iptv.alfec-base":{source:"iana"},"application/vnd.dvb.iptv.alfec-enhancement":{source:"iana"},"application/vnd.dvb.notif-aggregate-root+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-container+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-generic+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-ia-msglist+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-ia-registration-request+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-ia-registration-response+xml":{source:"iana",compressible:!0},"application/vnd.dvb.notif-init+xml":{source:"iana",compressible:!0},"application/vnd.dvb.pfr":{source:"iana"},"application/vnd.dvb.service":{source:"iana",extensions:["svc"]},"application/vnd.dxr":{source:"iana"},"application/vnd.dynageo":{source:"iana",extensions:["geo"]},"application/vnd.dzr":{source:"iana"},"application/vnd.easykaraoke.cdgdownload":{source:"iana"},"application/vnd.ecdis-update":{source:"iana"},"application/vnd.ecip.rlp":{source:"iana"},"application/vnd.eclipse.ditto+json":{source:"iana",compressible:!0},"application/vnd.ecowin.chart":{source:"iana",extensions:["mag"]},"application/vnd.ecowin.filerequest":{source:"iana"},"application/vnd.ecowin.fileupdate":{source:"iana"},"application/vnd.ecowin.series":{source:"iana"},"application/vnd.ecowin.seriesrequest":{source:"iana"},"application/vnd.ecowin.seriesupdate":{source:"iana"},"application/vnd.efi.img":{source:"iana"},"application/vnd.efi.iso":{source:"iana"},"application/vnd.eln+zip":{source:"iana",compressible:!1},"application/vnd.emclient.accessrequest+xml":{source:"iana",compressible:!0},"application/vnd.enliven":{source:"iana",extensions:["nml"]},"application/vnd.enphase.envoy":{source:"iana"},"application/vnd.eprints.data+xml":{source:"iana",compressible:!0},"application/vnd.epson.esf":{source:"iana",extensions:["esf"]},"application/vnd.epson.msf":{source:"iana",extensions:["msf"]},"application/vnd.epson.quickanime":{source:"iana",extensions:["qam"]},"application/vnd.epson.salt":{source:"iana",extensions:["slt"]},"application/vnd.epson.ssf":{source:"iana",extensions:["ssf"]},"application/vnd.ericsson.quickcall":{source:"iana"},"application/vnd.erofs":{source:"iana"},"application/vnd.espass-espass+zip":{source:"iana",compressible:!1},"application/vnd.eszigno3+xml":{source:"iana",compressible:!0,extensions:["es3","et3"]},"application/vnd.etsi.aoc+xml":{source:"iana",compressible:!0},"application/vnd.etsi.asic-e+zip":{source:"iana",compressible:!1},"application/vnd.etsi.asic-s+zip":{source:"iana",compressible:!1},"application/vnd.etsi.cug+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvcommand+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvdiscovery+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvprofile+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsad-bc+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsad-cod+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsad-npvr+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvservice+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvsync+xml":{source:"iana",compressible:!0},"application/vnd.etsi.iptvueprofile+xml":{source:"iana",compressible:!0},"application/vnd.etsi.mcid+xml":{source:"iana",compressible:!0},"application/vnd.etsi.mheg5":{source:"iana"},"application/vnd.etsi.overload-control-policy-dataset+xml":{source:"iana",compressible:!0},"application/vnd.etsi.pstn+xml":{source:"iana",compressible:!0},"application/vnd.etsi.sci+xml":{source:"iana",compressible:!0},"application/vnd.etsi.simservs+xml":{source:"iana",compressible:!0},"application/vnd.etsi.timestamp-token":{source:"iana"},"application/vnd.etsi.tsl+xml":{source:"iana",compressible:!0},"application/vnd.etsi.tsl.der":{source:"iana"},"application/vnd.eu.kasparian.car+json":{source:"iana",compressible:!0},"application/vnd.eudora.data":{source:"iana"},"application/vnd.evolv.ecig.profile":{source:"iana"},"application/vnd.evolv.ecig.settings":{source:"iana"},"application/vnd.evolv.ecig.theme":{source:"iana"},"application/vnd.exstream-empower+zip":{source:"iana",compressible:!1},"application/vnd.exstream-package":{source:"iana"},"application/vnd.ezpix-album":{source:"iana",extensions:["ez2"]},"application/vnd.ezpix-package":{source:"iana",extensions:["ez3"]},"application/vnd.f-secure.mobile":{source:"iana"},"application/vnd.familysearch.gedcom+zip":{source:"iana",compressible:!1},"application/vnd.fastcopy-disk-image":{source:"iana"},"application/vnd.fdf":{source:"apache",extensions:["fdf"]},"application/vnd.fdsn.mseed":{source:"iana",extensions:["mseed"]},"application/vnd.fdsn.seed":{source:"iana",extensions:["seed","dataless"]},"application/vnd.fdsn.stationxml+xml":{source:"iana",charset:"XML-BASED",compressible:!0},"application/vnd.ffsns":{source:"iana"},"application/vnd.ficlab.flb+zip":{source:"iana",compressible:!1},"application/vnd.filmit.zfc":{source:"iana"},"application/vnd.fints":{source:"iana"},"application/vnd.firemonkeys.cloudcell":{source:"iana"},"application/vnd.flographit":{source:"iana",extensions:["gph"]},"application/vnd.fluxtime.clip":{source:"iana",extensions:["ftc"]},"application/vnd.font-fontforge-sfd":{source:"iana"},"application/vnd.framemaker":{source:"iana",extensions:["fm","frame","maker","book"]},"application/vnd.freelog.comic":{source:"iana"},"application/vnd.frogans.fnc":{source:"apache",extensions:["fnc"]},"application/vnd.frogans.ltf":{source:"apache",extensions:["ltf"]},"application/vnd.fsc.weblaunch":{source:"iana",extensions:["fsc"]},"application/vnd.fujifilm.fb.docuworks":{source:"iana"},"application/vnd.fujifilm.fb.docuworks.binder":{source:"iana"},"application/vnd.fujifilm.fb.docuworks.container":{source:"iana"},"application/vnd.fujifilm.fb.jfi+xml":{source:"iana",compressible:!0},"application/vnd.fujitsu.oasys":{source:"iana",extensions:["oas"]},"application/vnd.fujitsu.oasys2":{source:"iana",extensions:["oa2"]},"application/vnd.fujitsu.oasys3":{source:"iana",extensions:["oa3"]},"application/vnd.fujitsu.oasysgp":{source:"iana",extensions:["fg5"]},"application/vnd.fujitsu.oasysprs":{source:"iana",extensions:["bh2"]},"application/vnd.fujixerox.art-ex":{source:"iana"},"application/vnd.fujixerox.art4":{source:"iana"},"application/vnd.fujixerox.ddd":{source:"iana",extensions:["ddd"]},"application/vnd.fujixerox.docuworks":{source:"iana",extensions:["xdw"]},"application/vnd.fujixerox.docuworks.binder":{source:"iana",extensions:["xbd"]},"application/vnd.fujixerox.docuworks.container":{source:"iana"},"application/vnd.fujixerox.hbpl":{source:"iana"},"application/vnd.fut-misnet":{source:"iana"},"application/vnd.futoin+cbor":{source:"iana"},"application/vnd.futoin+json":{source:"iana",compressible:!0},"application/vnd.fuzzysheet":{source:"iana",extensions:["fzs"]},"application/vnd.ga4gh.passport+jwt":{source:"iana"},"application/vnd.genomatix.tuxedo":{source:"iana",extensions:["txd"]},"application/vnd.genozip":{source:"iana"},"application/vnd.gentics.grd+json":{source:"iana",compressible:!0},"application/vnd.gentoo.catmetadata+xml":{source:"iana",compressible:!0},"application/vnd.gentoo.ebuild":{source:"iana"},"application/vnd.gentoo.eclass":{source:"iana"},"application/vnd.gentoo.gpkg":{source:"iana"},"application/vnd.gentoo.manifest":{source:"iana"},"application/vnd.gentoo.pkgmetadata+xml":{source:"iana",compressible:!0},"application/vnd.gentoo.xpak":{source:"iana"},"application/vnd.geo+json":{source:"apache",compressible:!0},"application/vnd.geocube+xml":{source:"apache",compressible:!0},"application/vnd.geogebra.file":{source:"iana",extensions:["ggb"]},"application/vnd.geogebra.pinboard":{source:"iana"},"application/vnd.geogebra.slides":{source:"iana",extensions:["ggs"]},"application/vnd.geogebra.tool":{source:"iana",extensions:["ggt"]},"application/vnd.geometry-explorer":{source:"iana",extensions:["gex","gre"]},"application/vnd.geonext":{source:"iana",extensions:["gxt"]},"application/vnd.geoplan":{source:"iana",extensions:["g2w"]},"application/vnd.geospace":{source:"iana",extensions:["g3w"]},"application/vnd.gerber":{source:"iana"},"application/vnd.globalplatform.card-content-mgt":{source:"iana"},"application/vnd.globalplatform.card-content-mgt-response":{source:"iana"},"application/vnd.gmx":{source:"iana",extensions:["gmx"]},"application/vnd.gnu.taler.exchange+json":{source:"iana",compressible:!0},"application/vnd.gnu.taler.merchant+json":{source:"iana",compressible:!0},"application/vnd.google-apps.audio":{},"application/vnd.google-apps.document":{compressible:!1,extensions:["gdoc"]},"application/vnd.google-apps.drawing":{compressible:!1,extensions:["gdraw"]},"application/vnd.google-apps.drive-sdk":{compressible:!1},"application/vnd.google-apps.file":{},"application/vnd.google-apps.folder":{compressible:!1},"application/vnd.google-apps.form":{compressible:!1,extensions:["gform"]},"application/vnd.google-apps.fusiontable":{},"application/vnd.google-apps.jam":{compressible:!1,extensions:["gjam"]},"application/vnd.google-apps.mail-layout":{},"application/vnd.google-apps.map":{compressible:!1,extensions:["gmap"]},"application/vnd.google-apps.photo":{},"application/vnd.google-apps.presentation":{compressible:!1,extensions:["gslides"]},"application/vnd.google-apps.script":{compressible:!1,extensions:["gscript"]},"application/vnd.google-apps.shortcut":{},"application/vnd.google-apps.site":{compressible:!1,extensions:["gsite"]},"application/vnd.google-apps.spreadsheet":{compressible:!1,extensions:["gsheet"]},"application/vnd.google-apps.unknown":{},"application/vnd.google-apps.video":{},"application/vnd.google-earth.kml+xml":{source:"iana",compressible:!0,extensions:["kml"]},"application/vnd.google-earth.kmz":{source:"iana",compressible:!1,extensions:["kmz"]},"application/vnd.gov.sk.e-form+xml":{source:"apache",compressible:!0},"application/vnd.gov.sk.e-form+zip":{source:"iana",compressible:!1},"application/vnd.gov.sk.xmldatacontainer+xml":{source:"iana",compressible:!0,extensions:["xdcf"]},"application/vnd.gpxsee.map+xml":{source:"iana",compressible:!0},"application/vnd.grafeq":{source:"iana",extensions:["gqf","gqs"]},"application/vnd.gridmp":{source:"iana"},"application/vnd.groove-account":{source:"iana",extensions:["gac"]},"application/vnd.groove-help":{source:"iana",extensions:["ghf"]},"application/vnd.groove-identity-message":{source:"iana",extensions:["gim"]},"application/vnd.groove-injector":{source:"iana",extensions:["grv"]},"application/vnd.groove-tool-message":{source:"iana",extensions:["gtm"]},"application/vnd.groove-tool-template":{source:"iana",extensions:["tpl"]},"application/vnd.groove-vcard":{source:"iana",extensions:["vcg"]},"application/vnd.hal+json":{source:"iana",compressible:!0},"application/vnd.hal+xml":{source:"iana",compressible:!0,extensions:["hal"]},"application/vnd.handheld-entertainment+xml":{source:"iana",compressible:!0,extensions:["zmm"]},"application/vnd.hbci":{source:"iana",extensions:["hbci"]},"application/vnd.hc+json":{source:"iana",compressible:!0},"application/vnd.hcl-bireports":{source:"iana"},"application/vnd.hdt":{source:"iana"},"application/vnd.heroku+json":{source:"iana",compressible:!0},"application/vnd.hhe.lesson-player":{source:"iana",extensions:["les"]},"application/vnd.hp-hpgl":{source:"iana",extensions:["hpgl"]},"application/vnd.hp-hpid":{source:"iana",extensions:["hpid"]},"application/vnd.hp-hps":{source:"iana",extensions:["hps"]},"application/vnd.hp-jlyt":{source:"iana",extensions:["jlt"]},"application/vnd.hp-pcl":{source:"iana",extensions:["pcl"]},"application/vnd.hp-pclxl":{source:"iana",extensions:["pclxl"]},"application/vnd.hsl":{source:"iana"},"application/vnd.httphone":{source:"iana"},"application/vnd.hydrostatix.sof-data":{source:"iana",extensions:["sfd-hdstx"]},"application/vnd.hyper+json":{source:"iana",compressible:!0},"application/vnd.hyper-item+json":{source:"iana",compressible:!0},"application/vnd.hyperdrive+json":{source:"iana",compressible:!0},"application/vnd.hzn-3d-crossword":{source:"iana"},"application/vnd.ibm.afplinedata":{source:"apache"},"application/vnd.ibm.electronic-media":{source:"iana"},"application/vnd.ibm.minipay":{source:"iana",extensions:["mpy"]},"application/vnd.ibm.modcap":{source:"apache",extensions:["afp","listafp","list3820"]},"application/vnd.ibm.rights-management":{source:"iana",extensions:["irm"]},"application/vnd.ibm.secure-container":{source:"iana",extensions:["sc"]},"application/vnd.iccprofile":{source:"iana",extensions:["icc","icm"]},"application/vnd.ieee.1905":{source:"iana"},"application/vnd.igloader":{source:"iana",extensions:["igl"]},"application/vnd.imagemeter.folder+zip":{source:"iana",compressible:!1},"application/vnd.imagemeter.image+zip":{source:"iana",compressible:!1},"application/vnd.immervision-ivp":{source:"iana",extensions:["ivp"]},"application/vnd.immervision-ivu":{source:"iana",extensions:["ivu"]},"application/vnd.ims.imsccv1p1":{source:"iana"},"application/vnd.ims.imsccv1p2":{source:"iana"},"application/vnd.ims.imsccv1p3":{source:"iana"},"application/vnd.ims.lis.v2.result+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolconsumerprofile+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolproxy+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolproxy.id+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolsettings+json":{source:"iana",compressible:!0},"application/vnd.ims.lti.v2.toolsettings.simple+json":{source:"iana",compressible:!0},"application/vnd.informedcontrol.rms+xml":{source:"iana",compressible:!0},"application/vnd.informix-visionary":{source:"apache"},"application/vnd.infotech.project":{source:"iana"},"application/vnd.infotech.project+xml":{source:"iana",compressible:!0},"application/vnd.innopath.wamp.notification":{source:"iana"},"application/vnd.insors.igm":{source:"iana",extensions:["igm"]},"application/vnd.intercon.formnet":{source:"iana",extensions:["xpw","xpx"]},"application/vnd.intergeo":{source:"iana",extensions:["i2g"]},"application/vnd.intertrust.digibox":{source:"iana"},"application/vnd.intertrust.nncp":{source:"iana"},"application/vnd.intu.qbo":{source:"iana",extensions:["qbo"]},"application/vnd.intu.qfx":{source:"iana",extensions:["qfx"]},"application/vnd.ipfs.ipns-record":{source:"iana"},"application/vnd.ipld.car":{source:"iana"},"application/vnd.ipld.dag-cbor":{source:"iana"},"application/vnd.ipld.dag-json":{source:"iana"},"application/vnd.ipld.raw":{source:"iana"},"application/vnd.iptc.g2.catalogitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.conceptitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.knowledgeitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.newsitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.newsmessage+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.packageitem+xml":{source:"iana",compressible:!0},"application/vnd.iptc.g2.planningitem+xml":{source:"iana",compressible:!0},"application/vnd.ipunplugged.rcprofile":{source:"iana",extensions:["rcprofile"]},"application/vnd.irepository.package+xml":{source:"iana",compressible:!0,extensions:["irp"]},"application/vnd.is-xpr":{source:"iana",extensions:["xpr"]},"application/vnd.isac.fcs":{source:"iana",extensions:["fcs"]},"application/vnd.iso11783-10+zip":{source:"iana",compressible:!1},"application/vnd.jam":{source:"iana",extensions:["jam"]},"application/vnd.japannet-directory-service":{source:"iana"},"application/vnd.japannet-jpnstore-wakeup":{source:"iana"},"application/vnd.japannet-payment-wakeup":{source:"iana"},"application/vnd.japannet-registration":{source:"iana"},"application/vnd.japannet-registration-wakeup":{source:"iana"},"application/vnd.japannet-setstore-wakeup":{source:"iana"},"application/vnd.japannet-verification":{source:"iana"},"application/vnd.japannet-verification-wakeup":{source:"iana"},"application/vnd.jcp.javame.midlet-rms":{source:"iana",extensions:["rms"]},"application/vnd.jisp":{source:"iana",extensions:["jisp"]},"application/vnd.joost.joda-archive":{source:"iana",extensions:["joda"]},"application/vnd.jsk.isdn-ngn":{source:"iana"},"application/vnd.kahootz":{source:"iana",extensions:["ktz","ktr"]},"application/vnd.kde.karbon":{source:"iana",extensions:["karbon"]},"application/vnd.kde.kchart":{source:"iana",extensions:["chrt"]},"application/vnd.kde.kformula":{source:"iana",extensions:["kfo"]},"application/vnd.kde.kivio":{source:"iana",extensions:["flw"]},"application/vnd.kde.kontour":{source:"iana",extensions:["kon"]},"application/vnd.kde.kpresenter":{source:"iana",extensions:["kpr","kpt"]},"application/vnd.kde.kspread":{source:"iana",extensions:["ksp"]},"application/vnd.kde.kword":{source:"iana",extensions:["kwd","kwt"]},"application/vnd.kdl":{source:"iana"},"application/vnd.kenameaapp":{source:"iana",extensions:["htke"]},"application/vnd.keyman.kmp+zip":{source:"iana",compressible:!1},"application/vnd.keyman.kmx":{source:"iana"},"application/vnd.kidspiration":{source:"iana",extensions:["kia"]},"application/vnd.kinar":{source:"iana",extensions:["kne","knp"]},"application/vnd.koan":{source:"iana",extensions:["skp","skd","skt","skm"]},"application/vnd.kodak-descriptor":{source:"iana",extensions:["sse"]},"application/vnd.las":{source:"iana"},"application/vnd.las.las+json":{source:"iana",compressible:!0},"application/vnd.las.las+xml":{source:"iana",compressible:!0,extensions:["lasxml"]},"application/vnd.laszip":{source:"iana"},"application/vnd.ldev.productlicensing":{source:"iana"},"application/vnd.leap+json":{source:"iana",compressible:!0},"application/vnd.liberty-request+xml":{source:"iana",compressible:!0},"application/vnd.llamagraphics.life-balance.desktop":{source:"iana",extensions:["lbd"]},"application/vnd.llamagraphics.life-balance.exchange+xml":{source:"iana",compressible:!0,extensions:["lbe"]},"application/vnd.logipipe.circuit+zip":{source:"iana",compressible:!1},"application/vnd.loom":{source:"iana"},"application/vnd.lotus-1-2-3":{source:"iana",extensions:["123"]},"application/vnd.lotus-approach":{source:"iana",extensions:["apr"]},"application/vnd.lotus-freelance":{source:"iana",extensions:["pre"]},"application/vnd.lotus-notes":{source:"iana",extensions:["nsf"]},"application/vnd.lotus-organizer":{source:"iana",extensions:["org"]},"application/vnd.lotus-screencam":{source:"iana",extensions:["scm"]},"application/vnd.lotus-wordpro":{source:"iana",extensions:["lwp"]},"application/vnd.macports.portpkg":{source:"iana",extensions:["portpkg"]},"application/vnd.mapbox-vector-tile":{source:"iana",extensions:["mvt"]},"application/vnd.marlin.drm.actiontoken+xml":{source:"iana",compressible:!0},"application/vnd.marlin.drm.conftoken+xml":{source:"iana",compressible:!0},"application/vnd.marlin.drm.license+xml":{source:"iana",compressible:!0},"application/vnd.marlin.drm.mdcf":{source:"iana"},"application/vnd.mason+json":{source:"iana",compressible:!0},"application/vnd.maxar.archive.3tz+zip":{source:"iana",compressible:!1},"application/vnd.maxmind.maxmind-db":{source:"iana"},"application/vnd.mcd":{source:"iana",extensions:["mcd"]},"application/vnd.mdl":{source:"iana"},"application/vnd.mdl-mbsdf":{source:"iana"},"application/vnd.medcalcdata":{source:"iana",extensions:["mc1"]},"application/vnd.mediastation.cdkey":{source:"iana",extensions:["cdkey"]},"application/vnd.medicalholodeck.recordxr":{source:"iana"},"application/vnd.meridian-slingshot":{source:"iana"},"application/vnd.mermaid":{source:"iana"},"application/vnd.mfer":{source:"iana",extensions:["mwf"]},"application/vnd.mfmp":{source:"iana",extensions:["mfm"]},"application/vnd.micro+json":{source:"iana",compressible:!0},"application/vnd.micrografx.flo":{source:"iana",extensions:["flo"]},"application/vnd.micrografx.igx":{source:"iana",extensions:["igx"]},"application/vnd.microsoft.portable-executable":{source:"iana"},"application/vnd.microsoft.windows.thumbnail-cache":{source:"iana"},"application/vnd.miele+json":{source:"iana",compressible:!0},"application/vnd.mif":{source:"iana",extensions:["mif"]},"application/vnd.minisoft-hp3000-save":{source:"iana"},"application/vnd.mitsubishi.misty-guard.trustweb":{source:"iana"},"application/vnd.mobius.daf":{source:"iana",extensions:["daf"]},"application/vnd.mobius.dis":{source:"iana",extensions:["dis"]},"application/vnd.mobius.mbk":{source:"iana",extensions:["mbk"]},"application/vnd.mobius.mqy":{source:"iana",extensions:["mqy"]},"application/vnd.mobius.msl":{source:"iana",extensions:["msl"]},"application/vnd.mobius.plc":{source:"iana",extensions:["plc"]},"application/vnd.mobius.txf":{source:"iana",extensions:["txf"]},"application/vnd.modl":{source:"iana"},"application/vnd.mophun.application":{source:"iana",extensions:["mpn"]},"application/vnd.mophun.certificate":{source:"iana",extensions:["mpc"]},"application/vnd.motorola.flexsuite":{source:"iana"},"application/vnd.motorola.flexsuite.adsi":{source:"iana"},"application/vnd.motorola.flexsuite.fis":{source:"iana"},"application/vnd.motorola.flexsuite.gotap":{source:"iana"},"application/vnd.motorola.flexsuite.kmr":{source:"iana"},"application/vnd.motorola.flexsuite.ttc":{source:"iana"},"application/vnd.motorola.flexsuite.wem":{source:"iana"},"application/vnd.motorola.iprm":{source:"iana"},"application/vnd.mozilla.xul+xml":{source:"iana",compressible:!0,extensions:["xul"]},"application/vnd.ms-3mfdocument":{source:"iana"},"application/vnd.ms-artgalry":{source:"iana",extensions:["cil"]},"application/vnd.ms-asf":{source:"iana"},"application/vnd.ms-cab-compressed":{source:"iana",extensions:["cab"]},"application/vnd.ms-color.iccprofile":{source:"apache"},"application/vnd.ms-excel":{source:"iana",compressible:!1,extensions:["xls","xlm","xla","xlc","xlt","xlw"]},"application/vnd.ms-excel.addin.macroenabled.12":{source:"iana",extensions:["xlam"]},"application/vnd.ms-excel.sheet.binary.macroenabled.12":{source:"iana",extensions:["xlsb"]},"application/vnd.ms-excel.sheet.macroenabled.12":{source:"iana",extensions:["xlsm"]},"application/vnd.ms-excel.template.macroenabled.12":{source:"iana",extensions:["xltm"]},"application/vnd.ms-fontobject":{source:"iana",compressible:!0,extensions:["eot"]},"application/vnd.ms-htmlhelp":{source:"iana",extensions:["chm"]},"application/vnd.ms-ims":{source:"iana",extensions:["ims"]},"application/vnd.ms-lrm":{source:"iana",extensions:["lrm"]},"application/vnd.ms-office.activex+xml":{source:"iana",compressible:!0},"application/vnd.ms-officetheme":{source:"iana",extensions:["thmx"]},"application/vnd.ms-opentype":{source:"apache",compressible:!0},"application/vnd.ms-outlook":{compressible:!1,extensions:["msg"]},"application/vnd.ms-package.obfuscated-opentype":{source:"apache"},"application/vnd.ms-pki.seccat":{source:"apache",extensions:["cat"]},"application/vnd.ms-pki.stl":{source:"apache",extensions:["stl"]},"application/vnd.ms-playready.initiator+xml":{source:"iana",compressible:!0},"application/vnd.ms-powerpoint":{source:"iana",compressible:!1,extensions:["ppt","pps","pot"]},"application/vnd.ms-powerpoint.addin.macroenabled.12":{source:"iana",extensions:["ppam"]},"application/vnd.ms-powerpoint.presentation.macroenabled.12":{source:"iana",extensions:["pptm"]},"application/vnd.ms-powerpoint.slide.macroenabled.12":{source:"iana",extensions:["sldm"]},"application/vnd.ms-powerpoint.slideshow.macroenabled.12":{source:"iana",extensions:["ppsm"]},"application/vnd.ms-powerpoint.template.macroenabled.12":{source:"iana",extensions:["potm"]},"application/vnd.ms-printdevicecapabilities+xml":{source:"iana",compressible:!0},"application/vnd.ms-printing.printticket+xml":{source:"apache",compressible:!0},"application/vnd.ms-printschematicket+xml":{source:"iana",compressible:!0},"application/vnd.ms-project":{source:"iana",extensions:["mpp","mpt"]},"application/vnd.ms-tnef":{source:"iana"},"application/vnd.ms-visio.viewer":{extensions:["vdx"]},"application/vnd.ms-windows.devicepairing":{source:"iana"},"application/vnd.ms-windows.nwprinting.oob":{source:"iana"},"application/vnd.ms-windows.printerpairing":{source:"iana"},"application/vnd.ms-windows.wsd.oob":{source:"iana"},"application/vnd.ms-wmdrm.lic-chlg-req":{source:"iana"},"application/vnd.ms-wmdrm.lic-resp":{source:"iana"},"application/vnd.ms-wmdrm.meter-chlg-req":{source:"iana"},"application/vnd.ms-wmdrm.meter-resp":{source:"iana"},"application/vnd.ms-word.document.macroenabled.12":{source:"iana",extensions:["docm"]},"application/vnd.ms-word.template.macroenabled.12":{source:"iana",extensions:["dotm"]},"application/vnd.ms-works":{source:"iana",extensions:["wps","wks","wcm","wdb"]},"application/vnd.ms-wpl":{source:"iana",extensions:["wpl"]},"application/vnd.ms-xpsdocument":{source:"iana",compressible:!1,extensions:["xps"]},"application/vnd.msa-disk-image":{source:"iana"},"application/vnd.mseq":{source:"iana",extensions:["mseq"]},"application/vnd.msgpack":{source:"iana"},"application/vnd.msign":{source:"iana"},"application/vnd.multiad.creator":{source:"iana"},"application/vnd.multiad.creator.cif":{source:"iana"},"application/vnd.music-niff":{source:"iana"},"application/vnd.musician":{source:"iana",extensions:["mus"]},"application/vnd.muvee.style":{source:"iana",extensions:["msty"]},"application/vnd.mynfc":{source:"iana",extensions:["taglet"]},"application/vnd.nacamar.ybrid+json":{source:"iana",compressible:!0},"application/vnd.nato.bindingdataobject+cbor":{source:"iana"},"application/vnd.nato.bindingdataobject+json":{source:"iana",compressible:!0},"application/vnd.nato.bindingdataobject+xml":{source:"iana",compressible:!0,extensions:["bdo"]},"application/vnd.nato.openxmlformats-package.iepd+zip":{source:"iana",compressible:!1},"application/vnd.ncd.control":{source:"iana"},"application/vnd.ncd.reference":{source:"iana"},"application/vnd.nearst.inv+json":{source:"iana",compressible:!0},"application/vnd.nebumind.line":{source:"iana"},"application/vnd.nervana":{source:"iana"},"application/vnd.netfpx":{source:"iana"},"application/vnd.neurolanguage.nlu":{source:"iana",extensions:["nlu"]},"application/vnd.nimn":{source:"iana"},"application/vnd.nintendo.nitro.rom":{source:"iana"},"application/vnd.nintendo.snes.rom":{source:"iana"},"application/vnd.nitf":{source:"iana",extensions:["ntf","nitf"]},"application/vnd.noblenet-directory":{source:"iana",extensions:["nnd"]},"application/vnd.noblenet-sealer":{source:"iana",extensions:["nns"]},"application/vnd.noblenet-web":{source:"iana",extensions:["nnw"]},"application/vnd.nokia.catalogs":{source:"iana"},"application/vnd.nokia.conml+wbxml":{source:"iana"},"application/vnd.nokia.conml+xml":{source:"iana",compressible:!0},"application/vnd.nokia.iptv.config+xml":{source:"iana",compressible:!0},"application/vnd.nokia.isds-radio-presets":{source:"iana"},"application/vnd.nokia.landmark+wbxml":{source:"iana"},"application/vnd.nokia.landmark+xml":{source:"iana",compressible:!0},"application/vnd.nokia.landmarkcollection+xml":{source:"iana",compressible:!0},"application/vnd.nokia.n-gage.ac+xml":{source:"iana",compressible:!0,extensions:["ac"]},"application/vnd.nokia.n-gage.data":{source:"iana",extensions:["ngdat"]},"application/vnd.nokia.n-gage.symbian.install":{source:"apache",extensions:["n-gage"]},"application/vnd.nokia.ncd":{source:"iana"},"application/vnd.nokia.pcd+wbxml":{source:"iana"},"application/vnd.nokia.pcd+xml":{source:"iana",compressible:!0},"application/vnd.nokia.radio-preset":{source:"iana",extensions:["rpst"]},"application/vnd.nokia.radio-presets":{source:"iana",extensions:["rpss"]},"application/vnd.novadigm.edm":{source:"iana",extensions:["edm"]},"application/vnd.novadigm.edx":{source:"iana",extensions:["edx"]},"application/vnd.novadigm.ext":{source:"iana",extensions:["ext"]},"application/vnd.ntt-local.content-share":{source:"iana"},"application/vnd.ntt-local.file-transfer":{source:"iana"},"application/vnd.ntt-local.ogw_remote-access":{source:"iana"},"application/vnd.ntt-local.sip-ta_remote":{source:"iana"},"application/vnd.ntt-local.sip-ta_tcp_stream":{source:"iana"},"application/vnd.oai.workflows":{source:"iana"},"application/vnd.oai.workflows+json":{source:"iana",compressible:!0},"application/vnd.oai.workflows+yaml":{source:"iana"},"application/vnd.oasis.opendocument.base":{source:"iana"},"application/vnd.oasis.opendocument.chart":{source:"iana",extensions:["odc"]},"application/vnd.oasis.opendocument.chart-template":{source:"iana",extensions:["otc"]},"application/vnd.oasis.opendocument.database":{source:"apache",extensions:["odb"]},"application/vnd.oasis.opendocument.formula":{source:"iana",extensions:["odf"]},"application/vnd.oasis.opendocument.formula-template":{source:"iana",extensions:["odft"]},"application/vnd.oasis.opendocument.graphics":{source:"iana",compressible:!1,extensions:["odg"]},"application/vnd.oasis.opendocument.graphics-template":{source:"iana",extensions:["otg"]},"application/vnd.oasis.opendocument.image":{source:"iana",extensions:["odi"]},"application/vnd.oasis.opendocument.image-template":{source:"iana",extensions:["oti"]},"application/vnd.oasis.opendocument.presentation":{source:"iana",compressible:!1,extensions:["odp"]},"application/vnd.oasis.opendocument.presentation-template":{source:"iana",extensions:["otp"]},"application/vnd.oasis.opendocument.spreadsheet":{source:"iana",compressible:!1,extensions:["ods"]},"application/vnd.oasis.opendocument.spreadsheet-template":{source:"iana",extensions:["ots"]},"application/vnd.oasis.opendocument.text":{source:"iana",compressible:!1,extensions:["odt"]},"application/vnd.oasis.opendocument.text-master":{source:"iana",extensions:["odm"]},"application/vnd.oasis.opendocument.text-master-template":{source:"iana"},"application/vnd.oasis.opendocument.text-template":{source:"iana",extensions:["ott"]},"application/vnd.oasis.opendocument.text-web":{source:"iana",extensions:["oth"]},"application/vnd.obn":{source:"iana"},"application/vnd.ocf+cbor":{source:"iana"},"application/vnd.oci.image.manifest.v1+json":{source:"iana",compressible:!0},"application/vnd.oftn.l10n+json":{source:"iana",compressible:!0},"application/vnd.oipf.contentaccessdownload+xml":{source:"iana",compressible:!0},"application/vnd.oipf.contentaccessstreaming+xml":{source:"iana",compressible:!0},"application/vnd.oipf.cspg-hexbinary":{source:"iana"},"application/vnd.oipf.dae.svg+xml":{source:"iana",compressible:!0},"application/vnd.oipf.dae.xhtml+xml":{source:"iana",compressible:!0},"application/vnd.oipf.mippvcontrolmessage+xml":{source:"iana",compressible:!0},"application/vnd.oipf.pae.gem":{source:"iana"},"application/vnd.oipf.spdiscovery+xml":{source:"iana",compressible:!0},"application/vnd.oipf.spdlist+xml":{source:"iana",compressible:!0},"application/vnd.oipf.ueprofile+xml":{source:"iana",compressible:!0},"application/vnd.oipf.userprofile+xml":{source:"iana",compressible:!0},"application/vnd.olpc-sugar":{source:"iana",extensions:["xo"]},"application/vnd.oma-scws-config":{source:"iana"},"application/vnd.oma-scws-http-request":{source:"iana"},"application/vnd.oma-scws-http-response":{source:"iana"},"application/vnd.oma.bcast.associated-procedure-parameter+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.drm-trigger+xml":{source:"apache",compressible:!0},"application/vnd.oma.bcast.imd+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.ltkm":{source:"iana"},"application/vnd.oma.bcast.notification+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.provisioningtrigger":{source:"iana"},"application/vnd.oma.bcast.sgboot":{source:"iana"},"application/vnd.oma.bcast.sgdd+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.sgdu":{source:"iana"},"application/vnd.oma.bcast.simple-symbol-container":{source:"iana"},"application/vnd.oma.bcast.smartcard-trigger+xml":{source:"apache",compressible:!0},"application/vnd.oma.bcast.sprov+xml":{source:"iana",compressible:!0},"application/vnd.oma.bcast.stkm":{source:"iana"},"application/vnd.oma.cab-address-book+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-feature-handler+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-pcc+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-subs-invite+xml":{source:"iana",compressible:!0},"application/vnd.oma.cab-user-prefs+xml":{source:"iana",compressible:!0},"application/vnd.oma.dcd":{source:"iana"},"application/vnd.oma.dcdc":{source:"iana"},"application/vnd.oma.dd2+xml":{source:"iana",compressible:!0,extensions:["dd2"]},"application/vnd.oma.drm.risd+xml":{source:"iana",compressible:!0},"application/vnd.oma.group-usage-list+xml":{source:"iana",compressible:!0},"application/vnd.oma.lwm2m+cbor":{source:"iana"},"application/vnd.oma.lwm2m+json":{source:"iana",compressible:!0},"application/vnd.oma.lwm2m+tlv":{source:"iana"},"application/vnd.oma.pal+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.detailed-progress-report+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.final-report+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.groups+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.invocation-descriptor+xml":{source:"iana",compressible:!0},"application/vnd.oma.poc.optimized-progress-report+xml":{source:"iana",compressible:!0},"application/vnd.oma.push":{source:"iana"},"application/vnd.oma.scidm.messages+xml":{source:"iana",compressible:!0},"application/vnd.oma.xcap-directory+xml":{source:"iana",compressible:!0},"application/vnd.omads-email+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.omads-file+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.omads-folder+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.omaloc-supl-init":{source:"iana"},"application/vnd.onepager":{source:"iana"},"application/vnd.onepagertamp":{source:"iana"},"application/vnd.onepagertamx":{source:"iana"},"application/vnd.onepagertat":{source:"iana"},"application/vnd.onepagertatp":{source:"iana"},"application/vnd.onepagertatx":{source:"iana"},"application/vnd.onvif.metadata":{source:"iana"},"application/vnd.openblox.game+xml":{source:"iana",compressible:!0,extensions:["obgx"]},"application/vnd.openblox.game-binary":{source:"iana"},"application/vnd.openeye.oeb":{source:"iana"},"application/vnd.openofficeorg.extension":{source:"apache",extensions:["oxt"]},"application/vnd.openstreetmap.data+xml":{source:"iana",compressible:!0,extensions:["osm"]},"application/vnd.opentimestamps.ots":{source:"iana"},"application/vnd.openvpi.dspx+json":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.custom-properties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.customxmlproperties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawing+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.chart+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.extended-properties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.comments+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.presentation":{source:"iana",compressible:!1,extensions:["pptx"]},"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.presprops+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slide":{source:"iana",extensions:["sldx"]},"application/vnd.openxmlformats-officedocument.presentationml.slide+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slideshow":{source:"iana",extensions:["ppsx"]},"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.tags+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.template":{source:"iana",extensions:["potx"]},"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{source:"iana",compressible:!1,extensions:["xlsx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.template":{source:"iana",extensions:["xltx"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.theme+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.themeoverride+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.vmldrawing":{source:"iana"},"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{source:"iana",compressible:!1,extensions:["docx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.template":{source:"iana",extensions:["dotx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-package.core-properties+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml":{source:"iana",compressible:!0},"application/vnd.openxmlformats-package.relationships+xml":{source:"iana",compressible:!0},"application/vnd.oracle.resource+json":{source:"iana",compressible:!0},"application/vnd.orange.indata":{source:"iana"},"application/vnd.osa.netdeploy":{source:"iana"},"application/vnd.osgeo.mapguide.package":{source:"iana",extensions:["mgp"]},"application/vnd.osgi.bundle":{source:"iana"},"application/vnd.osgi.dp":{source:"iana",extensions:["dp"]},"application/vnd.osgi.subsystem":{source:"iana",extensions:["esa"]},"application/vnd.otps.ct-kip+xml":{source:"iana",compressible:!0},"application/vnd.oxli.countgraph":{source:"iana"},"application/vnd.pagerduty+json":{source:"iana",compressible:!0},"application/vnd.palm":{source:"iana",extensions:["pdb","pqa","oprc"]},"application/vnd.panoply":{source:"iana"},"application/vnd.paos.xml":{source:"iana"},"application/vnd.patentdive":{source:"iana"},"application/vnd.patientecommsdoc":{source:"iana"},"application/vnd.pawaafile":{source:"iana",extensions:["paw"]},"application/vnd.pcos":{source:"iana"},"application/vnd.pg.format":{source:"iana",extensions:["str"]},"application/vnd.pg.osasli":{source:"iana",extensions:["ei6"]},"application/vnd.piaccess.application-licence":{source:"iana"},"application/vnd.picsel":{source:"iana",extensions:["efif"]},"application/vnd.pmi.widget":{source:"iana",extensions:["wg"]},"application/vnd.poc.group-advertisement+xml":{source:"iana",compressible:!0},"application/vnd.pocketlearn":{source:"iana",extensions:["plf"]},"application/vnd.powerbuilder6":{source:"iana",extensions:["pbd"]},"application/vnd.powerbuilder6-s":{source:"iana"},"application/vnd.powerbuilder7":{source:"iana"},"application/vnd.powerbuilder7-s":{source:"iana"},"application/vnd.powerbuilder75":{source:"iana"},"application/vnd.powerbuilder75-s":{source:"iana"},"application/vnd.preminet":{source:"iana"},"application/vnd.previewsystems.box":{source:"iana",extensions:["box"]},"application/vnd.procrate.brushset":{extensions:["brushset"]},"application/vnd.procreate.brush":{extensions:["brush"]},"application/vnd.procreate.dream":{extensions:["drm"]},"application/vnd.proteus.magazine":{source:"iana",extensions:["mgz"]},"application/vnd.psfs":{source:"iana"},"application/vnd.pt.mundusmundi":{source:"iana"},"application/vnd.publishare-delta-tree":{source:"iana",extensions:["qps"]},"application/vnd.pvi.ptid1":{source:"iana",extensions:["ptid"]},"application/vnd.pwg-multiplexed":{source:"iana"},"application/vnd.pwg-xhtml-print+xml":{source:"iana",compressible:!0,extensions:["xhtm"]},"application/vnd.qualcomm.brew-app-res":{source:"iana"},"application/vnd.quarantainenet":{source:"iana"},"application/vnd.quark.quarkxpress":{source:"iana",extensions:["qxd","qxt","qwd","qwt","qxl","qxb"]},"application/vnd.quobject-quoxdocument":{source:"iana"},"application/vnd.radisys.moml+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-conf+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-conn+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-dialog+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-audit-stream+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-conf+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-base+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-fax-detect+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-fax-sendrecv+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-group+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-speech+xml":{source:"iana",compressible:!0},"application/vnd.radisys.msml-dialog-transform+xml":{source:"iana",compressible:!0},"application/vnd.rainstor.data":{source:"iana"},"application/vnd.rapid":{source:"iana"},"application/vnd.rar":{source:"iana",extensions:["rar"]},"application/vnd.realvnc.bed":{source:"iana",extensions:["bed"]},"application/vnd.recordare.musicxml":{source:"iana",extensions:["mxl"]},"application/vnd.recordare.musicxml+xml":{source:"iana",compressible:!0,extensions:["musicxml"]},"application/vnd.relpipe":{source:"iana"},"application/vnd.renlearn.rlprint":{source:"iana"},"application/vnd.resilient.logic":{source:"iana"},"application/vnd.restful+json":{source:"iana",compressible:!0},"application/vnd.rig.cryptonote":{source:"iana",extensions:["cryptonote"]},"application/vnd.rim.cod":{source:"apache",extensions:["cod"]},"application/vnd.rn-realmedia":{source:"apache",extensions:["rm"]},"application/vnd.rn-realmedia-vbr":{source:"apache",extensions:["rmvb"]},"application/vnd.route66.link66+xml":{source:"iana",compressible:!0,extensions:["link66"]},"application/vnd.rs-274x":{source:"iana"},"application/vnd.ruckus.download":{source:"iana"},"application/vnd.s3sms":{source:"iana"},"application/vnd.sailingtracker.track":{source:"iana",extensions:["st"]},"application/vnd.sar":{source:"iana"},"application/vnd.sbm.cid":{source:"iana"},"application/vnd.sbm.mid2":{source:"iana"},"application/vnd.scribus":{source:"iana"},"application/vnd.sealed.3df":{source:"iana"},"application/vnd.sealed.csf":{source:"iana"},"application/vnd.sealed.doc":{source:"iana"},"application/vnd.sealed.eml":{source:"iana"},"application/vnd.sealed.mht":{source:"iana"},"application/vnd.sealed.net":{source:"iana"},"application/vnd.sealed.ppt":{source:"iana"},"application/vnd.sealed.tiff":{source:"iana"},"application/vnd.sealed.xls":{source:"iana"},"application/vnd.sealedmedia.softseal.html":{source:"iana"},"application/vnd.sealedmedia.softseal.pdf":{source:"iana"},"application/vnd.seemail":{source:"iana",extensions:["see"]},"application/vnd.seis+json":{source:"iana",compressible:!0},"application/vnd.sema":{source:"iana",extensions:["sema"]},"application/vnd.semd":{source:"iana",extensions:["semd"]},"application/vnd.semf":{source:"iana",extensions:["semf"]},"application/vnd.shade-save-file":{source:"iana"},"application/vnd.shana.informed.formdata":{source:"iana",extensions:["ifm"]},"application/vnd.shana.informed.formtemplate":{source:"iana",extensions:["itp"]},"application/vnd.shana.informed.interchange":{source:"iana",extensions:["iif"]},"application/vnd.shana.informed.package":{source:"iana",extensions:["ipk"]},"application/vnd.shootproof+json":{source:"iana",compressible:!0},"application/vnd.shopkick+json":{source:"iana",compressible:!0},"application/vnd.shp":{source:"iana"},"application/vnd.shx":{source:"iana"},"application/vnd.sigrok.session":{source:"iana"},"application/vnd.simtech-mindmapper":{source:"iana",extensions:["twd","twds"]},"application/vnd.siren+json":{source:"iana",compressible:!0},"application/vnd.sketchometry":{source:"iana"},"application/vnd.smaf":{source:"iana",extensions:["mmf"]},"application/vnd.smart.notebook":{source:"iana"},"application/vnd.smart.teacher":{source:"iana",extensions:["teacher"]},"application/vnd.smintio.portals.archive":{source:"iana"},"application/vnd.snesdev-page-table":{source:"iana"},"application/vnd.software602.filler.form+xml":{source:"iana",compressible:!0,extensions:["fo"]},"application/vnd.software602.filler.form-xml-zip":{source:"iana"},"application/vnd.solent.sdkm+xml":{source:"iana",compressible:!0,extensions:["sdkm","sdkd"]},"application/vnd.spotfire.dxp":{source:"iana",extensions:["dxp"]},"application/vnd.spotfire.sfs":{source:"iana",extensions:["sfs"]},"application/vnd.sqlite3":{source:"iana"},"application/vnd.sss-cod":{source:"iana"},"application/vnd.sss-dtf":{source:"iana"},"application/vnd.sss-ntf":{source:"iana"},"application/vnd.stardivision.calc":{source:"apache",extensions:["sdc"]},"application/vnd.stardivision.draw":{source:"apache",extensions:["sda"]},"application/vnd.stardivision.impress":{source:"apache",extensions:["sdd"]},"application/vnd.stardivision.math":{source:"apache",extensions:["smf"]},"application/vnd.stardivision.writer":{source:"apache",extensions:["sdw","vor"]},"application/vnd.stardivision.writer-global":{source:"apache",extensions:["sgl"]},"application/vnd.stepmania.package":{source:"iana",extensions:["smzip"]},"application/vnd.stepmania.stepchart":{source:"iana",extensions:["sm"]},"application/vnd.street-stream":{source:"iana"},"application/vnd.sun.wadl+xml":{source:"iana",compressible:!0,extensions:["wadl"]},"application/vnd.sun.xml.calc":{source:"apache",extensions:["sxc"]},"application/vnd.sun.xml.calc.template":{source:"apache",extensions:["stc"]},"application/vnd.sun.xml.draw":{source:"apache",extensions:["sxd"]},"application/vnd.sun.xml.draw.template":{source:"apache",extensions:["std"]},"application/vnd.sun.xml.impress":{source:"apache",extensions:["sxi"]},"application/vnd.sun.xml.impress.template":{source:"apache",extensions:["sti"]},"application/vnd.sun.xml.math":{source:"apache",extensions:["sxm"]},"application/vnd.sun.xml.writer":{source:"apache",extensions:["sxw"]},"application/vnd.sun.xml.writer.global":{source:"apache",extensions:["sxg"]},"application/vnd.sun.xml.writer.template":{source:"apache",extensions:["stw"]},"application/vnd.sus-calendar":{source:"iana",extensions:["sus","susp"]},"application/vnd.svd":{source:"iana",extensions:["svd"]},"application/vnd.swiftview-ics":{source:"iana"},"application/vnd.sybyl.mol2":{source:"iana"},"application/vnd.sycle+xml":{source:"iana",compressible:!0},"application/vnd.syft+json":{source:"iana",compressible:!0},"application/vnd.symbian.install":{source:"apache",extensions:["sis","sisx"]},"application/vnd.syncml+xml":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["xsm"]},"application/vnd.syncml.dm+wbxml":{source:"iana",charset:"UTF-8",extensions:["bdm"]},"application/vnd.syncml.dm+xml":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["xdm"]},"application/vnd.syncml.dm.notification":{source:"iana"},"application/vnd.syncml.dmddf+wbxml":{source:"iana"},"application/vnd.syncml.dmddf+xml":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["ddf"]},"application/vnd.syncml.dmtnds+wbxml":{source:"iana"},"application/vnd.syncml.dmtnds+xml":{source:"iana",charset:"UTF-8",compressible:!0},"application/vnd.syncml.ds.notification":{source:"iana"},"application/vnd.tableschema+json":{source:"iana",compressible:!0},"application/vnd.tao.intent-module-archive":{source:"iana",extensions:["tao"]},"application/vnd.tcpdump.pcap":{source:"iana",extensions:["pcap","cap","dmp"]},"application/vnd.think-cell.ppttc+json":{source:"iana",compressible:!0},"application/vnd.tmd.mediaflex.api+xml":{source:"iana",compressible:!0},"application/vnd.tml":{source:"iana"},"application/vnd.tmobile-livetv":{source:"iana",extensions:["tmo"]},"application/vnd.tri.onesource":{source:"iana"},"application/vnd.trid.tpt":{source:"iana",extensions:["tpt"]},"application/vnd.triscape.mxs":{source:"iana",extensions:["mxs"]},"application/vnd.trueapp":{source:"iana",extensions:["tra"]},"application/vnd.truedoc":{source:"iana"},"application/vnd.ubisoft.webplayer":{source:"iana"},"application/vnd.ufdl":{source:"iana",extensions:["ufd","ufdl"]},"application/vnd.uic.osdm+json":{source:"iana",compressible:!0},"application/vnd.uiq.theme":{source:"iana",extensions:["utz"]},"application/vnd.umajin":{source:"iana",extensions:["umj"]},"application/vnd.unity":{source:"iana",extensions:["unityweb"]},"application/vnd.uoml+xml":{source:"iana",compressible:!0,extensions:["uoml","uo"]},"application/vnd.uplanet.alert":{source:"iana"},"application/vnd.uplanet.alert-wbxml":{source:"iana"},"application/vnd.uplanet.bearer-choice":{source:"iana"},"application/vnd.uplanet.bearer-choice-wbxml":{source:"iana"},"application/vnd.uplanet.cacheop":{source:"iana"},"application/vnd.uplanet.cacheop-wbxml":{source:"iana"},"application/vnd.uplanet.channel":{source:"iana"},"application/vnd.uplanet.channel-wbxml":{source:"iana"},"application/vnd.uplanet.list":{source:"iana"},"application/vnd.uplanet.list-wbxml":{source:"iana"},"application/vnd.uplanet.listcmd":{source:"iana"},"application/vnd.uplanet.listcmd-wbxml":{source:"iana"},"application/vnd.uplanet.signal":{source:"iana"},"application/vnd.uri-map":{source:"iana"},"application/vnd.valve.source.material":{source:"iana"},"application/vnd.vcx":{source:"iana",extensions:["vcx"]},"application/vnd.vd-study":{source:"iana"},"application/vnd.vectorworks":{source:"iana"},"application/vnd.vel+json":{source:"iana",compressible:!0},"application/vnd.veraison.tsm-report+cbor":{source:"iana"},"application/vnd.veraison.tsm-report+json":{source:"iana",compressible:!0},"application/vnd.verimatrix.vcas":{source:"iana"},"application/vnd.veritone.aion+json":{source:"iana",compressible:!0},"application/vnd.veryant.thin":{source:"iana"},"application/vnd.ves.encrypted":{source:"iana"},"application/vnd.vidsoft.vidconference":{source:"iana"},"application/vnd.visio":{source:"iana",extensions:["vsd","vst","vss","vsw","vsdx","vtx"]},"application/vnd.visionary":{source:"iana",extensions:["vis"]},"application/vnd.vividence.scriptfile":{source:"iana"},"application/vnd.vocalshaper.vsp4":{source:"iana"},"application/vnd.vsf":{source:"iana",extensions:["vsf"]},"application/vnd.wap.sic":{source:"iana"},"application/vnd.wap.slc":{source:"iana"},"application/vnd.wap.wbxml":{source:"iana",charset:"UTF-8",extensions:["wbxml"]},"application/vnd.wap.wmlc":{source:"iana",extensions:["wmlc"]},"application/vnd.wap.wmlscriptc":{source:"iana",extensions:["wmlsc"]},"application/vnd.wasmflow.wafl":{source:"iana"},"application/vnd.webturbo":{source:"iana",extensions:["wtb"]},"application/vnd.wfa.dpp":{source:"iana"},"application/vnd.wfa.p2p":{source:"iana"},"application/vnd.wfa.wsc":{source:"iana"},"application/vnd.windows.devicepairing":{source:"iana"},"application/vnd.wmc":{source:"iana"},"application/vnd.wmf.bootstrap":{source:"iana"},"application/vnd.wolfram.mathematica":{source:"iana"},"application/vnd.wolfram.mathematica.package":{source:"iana"},"application/vnd.wolfram.player":{source:"iana",extensions:["nbp"]},"application/vnd.wordlift":{source:"iana"},"application/vnd.wordperfect":{source:"iana",extensions:["wpd"]},"application/vnd.wqd":{source:"iana",extensions:["wqd"]},"application/vnd.wrq-hp3000-labelled":{source:"iana"},"application/vnd.wt.stf":{source:"iana",extensions:["stf"]},"application/vnd.wv.csp+wbxml":{source:"iana"},"application/vnd.wv.csp+xml":{source:"iana",compressible:!0},"application/vnd.wv.ssp+xml":{source:"iana",compressible:!0},"application/vnd.xacml+json":{source:"iana",compressible:!0},"application/vnd.xara":{source:"iana",extensions:["xar"]},"application/vnd.xarin.cpj":{source:"iana"},"application/vnd.xecrets-encrypted":{source:"iana"},"application/vnd.xfdl":{source:"iana",extensions:["xfdl"]},"application/vnd.xfdl.webform":{source:"iana"},"application/vnd.xmi+xml":{source:"iana",compressible:!0},"application/vnd.xmpie.cpkg":{source:"iana"},"application/vnd.xmpie.dpkg":{source:"iana"},"application/vnd.xmpie.plan":{source:"iana"},"application/vnd.xmpie.ppkg":{source:"iana"},"application/vnd.xmpie.xlim":{source:"iana"},"application/vnd.yamaha.hv-dic":{source:"iana",extensions:["hvd"]},"application/vnd.yamaha.hv-script":{source:"iana",extensions:["hvs"]},"application/vnd.yamaha.hv-voice":{source:"iana",extensions:["hvp"]},"application/vnd.yamaha.openscoreformat":{source:"iana",extensions:["osf"]},"application/vnd.yamaha.openscoreformat.osfpvg+xml":{source:"iana",compressible:!0,extensions:["osfpvg"]},"application/vnd.yamaha.remote-setup":{source:"iana"},"application/vnd.yamaha.smaf-audio":{source:"iana",extensions:["saf"]},"application/vnd.yamaha.smaf-phrase":{source:"iana",extensions:["spf"]},"application/vnd.yamaha.through-ngn":{source:"iana"},"application/vnd.yamaha.tunnel-udpencap":{source:"iana"},"application/vnd.yaoweme":{source:"iana"},"application/vnd.yellowriver-custom-menu":{source:"iana",extensions:["cmp"]},"application/vnd.zul":{source:"iana",extensions:["zir","zirz"]},"application/vnd.zzazz.deck+xml":{source:"iana",compressible:!0,extensions:["zaz"]},"application/voicexml+xml":{source:"iana",compressible:!0,extensions:["vxml"]},"application/voucher-cms+json":{source:"iana",compressible:!0},"application/voucher-jws+json":{source:"iana",compressible:!0},"application/vp":{source:"iana"},"application/vp+cose":{source:"iana"},"application/vp+jwt":{source:"iana"},"application/vq-rtcpxr":{source:"iana"},"application/wasm":{source:"iana",compressible:!0,extensions:["wasm"]},"application/watcherinfo+xml":{source:"iana",compressible:!0,extensions:["wif"]},"application/webpush-options+json":{source:"iana",compressible:!0},"application/whoispp-query":{source:"iana"},"application/whoispp-response":{source:"iana"},"application/widget":{source:"iana",extensions:["wgt"]},"application/winhlp":{source:"apache",extensions:["hlp"]},"application/wita":{source:"iana"},"application/wordperfect5.1":{source:"iana"},"application/wsdl+xml":{source:"iana",compressible:!0,extensions:["wsdl"]},"application/wspolicy+xml":{source:"iana",compressible:!0,extensions:["wspolicy"]},"application/x-7z-compressed":{source:"apache",compressible:!1,extensions:["7z"]},"application/x-abiword":{source:"apache",extensions:["abw"]},"application/x-ace-compressed":{source:"apache",extensions:["ace"]},"application/x-amf":{source:"apache"},"application/x-apple-diskimage":{source:"apache",extensions:["dmg"]},"application/x-arj":{compressible:!1,extensions:["arj"]},"application/x-authorware-bin":{source:"apache",extensions:["aab","x32","u32","vox"]},"application/x-authorware-map":{source:"apache",extensions:["aam"]},"application/x-authorware-seg":{source:"apache",extensions:["aas"]},"application/x-bcpio":{source:"apache",extensions:["bcpio"]},"application/x-bdoc":{compressible:!1,extensions:["bdoc"]},"application/x-bittorrent":{source:"apache",extensions:["torrent"]},"application/x-blender":{extensions:["blend"]},"application/x-blorb":{source:"apache",extensions:["blb","blorb"]},"application/x-bzip":{source:"apache",compressible:!1,extensions:["bz"]},"application/x-bzip2":{source:"apache",compressible:!1,extensions:["bz2","boz"]},"application/x-cbr":{source:"apache",extensions:["cbr","cba","cbt","cbz","cb7"]},"application/x-cdlink":{source:"apache",extensions:["vcd"]},"application/x-cfs-compressed":{source:"apache",extensions:["cfs"]},"application/x-chat":{source:"apache",extensions:["chat"]},"application/x-chess-pgn":{source:"apache",extensions:["pgn"]},"application/x-chrome-extension":{extensions:["crx"]},"application/x-cocoa":{source:"nginx",extensions:["cco"]},"application/x-compress":{source:"apache"},"application/x-compressed":{extensions:["rar"]},"application/x-conference":{source:"apache",extensions:["nsc"]},"application/x-cpio":{source:"apache",extensions:["cpio"]},"application/x-csh":{source:"apache",extensions:["csh"]},"application/x-deb":{compressible:!1},"application/x-debian-package":{source:"apache",extensions:["deb","udeb"]},"application/x-dgc-compressed":{source:"apache",extensions:["dgc"]},"application/x-director":{source:"apache",extensions:["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"]},"application/x-doom":{source:"apache",extensions:["wad"]},"application/x-dtbncx+xml":{source:"apache",compressible:!0,extensions:["ncx"]},"application/x-dtbook+xml":{source:"apache",compressible:!0,extensions:["dtb"]},"application/x-dtbresource+xml":{source:"apache",compressible:!0,extensions:["res"]},"application/x-dvi":{source:"apache",compressible:!1,extensions:["dvi"]},"application/x-envoy":{source:"apache",extensions:["evy"]},"application/x-eva":{source:"apache",extensions:["eva"]},"application/x-font-bdf":{source:"apache",extensions:["bdf"]},"application/x-font-dos":{source:"apache"},"application/x-font-framemaker":{source:"apache"},"application/x-font-ghostscript":{source:"apache",extensions:["gsf"]},"application/x-font-libgrx":{source:"apache"},"application/x-font-linux-psf":{source:"apache",extensions:["psf"]},"application/x-font-pcf":{source:"apache",extensions:["pcf"]},"application/x-font-snf":{source:"apache",extensions:["snf"]},"application/x-font-speedo":{source:"apache"},"application/x-font-sunos-news":{source:"apache"},"application/x-font-type1":{source:"apache",extensions:["pfa","pfb","pfm","afm"]},"application/x-font-vfont":{source:"apache"},"application/x-freearc":{source:"apache",extensions:["arc"]},"application/x-futuresplash":{source:"apache",extensions:["spl"]},"application/x-gca-compressed":{source:"apache",extensions:["gca"]},"application/x-glulx":{source:"apache",extensions:["ulx"]},"application/x-gnumeric":{source:"apache",extensions:["gnumeric"]},"application/x-gramps-xml":{source:"apache",extensions:["gramps"]},"application/x-gtar":{source:"apache",extensions:["gtar"]},"application/x-gzip":{source:"apache"},"application/x-hdf":{source:"apache",extensions:["hdf"]},"application/x-httpd-php":{compressible:!0,extensions:["php"]},"application/x-install-instructions":{source:"apache",extensions:["install"]},"application/x-ipynb+json":{compressible:!0,extensions:["ipynb"]},"application/x-iso9660-image":{source:"apache",extensions:["iso"]},"application/x-iwork-keynote-sffkey":{extensions:["key"]},"application/x-iwork-numbers-sffnumbers":{extensions:["numbers"]},"application/x-iwork-pages-sffpages":{extensions:["pages"]},"application/x-java-archive-diff":{source:"nginx",extensions:["jardiff"]},"application/x-java-jnlp-file":{source:"apache",compressible:!1,extensions:["jnlp"]},"application/x-javascript":{compressible:!0},"application/x-keepass2":{extensions:["kdbx"]},"application/x-latex":{source:"apache",compressible:!1,extensions:["latex"]},"application/x-lua-bytecode":{extensions:["luac"]},"application/x-lzh-compressed":{source:"apache",extensions:["lzh","lha"]},"application/x-makeself":{source:"nginx",extensions:["run"]},"application/x-mie":{source:"apache",extensions:["mie"]},"application/x-mobipocket-ebook":{source:"apache",extensions:["prc","mobi"]},"application/x-mpegurl":{compressible:!1},"application/x-ms-application":{source:"apache",extensions:["application"]},"application/x-ms-shortcut":{source:"apache",extensions:["lnk"]},"application/x-ms-wmd":{source:"apache",extensions:["wmd"]},"application/x-ms-wmz":{source:"apache",extensions:["wmz"]},"application/x-ms-xbap":{source:"apache",extensions:["xbap"]},"application/x-msaccess":{source:"apache",extensions:["mdb"]},"application/x-msbinder":{source:"apache",extensions:["obd"]},"application/x-mscardfile":{source:"apache",extensions:["crd"]},"application/x-msclip":{source:"apache",extensions:["clp"]},"application/x-msdos-program":{extensions:["exe"]},"application/x-msdownload":{source:"apache",extensions:["exe","dll","com","bat","msi"]},"application/x-msmediaview":{source:"apache",extensions:["mvb","m13","m14"]},"application/x-msmetafile":{source:"apache",extensions:["wmf","wmz","emf","emz"]},"application/x-msmoney":{source:"apache",extensions:["mny"]},"application/x-mspublisher":{source:"apache",extensions:["pub"]},"application/x-msschedule":{source:"apache",extensions:["scd"]},"application/x-msterminal":{source:"apache",extensions:["trm"]},"application/x-mswrite":{source:"apache",extensions:["wri"]},"application/x-netcdf":{source:"apache",extensions:["nc","cdf"]},"application/x-ns-proxy-autoconfig":{compressible:!0,extensions:["pac"]},"application/x-nzb":{source:"apache",extensions:["nzb"]},"application/x-perl":{source:"nginx",extensions:["pl","pm"]},"application/x-pilot":{source:"nginx",extensions:["prc","pdb"]},"application/x-pkcs12":{source:"apache",compressible:!1,extensions:["p12","pfx"]},"application/x-pkcs7-certificates":{source:"apache",extensions:["p7b","spc"]},"application/x-pkcs7-certreqresp":{source:"apache",extensions:["p7r"]},"application/x-pki-message":{source:"iana"},"application/x-rar-compressed":{source:"apache",compressible:!1,extensions:["rar"]},"application/x-redhat-package-manager":{source:"nginx",extensions:["rpm"]},"application/x-research-info-systems":{source:"apache",extensions:["ris"]},"application/x-sea":{source:"nginx",extensions:["sea"]},"application/x-sh":{source:"apache",compressible:!0,extensions:["sh"]},"application/x-shar":{source:"apache",extensions:["shar"]},"application/x-shockwave-flash":{source:"apache",compressible:!1,extensions:["swf"]},"application/x-silverlight-app":{source:"apache",extensions:["xap"]},"application/x-sql":{source:"apache",extensions:["sql"]},"application/x-stuffit":{source:"apache",compressible:!1,extensions:["sit"]},"application/x-stuffitx":{source:"apache",extensions:["sitx"]},"application/x-subrip":{source:"apache",extensions:["srt"]},"application/x-sv4cpio":{source:"apache",extensions:["sv4cpio"]},"application/x-sv4crc":{source:"apache",extensions:["sv4crc"]},"application/x-t3vm-image":{source:"apache",extensions:["t3"]},"application/x-tads":{source:"apache",extensions:["gam"]},"application/x-tar":{source:"apache",compressible:!0,extensions:["tar"]},"application/x-tcl":{source:"apache",extensions:["tcl","tk"]},"application/x-tex":{source:"apache",extensions:["tex"]},"application/x-tex-tfm":{source:"apache",extensions:["tfm"]},"application/x-texinfo":{source:"apache",extensions:["texinfo","texi"]},"application/x-tgif":{source:"apache",extensions:["obj"]},"application/x-ustar":{source:"apache",extensions:["ustar"]},"application/x-virtualbox-hdd":{compressible:!0,extensions:["hdd"]},"application/x-virtualbox-ova":{compressible:!0,extensions:["ova"]},"application/x-virtualbox-ovf":{compressible:!0,extensions:["ovf"]},"application/x-virtualbox-vbox":{compressible:!0,extensions:["vbox"]},"application/x-virtualbox-vbox-extpack":{compressible:!1,extensions:["vbox-extpack"]},"application/x-virtualbox-vdi":{compressible:!0,extensions:["vdi"]},"application/x-virtualbox-vhd":{compressible:!0,extensions:["vhd"]},"application/x-virtualbox-vmdk":{compressible:!0,extensions:["vmdk"]},"application/x-wais-source":{source:"apache",extensions:["src"]},"application/x-web-app-manifest+json":{compressible:!0,extensions:["webapp"]},"application/x-www-form-urlencoded":{source:"iana",compressible:!0},"application/x-x509-ca-cert":{source:"iana",extensions:["der","crt","pem"]},"application/x-x509-ca-ra-cert":{source:"iana"},"application/x-x509-next-ca-cert":{source:"iana"},"application/x-xfig":{source:"apache",extensions:["fig"]},"application/x-xliff+xml":{source:"apache",compressible:!0,extensions:["xlf"]},"application/x-xpinstall":{source:"apache",compressible:!1,extensions:["xpi"]},"application/x-xz":{source:"apache",extensions:["xz"]},"application/x-zip-compressed":{extensions:["zip"]},"application/x-zmachine":{source:"apache",extensions:["z1","z2","z3","z4","z5","z6","z7","z8"]},"application/x400-bp":{source:"iana"},"application/xacml+xml":{source:"iana",compressible:!0},"application/xaml+xml":{source:"apache",compressible:!0,extensions:["xaml"]},"application/xcap-att+xml":{source:"iana",compressible:!0,extensions:["xav"]},"application/xcap-caps+xml":{source:"iana",compressible:!0,extensions:["xca"]},"application/xcap-diff+xml":{source:"iana",compressible:!0,extensions:["xdf"]},"application/xcap-el+xml":{source:"iana",compressible:!0,extensions:["xel"]},"application/xcap-error+xml":{source:"iana",compressible:!0},"application/xcap-ns+xml":{source:"iana",compressible:!0,extensions:["xns"]},"application/xcon-conference-info+xml":{source:"iana",compressible:!0},"application/xcon-conference-info-diff+xml":{source:"iana",compressible:!0},"application/xenc+xml":{source:"iana",compressible:!0,extensions:["xenc"]},"application/xfdf":{source:"iana",extensions:["xfdf"]},"application/xhtml+xml":{source:"iana",compressible:!0,extensions:["xhtml","xht"]},"application/xhtml-voice+xml":{source:"apache",compressible:!0},"application/xliff+xml":{source:"iana",compressible:!0,extensions:["xlf"]},"application/xml":{source:"iana",compressible:!0,extensions:["xml","xsl","xsd","rng"]},"application/xml-dtd":{source:"iana",compressible:!0,extensions:["dtd"]},"application/xml-external-parsed-entity":{source:"iana"},"application/xml-patch+xml":{source:"iana",compressible:!0},"application/xmpp+xml":{source:"iana",compressible:!0},"application/xop+xml":{source:"iana",compressible:!0,extensions:["xop"]},"application/xproc+xml":{source:"apache",compressible:!0,extensions:["xpl"]},"application/xslt+xml":{source:"iana",compressible:!0,extensions:["xsl","xslt"]},"application/xspf+xml":{source:"apache",compressible:!0,extensions:["xspf"]},"application/xv+xml":{source:"iana",compressible:!0,extensions:["mxml","xhvml","xvml","xvm"]},"application/yaml":{source:"iana"},"application/yang":{source:"iana",extensions:["yang"]},"application/yang-data+cbor":{source:"iana"},"application/yang-data+json":{source:"iana",compressible:!0},"application/yang-data+xml":{source:"iana",compressible:!0},"application/yang-patch+json":{source:"iana",compressible:!0},"application/yang-patch+xml":{source:"iana",compressible:!0},"application/yang-sid+json":{source:"iana",compressible:!0},"application/yin+xml":{source:"iana",compressible:!0,extensions:["yin"]},"application/zip":{source:"iana",compressible:!1,extensions:["zip"]},"application/zip+dotlottie":{extensions:["lottie"]},"application/zlib":{source:"iana"},"application/zstd":{source:"iana"},"audio/1d-interleaved-parityfec":{source:"iana"},"audio/32kadpcm":{source:"iana"},"audio/3gpp":{source:"iana",compressible:!1,extensions:["3gpp"]},"audio/3gpp2":{source:"iana"},"audio/aac":{source:"iana",extensions:["adts","aac"]},"audio/ac3":{source:"iana"},"audio/adpcm":{source:"apache",extensions:["adp"]},"audio/amr":{source:"iana",extensions:["amr"]},"audio/amr-wb":{source:"iana"},"audio/amr-wb+":{source:"iana"},"audio/aptx":{source:"iana"},"audio/asc":{source:"iana"},"audio/atrac-advanced-lossless":{source:"iana"},"audio/atrac-x":{source:"iana"},"audio/atrac3":{source:"iana"},"audio/basic":{source:"iana",compressible:!1,extensions:["au","snd"]},"audio/bv16":{source:"iana"},"audio/bv32":{source:"iana"},"audio/clearmode":{source:"iana"},"audio/cn":{source:"iana"},"audio/dat12":{source:"iana"},"audio/dls":{source:"iana"},"audio/dsr-es201108":{source:"iana"},"audio/dsr-es202050":{source:"iana"},"audio/dsr-es202211":{source:"iana"},"audio/dsr-es202212":{source:"iana"},"audio/dv":{source:"iana"},"audio/dvi4":{source:"iana"},"audio/eac3":{source:"iana"},"audio/encaprtp":{source:"iana"},"audio/evrc":{source:"iana"},"audio/evrc-qcp":{source:"iana"},"audio/evrc0":{source:"iana"},"audio/evrc1":{source:"iana"},"audio/evrcb":{source:"iana"},"audio/evrcb0":{source:"iana"},"audio/evrcb1":{source:"iana"},"audio/evrcnw":{source:"iana"},"audio/evrcnw0":{source:"iana"},"audio/evrcnw1":{source:"iana"},"audio/evrcwb":{source:"iana"},"audio/evrcwb0":{source:"iana"},"audio/evrcwb1":{source:"iana"},"audio/evs":{source:"iana"},"audio/flac":{source:"iana"},"audio/flexfec":{source:"iana"},"audio/fwdred":{source:"iana"},"audio/g711-0":{source:"iana"},"audio/g719":{source:"iana"},"audio/g722":{source:"iana"},"audio/g7221":{source:"iana"},"audio/g723":{source:"iana"},"audio/g726-16":{source:"iana"},"audio/g726-24":{source:"iana"},"audio/g726-32":{source:"iana"},"audio/g726-40":{source:"iana"},"audio/g728":{source:"iana"},"audio/g729":{source:"iana"},"audio/g7291":{source:"iana"},"audio/g729d":{source:"iana"},"audio/g729e":{source:"iana"},"audio/gsm":{source:"iana"},"audio/gsm-efr":{source:"iana"},"audio/gsm-hr-08":{source:"iana"},"audio/ilbc":{source:"iana"},"audio/ip-mr_v2.5":{source:"iana"},"audio/isac":{source:"apache"},"audio/l16":{source:"iana"},"audio/l20":{source:"iana"},"audio/l24":{source:"iana",compressible:!1},"audio/l8":{source:"iana"},"audio/lpc":{source:"iana"},"audio/matroska":{source:"iana"},"audio/melp":{source:"iana"},"audio/melp1200":{source:"iana"},"audio/melp2400":{source:"iana"},"audio/melp600":{source:"iana"},"audio/mhas":{source:"iana"},"audio/midi":{source:"apache",extensions:["mid","midi","kar","rmi"]},"audio/midi-clip":{source:"iana"},"audio/mobile-xmf":{source:"iana",extensions:["mxmf"]},"audio/mp3":{compressible:!1,extensions:["mp3"]},"audio/mp4":{source:"iana",compressible:!1,extensions:["m4a","mp4a","m4b"]},"audio/mp4a-latm":{source:"iana"},"audio/mpa":{source:"iana"},"audio/mpa-robust":{source:"iana"},"audio/mpeg":{source:"iana",compressible:!1,extensions:["mpga","mp2","mp2a","mp3","m2a","m3a"]},"audio/mpeg4-generic":{source:"iana"},"audio/musepack":{source:"apache"},"audio/ogg":{source:"iana",compressible:!1,extensions:["oga","ogg","spx","opus"]},"audio/opus":{source:"iana"},"audio/parityfec":{source:"iana"},"audio/pcma":{source:"iana"},"audio/pcma-wb":{source:"iana"},"audio/pcmu":{source:"iana"},"audio/pcmu-wb":{source:"iana"},"audio/prs.sid":{source:"iana"},"audio/qcelp":{source:"iana"},"audio/raptorfec":{source:"iana"},"audio/red":{source:"iana"},"audio/rtp-enc-aescm128":{source:"iana"},"audio/rtp-midi":{source:"iana"},"audio/rtploopback":{source:"iana"},"audio/rtx":{source:"iana"},"audio/s3m":{source:"apache",extensions:["s3m"]},"audio/scip":{source:"iana"},"audio/silk":{source:"apache",extensions:["sil"]},"audio/smv":{source:"iana"},"audio/smv-qcp":{source:"iana"},"audio/smv0":{source:"iana"},"audio/sofa":{source:"iana"},"audio/sp-midi":{source:"iana"},"audio/speex":{source:"iana"},"audio/t140c":{source:"iana"},"audio/t38":{source:"iana"},"audio/telephone-event":{source:"iana"},"audio/tetra_acelp":{source:"iana"},"audio/tetra_acelp_bb":{source:"iana"},"audio/tone":{source:"iana"},"audio/tsvcis":{source:"iana"},"audio/uemclip":{source:"iana"},"audio/ulpfec":{source:"iana"},"audio/usac":{source:"iana"},"audio/vdvi":{source:"iana"},"audio/vmr-wb":{source:"iana"},"audio/vnd.3gpp.iufp":{source:"iana"},"audio/vnd.4sb":{source:"iana"},"audio/vnd.audiokoz":{source:"iana"},"audio/vnd.celp":{source:"iana"},"audio/vnd.cisco.nse":{source:"iana"},"audio/vnd.cmles.radio-events":{source:"iana"},"audio/vnd.cns.anp1":{source:"iana"},"audio/vnd.cns.inf1":{source:"iana"},"audio/vnd.dece.audio":{source:"iana",extensions:["uva","uvva"]},"audio/vnd.digital-winds":{source:"iana",extensions:["eol"]},"audio/vnd.dlna.adts":{source:"iana"},"audio/vnd.dolby.heaac.1":{source:"iana"},"audio/vnd.dolby.heaac.2":{source:"iana"},"audio/vnd.dolby.mlp":{source:"iana"},"audio/vnd.dolby.mps":{source:"iana"},"audio/vnd.dolby.pl2":{source:"iana"},"audio/vnd.dolby.pl2x":{source:"iana"},"audio/vnd.dolby.pl2z":{source:"iana"},"audio/vnd.dolby.pulse.1":{source:"iana"},"audio/vnd.dra":{source:"iana",extensions:["dra"]},"audio/vnd.dts":{source:"iana",extensions:["dts"]},"audio/vnd.dts.hd":{source:"iana",extensions:["dtshd"]},"audio/vnd.dts.uhd":{source:"iana"},"audio/vnd.dvb.file":{source:"iana"},"audio/vnd.everad.plj":{source:"iana"},"audio/vnd.hns.audio":{source:"iana"},"audio/vnd.lucent.voice":{source:"iana",extensions:["lvp"]},"audio/vnd.ms-playready.media.pya":{source:"iana",extensions:["pya"]},"audio/vnd.nokia.mobile-xmf":{source:"iana"},"audio/vnd.nortel.vbk":{source:"iana"},"audio/vnd.nuera.ecelp4800":{source:"iana",extensions:["ecelp4800"]},"audio/vnd.nuera.ecelp7470":{source:"iana",extensions:["ecelp7470"]},"audio/vnd.nuera.ecelp9600":{source:"iana",extensions:["ecelp9600"]},"audio/vnd.octel.sbc":{source:"iana"},"audio/vnd.presonus.multitrack":{source:"iana"},"audio/vnd.qcelp":{source:"apache"},"audio/vnd.rhetorex.32kadpcm":{source:"iana"},"audio/vnd.rip":{source:"iana",extensions:["rip"]},"audio/vnd.rn-realaudio":{compressible:!1},"audio/vnd.sealedmedia.softseal.mpeg":{source:"iana"},"audio/vnd.vmx.cvsd":{source:"iana"},"audio/vnd.wave":{compressible:!1},"audio/vorbis":{source:"iana",compressible:!1},"audio/vorbis-config":{source:"iana"},"audio/wav":{compressible:!1,extensions:["wav"]},"audio/wave":{compressible:!1,extensions:["wav"]},"audio/webm":{source:"apache",compressible:!1,extensions:["weba"]},"audio/x-aac":{source:"apache",compressible:!1,extensions:["aac"]},"audio/x-aiff":{source:"apache",extensions:["aif","aiff","aifc"]},"audio/x-caf":{source:"apache",compressible:!1,extensions:["caf"]},"audio/x-flac":{source:"apache",extensions:["flac"]},"audio/x-m4a":{source:"nginx",extensions:["m4a"]},"audio/x-matroska":{source:"apache",extensions:["mka"]},"audio/x-mpegurl":{source:"apache",extensions:["m3u"]},"audio/x-ms-wax":{source:"apache",extensions:["wax"]},"audio/x-ms-wma":{source:"apache",extensions:["wma"]},"audio/x-pn-realaudio":{source:"apache",extensions:["ram","ra"]},"audio/x-pn-realaudio-plugin":{source:"apache",extensions:["rmp"]},"audio/x-realaudio":{source:"nginx",extensions:["ra"]},"audio/x-tta":{source:"apache"},"audio/x-wav":{source:"apache",extensions:["wav"]},"audio/xm":{source:"apache",extensions:["xm"]},"chemical/x-cdx":{source:"apache",extensions:["cdx"]},"chemical/x-cif":{source:"apache",extensions:["cif"]},"chemical/x-cmdf":{source:"apache",extensions:["cmdf"]},"chemical/x-cml":{source:"apache",extensions:["cml"]},"chemical/x-csml":{source:"apache",extensions:["csml"]},"chemical/x-pdb":{source:"apache"},"chemical/x-xyz":{source:"apache",extensions:["xyz"]},"font/collection":{source:"iana",extensions:["ttc"]},"font/otf":{source:"iana",compressible:!0,extensions:["otf"]},"font/sfnt":{source:"iana"},"font/ttf":{source:"iana",compressible:!0,extensions:["ttf"]},"font/woff":{source:"iana",extensions:["woff"]},"font/woff2":{source:"iana",extensions:["woff2"]},"image/aces":{source:"iana",extensions:["exr"]},"image/apng":{source:"iana",compressible:!1,extensions:["apng"]},"image/avci":{source:"iana",extensions:["avci"]},"image/avcs":{source:"iana",extensions:["avcs"]},"image/avif":{source:"iana",compressible:!1,extensions:["avif"]},"image/bmp":{source:"iana",compressible:!0,extensions:["bmp","dib"]},"image/cgm":{source:"iana",extensions:["cgm"]},"image/dicom-rle":{source:"iana",extensions:["drle"]},"image/dpx":{source:"iana",extensions:["dpx"]},"image/emf":{source:"iana",extensions:["emf"]},"image/fits":{source:"iana",extensions:["fits"]},"image/g3fax":{source:"iana",extensions:["g3"]},"image/gif":{source:"iana",compressible:!1,extensions:["gif"]},"image/heic":{source:"iana",extensions:["heic"]},"image/heic-sequence":{source:"iana",extensions:["heics"]},"image/heif":{source:"iana",extensions:["heif"]},"image/heif-sequence":{source:"iana",extensions:["heifs"]},"image/hej2k":{source:"iana",extensions:["hej2"]},"image/ief":{source:"iana",extensions:["ief"]},"image/j2c":{source:"iana"},"image/jaii":{source:"iana",extensions:["jaii"]},"image/jais":{source:"iana",extensions:["jais"]},"image/jls":{source:"iana",extensions:["jls"]},"image/jp2":{source:"iana",compressible:!1,extensions:["jp2","jpg2"]},"image/jpeg":{source:"iana",compressible:!1,extensions:["jpg","jpeg","jpe"]},"image/jph":{source:"iana",extensions:["jph"]},"image/jphc":{source:"iana",extensions:["jhc"]},"image/jpm":{source:"iana",compressible:!1,extensions:["jpm","jpgm"]},"image/jpx":{source:"iana",compressible:!1,extensions:["jpx","jpf"]},"image/jxl":{source:"iana",extensions:["jxl"]},"image/jxr":{source:"iana",extensions:["jxr"]},"image/jxra":{source:"iana",extensions:["jxra"]},"image/jxrs":{source:"iana",extensions:["jxrs"]},"image/jxs":{source:"iana",extensions:["jxs"]},"image/jxsc":{source:"iana",extensions:["jxsc"]},"image/jxsi":{source:"iana",extensions:["jxsi"]},"image/jxss":{source:"iana",extensions:["jxss"]},"image/ktx":{source:"iana",extensions:["ktx"]},"image/ktx2":{source:"iana",extensions:["ktx2"]},"image/naplps":{source:"iana"},"image/pjpeg":{compressible:!1,extensions:["jfif"]},"image/png":{source:"iana",compressible:!1,extensions:["png"]},"image/prs.btif":{source:"iana",extensions:["btif","btf"]},"image/prs.pti":{source:"iana",extensions:["pti"]},"image/pwg-raster":{source:"iana"},"image/sgi":{source:"apache",extensions:["sgi"]},"image/svg+xml":{source:"iana",compressible:!0,extensions:["svg","svgz"]},"image/t38":{source:"iana",extensions:["t38"]},"image/tiff":{source:"iana",compressible:!1,extensions:["tif","tiff"]},"image/tiff-fx":{source:"iana",extensions:["tfx"]},"image/vnd.adobe.photoshop":{source:"iana",compressible:!0,extensions:["psd"]},"image/vnd.airzip.accelerator.azv":{source:"iana",extensions:["azv"]},"image/vnd.clip":{source:"iana"},"image/vnd.cns.inf2":{source:"iana"},"image/vnd.dece.graphic":{source:"iana",extensions:["uvi","uvvi","uvg","uvvg"]},"image/vnd.djvu":{source:"iana",extensions:["djvu","djv"]},"image/vnd.dvb.subtitle":{source:"iana",extensions:["sub"]},"image/vnd.dwg":{source:"iana",extensions:["dwg"]},"image/vnd.dxf":{source:"iana",extensions:["dxf"]},"image/vnd.fastbidsheet":{source:"iana",extensions:["fbs"]},"image/vnd.fpx":{source:"iana",extensions:["fpx"]},"image/vnd.fst":{source:"iana",extensions:["fst"]},"image/vnd.fujixerox.edmics-mmr":{source:"iana",extensions:["mmr"]},"image/vnd.fujixerox.edmics-rlc":{source:"iana",extensions:["rlc"]},"image/vnd.globalgraphics.pgb":{source:"iana"},"image/vnd.microsoft.icon":{source:"iana",compressible:!0,extensions:["ico"]},"image/vnd.mix":{source:"iana"},"image/vnd.mozilla.apng":{source:"iana"},"image/vnd.ms-dds":{compressible:!0,extensions:["dds"]},"image/vnd.ms-modi":{source:"iana",extensions:["mdi"]},"image/vnd.ms-photo":{source:"apache",extensions:["wdp"]},"image/vnd.net-fpx":{source:"iana",extensions:["npx"]},"image/vnd.pco.b16":{source:"iana",extensions:["b16"]},"image/vnd.radiance":{source:"iana"},"image/vnd.sealed.png":{source:"iana"},"image/vnd.sealedmedia.softseal.gif":{source:"iana"},"image/vnd.sealedmedia.softseal.jpg":{source:"iana"},"image/vnd.svf":{source:"iana"},"image/vnd.tencent.tap":{source:"iana",extensions:["tap"]},"image/vnd.valve.source.texture":{source:"iana",extensions:["vtf"]},"image/vnd.wap.wbmp":{source:"iana",extensions:["wbmp"]},"image/vnd.xiff":{source:"iana",extensions:["xif"]},"image/vnd.zbrush.pcx":{source:"iana",extensions:["pcx"]},"image/webp":{source:"iana",extensions:["webp"]},"image/wmf":{source:"iana",extensions:["wmf"]},"image/x-3ds":{source:"apache",extensions:["3ds"]},"image/x-adobe-dng":{extensions:["dng"]},"image/x-cmu-raster":{source:"apache",extensions:["ras"]},"image/x-cmx":{source:"apache",extensions:["cmx"]},"image/x-emf":{source:"iana"},"image/x-freehand":{source:"apache",extensions:["fh","fhc","fh4","fh5","fh7"]},"image/x-icon":{source:"apache",compressible:!0,extensions:["ico"]},"image/x-jng":{source:"nginx",extensions:["jng"]},"image/x-mrsid-image":{source:"apache",extensions:["sid"]},"image/x-ms-bmp":{source:"nginx",compressible:!0,extensions:["bmp"]},"image/x-pcx":{source:"apache",extensions:["pcx"]},"image/x-pict":{source:"apache",extensions:["pic","pct"]},"image/x-portable-anymap":{source:"apache",extensions:["pnm"]},"image/x-portable-bitmap":{source:"apache",extensions:["pbm"]},"image/x-portable-graymap":{source:"apache",extensions:["pgm"]},"image/x-portable-pixmap":{source:"apache",extensions:["ppm"]},"image/x-rgb":{source:"apache",extensions:["rgb"]},"image/x-tga":{source:"apache",extensions:["tga"]},"image/x-wmf":{source:"iana"},"image/x-xbitmap":{source:"apache",extensions:["xbm"]},"image/x-xcf":{compressible:!1},"image/x-xpixmap":{source:"apache",extensions:["xpm"]},"image/x-xwindowdump":{source:"apache",extensions:["xwd"]},"message/bhttp":{source:"iana"},"message/cpim":{source:"iana"},"message/delivery-status":{source:"iana"},"message/disposition-notification":{source:"iana",extensions:["disposition-notification"]},"message/external-body":{source:"iana"},"message/feedback-report":{source:"iana"},"message/global":{source:"iana",extensions:["u8msg"]},"message/global-delivery-status":{source:"iana",extensions:["u8dsn"]},"message/global-disposition-notification":{source:"iana",extensions:["u8mdn"]},"message/global-headers":{source:"iana",extensions:["u8hdr"]},"message/http":{source:"iana",compressible:!1},"message/imdn+xml":{source:"iana",compressible:!0},"message/mls":{source:"iana"},"message/news":{source:"apache"},"message/ohttp-req":{source:"iana"},"message/ohttp-res":{source:"iana"},"message/partial":{source:"iana",compressible:!1},"message/rfc822":{source:"iana",compressible:!0,extensions:["eml","mime","mht","mhtml"]},"message/s-http":{source:"apache"},"message/sip":{source:"iana"},"message/sipfrag":{source:"iana"},"message/tracking-status":{source:"iana"},"message/vnd.si.simp":{source:"apache"},"message/vnd.wfa.wsc":{source:"iana",extensions:["wsc"]},"model/3mf":{source:"iana",extensions:["3mf"]},"model/e57":{source:"iana"},"model/gltf+json":{source:"iana",compressible:!0,extensions:["gltf"]},"model/gltf-binary":{source:"iana",compressible:!0,extensions:["glb"]},"model/iges":{source:"iana",compressible:!1,extensions:["igs","iges"]},"model/jt":{source:"iana",extensions:["jt"]},"model/mesh":{source:"iana",compressible:!1,extensions:["msh","mesh","silo"]},"model/mtl":{source:"iana",extensions:["mtl"]},"model/obj":{source:"iana",extensions:["obj"]},"model/prc":{source:"iana",extensions:["prc"]},"model/step":{source:"iana",extensions:["step","stp","stpnc","p21","210"]},"model/step+xml":{source:"iana",compressible:!0,extensions:["stpx"]},"model/step+zip":{source:"iana",compressible:!1,extensions:["stpz"]},"model/step-xml+zip":{source:"iana",compressible:!1,extensions:["stpxz"]},"model/stl":{source:"iana",extensions:["stl"]},"model/u3d":{source:"iana",extensions:["u3d"]},"model/vnd.bary":{source:"iana",extensions:["bary"]},"model/vnd.cld":{source:"iana",extensions:["cld"]},"model/vnd.collada+xml":{source:"iana",compressible:!0,extensions:["dae"]},"model/vnd.dwf":{source:"iana",extensions:["dwf"]},"model/vnd.flatland.3dml":{source:"iana"},"model/vnd.gdl":{source:"iana",extensions:["gdl"]},"model/vnd.gs-gdl":{source:"apache"},"model/vnd.gs.gdl":{source:"iana"},"model/vnd.gtw":{source:"iana",extensions:["gtw"]},"model/vnd.moml+xml":{source:"iana",compressible:!0},"model/vnd.mts":{source:"iana",extensions:["mts"]},"model/vnd.opengex":{source:"iana",extensions:["ogex"]},"model/vnd.parasolid.transmit.binary":{source:"iana",extensions:["x_b"]},"model/vnd.parasolid.transmit.text":{source:"iana",extensions:["x_t"]},"model/vnd.pytha.pyox":{source:"iana",extensions:["pyo","pyox"]},"model/vnd.rosette.annotated-data-model":{source:"iana"},"model/vnd.sap.vds":{source:"iana",extensions:["vds"]},"model/vnd.usda":{source:"iana",extensions:["usda"]},"model/vnd.usdz+zip":{source:"iana",compressible:!1,extensions:["usdz"]},"model/vnd.valve.source.compiled-map":{source:"iana",extensions:["bsp"]},"model/vnd.vtu":{source:"iana",extensions:["vtu"]},"model/vrml":{source:"iana",compressible:!1,extensions:["wrl","vrml"]},"model/x3d+binary":{source:"apache",compressible:!1,extensions:["x3db","x3dbz"]},"model/x3d+fastinfoset":{source:"iana",extensions:["x3db"]},"model/x3d+vrml":{source:"apache",compressible:!1,extensions:["x3dv","x3dvz"]},"model/x3d+xml":{source:"iana",compressible:!0,extensions:["x3d","x3dz"]},"model/x3d-vrml":{source:"iana",extensions:["x3dv"]},"multipart/alternative":{source:"iana",compressible:!1},"multipart/appledouble":{source:"iana"},"multipart/byteranges":{source:"iana"},"multipart/digest":{source:"iana"},"multipart/encrypted":{source:"iana",compressible:!1},"multipart/form-data":{source:"iana",compressible:!1},"multipart/header-set":{source:"iana"},"multipart/mixed":{source:"iana"},"multipart/multilingual":{source:"iana"},"multipart/parallel":{source:"iana"},"multipart/related":{source:"iana",compressible:!1},"multipart/report":{source:"iana"},"multipart/signed":{source:"iana",compressible:!1},"multipart/vnd.bint.med-plus":{source:"iana"},"multipart/voice-message":{source:"iana"},"multipart/x-mixed-replace":{source:"iana"},"text/1d-interleaved-parityfec":{source:"iana"},"text/cache-manifest":{source:"iana",compressible:!0,extensions:["appcache","manifest"]},"text/calendar":{source:"iana",extensions:["ics","ifb"]},"text/calender":{compressible:!0},"text/cmd":{compressible:!0},"text/coffeescript":{extensions:["coffee","litcoffee"]},"text/cql":{source:"iana"},"text/cql-expression":{source:"iana"},"text/cql-identifier":{source:"iana"},"text/css":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["css"]},"text/csv":{source:"iana",compressible:!0,extensions:["csv"]},"text/csv-schema":{source:"iana"},"text/directory":{source:"iana"},"text/dns":{source:"iana"},"text/ecmascript":{source:"apache"},"text/encaprtp":{source:"iana"},"text/enriched":{source:"iana"},"text/fhirpath":{source:"iana"},"text/flexfec":{source:"iana"},"text/fwdred":{source:"iana"},"text/gff3":{source:"iana"},"text/grammar-ref-list":{source:"iana"},"text/hl7v2":{source:"iana"},"text/html":{source:"iana",compressible:!0,extensions:["html","htm","shtml"]},"text/jade":{extensions:["jade"]},"text/javascript":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["js","mjs"]},"text/jcr-cnd":{source:"iana"},"text/jsx":{compressible:!0,extensions:["jsx"]},"text/less":{compressible:!0,extensions:["less"]},"text/markdown":{source:"iana",compressible:!0,extensions:["md","markdown"]},"text/mathml":{source:"nginx",extensions:["mml"]},"text/mdx":{compressible:!0,extensions:["mdx"]},"text/mizar":{source:"iana"},"text/n3":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["n3"]},"text/parameters":{source:"iana",charset:"UTF-8"},"text/parityfec":{source:"iana"},"text/plain":{source:"iana",compressible:!0,extensions:["txt","text","conf","def","list","log","in","ini"]},"text/provenance-notation":{source:"iana",charset:"UTF-8"},"text/prs.fallenstein.rst":{source:"iana"},"text/prs.lines.tag":{source:"iana",extensions:["dsc"]},"text/prs.prop.logic":{source:"iana"},"text/prs.texi":{source:"iana"},"text/raptorfec":{source:"iana"},"text/red":{source:"iana"},"text/rfc822-headers":{source:"iana"},"text/richtext":{source:"iana",compressible:!0,extensions:["rtx"]},"text/rtf":{source:"iana",compressible:!0,extensions:["rtf"]},"text/rtp-enc-aescm128":{source:"iana"},"text/rtploopback":{source:"iana"},"text/rtx":{source:"iana"},"text/sgml":{source:"iana",extensions:["sgml","sgm"]},"text/shaclc":{source:"iana"},"text/shex":{source:"iana",extensions:["shex"]},"text/slim":{extensions:["slim","slm"]},"text/spdx":{source:"iana",extensions:["spdx"]},"text/strings":{source:"iana"},"text/stylus":{extensions:["stylus","styl"]},"text/t140":{source:"iana"},"text/tab-separated-values":{source:"iana",compressible:!0,extensions:["tsv"]},"text/troff":{source:"iana",extensions:["t","tr","roff","man","me","ms"]},"text/turtle":{source:"iana",charset:"UTF-8",extensions:["ttl"]},"text/ulpfec":{source:"iana"},"text/uri-list":{source:"iana",compressible:!0,extensions:["uri","uris","urls"]},"text/vcard":{source:"iana",compressible:!0,extensions:["vcard"]},"text/vnd.a":{source:"iana"},"text/vnd.abc":{source:"iana"},"text/vnd.ascii-art":{source:"iana"},"text/vnd.curl":{source:"iana",extensions:["curl"]},"text/vnd.curl.dcurl":{source:"apache",extensions:["dcurl"]},"text/vnd.curl.mcurl":{source:"apache",extensions:["mcurl"]},"text/vnd.curl.scurl":{source:"apache",extensions:["scurl"]},"text/vnd.debian.copyright":{source:"iana",charset:"UTF-8"},"text/vnd.dmclientscript":{source:"iana"},"text/vnd.dvb.subtitle":{source:"iana",extensions:["sub"]},"text/vnd.esmertec.theme-descriptor":{source:"iana",charset:"UTF-8"},"text/vnd.exchangeable":{source:"iana"},"text/vnd.familysearch.gedcom":{source:"iana",extensions:["ged"]},"text/vnd.ficlab.flt":{source:"iana"},"text/vnd.fly":{source:"iana",extensions:["fly"]},"text/vnd.fmi.flexstor":{source:"iana",extensions:["flx"]},"text/vnd.gml":{source:"iana"},"text/vnd.graphviz":{source:"iana",extensions:["gv"]},"text/vnd.hans":{source:"iana"},"text/vnd.hgl":{source:"iana"},"text/vnd.in3d.3dml":{source:"iana",extensions:["3dml"]},"text/vnd.in3d.spot":{source:"iana",extensions:["spot"]},"text/vnd.iptc.newsml":{source:"iana"},"text/vnd.iptc.nitf":{source:"iana"},"text/vnd.latex-z":{source:"iana"},"text/vnd.motorola.reflex":{source:"iana"},"text/vnd.ms-mediapackage":{source:"iana"},"text/vnd.net2phone.commcenter.command":{source:"iana"},"text/vnd.radisys.msml-basic-layout":{source:"iana"},"text/vnd.senx.warpscript":{source:"iana"},"text/vnd.si.uricatalogue":{source:"apache"},"text/vnd.sosi":{source:"iana"},"text/vnd.sun.j2me.app-descriptor":{source:"iana",charset:"UTF-8",extensions:["jad"]},"text/vnd.trolltech.linguist":{source:"iana",charset:"UTF-8"},"text/vnd.vcf":{source:"iana"},"text/vnd.wap.si":{source:"iana"},"text/vnd.wap.sl":{source:"iana"},"text/vnd.wap.wml":{source:"iana",extensions:["wml"]},"text/vnd.wap.wmlscript":{source:"iana",extensions:["wmls"]},"text/vnd.zoo.kcl":{source:"iana"},"text/vtt":{source:"iana",charset:"UTF-8",compressible:!0,extensions:["vtt"]},"text/wgsl":{source:"iana",extensions:["wgsl"]},"text/x-asm":{source:"apache",extensions:["s","asm"]},"text/x-c":{source:"apache",extensions:["c","cc","cxx","cpp","h","hh","dic"]},"text/x-component":{source:"nginx",extensions:["htc"]},"text/x-fortran":{source:"apache",extensions:["f","for","f77","f90"]},"text/x-gwt-rpc":{compressible:!0},"text/x-handlebars-template":{extensions:["hbs"]},"text/x-java-source":{source:"apache",extensions:["java"]},"text/x-jquery-tmpl":{compressible:!0},"text/x-lua":{extensions:["lua"]},"text/x-markdown":{compressible:!0,extensions:["mkd"]},"text/x-nfo":{source:"apache",extensions:["nfo"]},"text/x-opml":{source:"apache",extensions:["opml"]},"text/x-org":{compressible:!0,extensions:["org"]},"text/x-pascal":{source:"apache",extensions:["p","pas"]},"text/x-processing":{compressible:!0,extensions:["pde"]},"text/x-sass":{extensions:["sass"]},"text/x-scss":{extensions:["scss"]},"text/x-setext":{source:"apache",extensions:["etx"]},"text/x-sfv":{source:"apache",extensions:["sfv"]},"text/x-suse-ymp":{compressible:!0,extensions:["ymp"]},"text/x-uuencode":{source:"apache",extensions:["uu"]},"text/x-vcalendar":{source:"apache",extensions:["vcs"]},"text/x-vcard":{source:"apache",extensions:["vcf"]},"text/xml":{source:"iana",compressible:!0,extensions:["xml"]},"text/xml-external-parsed-entity":{source:"iana"},"text/yaml":{compressible:!0,extensions:["yaml","yml"]},"video/1d-interleaved-parityfec":{source:"iana"},"video/3gpp":{source:"iana",extensions:["3gp","3gpp"]},"video/3gpp-tt":{source:"iana"},"video/3gpp2":{source:"iana",extensions:["3g2"]},"video/av1":{source:"iana"},"video/bmpeg":{source:"iana"},"video/bt656":{source:"iana"},"video/celb":{source:"iana"},"video/dv":{source:"iana"},"video/encaprtp":{source:"iana"},"video/evc":{source:"iana"},"video/ffv1":{source:"iana"},"video/flexfec":{source:"iana"},"video/h261":{source:"iana",extensions:["h261"]},"video/h263":{source:"iana",extensions:["h263"]},"video/h263-1998":{source:"iana"},"video/h263-2000":{source:"iana"},"video/h264":{source:"iana",extensions:["h264"]},"video/h264-rcdo":{source:"iana"},"video/h264-svc":{source:"iana"},"video/h265":{source:"iana"},"video/h266":{source:"iana"},"video/iso.segment":{source:"iana",extensions:["m4s"]},"video/jpeg":{source:"iana",extensions:["jpgv"]},"video/jpeg2000":{source:"iana"},"video/jpm":{source:"apache",extensions:["jpm","jpgm"]},"video/jxsv":{source:"iana"},"video/lottie+json":{source:"iana",compressible:!0},"video/matroska":{source:"iana"},"video/matroska-3d":{source:"iana"},"video/mj2":{source:"iana",extensions:["mj2","mjp2"]},"video/mp1s":{source:"iana"},"video/mp2p":{source:"iana"},"video/mp2t":{source:"iana",extensions:["ts","m2t","m2ts","mts"]},"video/mp4":{source:"iana",compressible:!1,extensions:["mp4","mp4v","mpg4"]},"video/mp4v-es":{source:"iana"},"video/mpeg":{source:"iana",compressible:!1,extensions:["mpeg","mpg","mpe","m1v","m2v"]},"video/mpeg4-generic":{source:"iana"},"video/mpv":{source:"iana"},"video/nv":{source:"iana"},"video/ogg":{source:"iana",compressible:!1,extensions:["ogv"]},"video/parityfec":{source:"iana"},"video/pointer":{source:"iana"},"video/quicktime":{source:"iana",compressible:!1,extensions:["qt","mov"]},"video/raptorfec":{source:"iana"},"video/raw":{source:"iana"},"video/rtp-enc-aescm128":{source:"iana"},"video/rtploopback":{source:"iana"},"video/rtx":{source:"iana"},"video/scip":{source:"iana"},"video/smpte291":{source:"iana"},"video/smpte292m":{source:"iana"},"video/ulpfec":{source:"iana"},"video/vc1":{source:"iana"},"video/vc2":{source:"iana"},"video/vnd.cctv":{source:"iana"},"video/vnd.dece.hd":{source:"iana",extensions:["uvh","uvvh"]},"video/vnd.dece.mobile":{source:"iana",extensions:["uvm","uvvm"]},"video/vnd.dece.mp4":{source:"iana"},"video/vnd.dece.pd":{source:"iana",extensions:["uvp","uvvp"]},"video/vnd.dece.sd":{source:"iana",extensions:["uvs","uvvs"]},"video/vnd.dece.video":{source:"iana",extensions:["uvv","uvvv"]},"video/vnd.directv.mpeg":{source:"iana"},"video/vnd.directv.mpeg-tts":{source:"iana"},"video/vnd.dlna.mpeg-tts":{source:"iana"},"video/vnd.dvb.file":{source:"iana",extensions:["dvb"]},"video/vnd.fvt":{source:"iana",extensions:["fvt"]},"video/vnd.hns.video":{source:"iana"},"video/vnd.iptvforum.1dparityfec-1010":{source:"iana"},"video/vnd.iptvforum.1dparityfec-2005":{source:"iana"},"video/vnd.iptvforum.2dparityfec-1010":{source:"iana"},"video/vnd.iptvforum.2dparityfec-2005":{source:"iana"},"video/vnd.iptvforum.ttsavc":{source:"iana"},"video/vnd.iptvforum.ttsmpeg2":{source:"iana"},"video/vnd.motorola.video":{source:"iana"},"video/vnd.motorola.videop":{source:"iana"},"video/vnd.mpegurl":{source:"iana",extensions:["mxu","m4u"]},"video/vnd.ms-playready.media.pyv":{source:"iana",extensions:["pyv"]},"video/vnd.nokia.interleaved-multimedia":{source:"iana"},"video/vnd.nokia.mp4vr":{source:"iana"},"video/vnd.nokia.videovoip":{source:"iana"},"video/vnd.objectvideo":{source:"iana"},"video/vnd.planar":{source:"iana"},"video/vnd.radgamettools.bink":{source:"iana"},"video/vnd.radgamettools.smacker":{source:"apache"},"video/vnd.sealed.mpeg1":{source:"iana"},"video/vnd.sealed.mpeg4":{source:"iana"},"video/vnd.sealed.swf":{source:"iana"},"video/vnd.sealedmedia.softseal.mov":{source:"iana"},"video/vnd.uvvu.mp4":{source:"iana",extensions:["uvu","uvvu"]},"video/vnd.vivo":{source:"iana",extensions:["viv"]},"video/vnd.youtube.yt":{source:"iana"},"video/vp8":{source:"iana"},"video/vp9":{source:"iana"},"video/webm":{source:"apache",compressible:!1,extensions:["webm"]},"video/x-f4v":{source:"apache",extensions:["f4v"]},"video/x-fli":{source:"apache",extensions:["fli"]},"video/x-flv":{source:"apache",compressible:!1,extensions:["flv"]},"video/x-m4v":{source:"apache",extensions:["m4v"]},"video/x-matroska":{source:"apache",compressible:!1,extensions:["mkv","mk3d","mks"]},"video/x-mng":{source:"apache",extensions:["mng"]},"video/x-ms-asf":{source:"apache",extensions:["asf","asx"]},"video/x-ms-vob":{source:"apache",extensions:["vob"]},"video/x-ms-wm":{source:"apache",extensions:["wm"]},"video/x-ms-wmv":{source:"apache",compressible:!1,extensions:["wmv"]},"video/x-ms-wmx":{source:"apache",extensions:["wmx"]},"video/x-ms-wvx":{source:"apache",extensions:["wvx"]},"video/x-msvideo":{source:"apache",extensions:["avi"]},"video/x-sgi-movie":{source:"apache",extensions:["movie"]},"video/x-smv":{source:"apache",extensions:["smv"]},"x-conference/x-cooltalk":{source:"apache",extensions:["ice"]},"x-shader/x-fragment":{compressible:!0},"x-shader/x-vertex":{compressible:!0}},se={};var ae,oe,re={exports:{}},ce={exports:{}};function de(){if(oe)return ae;oe=1;class e extends Error{constructor(e){if(!Array.isArray(e))throw new TypeError("Expected input to be an Array, got "+typeof e);let t="";for(let n=0;n<e.length;n++)t+=` ${e[n].stack}\n`;super(t),this.name="AggregateError",this.errors=e}}return ae={AggregateError:e,ArrayIsArray:e=>Array.isArray(e),ArrayPrototypeIncludes:(e,t)=>e.includes(t),ArrayPrototypeIndexOf:(e,t)=>e.indexOf(t),ArrayPrototypeJoin:(e,t)=>e.join(t),ArrayPrototypeMap:(e,t)=>e.map(t),ArrayPrototypePop:(e,t)=>e.pop(t),ArrayPrototypePush:(e,t)=>e.push(t),ArrayPrototypeSlice:(e,t,n)=>e.slice(t,n),Error:Error,FunctionPrototypeCall:(e,t,...n)=>e.call(t,...n),FunctionPrototypeSymbolHasInstance:(e,t)=>Function.prototype[Symbol.hasInstance].call(e,t),MathFloor:Math.floor,Number:Number,NumberIsInteger:Number.isInteger,NumberIsNaN:Number.isNaN,NumberMAX_SAFE_INTEGER:Number.MAX_SAFE_INTEGER,NumberMIN_SAFE_INTEGER:Number.MIN_SAFE_INTEGER,NumberParseInt:Number.parseInt,ObjectDefineProperties:(e,t)=>Object.defineProperties(e,t),ObjectDefineProperty:(e,t,n)=>Object.defineProperty(e,t,n),ObjectGetOwnPropertyDescriptor:(e,t)=>Object.getOwnPropertyDescriptor(e,t),ObjectKeys:e=>Object.keys(e),ObjectSetPrototypeOf:(e,t)=>Object.setPrototypeOf(e,t),Promise:Promise,PromisePrototypeCatch:(e,t)=>e.catch(t),PromisePrototypeThen:(e,t,n)=>e.then(t,n),PromiseReject:e=>Promise.reject(e),PromiseResolve:e=>Promise.resolve(e),ReflectApply:Reflect.apply,RegExpPrototypeTest:(e,t)=>e.test(t),SafeSet:Set,String:String,StringPrototypeSlice:(e,t,n)=>e.slice(t,n),StringPrototypeToLowerCase:e=>e.toLowerCase(),StringPrototypeToUpperCase:e=>e.toUpperCase(),StringPrototypeTrim:e=>e.trim(),Symbol:Symbol,SymbolFor:Symbol.for,SymbolAsyncIterator:Symbol.asyncIterator,SymbolHasInstance:Symbol.hasInstance,SymbolIterator:Symbol.iterator,SymbolDispose:Symbol.dispose||Symbol("Symbol.dispose"),SymbolAsyncDispose:Symbol.asyncDispose||Symbol("Symbol.asyncDispose"),TypedArrayPrototypeSet:(e,t,n)=>e.set(t,n),Boolean:Boolean,Uint8Array:Uint8Array}}var le,pe,ue,me,he={exports:{}};function ge(){return pe?le:(pe=1,le={format:(e,...t)=>e.replace(/%([sdifj])/g,function(...[e,n]){const i=t.shift();return"f"===n?i.toFixed(6):"j"===n?JSON.stringify(i):"s"===n&&"object"==typeof i?`${i.constructor!==Object?i.constructor.name:""} {}`.trim():i.toString()}),inspect(e){switch(typeof e){case"string":if(e.includes("'")){if(!e.includes('"'))return`"${e}"`;if(!e.includes("`")&&!e.includes("${"))return`\`${e}\``}return`'${e}'`;case"number":return isNaN(e)?"NaN":Object.is(e,-0)?String(e):e;case"bigint":return`${String(e)}n`;case"boolean":case"undefined":return String(e);case"object":return"{}"}}})}function fe(){if(me)return ue;me=1;const{format:e,inspect:t}=ge(),{AggregateError:n}=de(),i=globalThis.AggregateError||n,s=Symbol("kIsNodeError"),a=["string","function","number","object","Function","Object","boolean","bigint","symbol"],o=/^([A-Z][a-z0-9]*)+$/,r={};function c(e,t){if(!e)throw new r.ERR_INTERNAL_ASSERTION(t)}function d(e){let t="",n=e.length;const i="-"===e[0]?1:0;for(;n>=i+4;n-=3)t=`_${e.slice(n-3,n)}${t}`;return`${e.slice(0,n)}${t}`}function l(t,n,i){i||(i=Error);class a extends i{constructor(...i){super(function(t,n,i){if("function"==typeof n)return c(n.length<=i.length,`Code: ${t}; The provided arguments length (${i.length}) does not match the required ones (${n.length}).`),n(...i);const s=(n.match(/%[dfijoOs]/g)||[]).length;return c(s===i.length,`Code: ${t}; The provided arguments length (${i.length}) does not match the required ones (${s}).`),0===i.length?n:e(n,...i)}(t,n,i))}toString(){return`${this.name} [${t}]: ${this.message}`}}Object.defineProperties(a.prototype,{name:{value:i.name,writable:!0,enumerable:!1,configurable:!0},toString:{value(){return`${this.name} [${t}]: ${this.message}`},writable:!0,enumerable:!1,configurable:!0}}),a.prototype.code=t,a.prototype[s]=!0,r[t]=a}function p(e){const t="__node_internal_"+e.name;return Object.defineProperty(e,"name",{value:t}),e}class u extends Error{constructor(e="The operation was aborted",t=void 0){if(void 0!==t&&"object"!=typeof t)throw new r.ERR_INVALID_ARG_TYPE("options","Object",t);super(e,t),this.code="ABORT_ERR",this.name="AbortError"}}return l("ERR_ASSERTION","%s",Error),l("ERR_INVALID_ARG_TYPE",(e,n,i)=>{c("string"==typeof e,"'name' must be a string"),Array.isArray(n)||(n=[n]);let s="The ";e.endsWith(" argument")?s+=`${e} `:s+=`"${e}" ${e.includes(".")?"property":"argument"} `,s+="must be ";const r=[],d=[],l=[];for(const e of n)c("string"==typeof e,"All expected entries have to be of type string"),a.includes(e)?r.push(e.toLowerCase()):o.test(e)?d.push(e):(c("object"!==e,'The value "object" should be written as "Object"'),l.push(e));if(d.length>0){const e=r.indexOf("object");-1!==e&&(r.splice(r,e,1),d.push("Object"))}if(r.length>0){switch(r.length){case 1:s+=`of type ${r[0]}`;break;case 2:s+=`one of type ${r[0]} or ${r[1]}`;break;default:{const e=r.pop();s+=`one of type ${r.join(", ")}, or ${e}`}}(d.length>0||l.length>0)&&(s+=" or ")}if(d.length>0){switch(d.length){case 1:s+=`an instance of ${d[0]}`;break;case 2:s+=`an instance of ${d[0]} or ${d[1]}`;break;default:{const e=d.pop();s+=`an instance of ${d.join(", ")}, or ${e}`}}l.length>0&&(s+=" or ")}switch(l.length){case 0:break;case 1:l[0].toLowerCase()!==l[0]&&(s+="an "),s+=`${l[0]}`;break;case 2:s+=`one of ${l[0]} or ${l[1]}`;break;default:{const e=l.pop();s+=`one of ${l.join(", ")}, or ${e}`}}if(null==i)s+=`. Received ${i}`;else if("function"==typeof i&&i.name)s+=`. Received function ${i.name}`;else if("object"==typeof i){var p;null!==(p=i.constructor)&&void 0!==p&&p.name?s+=`. Received an instance of ${i.constructor.name}`:s+=`. Received ${t(i,{depth:-1})}`}else{let e=t(i,{colors:!1});e.length>25&&(e=`${e.slice(0,25)}...`),s+=`. Received type ${typeof i} (${e})`}return s},TypeError),l("ERR_INVALID_ARG_VALUE",(e,n,i="is invalid")=>{let s=t(n);return s.length>128&&(s=s.slice(0,128)+"..."),`The ${e.includes(".")?"property":"argument"} '${e}' ${i}. Received ${s}`},TypeError),l("ERR_INVALID_RETURN_VALUE",(e,t,n)=>{var i;return`Expected ${e} to be returned from the "${t}" function but got ${null!=n&&null!==(i=n.constructor)&&void 0!==i&&i.name?`instance of ${n.constructor.name}`:"type "+typeof n}.`},TypeError),l("ERR_MISSING_ARGS",(...e)=>{let t;c(e.length>0,"At least one arg needs to be specified");const n=e.length;switch(e=(Array.isArray(e)?e:[e]).map(e=>`"${e}"`).join(" or "),n){case 1:t+=`The ${e[0]} argument`;break;case 2:t+=`The ${e[0]} and ${e[1]} arguments`;break;default:{const n=e.pop();t+=`The ${e.join(", ")}, and ${n} arguments`}}return`${t} must be specified`},TypeError),l("ERR_OUT_OF_RANGE",(e,n,i)=>{let s;if(c(n,'Missing "range" argument'),Number.isInteger(i)&&Math.abs(i)>2**32)s=d(String(i));else if("bigint"==typeof i){s=String(i);const e=BigInt(2)**BigInt(32);(i>e||i<-e)&&(s=d(s)),s+="n"}else s=t(i);return`The value of "${e}" is out of range. It must be ${n}. Received ${s}`},RangeError),l("ERR_MULTIPLE_CALLBACK","Callback called multiple times",Error),l("ERR_METHOD_NOT_IMPLEMENTED","The %s method is not implemented",Error),l("ERR_STREAM_ALREADY_FINISHED","Cannot call %s after a stream was finished",Error),l("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable",Error),l("ERR_STREAM_DESTROYED","Cannot call %s after a stream was destroyed",Error),l("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError),l("ERR_STREAM_PREMATURE_CLOSE","Premature close",Error),l("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF",Error),l("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event",Error),l("ERR_STREAM_WRITE_AFTER_END","write after end",Error),l("ERR_UNKNOWN_ENCODING","Unknown encoding: %s",TypeError),ue={AbortError:u,aggregateTwoErrors:p(function(e,t){if(e&&t&&e!==t){if(Array.isArray(t.errors))return t.errors.push(e),t;const n=new i([t,e],t.message);return n.code=t.code,n}return e||t}),hideStackFrames:p,codes:r}}const ye=new WeakMap,be=new WeakMap;function ve(e){const t=ye.get(e);return console.assert(null!=t,"'this' is expected an Event object, but got",e),t}function Ie(e){null==e.passiveListener?e.event.cancelable&&(e.canceled=!0,"function"==typeof e.event.preventDefault&&e.event.preventDefault()):"undefined"!=typeof console&&"function"==typeof console.error&&console.error("Unable to preventDefault inside passive event listener invocation.",e.passiveListener)}function xe(e,t){ye.set(this,{eventTarget:e,event:t,eventPhase:2,currentTarget:e,canceled:!1,stopped:!1,immediateStopped:!1,passiveListener:null,timeStamp:t.timeStamp||Date.now()}),Object.defineProperty(this,"isTrusted",{value:!1,enumerable:!0});const n=Object.keys(t);for(let e=0;e<n.length;++e){const t=n[e];t in this||Object.defineProperty(this,t,we(t))}}function we(e){return{get(){return ve(this).event[e]},set(t){ve(this).event[e]=t},configurable:!0,enumerable:!0}}function Se(e){return{value(){const t=ve(this).event;return t[e].apply(t,arguments)},configurable:!0,enumerable:!0}}function Ae(e){if(null==e||e===Object.prototype)return xe;let t=be.get(e);return null==t&&(t=function(e,t){const n=Object.keys(t);if(0===n.length)return e;function i(t,n){e.call(this,t,n)}i.prototype=Object.create(e.prototype,{constructor:{value:i,configurable:!0,writable:!0}});for(let s=0;s<n.length;++s){const a=n[s];if(!(a in e.prototype)){const e="function"==typeof Object.getOwnPropertyDescriptor(t,a).value;Object.defineProperty(i.prototype,a,e?Se(a):we(a))}}return i}(Ae(Object.getPrototypeOf(e)),e),be.set(e,t)),t}function Ee(e){return ve(e).immediateStopped}function _e(e,t){ve(e).passiveListener=t}xe.prototype={get type(){return ve(this).event.type},get target(){return ve(this).eventTarget},get currentTarget(){return ve(this).currentTarget},composedPath(){const e=ve(this).currentTarget;return null==e?[]:[e]},get NONE(){return 0},get CAPTURING_PHASE(){return 1},get AT_TARGET(){return 2},get BUBBLING_PHASE(){return 3},get eventPhase(){return ve(this).eventPhase},stopPropagation(){const e=ve(this);e.stopped=!0,"function"==typeof e.event.stopPropagation&&e.event.stopPropagation()},stopImmediatePropagation(){const e=ve(this);e.stopped=!0,e.immediateStopped=!0,"function"==typeof e.event.stopImmediatePropagation&&e.event.stopImmediatePropagation()},get bubbles(){return Boolean(ve(this).event.bubbles)},get cancelable(){return Boolean(ve(this).event.cancelable)},preventDefault(){Ie(ve(this))},get defaultPrevented(){return ve(this).canceled},get composed(){return Boolean(ve(this).event.composed)},get timeStamp(){return ve(this).timeStamp},get srcElement(){return ve(this).eventTarget},get cancelBubble(){return ve(this).stopped},set cancelBubble(e){if(!e)return;const t=ve(this);t.stopped=!0,"boolean"==typeof t.event.cancelBubble&&(t.event.cancelBubble=!0)},get returnValue(){return!ve(this).canceled},set returnValue(e){e||Ie(ve(this))},initEvent(){}},Object.defineProperty(xe.prototype,"constructor",{value:xe,configurable:!0,writable:!0}),"undefined"!=typeof window&&void 0!==window.Event&&(Object.setPrototypeOf(xe.prototype,window.Event.prototype),be.set(window.Event.prototype,xe));const Te=new WeakMap;function ze(e){return null!==e&&"object"==typeof e}function ke(e){const t=Te.get(e);if(null==t)throw new TypeError("'this' is expected an EventTarget object, but got another value.");return t}function Ne(e,t){Object.defineProperty(e,`on${t}`,function(e){return{get(){let t=ke(this).get(e);for(;null!=t;){if(3===t.listenerType)return t.listener;t=t.next}return null},set(t){"function"==typeof t||ze(t)||(t=null);const n=ke(this);let i=null,s=n.get(e);for(;null!=s;)3===s.listenerType?null!==i?i.next=s.next:null!==s.next?n.set(e,s.next):n.delete(e):i=s,s=s.next;if(null!==t){const s={listener:t,listenerType:3,passive:!1,once:!1,next:null};null===i?n.set(e,s):i.next=s}},configurable:!0,enumerable:!0}}(t))}function Ce(e){function t(){Re.call(this)}t.prototype=Object.create(Re.prototype,{constructor:{value:t,configurable:!0,writable:!0}});for(let n=0;n<e.length;++n)Ne(t.prototype,e[n]);return t}function Re(){if(!(this instanceof Re)){if(1===arguments.length&&Array.isArray(arguments[0]))return Ce(arguments[0]);if(arguments.length>0){const e=new Array(arguments.length);for(let t=0;t<arguments.length;++t)e[t]=arguments[t];return Ce(e)}throw new TypeError("Cannot call a class as a function")}Te.set(this,new Map)}Re.prototype={addEventListener(e,t,n){if(null==t)return;if("function"!=typeof t&&!ze(t))throw new TypeError("'listener' should be a function or an object.");const i=ke(this),s=ze(n),a=(s?Boolean(n.capture):Boolean(n))?1:2,o={listener:t,listenerType:a,passive:s&&Boolean(n.passive),once:s&&Boolean(n.once),next:null};let r=i.get(e);if(void 0===r)return void i.set(e,o);let c=null;for(;null!=r;){if(r.listener===t&&r.listenerType===a)return;c=r,r=r.next}c.next=o},removeEventListener(e,t,n){if(null==t)return;const i=ke(this),s=(ze(n)?Boolean(n.capture):Boolean(n))?1:2;let a=null,o=i.get(e);for(;null!=o;){if(o.listener===t&&o.listenerType===s)return void(null!==a?a.next=o.next:null!==o.next?i.set(e,o.next):i.delete(e));a=o,o=o.next}},dispatchEvent(e){if(null==e||"string"!=typeof e.type)throw new TypeError('"event.type" should be a string.');const t=ke(this),n=e.type;let i=t.get(n);if(null==i)return!0;const s=function(e,t){return new(Ae(Object.getPrototypeOf(t)))(e,t)}(this,e);let a=null;for(;null!=i;){if(i.once?null!==a?a.next=i.next:null!==i.next?t.set(n,i.next):t.delete(n):a=i,_e(s,i.passive?i.listener:null),"function"==typeof i.listener)try{i.listener.call(this,s)}catch(e){"undefined"!=typeof console&&"function"==typeof console.error&&console.error(e)}else 3!==i.listenerType&&"function"==typeof i.listener.handleEvent&&i.listener.handleEvent(s);if(Ee(s))break;i=i.next}return _e(s,null),function(e){ve(e).eventPhase=0}(s),function(e){ve(e).currentTarget=null}(s),!s.defaultPrevented}},Object.defineProperty(Re.prototype,"constructor",{value:Re,configurable:!0,writable:!0}),"undefined"!=typeof window&&void 0!==window.EventTarget&&Object.setPrototypeOf(Re.prototype,window.EventTarget.prototype);let Oe=class extends Re{constructor(){throw super(),new TypeError("AbortSignal cannot be constructed directly")}get aborted(){const e=je.get(this);if("boolean"!=typeof e)throw new TypeError("Expected 'this' to be an 'AbortSignal' object, but got "+(null===this?"null":typeof this));return e}};Ne(Oe.prototype,"abort");const je=new WeakMap;Object.defineProperties(Oe.prototype,{aborted:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(Oe.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortSignal"});let Pe=class{constructor(){De.set(this,function(){const e=Object.create(Oe.prototype);return Re.call(e),je.set(e,!1),e}())}get signal(){return Le(this)}abort(){var e;e=Le(this),!1===je.get(e)&&(je.set(e,!0),e.dispatchEvent({type:"abort"}))}};const De=new WeakMap;function Le(e){const t=De.get(e);if(null==t)throw new TypeError("Expected 'this' to be an 'AbortController' object, but got "+(null===e?"null":typeof e));return t}Object.defineProperties(Pe.prototype,{signal:{enumerable:!0},abort:{enumerable:!0}}),"function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag&&Object.defineProperty(Pe.prototype,Symbol.toStringTag,{configurable:!0,value:"AbortController"});var Me,qe=B(Object.freeze({__proto__:null,AbortController:Pe,AbortSignal:Oe,default:Pe}));function Ue(){return Me||(Me=1,function(e){const t=p,{format:n,inspect:i}=ge(),{codes:{ERR_INVALID_ARG_TYPE:s}}=fe(),{kResistStopPropagation:a,AggregateError:o,SymbolDispose:r}=de(),c=globalThis.AbortSignal||qe.AbortSignal,d=globalThis.AbortController||qe.AbortController,l=Object.getPrototypeOf(async function(){}).constructor,m=globalThis.Blob||t.Blob,h=void 0!==m?function(e){return e instanceof m}:function(e){return!1},g=(e,t)=>{if(void 0!==e&&(null===e||"object"!=typeof e||!("aborted"in e)))throw new s(t,"AbortSignal",e)};e.exports={AggregateError:o,kEmptyObject:Object.freeze({}),once(e){let t=!1;return function(...n){t||(t=!0,e.apply(this,n))}},createDeferredPromise:function(){let e,t;return{promise:new Promise((n,i)=>{e=n,t=i}),resolve:e,reject:t}},promisify:e=>new Promise((t,n)=>{e((e,...i)=>e?n(e):t(...i))}),debuglog:()=>function(){},format:n,inspect:i,types:{isAsyncFunction:e=>e instanceof l,isArrayBufferView:e=>ArrayBuffer.isView(e)},isBlob:h,deprecate:(e,t)=>e,addAbortListener:u.addAbortListener||function(e,t){if(void 0===e)throw new s("signal","AbortSignal",e);let n;return g(e,"signal"),(e=>{if("function"!=typeof e)throw new s("listener","Function",e)})(t),e.aborted?queueMicrotask(()=>t()):(e.addEventListener("abort",t,{__proto__:null,once:!0,[a]:!0}),n=()=>{e.removeEventListener("abort",t)}),{__proto__:null,[r](){var e;null===(e=n)||void 0===e||e()}}},AbortSignalAny:c.any||function(e){if(1===e.length)return e[0];const t=new d,n=()=>t.abort();return e.forEach(e=>{g(e,"signals"),e.addEventListener("abort",n,{once:!0})}),t.signal.addEventListener("abort",()=>{e.forEach(e=>e.removeEventListener("abort",n))},{once:!0}),t.signal}},e.exports.promisify.custom=Symbol.for("nodejs.util.promisify.custom")}(he)),he.exports}var $e,Be,Fe={};function He(){if(Be)return $e;Be=1;const{ArrayIsArray:e,ArrayPrototypeIncludes:t,ArrayPrototypeJoin:n,ArrayPrototypeMap:i,NumberIsInteger:s,NumberIsNaN:a,NumberMAX_SAFE_INTEGER:o,NumberMIN_SAFE_INTEGER:r,NumberParseInt:c,ObjectPrototypeHasOwnProperty:d,RegExpPrototypeExec:l,String:p,StringPrototypeToUpperCase:u,StringPrototypeTrim:m}=de(),{hideStackFrames:h,codes:{ERR_SOCKET_BAD_PORT:g,ERR_INVALID_ARG_TYPE:f,ERR_INVALID_ARG_VALUE:y,ERR_OUT_OF_RANGE:b,ERR_UNKNOWN_SIGNAL:v}}=fe(),{normalizeEncoding:I}=Ue(),{isAsyncFunction:x,isArrayBufferView:w}=Ue().types,S={},A=/^[0-7]+$/,E=h((e,t,n=r,i=o)=>{if("number"!=typeof e)throw new f(t,"number",e);if(!s(e))throw new b(t,"an integer",e);if(e<n||e>i)throw new b(t,`>= ${n} && <= ${i}`,e)}),_=h((e,t,n=-2147483648,i=2147483647)=>{if("number"!=typeof e)throw new f(t,"number",e);if(!s(e))throw new b(t,"an integer",e);if(e<n||e>i)throw new b(t,`>= ${n} && <= ${i}`,e)}),T=h((e,t,n=!1)=>{if("number"!=typeof e)throw new f(t,"number",e);if(!s(e))throw new b(t,"an integer",e);const i=n?1:0,a=4294967295;if(e<i||e>a)throw new b(t,`>= ${i} && <= ${a}`,e)});function z(e,t){if("string"!=typeof e)throw new f(t,"string",e)}const k=h((e,s,a)=>{if(!t(a,e)){const t=n(i(a,e=>"string"==typeof e?`'${e}'`:p(e)),", ");throw new y(s,e,"must be one of: "+t)}});function N(e,t){if("boolean"!=typeof e)throw new f(t,"boolean",e)}function C(e,t,n){return null!=e&&d(e,t)?e[t]:n}const R=h((t,n,i=null)=>{const s=C(i,"allowArray",!1),a=C(i,"allowFunction",!1);if(!C(i,"nullable",!1)&&null===t||!s&&e(t)||"object"!=typeof t&&(!a||"function"!=typeof t))throw new f(n,"Object",t)}),O=h((e,t)=>{if(null!=e&&"object"!=typeof e&&"function"!=typeof e)throw new f(t,"a dictionary",e)}),j=h((t,n,i=0)=>{if(!e(t))throw new f(n,"Array",t);if(t.length<i)throw new y(n,t,`must be longer than ${i}`)}),P=h((e,t="buffer")=>{if(!w(e))throw new f(t,["Buffer","TypedArray","DataView"],e)}),D=h((e,t)=>{if(void 0!==e&&(null===e||"object"!=typeof e||!("aborted"in e)))throw new f(t,"AbortSignal",e)}),L=h((e,t)=>{if("function"!=typeof e)throw new f(t,"Function",e)}),M=h((e,t)=>{if("function"!=typeof e||x(e))throw new f(t,"Function",e)}),q=h((e,t)=>{if(void 0!==e)throw new f(t,"undefined",e)}),U=/^(?:<[^>]*>)(?:\s*;\s*[^;"\s]+(?:=(")?[^;"\s]*\1)?)*$/;function $(e,t){if(void 0===e||!l(U,e))throw new y(t,e,'must be an array or string of format "</styles.css>; rel=preload; as=style"')}return $e={isInt32:function(e){return e===(0|e)},isUint32:function(e){return e===e>>>0},parseFileMode:function(e,t,n){if(void 0===e&&(e=n),"string"==typeof e){if(null===l(A,e))throw new y(t,e,"must be a 32-bit unsigned integer or an octal string");e=c(e,8)}return T(e,t),e},validateArray:j,validateStringArray:function(e,t){j(e,t);for(let n=0;n<e.length;n++)z(e[n],`${t}[${n}]`)},validateBooleanArray:function(e,t){j(e,t);for(let n=0;n<e.length;n++)N(e[n],`${t}[${n}]`)},validateAbortSignalArray:function(e,t){j(e,t);for(let n=0;n<e.length;n++){const i=e[n],s=`${t}[${n}]`;if(null==i)throw new f(s,"AbortSignal",i);D(i,s)}},validateBoolean:N,validateBuffer:P,validateDictionary:O,validateEncoding:function(e,t){const n=I(t),i=e.length;if("hex"===n&&i%2!=0)throw new y("encoding",t,`is invalid for data of length ${i}`)},validateFunction:L,validateInt32:_,validateInteger:E,validateNumber:function(e,t,n=void 0,i){if("number"!=typeof e)throw new f(t,"number",e);if(null!=n&&e<n||null!=i&&e>i||(null!=n||null!=i)&&a(e))throw new b(t,`${null!=n?`>= ${n}`:""}${null!=n&&null!=i?" && ":""}${null!=i?`<= ${i}`:""}`,e)},validateObject:R,validateOneOf:k,validatePlainFunction:M,validatePort:function(e,t="Port",n=!0){if("number"!=typeof e&&"string"!=typeof e||"string"==typeof e&&0===m(e).length||+e!==+e>>>0||e>65535||0===e&&!n)throw new g(t,e,n);return 0|e},validateSignalName:function(e,t="signal"){if(z(e,t),void 0===S[e]){if(void 0!==S[u(e)])throw new v(e+" (signals must use all capital letters)");throw new v(e)}},validateString:z,validateUint32:T,validateUndefined:q,validateUnion:function(e,i,s){if(!t(s,e))throw new f(i,`('${n(s,"|")}')`,e)},validateAbortSignal:D,validateLinkHeaderValue:function(t){if("string"==typeof t)return $(t,"hints"),t;if(e(t)){const e=t.length;let n="";if(0===e)return n;for(let i=0;i<e;i++){const s=t[i];$(s,"hints"),n+=s,i!==e-1&&(n+=", ")}return n}throw new y("hints",t,'must be an array or string of format "</styles.css>; rel=preload; as=style"')}}}var Ge,We,Ve,Ke,Ye,Xe,Je,Qe,Ze,et={exports:{}};function tt(){return We?Ge:(We=1,Ge=U.process)}function nt(){if(Ke)return Ve;Ke=1;const{SymbolAsyncIterator:e,SymbolIterator:t,SymbolFor:n}=de(),i=n("nodejs.stream.destroyed"),s=n("nodejs.stream.errored"),a=n("nodejs.stream.readable"),o=n("nodejs.stream.writable"),r=n("nodejs.stream.disturbed"),c=n("nodejs.webstream.isClosedPromise"),d=n("nodejs.webstream.controllerErrorFunction");function l(e,t=!1){var n;return!(!e||"function"!=typeof e.pipe||"function"!=typeof e.on||t&&("function"!=typeof e.pause||"function"!=typeof e.resume)||e._writableState&&!1===(null===(n=e._readableState)||void 0===n?void 0:n.readable)||e._writableState&&!e._readableState)}function p(e){var t;return!(!e||"function"!=typeof e.write||"function"!=typeof e.on||e._readableState&&!1===(null===(t=e._writableState)||void 0===t?void 0:t.writable))}function u(e){return e&&(e._readableState||e._writableState||"function"==typeof e.write&&"function"==typeof e.on||"function"==typeof e.pipe&&"function"==typeof e.on)}function m(e){return!(!e||u(e)||"function"!=typeof e.pipeThrough||"function"!=typeof e.getReader||"function"!=typeof e.cancel)}function h(e){return!(!e||u(e)||"function"!=typeof e.getWriter||"function"!=typeof e.abort)}function g(e){return!(!e||u(e)||"object"!=typeof e.readable||"object"!=typeof e.writable)}function f(e){if(!u(e))return null;const t=e._writableState,n=e._readableState,s=t||n;return!!(e.destroyed||e[i]||null!=s&&s.destroyed)}function y(e){if(!p(e))return null;if(!0===e.writableEnded)return!0;const t=e._writableState;return(null==t||!t.errored)&&("boolean"!=typeof(null==t?void 0:t.ended)?null:t.ended)}function b(e,t){if(!l(e))return null;const n=e._readableState;return(null==n||!n.errored)&&("boolean"!=typeof(null==n?void 0:n.endEmitted)?null:!!(n.endEmitted||!1===t&&!0===n.ended&&0===n.length))}function v(e){return e&&null!=e[a]?e[a]:"boolean"!=typeof(null==e?void 0:e.readable)?null:!f(e)&&l(e)&&e.readable&&!b(e)}function I(e){return e&&null!=e[o]?e[o]:"boolean"!=typeof(null==e?void 0:e.writable)?null:!f(e)&&p(e)&&e.writable&&!y(e)}function x(e){return"boolean"==typeof e._closed&&"boolean"==typeof e._defaultKeepAlive&&"boolean"==typeof e._removedConnection&&"boolean"==typeof e._removedContLen}function w(e){return"boolean"==typeof e._sent100&&x(e)}return Ve={isDestroyed:f,kIsDestroyed:i,isDisturbed:function(e){var t;return!(!e||!(null!==(t=e[r])&&void 0!==t?t:e.readableDidRead||e.readableAborted))},kIsDisturbed:r,isErrored:function(e){var t,n,i,a,o,r,c,d,l,p;return!(!e||!(null!==(t=null!==(n=null!==(i=null!==(a=null!==(o=null!==(r=e[s])&&void 0!==r?r:e.readableErrored)&&void 0!==o?o:e.writableErrored)&&void 0!==a?a:null===(c=e._readableState)||void 0===c?void 0:c.errorEmitted)&&void 0!==i?i:null===(d=e._writableState)||void 0===d?void 0:d.errorEmitted)&&void 0!==n?n:null===(l=e._readableState)||void 0===l?void 0:l.errored)&&void 0!==t?t:null===(p=e._writableState)||void 0===p?void 0:p.errored))},kIsErrored:s,isReadable:v,kIsReadable:a,kIsClosedPromise:c,kControllerErrorFunction:d,kIsWritable:o,isClosed:function(e){if(!u(e))return null;if("boolean"==typeof e.closed)return e.closed;const t=e._writableState,n=e._readableState;return"boolean"==typeof(null==t?void 0:t.closed)||"boolean"==typeof(null==n?void 0:n.closed)?(null==t?void 0:t.closed)||(null==n?void 0:n.closed):"boolean"==typeof e._closed&&x(e)?e._closed:null},isDuplexNodeStream:function(e){return!(!e||"function"!=typeof e.pipe||!e._readableState||"function"!=typeof e.on||"function"!=typeof e.write)},isFinished:function(e,t){return u(e)?!(!f(e)&&(!1!==(null==t?void 0:t.readable)&&v(e)||!1!==(null==t?void 0:t.writable)&&I(e))):null},isIterable:function(n,i){return null!=n&&(!0===i?"function"==typeof n[e]:!1===i?"function"==typeof n[t]:"function"==typeof n[e]||"function"==typeof n[t])},isReadableNodeStream:l,isReadableStream:m,isReadableEnded:function(e){if(!l(e))return null;if(!0===e.readableEnded)return!0;const t=e._readableState;return!(!t||t.errored)&&("boolean"!=typeof(null==t?void 0:t.ended)?null:t.ended)},isReadableFinished:b,isReadableErrored:function(e){var t,n;return u(e)?e.readableErrored?e.readableErrored:null!==(t=null===(n=e._readableState)||void 0===n?void 0:n.errored)&&void 0!==t?t:null:null},isNodeStream:u,isWebStream:function(e){return m(e)||h(e)||g(e)},isWritable:I,isWritableNodeStream:p,isWritableStream:h,isWritableEnded:y,isWritableFinished:function(e,t){if(!p(e))return null;if(!0===e.writableFinished)return!0;const n=e._writableState;return(null==n||!n.errored)&&("boolean"!=typeof(null==n?void 0:n.finished)?null:!!(n.finished||!1===t&&!0===n.ended&&0===n.length))},isWritableErrored:function(e){var t,n;return u(e)?e.writableErrored?e.writableErrored:null!==(t=null===(n=e._writableState)||void 0===n?void 0:n.errored)&&void 0!==t?t:null:null},isServerRequest:function(e){var t;return"boolean"==typeof e._consuming&&"boolean"==typeof e._dumped&&void 0===(null===(t=e.req)||void 0===t?void 0:t.upgradeOrConnect)},isServerResponse:w,willEmitClose:function(e){if(!u(e))return null;const t=e._writableState,n=e._readableState,i=t||n;return!i&&w(e)||!!(i&&i.autoDestroy&&i.emitClose&&!1===i.closed)},isTransformStream:g},Ve}function it(){if(Ye)return et.exports;Ye=1;const e=tt(),{AbortError:t,codes:n}=fe(),{ERR_INVALID_ARG_TYPE:i,ERR_STREAM_PREMATURE_CLOSE:s}=n,{kEmptyObject:a,once:o}=Ue(),{validateAbortSignal:r,validateFunction:c,validateObject:d,validateBoolean:l}=He(),{Promise:p,PromisePrototypeThen:u,SymbolDispose:m}=de(),{isClosed:h,isReadable:g,isReadableNodeStream:f,isReadableStream:y,isReadableFinished:b,isReadableErrored:v,isWritable:I,isWritableNodeStream:x,isWritableStream:w,isWritableFinished:S,isWritableErrored:A,isNodeStream:E,willEmitClose:_,kIsClosedPromise:T}=nt();let z;const k=()=>{};function N(n,l,p){var N,C;if(2===arguments.length?(p=l,l=a):null==l?l=a:d(l,"options"),c(p,"callback"),r(l.signal,"options.signal"),p=o(p),y(n)||w(n))return function(n,i,s){let a=!1,r=k;if(i.signal)if(r=()=>{a=!0,s.call(n,new t(void 0,{cause:i.signal.reason}))},i.signal.aborted)e.nextTick(r);else{z=z||Ue().addAbortListener;const e=z(i.signal,r),t=s;s=o((...i)=>{e[m](),t.apply(n,i)})}const c=(...t)=>{a||e.nextTick(()=>s.apply(n,t))};return u(n[T].promise,c,c),k}(n,l,p);if(!E(n))throw new i("stream",["ReadableStream","WritableStream","Stream"],n);const R=null!==(N=l.readable)&&void 0!==N?N:f(n),O=null!==(C=l.writable)&&void 0!==C?C:x(n),j=n._writableState,P=n._readableState,D=()=>{n.writable||q()};let L=_(n)&&f(n)===R&&x(n)===O,M=S(n,!1);const q=()=>{M=!0,n.destroyed&&(L=!1),(!L||n.readable&&!R)&&(R&&!U||p.call(n))};let U=b(n,!1);const $=()=>{U=!0,n.destroyed&&(L=!1),(!L||n.writable&&!O)&&(O&&!M||p.call(n))},B=e=>{p.call(n,e)};let F=h(n);const H=()=>{F=!0;const e=A(n)||v(n);return e&&"boolean"!=typeof e?p.call(n,e):R&&!U&&f(n,!0)&&!b(n,!1)?p.call(n,new s):!O||M||S(n,!1)?void p.call(n):p.call(n,new s)},G=()=>{F=!0;const e=A(n)||v(n);if(e&&"boolean"!=typeof e)return p.call(n,e);p.call(n)},W=()=>{n.req.on("finish",q)};!function(e){return e.setHeader&&"function"==typeof e.abort}(n)?O&&!j&&(n.on("end",D),n.on("close",D)):(n.on("complete",q),L||n.on("abort",H),n.req?W():n.on("request",W)),L||"boolean"!=typeof n.aborted||n.on("aborted",H),n.on("end",$),n.on("finish",q),!1!==l.error&&n.on("error",B),n.on("close",H),F?e.nextTick(H):null!=j&&j.errorEmitted||null!=P&&P.errorEmitted?L||e.nextTick(G):(R||L&&!g(n)||!M&&!1!==I(n))&&(O||L&&!I(n)||!U&&!1!==g(n))?P&&n.req&&n.aborted&&e.nextTick(G):e.nextTick(G);const V=()=>{p=k,n.removeListener("aborted",H),n.removeListener("complete",q),n.removeListener("abort",H),n.removeListener("request",W),n.req&&n.req.removeListener("finish",q),n.removeListener("end",D),n.removeListener("close",D),n.removeListener("finish",q),n.removeListener("end",$),n.removeListener("error",B),n.removeListener("close",H)};if(l.signal&&!F){const i=()=>{const e=p;V(),e.call(n,new t(void 0,{cause:l.signal.reason}))};if(l.signal.aborted)e.nextTick(i);else{z=z||Ue().addAbortListener;const e=z(l.signal,i),t=p;p=o((...i)=>{e[m](),t.apply(n,i)})}}return V}return et.exports=N,et.exports.finished=function(e,t){var n;let i=!1;return null===t&&(t=a),null!==(n=t)&&void 0!==n&&n.cleanup&&(l(t.cleanup,"cleanup"),i=t.cleanup),new p((n,s)=>{const a=N(e,t,e=>{i&&a(),e?s(e):n()})})},et.exports}function st(){if(Je)return Xe;Je=1;const e=tt(),{aggregateTwoErrors:t,codes:{ERR_MULTIPLE_CALLBACK:n},AbortError:i}=fe(),{Symbol:s}=de(),{kIsDestroyed:a,isDestroyed:o,isFinished:r,isServerRequest:c}=nt(),d=s("kDestroy"),l=s("kConstruct");function p(e,t,n){e&&(e.stack,t&&!t.errored&&(t.errored=e),n&&!n.errored&&(n.errored=e))}function u(t,n,i){let s=!1;function a(n){if(s)return;s=!0;const a=t._readableState,o=t._writableState;p(n,o,a),o&&(o.closed=!0),a&&(a.closed=!0),"function"==typeof i&&i(n),n?e.nextTick(m,t,n):e.nextTick(h,t)}try{t._destroy(n||null,a)}catch(n){a(n)}}function m(e,t){g(e,t),h(e)}function h(e){const t=e._readableState,n=e._writableState;n&&(n.closeEmitted=!0),t&&(t.closeEmitted=!0),(null!=n&&n.emitClose||null!=t&&t.emitClose)&&e.emit("close")}function g(e,t){const n=e._readableState,i=e._writableState;null!=i&&i.errorEmitted||null!=n&&n.errorEmitted||(i&&(i.errorEmitted=!0),n&&(n.errorEmitted=!0),e.emit("error",t))}function f(t,n,i){const s=t._readableState,a=t._writableState;if(null!=a&&a.destroyed||null!=s&&s.destroyed)return this;null!=s&&s.autoDestroy||null!=a&&a.autoDestroy?t.destroy(n):n&&(n.stack,a&&!a.errored&&(a.errored=n),s&&!s.errored&&(s.errored=n),i?e.nextTick(g,t,n):g(t,n))}function y(t){let i=!1;function s(s){if(i)return void f(t,null!=s?s:new n);i=!0;const a=t._readableState,o=t._writableState,r=o||a;a&&(a.constructed=!0),o&&(o.constructed=!0),r.destroyed?t.emit(d,s):s?f(t,s,!0):e.nextTick(b,t)}try{t._construct(t=>{e.nextTick(s,t)})}catch(t){e.nextTick(s,t)}}function b(e){e.emit(l)}function v(e){return(null==e?void 0:e.setHeader)&&"function"==typeof e.abort}function I(e){e.emit("close")}function x(t,n){t.emit("error",n),e.nextTick(I,t)}return Xe={construct:function(t,n){if("function"!=typeof t._construct)return;const i=t._readableState,s=t._writableState;i&&(i.constructed=!1),s&&(s.constructed=!1),t.once(l,n),t.listenerCount(l)>1||e.nextTick(y,t)},destroyer:function(t,n){t&&!o(t)&&(n||r(t)||(n=new i),c(t)?(t.socket=null,t.destroy(n)):v(t)?t.abort():v(t.req)?t.req.abort():"function"==typeof t.destroy?t.destroy(n):"function"==typeof t.close?t.close():n?e.nextTick(x,t,n):e.nextTick(I,t),t.destroyed||(t[a]=!0))},destroy:function(e,n){const i=this._readableState,s=this._writableState,a=s||i;return null!=s&&s.destroyed||null!=i&&i.destroyed?("function"==typeof n&&n(),this):(p(e,s,i),s&&(s.destroyed=!0),i&&(i.destroyed=!0),a.constructed?u(this,e,n):this.once(d,function(i){u(this,t(i,e),n)}),this)},undestroy:function(){const e=this._readableState,t=this._writableState;e&&(e.constructed=!0,e.closed=!1,e.closeEmitted=!1,e.destroyed=!1,e.errored=null,e.errorEmitted=!1,e.reading=!1,e.ended=!1===e.readable,e.endEmitted=!1===e.readable),t&&(t.constructed=!0,t.destroyed=!1,t.closed=!1,t.closeEmitted=!1,t.errored=null,t.errorEmitted=!1,t.finalCalled=!1,t.prefinished=!1,t.ended=!1===t.writable,t.ending=!1===t.writable,t.finished=!1===t.writable)},errorOrDestroy:f},Xe}function at(){if(Ze)return Qe;Ze=1;const{ArrayIsArray:e,ObjectSetPrototypeOf:t}=de(),{EventEmitter:n}=u;function i(e){n.call(this,e)}function s(t,n,i){if("function"==typeof t.prependListener)return t.prependListener(n,i);t._events&&t._events[n]?e(t._events[n])?t._events[n].unshift(i):t._events[n]=[i,t._events[n]]:t.on(n,i)}return t(i.prototype,n.prototype),t(i,n),i.prototype.pipe=function(e,t){const i=this;function a(t){e.writable&&!1===e.write(t)&&i.pause&&i.pause()}function o(){i.readable&&i.resume&&i.resume()}i.on("data",a),e.on("drain",o),e._isStdio||t&&!1===t.end||(i.on("end",c),i.on("close",d));let r=!1;function c(){r||(r=!0,e.end())}function d(){r||(r=!0,"function"==typeof e.destroy&&e.destroy())}function l(e){p(),0===n.listenerCount(this,"error")&&this.emit("error",e)}function p(){i.removeListener("data",a),e.removeListener("drain",o),i.removeListener("end",c),i.removeListener("close",d),i.removeListener("error",l),e.removeListener("error",l),i.removeListener("end",p),i.removeListener("close",p),e.removeListener("close",p)}return s(i,"error",l),s(e,"error",l),i.on("end",p),i.on("close",p),e.on("close",p),e.emit("pipe",i),e},Qe={Stream:i,prependListener:s}}var ot,rt,ct,dt,lt,pt={exports:{}};function ut(){return ot||(ot=1,function(e){const{SymbolDispose:t}=de(),{AbortError:n,codes:i}=fe(),{isNodeStream:s,isWebStream:a,kControllerErrorFunction:o}=nt(),r=it(),{ERR_INVALID_ARG_TYPE:c}=i;let d;e.exports.addAbortSignal=function(t,n){if((e=>{if("object"!=typeof e||!("aborted"in e))throw new c("signal","AbortSignal",e)})(t),!s(n)&&!a(n))throw new c("stream",["ReadableStream","WritableStream","Stream"],n);return e.exports.addAbortSignalNoValidate(t,n)},e.exports.addAbortSignalNoValidate=function(e,i){if("object"!=typeof e||!("aborted"in e))return i;const a=s(i)?()=>{i.destroy(new n(void 0,{cause:e.reason}))}:()=>{i[o](new n(void 0,{cause:e.reason}))};if(e.aborted)a();else{d=d||Ue().addAbortListener;const n=d(e,a);r(i,n[t])}return i}}(pt)),pt.exports}function mt(){if(ct)return rt;ct=1;const{StringPrototypeSlice:e,SymbolIterator:t,TypedArrayPrototypeSet:n,Uint8Array:i}=de(),{Buffer:s}=p,{inspect:a}=Ue();return rt=class{constructor(){this.head=null,this.tail=null,this.length=0}push(e){const t={data:e,next:null};this.length>0?this.tail.next=t:this.head=t,this.tail=t,++this.length}unshift(e){const t={data:e,next:this.head};0===this.length&&(this.tail=t),this.head=t,++this.length}shift(){if(0===this.length)return;const e=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,e}clear(){this.head=this.tail=null,this.length=0}join(e){if(0===this.length)return"";let t=this.head,n=""+t.data;for(;null!==(t=t.next);)n+=e+t.data;return n}concat(e){if(0===this.length)return s.alloc(0);const t=s.allocUnsafe(e>>>0);let i=this.head,a=0;for(;i;)n(t,i.data,a),a+=i.data.length,i=i.next;return t}consume(e,t){const n=this.head.data;if(e<n.length){const t=n.slice(0,e);return this.head.data=n.slice(e),t}return e===n.length?this.shift():t?this._getString(e):this._getBuffer(e)}first(){return this.head.data}*[t](){for(let e=this.head;e;e=e.next)yield e.data}_getString(t){let n="",i=this.head,s=0;do{const a=i.data;if(!(t>a.length)){t===a.length?(n+=a,++s,i.next?this.head=i.next:this.head=this.tail=null):(n+=e(a,0,t),this.head=i,i.data=e(a,t));break}n+=a,t-=a.length,++s}while(null!==(i=i.next));return this.length-=s,n}_getBuffer(e){const t=s.allocUnsafe(e),a=e;let o=this.head,r=0;do{const s=o.data;if(!(e>s.length)){e===s.length?(n(t,s,a-e),++r,o.next?this.head=o.next:this.head=this.tail=null):(n(t,new i(s.buffer,s.byteOffset,e),a-e),this.head=o,o.data=s.slice(e));break}n(t,s,a-e),e-=s.length,++r}while(null!==(o=o.next));return this.length-=r,t}[Symbol.for("nodejs.util.inspect.custom")](e,t){return a(this,{...t,depth:0,customInspect:!1})}}}function ht(){if(lt)return dt;lt=1;const{MathFloor:e,NumberIsInteger:t}=de(),{validateInteger:n}=He(),{ERR_INVALID_ARG_VALUE:i}=fe().codes;let s=16384,a=16;function o(e){return e?a:s}return dt={getHighWaterMark:function(n,s,a,r){const c=function(e,t,n){return null!=e.highWaterMark?e.highWaterMark:t?e[n]:null}(s,r,a);if(null!=c){if(!t(c)||c<0)throw new i(r?`options.${a}`:"options.highWaterMark",c);return e(c)}return o(n.objectMode)},getDefaultHighWaterMark:o,setDefaultHighWaterMark:function(e,t){n(t,"value",0),e?a=t:s=t}}}var gt,ft,yt,bt,vt,It,xt,wt,St,At,Et,_t,Tt,zt,kt,Nt,Ct,Rt,Ot,jt,Pt,Dt,Lt,Mt,qt,Ut,$t,Bt,Ft={},Ht={exports:{}};function Gt(){if(bt)return yt;bt=1;const e=tt(),{PromisePrototypeThen:t,SymbolAsyncIterator:n,SymbolIterator:i}=de(),{Buffer:s}=p,{ERR_INVALID_ARG_TYPE:a,ERR_STREAM_NULL_VALUES:o}=fe().codes;return yt=function(r,c,d){let l,p;if("string"==typeof c||c instanceof s)return new r({objectMode:!0,...d,read(){this.push(c),this.push(null)}});if(c&&c[n])p=!0,l=c[n]();else{if(!c||!c[i])throw new a("iterable",["Iterable"],c);p=!1,l=c[i]()}const u=new r({objectMode:!0,highWaterMark:1,...d});let m=!1;return u._read=function(){m||(m=!0,async function(){for(;;){try{const{value:e,done:t}=p?await l.next():l.next();if(t)u.push(null);else{const t=e&&"function"==typeof e.then?await e:e;if(null===t)throw m=!1,new o;if(u.push(t))continue;m=!1}}catch(e){u.destroy(e)}break}}())},u._destroy=function(n,i){t(async function(e){const t=null!=e,n="function"==typeof l.throw;if(t&&n){const{value:t,done:n}=await l.throw(e);if(await t,n)return}if("function"==typeof l.return){const{value:e}=await l.return();await e}}(n),()=>e.nextTick(i,n),t=>e.nextTick(i,t||n))},u},yt}function Wt(){if(It)return vt;It=1;const e=tt(),{ArrayPrototypeIndexOf:t,NumberIsInteger:n,NumberIsNaN:i,NumberParseInt:s,ObjectDefineProperties:a,ObjectKeys:o,ObjectSetPrototypeOf:r,Promise:c,SafeSet:d,SymbolAsyncDispose:l,SymbolAsyncIterator:m,Symbol:h}=de();vt=W,W.ReadableState=G;const{EventEmitter:g}=u,{Stream:f,prependListener:y}=at(),{Buffer:b}=p,{addAbortSignal:v}=ut(),I=it();let x=Ue().debuglog("stream",e=>{x=e});const w=mt(),S=st(),{getHighWaterMark:A,getDefaultHighWaterMark:E}=ht(),{aggregateTwoErrors:_,codes:{ERR_INVALID_ARG_TYPE:T,ERR_METHOD_NOT_IMPLEMENTED:z,ERR_OUT_OF_RANGE:k,ERR_STREAM_PUSH_AFTER_EOF:N,ERR_STREAM_UNSHIFT_AFTER_END_EVENT:C},AbortError:R}=fe(),{validateObject:O}=He(),j=h("kPaused"),{StringDecoder:P}=function(){if(ft)return Ft;ft=1;var e=(gt||(gt=1,function(e,t){var n=p,i=n.Buffer;function s(e,t){for(var n in e)t[n]=e[n]}function a(e,t,n){return i(e,t,n)}i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow?e.exports=n:(s(n,t),t.Buffer=a),a.prototype=Object.create(i.prototype),s(i,a),a.from=function(e,t,n){if("number"==typeof e)throw new TypeError("Argument must not be a number");return i(e,t,n)},a.alloc=function(e,t,n){if("number"!=typeof e)throw new TypeError("Argument must be a number");var s=i(e);return void 0!==t?"string"==typeof n?s.fill(t,n):s.fill(t):s.fill(0),s},a.allocUnsafe=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return i(e)},a.allocUnsafeSlow=function(e){if("number"!=typeof e)throw new TypeError("Argument must be a number");return n.SlowBuffer(e)}}(Ht,Ht.exports)),Ht.exports).Buffer,t=e.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function n(n){var i;switch(this.encoding=function(n){var i=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(n);if("string"!=typeof i&&(e.isEncoding===t||!t(n)))throw new Error("Unknown encoding: "+n);return i||n}(n),this.encoding){case"utf16le":this.text=a,this.end=o,i=4;break;case"utf8":this.fillLast=s,i=4;break;case"base64":this.text=r,this.end=c,i=3;break;default:return this.write=d,void(this.end=l)}this.lastNeed=0,this.lastTotal=0,this.lastChar=e.allocUnsafe(i)}function i(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function s(e){var t=this.lastTotal-this.lastNeed,n=function(e,t){if(128!=(192&t[0]))return e.lastNeed=0,"�";if(e.lastNeed>1&&t.length>1){if(128!=(192&t[1]))return e.lastNeed=1,"�";if(e.lastNeed>2&&t.length>2&&128!=(192&t[2]))return e.lastNeed=2,"�"}}(this,e);return void 0!==n?n:this.lastNeed<=e.length?(e.copy(this.lastChar,t,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(e.copy(this.lastChar,t,0,e.length),void(this.lastNeed-=e.length))}function a(e,t){if((e.length-t)%2==0){var n=e.toString("utf16le",t);if(n){var i=n.charCodeAt(n.length-1);if(i>=55296&&i<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1],n.slice(0,-1)}return n}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=e[e.length-1],e.toString("utf16le",t,e.length-1)}function o(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var n=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,n)}return t}function r(e,t){var n=(e.length-t)%3;return 0===n?e.toString("base64",t):(this.lastNeed=3-n,this.lastTotal=3,1===n?this.lastChar[0]=e[e.length-1]:(this.lastChar[0]=e[e.length-2],this.lastChar[1]=e[e.length-1]),e.toString("base64",t,e.length-n))}function c(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+this.lastChar.toString("base64",0,3-this.lastNeed):t}function d(e){return e.toString(this.encoding)}function l(e){return e&&e.length?this.write(e):""}return Ft.StringDecoder=n,n.prototype.write=function(e){if(0===e.length)return"";var t,n;if(this.lastNeed){if(void 0===(t=this.fillLast(e)))return"";n=this.lastNeed,this.lastNeed=0}else n=0;return n<e.length?t?t+this.text(e,n):this.text(e,n):t||""},n.prototype.end=function(e){var t=e&&e.length?this.write(e):"";return this.lastNeed?t+"�":t},n.prototype.text=function(e,t){var n=function(e,t,n){var s=t.length-1;if(s<n)return 0;var a=i(t[s]);return a>=0?(a>0&&(e.lastNeed=a-1),a):--s<n||-2===a?0:(a=i(t[s]))>=0?(a>0&&(e.lastNeed=a-2),a):--s<n||-2===a?0:(a=i(t[s]))>=0?(a>0&&(2===a?a=0:e.lastNeed=a-3),a):0}(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=n;var s=e.length-(n-this.lastNeed);return e.copy(this.lastChar,0,s),e.toString("utf8",t,s)},n.prototype.fillLast=function(e){if(this.lastNeed<=e.length)return e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal);e.copy(this.lastChar,this.lastTotal-this.lastNeed,0,e.length),this.lastNeed-=e.length},Ft}(),D=Gt();r(W.prototype,f.prototype),r(W,f);const L=()=>{},{errorOrDestroy:M}=S,q=1,U=16,$=32,B=2048,F=4096;function H(e){return{enumerable:!1,get(){return 0!==(this.state&e)},set(t){t?this.state|=e:this.state&=~e}}}function G(e,t,n){"boolean"!=typeof n&&(n=t instanceof Yt()),this.state=B|F|U|$,e&&e.objectMode&&(this.state|=q),n&&e&&e.readableObjectMode&&(this.state|=q),this.highWaterMark=e?A(this,e,"readableHighWaterMark",n):E(!1),this.buffer=new w,this.length=0,this.pipes=[],this.flowing=null,this[j]=null,e&&!1===e.emitClose&&(this.state&=~B),e&&!1===e.autoDestroy&&(this.state&=~F),this.errored=null,this.defaultEncoding=e&&e.defaultEncoding||"utf8",this.awaitDrainWriters=null,this.decoder=null,this.encoding=null,e&&e.encoding&&(this.decoder=new P(e.encoding),this.encoding=e.encoding)}function W(e){if(!(this instanceof W))return new W(e);const t=this instanceof Yt();this._readableState=new G(e,this,t),e&&("function"==typeof e.read&&(this._read=e.read),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.construct&&(this._construct=e.construct),e.signal&&!t&&v(e.signal,this)),f.call(this,e),S.construct(this,()=>{this._readableState.needReadable&&Q(this,this._readableState)})}function V(e,t,n,i){x("readableAddChunk",t);const s=e._readableState;let a;if(0===(s.state&q)&&("string"==typeof t?(n=n||s.defaultEncoding,s.encoding!==n&&(i&&s.encoding?t=b.from(t,n).toString(s.encoding):(t=b.from(t,n),n=""))):t instanceof b?n="":f._isUint8Array(t)?(t=f._uint8ArrayToBuffer(t),n=""):null!=t&&(a=new T("chunk",["string","Buffer","Uint8Array"],t))),a)M(e,a);else if(null===t)s.state&=-9,function(e,t){if(x("onEofChunk"),!t.ended){if(t.decoder){const e=t.decoder.end();e&&e.length&&(t.buffer.push(e),t.length+=t.objectMode?1:e.length)}t.ended=!0,t.sync?X(e):(t.needReadable=!1,t.emittedReadable=!0,J(e))}}(e,s);else if(0!==(s.state&q)||t&&t.length>0)if(i)if(4&s.state)M(e,new C);else{if(s.destroyed||s.errored)return!1;K(e,s,t,!0)}else if(s.ended)M(e,new N);else{if(s.destroyed||s.errored)return!1;s.state&=-9,s.decoder&&!n?(t=s.decoder.write(t),s.objectMode||0!==t.length?K(e,s,t,!1):Q(e,s)):K(e,s,t,!1)}else i||(s.state&=-9,Q(e,s));return!s.ended&&(s.length<s.highWaterMark||0===s.length)}function K(e,t,n,i){t.flowing&&0===t.length&&!t.sync&&e.listenerCount("data")>0?(65536&t.state?t.awaitDrainWriters.clear():t.awaitDrainWriters=null,t.dataEmitted=!0,e.emit("data",n)):(t.length+=t.objectMode?1:n.length,i?t.buffer.unshift(n):t.buffer.push(n),64&t.state&&X(e)),Q(e,t)}function Y(e,t){return e<=0||0===t.length&&t.ended?0:0!==(t.state&q)?1:i(e)?t.flowing&&t.length?t.buffer.first().length:t.length:e<=t.length?e:t.ended?t.length:0}function X(t){const n=t._readableState;x("emitReadable",n.needReadable,n.emittedReadable),n.needReadable=!1,n.emittedReadable||(x("emitReadable",n.flowing),n.emittedReadable=!0,e.nextTick(J,t))}function J(e){const t=e._readableState;x("emitReadable_",t.destroyed,t.length,t.ended),t.destroyed||t.errored||!t.length&&!t.ended||(e.emit("readable"),t.emittedReadable=!1),t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark,ie(e)}function Q(t,n){!n.readingMore&&n.constructed&&(n.readingMore=!0,e.nextTick(Z,t,n))}function Z(e,t){for(;!t.reading&&!t.ended&&(t.length<t.highWaterMark||t.flowing&&0===t.length);){const n=t.length;if(x("maybeReadMore read 0"),e.read(0),n===t.length)break}t.readingMore=!1}function ee(e){const t=e._readableState;t.readableListening=e.listenerCount("readable")>0,t.resumeScheduled&&!1===t[j]?t.flowing=!0:e.listenerCount("data")>0?e.resume():t.readableListening||(t.flowing=null)}function te(e){x("readable nexttick read 0"),e.read(0)}function ne(e,t){x("resume",t.reading),t.reading||e.read(0),t.resumeScheduled=!1,e.emit("resume"),ie(e),t.flowing&&!t.reading&&e.read(0)}function ie(e){const t=e._readableState;for(x("flow",t.flowing);t.flowing&&null!==e.read(););}function se(e,t){"function"!=typeof e.read&&(e=W.wrap(e,{objectMode:!0}));const n=async function*(e,t){let n,i=L;function s(t){this===e?(i(),i=L):i=t}e.on("readable",s);const a=I(e,{writable:!1},e=>{n=e?_(n,e):null,i(),i=L});try{for(;;){const t=e.destroyed?null:e.read();if(null!==t)yield t;else{if(n)throw n;if(null===n)return;await new c(s)}}}catch(e){throw n=_(n,e),n}finally{!n&&!1===(null==t?void 0:t.destroyOnReturn)||void 0!==n&&!e._readableState.autoDestroy?(e.off("readable",s),a()):S.destroyer(e,null)}}(e,t);return n.stream=e,n}function ae(e,t){if(0===t.length)return null;let n;return t.objectMode?n=t.buffer.shift():!e||e>=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.first():t.buffer.concat(t.length),t.buffer.clear()):n=t.buffer.consume(e,t.decoder),n}function oe(t){const n=t._readableState;x("endReadable",n.endEmitted),n.endEmitted||(n.ended=!0,e.nextTick(re,n,t))}function re(t,n){if(x("endReadableNT",t.endEmitted,t.length),!t.errored&&!t.closeEmitted&&!t.endEmitted&&0===t.length)if(t.endEmitted=!0,n.emit("end"),n.writable&&!1===n.allowHalfOpen)e.nextTick(ce,n);else if(t.autoDestroy){const e=n._writableState;(!e||e.autoDestroy&&(e.finished||!1===e.writable))&&n.destroy()}}function ce(e){e.writable&&!e.writableEnded&&!e.destroyed&&e.end()}let le;function pe(){return void 0===le&&(le={}),le}return a(G.prototype,{objectMode:H(q),ended:H(2),endEmitted:H(4),reading:H(8),constructed:H(U),sync:H($),needReadable:H(64),emittedReadable:H(128),readableListening:H(256),resumeScheduled:H(512),errorEmitted:H(1024),emitClose:H(B),autoDestroy:H(F),destroyed:H(8192),closed:H(16384),closeEmitted:H(32768),multiAwaitDrain:H(65536),readingMore:H(1<<17),dataEmitted:H(1<<18)}),W.prototype.destroy=S.destroy,W.prototype._undestroy=S.undestroy,W.prototype._destroy=function(e,t){t(e)},W.prototype[g.captureRejectionSymbol]=function(e){this.destroy(e)},W.prototype[l]=function(){let e;return this.destroyed||(e=this.readableEnded?null:new R,this.destroy(e)),new c((t,n)=>I(this,i=>i&&i!==e?n(i):t(null)))},W.prototype.push=function(e,t){return V(this,e,t,!1)},W.prototype.unshift=function(e,t){return V(this,e,t,!0)},W.prototype.isPaused=function(){const e=this._readableState;return!0===e[j]||!1===e.flowing},W.prototype.setEncoding=function(e){const t=new P(e);this._readableState.decoder=t,this._readableState.encoding=this._readableState.decoder.encoding;const n=this._readableState.buffer;let i="";for(const e of n)i+=t.write(e);return n.clear(),""!==i&&n.push(i),this._readableState.length=i.length,this},W.prototype.read=function(e){x("read",e),void 0===e?e=NaN:n(e)||(e=s(e,10));const t=this._readableState,i=e;if(e>t.highWaterMark&&(t.highWaterMark=function(e){if(e>1073741824)throw new k("size","<= 1GiB",e);return e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,++e}(e)),0!==e&&(t.state&=-129),0===e&&t.needReadable&&((0!==t.highWaterMark?t.length>=t.highWaterMark:t.length>0)||t.ended))return x("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?oe(this):X(this),null;if(0===(e=Y(e,t))&&t.ended)return 0===t.length&&oe(this),null;let a,o=!!(64&t.state);if(x("need readable",o),(0===t.length||t.length-e<t.highWaterMark)&&(o=!0,x("length less than watermark",o)),t.ended||t.reading||t.destroyed||t.errored||!t.constructed)o=!1,x("reading, ended or constructing",o);else if(o){x("do read"),t.state|=8|$,0===t.length&&(t.state|=64);try{this._read(t.highWaterMark)}catch(e){M(this,e)}t.state&=~$,t.reading||(e=Y(i,t))}return a=e>0?ae(e,t):null,null===a?(t.needReadable=t.length<=t.highWaterMark,e=0):(t.length-=e,t.multiAwaitDrain?t.awaitDrainWriters.clear():t.awaitDrainWriters=null),0===t.length&&(t.ended||(t.needReadable=!0),i!==e&&t.ended&&oe(this)),null===a||t.errorEmitted||t.closeEmitted||(t.dataEmitted=!0,this.emit("data",a)),a},W.prototype._read=function(e){throw new z("_read()")},W.prototype.pipe=function(t,n){const i=this,s=this._readableState;1===s.pipes.length&&(s.multiAwaitDrain||(s.multiAwaitDrain=!0,s.awaitDrainWriters=new d(s.awaitDrainWriters?[s.awaitDrainWriters]:[]))),s.pipes.push(t),x("pipe count=%d opts=%j",s.pipes.length,n);const a=n&&!1===n.end||t===e.stdout||t===e.stderr?g:o;function o(){x("onend"),t.end()}let r;s.endEmitted?e.nextTick(a):i.once("end",a),t.on("unpipe",function e(n,a){x("onunpipe"),n===i&&a&&!1===a.hasUnpiped&&(a.hasUnpiped=!0,x("cleanup"),t.removeListener("close",m),t.removeListener("finish",h),r&&t.removeListener("drain",r),t.removeListener("error",u),t.removeListener("unpipe",e),i.removeListener("end",o),i.removeListener("end",g),i.removeListener("data",p),c=!0,r&&s.awaitDrainWriters&&(!t._writableState||t._writableState.needDrain)&&r())});let c=!1;function l(){c||(1===s.pipes.length&&s.pipes[0]===t?(x("false write response, pause",0),s.awaitDrainWriters=t,s.multiAwaitDrain=!1):s.pipes.length>1&&s.pipes.includes(t)&&(x("false write response, pause",s.awaitDrainWriters.size),s.awaitDrainWriters.add(t)),i.pause()),r||(r=function(e,t){return function(){const n=e._readableState;n.awaitDrainWriters===t?(x("pipeOnDrain",1),n.awaitDrainWriters=null):n.multiAwaitDrain&&(x("pipeOnDrain",n.awaitDrainWriters.size),n.awaitDrainWriters.delete(t)),n.awaitDrainWriters&&0!==n.awaitDrainWriters.size||!e.listenerCount("data")||e.resume()}}(i,t),t.on("drain",r))}function p(e){x("ondata");const n=t.write(e);x("dest.write",n),!1===n&&l()}function u(e){if(x("onerror",e),g(),t.removeListener("error",u),0===t.listenerCount("error")){const n=t._writableState||t._readableState;n&&!n.errorEmitted?M(t,e):t.emit("error",e)}}function m(){t.removeListener("finish",h),g()}function h(){x("onfinish"),t.removeListener("close",m),g()}function g(){x("unpipe"),i.unpipe(t)}return i.on("data",p),y(t,"error",u),t.once("close",m),t.once("finish",h),t.emit("pipe",i),!0===t.writableNeedDrain?l():s.flowing||(x("pipe resume"),i.resume()),t},W.prototype.unpipe=function(e){const n=this._readableState;if(0===n.pipes.length)return this;if(!e){const e=n.pipes;n.pipes=[],this.pause();for(let t=0;t<e.length;t++)e[t].emit("unpipe",this,{hasUnpiped:!1});return this}const i=t(n.pipes,e);return-1===i||(n.pipes.splice(i,1),0===n.pipes.length&&this.pause(),e.emit("unpipe",this,{hasUnpiped:!1})),this},W.prototype.on=function(t,n){const i=f.prototype.on.call(this,t,n),s=this._readableState;return"data"===t?(s.readableListening=this.listenerCount("readable")>0,!1!==s.flowing&&this.resume()):"readable"===t&&(s.endEmitted||s.readableListening||(s.readableListening=s.needReadable=!0,s.flowing=!1,s.emittedReadable=!1,x("on readable",s.length,s.reading),s.length?X(this):s.reading||e.nextTick(te,this))),i},W.prototype.addListener=W.prototype.on,W.prototype.removeListener=function(t,n){const i=f.prototype.removeListener.call(this,t,n);return"readable"===t&&e.nextTick(ee,this),i},W.prototype.off=W.prototype.removeListener,W.prototype.removeAllListeners=function(t){const n=f.prototype.removeAllListeners.apply(this,arguments);return"readable"!==t&&void 0!==t||e.nextTick(ee,this),n},W.prototype.resume=function(){const t=this._readableState;return t.flowing||(x("resume"),t.flowing=!t.readableListening,function(t,n){n.resumeScheduled||(n.resumeScheduled=!0,e.nextTick(ne,t,n))}(this,t)),t[j]=!1,this},W.prototype.pause=function(){return x("call pause flowing=%j",this._readableState.flowing),!1!==this._readableState.flowing&&(x("pause"),this._readableState.flowing=!1,this.emit("pause")),this._readableState[j]=!0,this},W.prototype.wrap=function(e){let t=!1;e.on("data",n=>{!this.push(n)&&e.pause&&(t=!0,e.pause())}),e.on("end",()=>{this.push(null)}),e.on("error",e=>{M(this,e)}),e.on("close",()=>{this.destroy()}),e.on("destroy",()=>{this.destroy()}),this._read=()=>{t&&e.resume&&(t=!1,e.resume())};const n=o(e);for(let t=1;t<n.length;t++){const i=n[t];void 0===this[i]&&"function"==typeof e[i]&&(this[i]=e[i].bind(e))}return this},W.prototype[m]=function(){return se(this)},W.prototype.iterator=function(e){return void 0!==e&&O(e,"options"),se(this,e)},a(W.prototype,{readable:{__proto__:null,get(){const e=this._readableState;return!(!e||!1===e.readable||e.destroyed||e.errorEmitted||e.endEmitted)},set(e){this._readableState&&(this._readableState.readable=!!e)}},readableDidRead:{__proto__:null,enumerable:!1,get:function(){return this._readableState.dataEmitted}},readableAborted:{__proto__:null,enumerable:!1,get:function(){return!(!1===this._readableState.readable||!this._readableState.destroyed&&!this._readableState.errored||this._readableState.endEmitted)}},readableHighWaterMark:{__proto__:null,enumerable:!1,get:function(){return this._readableState.highWaterMark}},readableBuffer:{__proto__:null,enumerable:!1,get:function(){return this._readableState&&this._readableState.buffer}},readableFlowing:{__proto__:null,enumerable:!1,get:function(){return this._readableState.flowing},set:function(e){this._readableState&&(this._readableState.flowing=e)}},readableLength:{__proto__:null,enumerable:!1,get(){return this._readableState.length}},readableObjectMode:{__proto__:null,enumerable:!1,get(){return!!this._readableState&&this._readableState.objectMode}},readableEncoding:{__proto__:null,enumerable:!1,get(){return this._readableState?this._readableState.encoding:null}},errored:{__proto__:null,enumerable:!1,get(){return this._readableState?this._readableState.errored:null}},closed:{__proto__:null,get(){return!!this._readableState&&this._readableState.closed}},destroyed:{__proto__:null,enumerable:!1,get(){return!!this._readableState&&this._readableState.destroyed},set(e){this._readableState&&(this._readableState.destroyed=e)}},readableEnded:{__proto__:null,enumerable:!1,get(){return!!this._readableState&&this._readableState.endEmitted}}}),a(G.prototype,{pipesCount:{__proto__:null,get(){return this.pipes.length}},paused:{__proto__:null,get(){return!1!==this[j]},set(e){this[j]=!!e}}}),W._fromList=ae,W.from=function(e,t){return D(W,e,t)},W.fromWeb=function(e,t){return pe().newStreamReadableFromReadableStream(e,t)},W.toWeb=function(e,t){return pe().newReadableStreamFromStreamReadable(e,t)},W.wrap=function(e,t){var n,i;return new W({objectMode:null===(n=null!==(i=e.readableObjectMode)&&void 0!==i?i:e.objectMode)||void 0===n||n,...t,destroy(t,n){S.destroyer(e,t),n(t)}}).wrap(e)},vt}function Vt(){if(wt)return xt;wt=1;const e=tt(),{ArrayPrototypeSlice:t,Error:n,FunctionPrototypeSymbolHasInstance:i,ObjectDefineProperty:s,ObjectDefineProperties:a,ObjectSetPrototypeOf:o,StringPrototypeToLowerCase:r,Symbol:c,SymbolHasInstance:d}=de();xt=O,O.WritableState=C;const{EventEmitter:l}=u,m=at().Stream,{Buffer:h}=p,g=st(),{addAbortSignal:f}=ut(),{getHighWaterMark:y,getDefaultHighWaterMark:b}=ht(),{ERR_INVALID_ARG_TYPE:v,ERR_METHOD_NOT_IMPLEMENTED:I,ERR_MULTIPLE_CALLBACK:x,ERR_STREAM_CANNOT_PIPE:w,ERR_STREAM_DESTROYED:S,ERR_STREAM_ALREADY_FINISHED:A,ERR_STREAM_NULL_VALUES:E,ERR_STREAM_WRITE_AFTER_END:_,ERR_UNKNOWN_ENCODING:T}=fe().codes,{errorOrDestroy:z}=g;function k(){}o(O.prototype,m.prototype),o(O,m);const N=c("kOnFinished");function C(e,t,n){"boolean"!=typeof n&&(n=t instanceof Yt()),this.objectMode=!(!e||!e.objectMode),n&&(this.objectMode=this.objectMode||!(!e||!e.writableObjectMode)),this.highWaterMark=e?y(this,e,"writableHighWaterMark",n):b(!1),this.finalCalled=!1,this.needDrain=!1,this.ending=!1,this.ended=!1,this.finished=!1,this.destroyed=!1;const i=!(!e||!1!==e.decodeStrings);this.decodeStrings=!i,this.defaultEncoding=e&&e.defaultEncoding||"utf8",this.length=0,this.writing=!1,this.corked=0,this.sync=!0,this.bufferProcessing=!1,this.onwrite=L.bind(void 0,t),this.writecb=null,this.writelen=0,this.afterWriteTickInfo=null,R(this),this.pendingcb=0,this.constructed=!0,this.prefinished=!1,this.errorEmitted=!1,this.emitClose=!e||!1!==e.emitClose,this.autoDestroy=!e||!1!==e.autoDestroy,this.errored=null,this.closed=!1,this.closeEmitted=!1,this[N]=[]}function R(e){e.buffered=[],e.bufferedIndex=0,e.allBuffers=!0,e.allNoop=!0}function O(e){const t=this instanceof Yt();if(!t&&!i(O,this))return new O(e);this._writableState=new C(e,this,t),e&&("function"==typeof e.write&&(this._write=e.write),"function"==typeof e.writev&&(this._writev=e.writev),"function"==typeof e.destroy&&(this._destroy=e.destroy),"function"==typeof e.final&&(this._final=e.final),"function"==typeof e.construct&&(this._construct=e.construct),e.signal&&f(e.signal,this)),m.call(this,e),g.construct(this,()=>{const e=this._writableState;e.writing||$(this,e),F(this,e)})}function j(t,n,i,s){const a=t._writableState;if("function"==typeof i)s=i,i=a.defaultEncoding;else{if(i){if("buffer"!==i&&!h.isEncoding(i))throw new T(i)}else i=a.defaultEncoding;"function"!=typeof s&&(s=k)}if(null===n)throw new E;if(!a.objectMode)if("string"==typeof n)!1!==a.decodeStrings&&(n=h.from(n,i),i="buffer");else if(n instanceof h)i="buffer";else{if(!m._isUint8Array(n))throw new v("chunk",["string","Buffer","Uint8Array"],n);n=m._uint8ArrayToBuffer(n),i="buffer"}let o;return a.ending?o=new _:a.destroyed&&(o=new S("write")),o?(e.nextTick(s,o),z(t,o,!0),o):(a.pendingcb++,function(e,t,n,i,s){const a=t.objectMode?1:n.length;t.length+=a;const o=t.length<t.highWaterMark;return o||(t.needDrain=!0),t.writing||t.corked||t.errored||!t.constructed?(t.buffered.push({chunk:n,encoding:i,callback:s}),t.allBuffers&&"buffer"!==i&&(t.allBuffers=!1),t.allNoop&&s!==k&&(t.allNoop=!1)):(t.writelen=a,t.writecb=s,t.writing=!0,t.sync=!0,e._write(n,i,t.onwrite),t.sync=!1),o&&!t.errored&&!t.destroyed}(t,a,n,i,s))}function P(e,t,n,i,s,a,o){t.writelen=i,t.writecb=o,t.writing=!0,t.sync=!0,t.destroyed?t.onwrite(new S("write")):n?e._writev(s,t.onwrite):e._write(s,a,t.onwrite),t.sync=!1}function D(e,t,n,i){--t.pendingcb,i(n),U(t),z(e,n)}function L(t,n){const i=t._writableState,s=i.sync,a=i.writecb;"function"==typeof a?(i.writing=!1,i.writecb=null,i.length-=i.writelen,i.writelen=0,n?(n.stack,i.errored||(i.errored=n),t._readableState&&!t._readableState.errored&&(t._readableState.errored=n),s?e.nextTick(D,t,i,n,a):D(t,i,n,a)):(i.buffered.length>i.bufferedIndex&&$(t,i),s?null!==i.afterWriteTickInfo&&i.afterWriteTickInfo.cb===a?i.afterWriteTickInfo.count++:(i.afterWriteTickInfo={count:1,cb:a,stream:t,state:i},e.nextTick(M,i.afterWriteTickInfo)):q(t,i,1,a))):z(t,new x)}function M({stream:e,state:t,count:n,cb:i}){return t.afterWriteTickInfo=null,q(e,t,n,i)}function q(e,t,n,i){for(!t.ending&&!e.destroyed&&0===t.length&&t.needDrain&&(t.needDrain=!1,e.emit("drain"));n-- >0;)t.pendingcb--,i();t.destroyed&&U(t),F(e,t)}function U(e){if(e.writing)return;for(let n=e.bufferedIndex;n<e.buffered.length;++n){var t;const{chunk:i,callback:s}=e.buffered[n],a=e.objectMode?1:i.length;e.length-=a,s(null!==(t=e.errored)&&void 0!==t?t:new S("write"))}const n=e[N].splice(0);for(let t=0;t<n.length;t++){var i;n[t](null!==(i=e.errored)&&void 0!==i?i:new S("end"))}R(e)}function $(e,n){if(n.corked||n.bufferProcessing||n.destroyed||!n.constructed)return;const{buffered:i,bufferedIndex:s,objectMode:a}=n,o=i.length-s;if(!o)return;let r=s;if(n.bufferProcessing=!0,o>1&&e._writev){n.pendingcb-=o-1;const s=n.allNoop?k:e=>{for(let t=r;t<i.length;++t)i[t].callback(e)},a=n.allNoop&&0===r?i:t(i,r);a.allBuffers=n.allBuffers,P(e,n,!0,n.length,a,"",s),R(n)}else{do{const{chunk:t,encoding:s,callback:o}=i[r];i[r++]=null,P(e,n,!1,a?1:t.length,t,s,o)}while(r<i.length&&!n.writing);r===i.length?R(n):r>256?(i.splice(0,r),n.bufferedIndex=0):n.bufferedIndex=r}n.bufferProcessing=!1}function B(e){return e.ending&&!e.destroyed&&e.constructed&&0===e.length&&!e.errored&&0===e.buffered.length&&!e.finished&&!e.writing&&!e.errorEmitted&&!e.closeEmitted}function F(t,n,i){B(n)&&(function(t,n){n.prefinished||n.finalCalled||("function"!=typeof t._final||n.destroyed?(n.prefinished=!0,t.emit("prefinish")):(n.finalCalled=!0,function(t,n){let i=!1;function s(s){if(i)z(t,null!=s?s:x());else if(i=!0,n.pendingcb--,s){const e=n[N].splice(0);for(let t=0;t<e.length;t++)e[t](s);z(t,s,n.sync)}else B(n)&&(n.prefinished=!0,t.emit("prefinish"),n.pendingcb++,e.nextTick(H,t,n))}n.sync=!0,n.pendingcb++;try{t._final(s)}catch(e){s(e)}n.sync=!1}(t,n)))}(t,n),0===n.pendingcb&&(i?(n.pendingcb++,e.nextTick((e,t)=>{B(t)?H(e,t):t.pendingcb--},t,n)):B(n)&&(n.pendingcb++,H(t,n))))}function H(e,t){t.pendingcb--,t.finished=!0;const n=t[N].splice(0);for(let e=0;e<n.length;e++)n[e]();if(e.emit("finish"),t.autoDestroy){const t=e._readableState;(!t||t.autoDestroy&&(t.endEmitted||!1===t.readable))&&e.destroy()}}C.prototype.getBuffer=function(){return t(this.buffered,this.bufferedIndex)},s(C.prototype,"bufferedRequestCount",{__proto__:null,get(){return this.buffered.length-this.bufferedIndex}}),s(O,d,{__proto__:null,value:function(e){return!!i(this,e)||this===O&&e&&e._writableState instanceof C}}),O.prototype.pipe=function(){z(this,new w)},O.prototype.write=function(e,t,n){return!0===j(this,e,t,n)},O.prototype.cork=function(){this._writableState.corked++},O.prototype.uncork=function(){const e=this._writableState;e.corked&&(e.corked--,e.writing||$(this,e))},O.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=r(e)),!h.isEncoding(e))throw new T(e);return this._writableState.defaultEncoding=e,this},O.prototype._write=function(e,t,n){if(!this._writev)throw new I("_write()");this._writev([{chunk:e,encoding:t}],n)},O.prototype._writev=null,O.prototype.end=function(t,i,s){const a=this._writableState;let o;if("function"==typeof t?(s=t,t=null,i=null):"function"==typeof i&&(s=i,i=null),null!=t){const e=j(this,t,i);e instanceof n&&(o=e)}return a.corked&&(a.corked=1,this.uncork()),o||(a.errored||a.ending?a.finished?o=new A("end"):a.destroyed&&(o=new S("end")):(a.ending=!0,F(this,a,!0),a.ended=!0)),"function"==typeof s&&(o||a.finished?e.nextTick(s,o):a[N].push(s)),this},a(O.prototype,{closed:{__proto__:null,get(){return!!this._writableState&&this._writableState.closed}},destroyed:{__proto__:null,get(){return!!this._writableState&&this._writableState.destroyed},set(e){this._writableState&&(this._writableState.destroyed=e)}},writable:{__proto__:null,get(){const e=this._writableState;return!(!e||!1===e.writable||e.destroyed||e.errored||e.ending||e.ended)},set(e){this._writableState&&(this._writableState.writable=!!e)}},writableFinished:{__proto__:null,get(){return!!this._writableState&&this._writableState.finished}},writableObjectMode:{__proto__:null,get(){return!!this._writableState&&this._writableState.objectMode}},writableBuffer:{__proto__:null,get(){return this._writableState&&this._writableState.getBuffer()}},writableEnded:{__proto__:null,get(){return!!this._writableState&&this._writableState.ending}},writableNeedDrain:{__proto__:null,get(){const e=this._writableState;return!!e&&!e.destroyed&&!e.ending&&e.needDrain}},writableHighWaterMark:{__proto__:null,get(){return this._writableState&&this._writableState.highWaterMark}},writableCorked:{__proto__:null,get(){return this._writableState?this._writableState.corked:0}},writableLength:{__proto__:null,get(){return this._writableState&&this._writableState.length}},errored:{__proto__:null,enumerable:!1,get(){return this._writableState?this._writableState.errored:null}},writableAborted:{__proto__:null,enumerable:!1,get:function(){return!(!1===this._writableState.writable||!this._writableState.destroyed&&!this._writableState.errored||this._writableState.finished)}}});const G=g.destroy;let W;function V(){return void 0===W&&(W={}),W}return O.prototype.destroy=function(t,n){const i=this._writableState;return!i.destroyed&&(i.bufferedIndex<i.buffered.length||i[N].length)&&e.nextTick(U,i),G.call(this,t,n),this},O.prototype._undestroy=g.undestroy,O.prototype._destroy=function(e,t){t(e)},O.prototype[l.captureRejectionSymbol]=function(e){this.destroy(e)},O.fromWeb=function(e,t){return V().newStreamWritableFromWritableStream(e,t)},O.toWeb=function(e){return V().newWritableStreamFromStreamWritable(e)},xt}function Kt(){if(At)return St;At=1;const e=tt(),t=p,{isReadable:n,isWritable:i,isIterable:s,isNodeStream:a,isReadableNodeStream:o,isWritableNodeStream:r,isDuplexNodeStream:c,isReadableStream:d,isWritableStream:l}=nt(),u=it(),{AbortError:m,codes:{ERR_INVALID_ARG_TYPE:h,ERR_INVALID_RETURN_VALUE:g}}=fe(),{destroyer:f}=st(),y=Yt(),b=Wt(),v=Vt(),{createDeferredPromise:I}=Ue(),x=Gt(),w=globalThis.Blob||t.Blob,S=void 0!==w?function(e){return e instanceof w}:function(e){return!1},A=globalThis.AbortController||qe.AbortController,{FunctionPrototypeCall:E}=de();class _ extends y{constructor(e){super(e),!1===(null==e?void 0:e.readable)&&(this._readableState.readable=!1,this._readableState.ended=!0,this._readableState.endEmitted=!0),!1===(null==e?void 0:e.writable)&&(this._writableState.writable=!1,this._writableState.ending=!0,this._writableState.ended=!0,this._writableState.finished=!0)}}function T(e){const t=e.readable&&"function"!=typeof e.readable.read?b.wrap(e.readable):e.readable,s=e.writable;let a,o,r,c,d,l=!!n(t),p=!!i(s);function h(e){const t=c;c=null,t?t(e):e&&d.destroy(e)}return d=new _({readableObjectMode:!(null==t||!t.readableObjectMode),writableObjectMode:!(null==s||!s.writableObjectMode),readable:l,writable:p}),p&&(u(s,e=>{p=!1,e&&f(t,e),h(e)}),d._write=function(e,t,n){s.write(e,t)?n():a=n},d._final=function(e){s.end(),o=e},s.on("drain",function(){if(a){const e=a;a=null,e()}}),s.on("finish",function(){if(o){const e=o;o=null,e()}})),l&&(u(t,e=>{l=!1,e&&f(t,e),h(e)}),t.on("readable",function(){if(r){const e=r;r=null,e()}}),t.on("end",function(){d.push(null)}),d._read=function(){for(;;){const e=t.read();if(null===e)return void(r=d._read);if(!d.push(e))return}}),d._destroy=function(e,n){e||null===c||(e=new m),r=null,a=null,o=null,null===c?n(e):(c=n,f(s,e),f(t,e))},d}return St=function t(n,i){if(c(n))return n;if(o(n))return T({readable:n});if(r(n))return T({writable:n});if(a(n))return T({writable:!1,readable:!1});if(d(n))return T({readable:b.fromWeb(n)});if(l(n))return T({writable:v.fromWeb(n)});if("function"==typeof n){const{value:t,write:a,final:o,destroy:r}=function(t){let{promise:n,resolve:i}=I();const s=new A,a=s.signal;return{value:t(async function*(){for(;;){const t=n;n=null;const{chunk:s,done:o,cb:r}=await t;if(e.nextTick(r),o)return;if(a.aborted)throw new m(void 0,{cause:a.reason});({promise:n,resolve:i}=I()),yield s}}(),{signal:a}),write(e,t,n){const s=i;i=null,s({chunk:e,done:!1,cb:n})},final(e){const t=i;i=null,t({done:!0,cb:e})},destroy(e,t){s.abort(),t(e)}}}(n);if(s(t))return x(_,t,{objectMode:!0,write:a,final:o,destroy:r});const c=null==t?void 0:t.then;if("function"==typeof c){let n;const i=E(c,t,e=>{if(null!=e)throw new g("nully","body",e)},e=>{f(n,e)});return n=new _({objectMode:!0,readable:!1,write:a,final(t){o(async()=>{try{await i,e.nextTick(t,null)}catch(n){e.nextTick(t,n)}})},destroy:r})}throw new g("Iterable, AsyncIterable or AsyncFunction",i,t)}if(S(n))return t(n.arrayBuffer());if(s(n))return x(_,n,{objectMode:!0,writable:!1});if(d(null==n?void 0:n.readable)&&l(null==n?void 0:n.writable))return _.fromWeb(n);if("object"==typeof(null==n?void 0:n.writable)||"object"==typeof(null==n?void 0:n.readable))return T({readable:null!=n&&n.readable?o(null==n?void 0:n.readable)?null==n?void 0:n.readable:t(n.readable):void 0,writable:null!=n&&n.writable?r(null==n?void 0:n.writable)?null==n?void 0:n.writable:t(n.writable):void 0});const p=null==n?void 0:n.then;if("function"==typeof p){let e;return E(p,n,t=>{null!=t&&e.push(t),e.push(null)},t=>{f(e,t)}),e=new _({objectMode:!0,writable:!1,read(){}})}throw new h(i,["Blob","ReadableStream","WritableStream","Stream","Iterable","AsyncIterable","Function","{ readable, writable } pair","Promise"],n)}}function Yt(){if(_t)return Et;_t=1;const{ObjectDefineProperties:e,ObjectGetOwnPropertyDescriptor:t,ObjectKeys:n,ObjectSetPrototypeOf:i}=de();Et=o;const s=Wt(),a=Vt();i(o.prototype,s.prototype),i(o,s);{const e=n(a.prototype);for(let t=0;t<e.length;t++){const n=e[t];o.prototype[n]||(o.prototype[n]=a.prototype[n])}}function o(e){if(!(this instanceof o))return new o(e);s.call(this,e),a.call(this,e),e?(this.allowHalfOpen=!1!==e.allowHalfOpen,!1===e.readable&&(this._readableState.readable=!1,this._readableState.ended=!0,this._readableState.endEmitted=!0),!1===e.writable&&(this._writableState.writable=!1,this._writableState.ending=!0,this._writableState.ended=!0,this._writableState.finished=!0)):this.allowHalfOpen=!0}let r,c;function d(){return void 0===r&&(r={}),r}return e(o.prototype,{writable:{__proto__:null,...t(a.prototype,"writable")},writableHighWaterMark:{__proto__:null,...t(a.prototype,"writableHighWaterMark")},writableObjectMode:{__proto__:null,...t(a.prototype,"writableObjectMode")},writableBuffer:{__proto__:null,...t(a.prototype,"writableBuffer")},writableLength:{__proto__:null,...t(a.prototype,"writableLength")},writableFinished:{__proto__:null,...t(a.prototype,"writableFinished")},writableCorked:{__proto__:null,...t(a.prototype,"writableCorked")},writableEnded:{__proto__:null,...t(a.prototype,"writableEnded")},writableNeedDrain:{__proto__:null,...t(a.prototype,"writableNeedDrain")},destroyed:{__proto__:null,get(){return void 0!==this._readableState&&void 0!==this._writableState&&this._readableState.destroyed&&this._writableState.destroyed},set(e){this._readableState&&this._writableState&&(this._readableState.destroyed=e,this._writableState.destroyed=e)}}}),o.fromWeb=function(e,t){return d().newStreamDuplexFromReadableWritablePair(e,t)},o.toWeb=function(e){return d().newReadableWritablePairFromDuplex(e)},o.from=function(e){return c||(c=Kt()),c(e,"body")},Et}function Xt(){if(zt)return Tt;zt=1;const{ObjectSetPrototypeOf:e,Symbol:t}=de();Tt=o;const{ERR_METHOD_NOT_IMPLEMENTED:n}=fe().codes,i=Yt(),{getHighWaterMark:s}=ht();e(o.prototype,i.prototype),e(o,i);const a=t("kCallback");function o(e){if(!(this instanceof o))return new o(e);const t=e?s(this,e,"readableHighWaterMark",!0):null;0===t&&(e={...e,highWaterMark:null,readableHighWaterMark:t,writableHighWaterMark:e.writableHighWaterMark||0}),i.call(this,e),this._readableState.sync=!1,this[a]=null,e&&("function"==typeof e.transform&&(this._transform=e.transform),"function"==typeof e.flush&&(this._flush=e.flush)),this.on("prefinish",c)}function r(e){"function"!=typeof this._flush||this.destroyed?(this.push(null),e&&e()):this._flush((t,n)=>{t?e?e(t):this.destroy(t):(null!=n&&this.push(n),this.push(null),e&&e())})}function c(){this._final!==r&&r.call(this)}return o.prototype._final=r,o.prototype._transform=function(e,t,i){throw new n("_transform()")},o.prototype._write=function(e,t,n){const i=this._readableState,s=this._writableState,o=i.length;this._transform(e,t,(e,t)=>{e?n(e):(null!=t&&this.push(t),s.ended||o===i.length||i.length<i.highWaterMark?n():this[a]=n)})},o.prototype._read=function(){if(this[a]){const e=this[a];this[a]=null,e()}},Tt}function Jt(){if(Nt)return kt;Nt=1;const{ObjectSetPrototypeOf:e}=de();kt=n;const t=Xt();function n(e){if(!(this instanceof n))return new n(e);t.call(this,e)}return e(n.prototype,t.prototype),e(n,t),n.prototype._transform=function(e,t,n){n(null,e)},kt}function Qt(){if(Rt)return Ct;Rt=1;const e=tt(),{ArrayIsArray:t,Promise:n,SymbolAsyncIterator:i,SymbolDispose:s}=de(),a=it(),{once:o}=Ue(),r=st(),c=Yt(),{aggregateTwoErrors:d,codes:{ERR_INVALID_ARG_TYPE:l,ERR_INVALID_RETURN_VALUE:p,ERR_MISSING_ARGS:u,ERR_STREAM_DESTROYED:m,ERR_STREAM_PREMATURE_CLOSE:h},AbortError:g}=fe(),{validateFunction:f,validateAbortSignal:y}=He(),{isIterable:b,isReadable:v,isReadableNodeStream:I,isNodeStream:x,isTransformStream:w,isWebStream:S,isReadableStream:A,isReadableFinished:E}=nt(),_=globalThis.AbortController||qe.AbortController;let T,z,k;function N(e,t,n){let i=!1;return e.on("close",()=>{i=!0}),{destroy:t=>{i||(i=!0,r.destroyer(e,t||new m("pipe")))},cleanup:a(e,{readable:t,writable:n},e=>{i=!e})}}function C(e){if(b(e))return e;if(I(e))return async function*(e){z||(z=Wt()),yield*z.prototype[i].call(e)}(e);throw new l("val",["Readable","Iterable","AsyncIterable"],e)}async function R(e,t,i,{end:s}){let o,r=null;const c=e=>{if(e&&(o=e),r){const e=r;r=null,e()}},l=()=>new n((e,t)=>{o?t(o):r=()=>{o?t(o):e()}});t.on("drain",c);const p=a(t,{readable:!1},c);try{t.writableNeedDrain&&await l();for await(const n of e)t.write(n)||await l();s&&(t.end(),await l()),i()}catch(e){i(o!==e?d(o,e):e)}finally{p(),t.off("drain",c)}}async function O(e,t,n,{end:i}){w(t)&&(t=t.writable);const s=t.getWriter();try{for await(const t of e)await s.ready,s.write(t).catch(()=>{});await s.ready,i&&await s.close(),n()}catch(e){try{await s.abort(e),n(e)}catch(e){n(e)}}}function j(n,i,a){if(1===n.length&&t(n[0])&&(n=n[0]),n.length<2)throw new u("streams");const o=new _,r=o.signal,d=null==a?void 0:a.signal,m=[];function h(){q(new g)}let f,E,z;y(d,"options.signal"),k=k||Ue().addAbortListener,d&&(f=k(d,h));const j=[];let D,L=0;function M(e){q(e,0===--L)}function q(t,n){var a;if(!t||E&&"ERR_STREAM_PREMATURE_CLOSE"!==E.code||(E=t),E||n){for(;j.length;)j.shift()(E);null===(a=f)||void 0===a||a[s](),o.abort(),n&&(E||m.forEach(e=>e()),e.nextTick(i,E,z))}}for(let B=0;B<n.length;B++){const F=n[B],H=B<n.length-1,G=B>0,W=H||!1!==(null==a?void 0:a.end),V=B===n.length-1;if(x(F)){if(W){const{destroy:Y,cleanup:X}=N(F,H,G);j.push(Y),v(F)&&V&&m.push(X)}function K(e){e&&"AbortError"!==e.name&&"ERR_STREAM_PREMATURE_CLOSE"!==e.code&&M(e)}F.on("error",K),v(F)&&V&&m.push(()=>{F.removeListener("error",K)})}if(0===B)if("function"==typeof F){if(D=F({signal:r}),!b(D))throw new p("Iterable, AsyncIterable or Stream","source",D)}else D=b(F)||I(F)||w(F)?F:c.from(F);else if("function"==typeof F){var U;if(D=w(D)?C(null===(U=D)||void 0===U?void 0:U.readable):C(D),D=F(D,{signal:r}),H){if(!b(D,!0))throw new p("AsyncIterable",`transform[${B-1}]`,D)}else{var $;T||(T=Jt());const J=new T({objectMode:!0}),Q=null===($=D)||void 0===$?void 0:$.then;if("function"==typeof Q)L++,Q.call(D,t=>{z=t,null!=t&&J.write(t),W&&J.end(),e.nextTick(M)},t=>{J.destroy(t),e.nextTick(M,t)});else if(b(D,!0))L++,R(D,J,M,{end:W});else{if(!A(D)&&!w(D))throw new p("AsyncIterable or Promise","destination",D);{const te=D.readable||D;L++,R(te,J,M,{end:W})}}D=J;const{destroy:Z,cleanup:ee}=N(D,!1,!0);j.push(Z),V&&m.push(ee)}}else if(x(F)){if(I(D)){L+=2;const ne=P(D,F,M,{end:W});v(F)&&V&&m.push(ne)}else if(w(D)||A(D)){const ie=D.readable||D;L++,R(ie,F,M,{end:W})}else{if(!b(D))throw new l("val",["Readable","Iterable","AsyncIterable","ReadableStream","TransformStream"],D);L++,R(D,F,M,{end:W})}D=F}else if(S(F)){if(I(D))L++,O(C(D),F,M,{end:W});else if(A(D)||b(D))L++,O(D,F,M,{end:W});else{if(!w(D))throw new l("val",["Readable","Iterable","AsyncIterable","ReadableStream","TransformStream"],D);L++,O(D.readable,F,M,{end:W})}D=F}else D=c.from(F)}return(null!=r&&r.aborted||null!=d&&d.aborted)&&e.nextTick(h),D}function P(t,n,i,{end:s}){let o=!1;if(n.on("close",()=>{o||i(new h)}),t.pipe(n,{end:!1}),s){function r(){o=!0,n.end()}E(t)?e.nextTick(r):t.once("end",r)}else i();return a(t,{readable:!0,writable:!1},e=>{const n=t._readableState;e&&"ERR_STREAM_PREMATURE_CLOSE"===e.code&&n&&n.ended&&!n.errored&&!n.errorEmitted?t.once("end",i).once("error",i):i(e)}),a(n,{readable:!1,writable:!0},i)}return Ct={pipelineImpl:j,pipeline:function(...e){return j(e,o(function(e){return f(e[e.length-1],"streams[stream.length - 1]"),e.pop()}(e)))}}}function Zt(){if(jt)return Ot;jt=1;const{pipeline:e}=Qt(),t=Yt(),{destroyer:n}=st(),{isNodeStream:i,isReadable:s,isWritable:a,isWebStream:o,isTransformStream:r,isWritableStream:c,isReadableStream:d}=nt(),{AbortError:l,codes:{ERR_INVALID_ARG_VALUE:p,ERR_MISSING_ARGS:u}}=fe(),m=it();return Ot=function(...h){if(0===h.length)throw new u("streams");if(1===h.length)return t.from(h[0]);const g=[...h];if("function"==typeof h[0]&&(h[0]=t.from(h[0])),"function"==typeof h[h.length-1]){const e=h.length-1;h[e]=t.from(h[e])}for(let e=0;e<h.length;++e)if(i(h[e])||o(h[e])){if(e<h.length-1&&!(s(h[e])||d(h[e])||r(h[e])))throw new p(`streams[${e}]`,g[e],"must be readable");if(e>0&&!(a(h[e])||c(h[e])||r(h[e])))throw new p(`streams[${e}]`,g[e],"must be writable")}let f,y,b,v,I;const x=h[0],w=e(h,function(e){const t=v;v=null,t?t(e):e?I.destroy(e):A||S||I.destroy()}),S=!!(a(x)||c(x)||r(x)),A=!!(s(w)||d(w)||r(w));if(I=new t({writableObjectMode:!(null==x||!x.writableObjectMode),readableObjectMode:!(null==w||!w.readableObjectMode),writable:S,readable:A}),S){if(i(x))I._write=function(e,t,n){x.write(e,t)?n():f=n},I._final=function(e){x.end(),y=e},x.on("drain",function(){if(f){const e=f;f=null,e()}});else if(o(x)){const e=(r(x)?x.writable:x).getWriter();I._write=async function(t,n,i){try{await e.ready,e.write(t).catch(()=>{}),i()}catch(e){i(e)}},I._final=async function(t){try{await e.ready,e.close().catch(()=>{}),y=t}catch(e){t(e)}}}const e=r(w)?w.readable:w;m(e,()=>{if(y){const e=y;y=null,e()}})}if(A)if(i(w))w.on("readable",function(){if(b){const e=b;b=null,e()}}),w.on("end",function(){I.push(null)}),I._read=function(){for(;;){const e=w.read();if(null===e)return void(b=I._read);if(!I.push(e))return}};else if(o(w)){const e=(r(w)?w.readable:w).getReader();I._read=async function(){for(;;)try{const{value:t,done:n}=await e.read();if(!I.push(t))return;if(n)return void I.push(null)}catch{return}}}return I._destroy=function(e,t){e||null===v||(e=new l),b=null,f=null,y=null,null===v?t(e):(v=t,i(w)&&n(w,e))},I},Ot}function en(){if(Lt)return Dt;Lt=1;const{ArrayPrototypePop:e,Promise:t}=de(),{isIterable:n,isNodeStream:i,isWebStream:s}=nt(),{pipelineImpl:a}=Qt(),{finished:o}=it();return tn(),Dt={finished:o,pipeline:function(...o){return new t((t,r)=>{let c,d;const l=o[o.length-1];if(l&&"object"==typeof l&&!i(l)&&!n(l)&&!s(l)){const t=e(o);c=t.signal,d=t.end}a(o,(e,n)=>{e?r(e):t(n)},{signal:c,end:d})})}}}function tn(){if(Mt)return ce.exports;Mt=1;const{Buffer:e}=p,{ObjectDefineProperty:t,ObjectKeys:n,ReflectApply:i}=de(),{promisify:{custom:s}}=Ue(),{streamReturningOperators:a,promiseReturningOperators:o}=function(){if(Pt)return Fe;Pt=1;const e=globalThis.AbortController||qe.AbortController,{codes:{ERR_INVALID_ARG_VALUE:t,ERR_INVALID_ARG_TYPE:n,ERR_MISSING_ARGS:i,ERR_OUT_OF_RANGE:s},AbortError:a}=fe(),{validateAbortSignal:o,validateInteger:r,validateObject:c}=He(),d=de().Symbol("kWeak"),l=de().Symbol("kResistStopPropagation"),{finished:p}=it(),u=Zt(),{addAbortSignalNoValidate:m}=ut(),{isWritable:h,isNodeStream:g}=nt(),{deprecate:f}=Ue(),{ArrayPrototypePush:y,Boolean:b,MathFloor:v,Number:I,NumberIsNaN:x,Promise:w,PromiseReject:S,PromiseResolve:A,PromisePrototypeThen:E,Symbol:_}=de(),T=_("kEmpty"),z=_("kEof");function k(e,t){if("function"!=typeof e)throw new n("fn",["Function","AsyncFunction"],e);null!=t&&c(t,"options"),null!=(null==t?void 0:t.signal)&&o(t.signal,"options.signal");let i=1;null!=(null==t?void 0:t.concurrency)&&(i=v(t.concurrency));let s=i-1;return null!=(null==t?void 0:t.highWaterMark)&&(s=v(t.highWaterMark)),r(i,"options.concurrency",1),r(s,"options.highWaterMark",0),s+=i,async function*(){const n=Ue().AbortSignalAny([null==t?void 0:t.signal].filter(b)),o=this,r=[],c={signal:n};let d,l,p=!1,u=0;function m(){p=!0,h()}function h(){u-=1,g()}function g(){l&&!p&&u<i&&r.length<s&&(l(),l=null)}!async function(){try{for await(let t of o){if(p)return;if(n.aborted)throw new a;try{if(t=e(t,c),t===T)continue;t=A(t)}catch(e){t=S(e)}u+=1,E(t,h,m),r.push(t),d&&(d(),d=null),!p&&(r.length>=s||u>=i)&&await new w(e=>{l=e})}r.push(z)}catch(e){const t=S(e);E(t,h,m),r.push(t)}finally{p=!0,d&&(d(),d=null)}}();try{for(;;){for(;r.length>0;){const e=await r[0];if(e===z)return;if(n.aborted)throw new a;e!==T&&(yield e),r.shift(),g()}await new w(e=>{d=e})}}finally{p=!0,l&&(l(),l=null)}}.call(this)}async function N(e,t=void 0){for await(const n of C.call(this,e,t))return!0;return!1}function C(e,t){if("function"!=typeof e)throw new n("fn",["Function","AsyncFunction"],e);return k.call(this,async function(t,n){return await e(t,n)?t:T},t)}class R extends i{constructor(){super("reduce"),this.message="Reduce of an empty stream requires an initial value"}}function O(e){if(e=I(e),x(e))return 0;if(e<0)throw new s("number",">= 0",e);return e}return Fe.streamReturningOperators={asIndexedPairs:f(function(e=void 0){return null!=e&&c(e,"options"),null!=(null==e?void 0:e.signal)&&o(e.signal,"options.signal"),async function*(){let t=0;for await(const i of this){var n;if(null!=e&&null!==(n=e.signal)&&void 0!==n&&n.aborted)throw new a({cause:e.signal.reason});yield[t++,i]}}.call(this)},"readable.asIndexedPairs will be removed in a future version."),drop:function(e,t=void 0){return null!=t&&c(t,"options"),null!=(null==t?void 0:t.signal)&&o(t.signal,"options.signal"),e=O(e),async function*(){var n;if(null!=t&&null!==(n=t.signal)&&void 0!==n&&n.aborted)throw new a;for await(const n of this){var i;if(null!=t&&null!==(i=t.signal)&&void 0!==i&&i.aborted)throw new a;e--<=0&&(yield n)}}.call(this)},filter:C,flatMap:function(e,t){const n=k.call(this,e,t);return async function*(){for await(const e of n)yield*e}.call(this)},map:k,take:function(e,t=void 0){return null!=t&&c(t,"options"),null!=(null==t?void 0:t.signal)&&o(t.signal,"options.signal"),e=O(e),async function*(){var n;if(null!=t&&null!==(n=t.signal)&&void 0!==n&&n.aborted)throw new a;for await(const n of this){var i;if(null!=t&&null!==(i=t.signal)&&void 0!==i&&i.aborted)throw new a;if(e-- >0&&(yield n),e<=0)return}}.call(this)},compose:function(e,n){if(null!=n&&c(n,"options"),null!=(null==n?void 0:n.signal)&&o(n.signal,"options.signal"),g(e)&&!h(e))throw new t("stream",e,"must be writable");const i=u(this,e);return null!=n&&n.signal&&m(n.signal,i),i}},Fe.promiseReturningOperators={every:async function(e,t=void 0){if("function"!=typeof e)throw new n("fn",["Function","AsyncFunction"],e);return!await N.call(this,async(...t)=>!await e(...t),t)},forEach:async function(e,t){if("function"!=typeof e)throw new n("fn",["Function","AsyncFunction"],e);for await(const n of k.call(this,async function(t,n){return await e(t,n),T},t));},reduce:async function(t,i,s){var r;if("function"!=typeof t)throw new n("reducer",["Function","AsyncFunction"],t);null!=s&&c(s,"options"),null!=(null==s?void 0:s.signal)&&o(s.signal,"options.signal");let u=arguments.length>1;if(null!=s&&null!==(r=s.signal)&&void 0!==r&&r.aborted){const e=new a(void 0,{cause:s.signal.reason});throw this.once("error",()=>{}),await p(this.destroy(e)),e}const m=new e,h=m.signal;if(null!=s&&s.signal){const e={once:!0,[d]:this,[l]:!0};s.signal.addEventListener("abort",()=>m.abort(),e)}let g=!1;try{for await(const e of this){var f;if(g=!0,null!=s&&null!==(f=s.signal)&&void 0!==f&&f.aborted)throw new a;u?i=await t(i,e,{signal:h}):(i=e,u=!0)}if(!g&&!u)throw new R}finally{m.abort()}return i},toArray:async function(e){null!=e&&c(e,"options"),null!=(null==e?void 0:e.signal)&&o(e.signal,"options.signal");const t=[];for await(const i of this){var n;if(null!=e&&null!==(n=e.signal)&&void 0!==n&&n.aborted)throw new a(void 0,{cause:e.signal.reason});y(t,i)}return t},some:N,find:async function(e,t){for await(const n of C.call(this,e,t))return n}},Fe}(),{codes:{ERR_ILLEGAL_CONSTRUCTOR:r}}=fe(),c=Zt(),{setDefaultHighWaterMark:d,getDefaultHighWaterMark:l}=ht(),{pipeline:u}=Qt(),{destroyer:m}=st(),h=it(),g=en(),f=nt(),y=ce.exports=at().Stream;y.isDestroyed=f.isDestroyed,y.isDisturbed=f.isDisturbed,y.isErrored=f.isErrored,y.isReadable=f.isReadable,y.isWritable=f.isWritable,y.Readable=Wt();for(const v of n(a)){const I=a[v];function x(...e){if(new.target)throw r();return y.Readable.from(i(I,this,e))}t(x,"name",{__proto__:null,value:I.name}),t(x,"length",{__proto__:null,value:I.length}),t(y.Readable.prototype,v,{__proto__:null,value:x,enumerable:!1,configurable:!0,writable:!0})}for(const w of n(o)){const S=o[w];function A(...e){if(new.target)throw r();return i(S,this,e)}t(A,"name",{__proto__:null,value:S.name}),t(A,"length",{__proto__:null,value:S.length}),t(y.Readable.prototype,w,{__proto__:null,value:A,enumerable:!1,configurable:!0,writable:!0})}y.Writable=Vt(),y.Duplex=Yt(),y.Transform=Xt(),y.PassThrough=Jt(),y.pipeline=u;const{addAbortSignal:b}=ut();return y.addAbortSignal=b,y.finished=h,y.destroy=m,y.compose=c,y.setDefaultHighWaterMark=d,y.getDefaultHighWaterMark=l,t(y,"promises",{__proto__:null,configurable:!0,enumerable:!0,get:()=>g}),t(u,s,{__proto__:null,enumerable:!0,get:()=>g.pipeline}),t(h,s,{__proto__:null,enumerable:!0,get:()=>g.finished}),y.Stream=y,y._isUint8Array=function(e){return e instanceof Uint8Array},y._uint8ArrayToBuffer=function(t){return e.from(t.buffer,t.byteOffset,t.byteLength)},ce.exports}function nn(){return qt||(qt=1,function(e){const t=l;if(t&&"disable"===process.env.READABLE_STREAM){const n=t.promises;e.exports._uint8ArrayToBuffer=t._uint8ArrayToBuffer,e.exports._isUint8Array=t._isUint8Array,e.exports.isDisturbed=t.isDisturbed,e.exports.isErrored=t.isErrored,e.exports.isReadable=t.isReadable,e.exports.Readable=t.Readable,e.exports.Writable=t.Writable,e.exports.Duplex=t.Duplex,e.exports.Transform=t.Transform,e.exports.PassThrough=t.PassThrough,e.exports.addAbortSignal=t.addAbortSignal,e.exports.finished=t.finished,e.exports.destroy=t.destroy,e.exports.pipeline=t.pipeline,e.exports.compose=t.compose,Object.defineProperty(t,"promises",{configurable:!0,enumerable:!0,get:()=>n}),e.exports.Stream=t.Stream}else{const t=tn(),n=en(),i=t.Readable.destroy;e.exports=t.Readable,e.exports._uint8ArrayToBuffer=t._uint8ArrayToBuffer,e.exports._isUint8Array=t._isUint8Array,e.exports.isDisturbed=t.isDisturbed,e.exports.isErrored=t.isErrored,e.exports.isReadable=t.isReadable,e.exports.Readable=t.Readable,e.exports.Writable=t.Writable,e.exports.Duplex=t.Duplex,e.exports.Transform=t.Transform,e.exports.PassThrough=t.PassThrough,e.exports.addAbortSignal=t.addAbortSignal,e.exports.finished=t.finished,e.exports.destroy=t.destroy,e.exports.destroy=i,e.exports.pipeline=t.pipeline,e.exports.compose=t.compose,Object.defineProperty(t,"promises",{configurable:!0,enumerable:!0,get:()=>n}),e.exports.Stream=t.Stream}e.exports.default=e.exports}(re)),re.exports}var sn=function(){if(Bt)return V.exports;Bt=1;const e=a,{inherits:t,format:n}=o,{pipeline:i,compose:s}=r,l=function(){if(W)return K.exports;W=1;const e=X(),t=J();let n=0;function i(i,s={}){let a=!1;if(void 0!==i.default&&(i=i.default),"function"!=typeof i)throw new TypeError(`fastify-plugin expects a function, instead got a '${typeof i}'`);if("string"==typeof s&&(s={fastify:s}),"object"!=typeof s||Array.isArray(s)||null===s)throw new TypeError("The options object should be an object");if(void 0!==s.fastify&&"string"!=typeof s.fastify)throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof s.fastify}'`);s.name||(a=!0,s.name=e(i)+"-auto-"+n++),i[Symbol.for("skip-override")]=!0!==s.encapsulate,i[Symbol.for("fastify.display-name")]=s.name,i[Symbol.for("plugin-meta")]=s,i.default||(i.default=i);const o=t(s.name);return a||i[o]||(i[o]=i),i}return K.exports=i,K.exports.default=i,K.exports.fastifyPlugin=i,K.exports}(),p=function(){if(Q)return Z.exports;function e(t){if(!new.target)return new e(t);const{supportedValues:n=[],cache:i}=t&&"object"==typeof t&&t||{};this.supportedValues=n,this.cache=i}function t(e,t){if(!e||!Array.isArray(t)||0===t.length)return null;if("*"===e)return t[0];let o=null,r=1/0,c=0;return function(e,t){let o,r="",c=n;for(let d=0,l=e.length;d<l;++d){const l=e[d];if(" "!==l&&"\t"!==l)if(";"!==l){if(","!==l){if(c===s){if("q"===l||"="===l)continue;if("."===l||"1"===l||"0"===l||"2"===l||"3"===l||"4"===l||"5"===l||"6"===l||"7"===l||"8"===l||"9"===l){o+=l;continue}}else if(c===n){c=i,r+=l;continue}if(c===i){const t=e[d-1];" "!==t&&"\t"!==t||(r=""),r+=l;continue}if(t(r,parseFloat(o)||0)){c=a;break}c=n,r=l,o=""}else if(c===i){if(t(r,1)){c=a;break}c=n,r=""}else if(c===s){if(t(r,parseFloat(o)||0)){c=a;break}c=n,r="",o=""}}else c===i&&(c=s,o="")}c===i?t(r,1):c===s&&t(r,parseFloat(o)||0)}(e,function(e,n){if(0===n||c>n)return!1;const i="*"===e&&t[0]||e,s=t.indexOf(i);return-1!==s&&(0===s&&1===n?(o=i,!0):((c<n||r>s)&&(o=i,r=s,c=n),!1))}),o}Q=1,e.prototype.negotiate=function(e){return"string"!=typeof e?null:this.cache?(this.cache.has(e)||this.cache.set(e,t(e,this.supportedValues)),this.cache.get(e)):t(e,this.supportedValues)};const n=0,i=1,s=2,a=3;return Z.exports=t,Z.exports.default=t,Z.exports.negotiate=t,Z.exports.Negotiator=e,Z.exports}(),u=te?ee:(te=1,ee=ie),{Minipass:h}=(ne||(ne=1,function(e){var t=se&&se.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.Minipass=e.isWritable=e.isReadable=e.isStream=void 0;const n="object"==typeof process&&process?process:{stdout:null,stderr:null},i=c,s=t(r),a=d;e.isStream=t=>!!t&&"object"==typeof t&&(t instanceof H||t instanceof s.default||(0,e.isReadable)(t)||(0,e.isWritable)(t)),e.isReadable=e=>!!e&&"object"==typeof e&&e instanceof i.EventEmitter&&"function"==typeof e.pipe&&e.pipe!==s.default.Writable.prototype.pipe,e.isWritable=e=>!!e&&"object"==typeof e&&e instanceof i.EventEmitter&&"function"==typeof e.write&&"function"==typeof e.end;const o=Symbol("EOF"),l=Symbol("maybeEmitEnd"),p=Symbol("emittedEnd"),u=Symbol("emittingEnd"),m=Symbol("emittedError"),h=Symbol("closed"),g=Symbol("read"),f=Symbol("flush"),y=Symbol("flushChunk"),b=Symbol("encoding"),v=Symbol("decoder"),I=Symbol("flowing"),x=Symbol("paused"),w=Symbol("resume"),S=Symbol("buffer"),A=Symbol("pipes"),E=Symbol("bufferLength"),_=Symbol("bufferPush"),T=Symbol("bufferShift"),z=Symbol("objectMode"),k=Symbol("destroyed"),N=Symbol("error"),C=Symbol("emitData"),R=Symbol("emitEnd"),O=Symbol("emitEnd2"),j=Symbol("async"),P=Symbol("abort"),D=Symbol("aborted"),L=Symbol("signal"),M=Symbol("dataListeners"),q=Symbol("discarded"),U=e=>Promise.resolve().then(e),$=e=>e();class B{src;dest;opts;ondrain;constructor(e,t,n){this.src=e,this.dest=t,this.opts=n,this.ondrain=()=>e[w](),this.dest.on("drain",this.ondrain)}unpipe(){this.dest.removeListener("drain",this.ondrain)}proxyErrors(e){}end(){this.unpipe(),this.opts.end&&this.dest.end()}}class F extends B{unpipe(){this.src.removeListener("error",this.proxyErrors),super.unpipe()}constructor(e,t,n){super(e,t,n),this.proxyErrors=e=>this.dest.emit("error",e),e.on("error",this.proxyErrors)}}class H extends i.EventEmitter{[I]=!1;[x]=!1;[A]=[];[S]=[];[z];[b];[j];[v];[o]=!1;[p]=!1;[u]=!1;[h]=!1;[m]=null;[E]=0;[k]=!1;[L];[D]=!1;[M]=0;[q]=!1;writable=!0;readable=!0;constructor(...e){const t=e[0]||{};if(super(),t.objectMode&&"string"==typeof t.encoding)throw new TypeError("Encoding and objectMode may not be used together");var n;t.objectMode?(this[z]=!0,this[b]=null):!(n=t).objectMode&&n.encoding&&"buffer"!==n.encoding?(this[b]=t.encoding,this[z]=!1):(this[z]=!1,this[b]=null),this[j]=!!t.async,this[v]=this[b]?new a.StringDecoder(this[b]):null,t&&!0===t.debugExposeBuffer&&Object.defineProperty(this,"buffer",{get:()=>this[S]}),t&&!0===t.debugExposePipes&&Object.defineProperty(this,"pipes",{get:()=>this[A]});const{signal:i}=t;i&&(this[L]=i,i.aborted?this[P]():i.addEventListener("abort",()=>this[P]()))}get bufferLength(){return this[E]}get encoding(){return this[b]}set encoding(e){throw new Error("Encoding must be set at instantiation time")}setEncoding(e){throw new Error("Encoding must be set at instantiation time")}get objectMode(){return this[z]}set objectMode(e){throw new Error("objectMode must be set at instantiation time")}get async(){return this[j]}set async(e){this[j]=this[j]||!!e}[P](){this[D]=!0,this.emit("abort",this[L]?.reason),this.destroy(this[L]?.reason)}get aborted(){return this[D]}set aborted(e){}write(e,t,n){if(this[D])return!1;if(this[o])throw new Error("write after end");if(this[k])return this.emit("error",Object.assign(new Error("Cannot call write after a stream was destroyed"),{code:"ERR_STREAM_DESTROYED"})),!0;"function"==typeof t&&(n=t,t="utf8"),t||(t="utf8");const i=this[j]?U:$;if(!this[z]&&!Buffer.isBuffer(e))if(s=e,!Buffer.isBuffer(s)&&ArrayBuffer.isView(s))e=Buffer.from(e.buffer,e.byteOffset,e.byteLength);else if((e=>e instanceof ArrayBuffer||!!e&&"object"==typeof e&&e.constructor&&"ArrayBuffer"===e.constructor.name&&e.byteLength>=0)(e))e=Buffer.from(e);else if("string"!=typeof e)throw new Error("Non-contiguous data written to non-objectMode stream");var s;return this[z]?(this[I]&&0!==this[E]&&this[f](!0),this[I]?this.emit("data",e):this[_](e),0!==this[E]&&this.emit("readable"),n&&i(n),this[I]):e.length?("string"!=typeof e||t===this[b]&&!this[v]?.lastNeed||(e=Buffer.from(e,t)),Buffer.isBuffer(e)&&this[b]&&(e=this[v].write(e)),this[I]&&0!==this[E]&&this[f](!0),this[I]?this.emit("data",e):this[_](e),0!==this[E]&&this.emit("readable"),n&&i(n),this[I]):(0!==this[E]&&this.emit("readable"),n&&i(n),this[I])}read(e){if(this[k])return null;if(this[q]=!1,0===this[E]||0===e||e&&e>this[E])return this[l](),null;this[z]&&(e=null),this[S].length>1&&!this[z]&&(this[S]=[this[b]?this[S].join(""):Buffer.concat(this[S],this[E])]);const t=this[g](e||null,this[S][0]);return this[l](),t}[g](e,t){if(this[z])this[T]();else{const n=t;e===n.length||null===e?this[T]():"string"==typeof n?(this[S][0]=n.slice(e),t=n.slice(0,e),this[E]-=e):(this[S][0]=n.subarray(e),t=n.subarray(0,e),this[E]-=e)}return this.emit("data",t),this[S].length||this[o]||this.emit("drain"),t}end(e,t,n){return"function"==typeof e&&(n=e,e=void 0),"function"==typeof t&&(n=t,t="utf8"),void 0!==e&&this.write(e,t),n&&this.once("end",n),this[o]=!0,this.writable=!1,!this[I]&&this[x]||this[l](),this}[w](){this[k]||(this[M]||this[A].length||(this[q]=!0),this[x]=!1,this[I]=!0,this.emit("resume"),this[S].length?this[f]():this[o]?this[l]():this.emit("drain"))}resume(){return this[w]()}pause(){this[I]=!1,this[x]=!0,this[q]=!1}get destroyed(){return this[k]}get flowing(){return this[I]}get paused(){return this[x]}[_](e){this[z]?this[E]+=1:this[E]+=e.length,this[S].push(e)}[T](){return this[z]?this[E]-=1:this[E]-=this[S][0].length,this[S].shift()}[f](e=!1){do{}while(this[y](this[T]())&&this[S].length);e||this[S].length||this[o]||this.emit("drain")}[y](e){return this.emit("data",e),this[I]}pipe(e,t){if(this[k])return e;this[q]=!1;const i=this[p];return t=t||{},e===n.stdout||e===n.stderr?t.end=!1:t.end=!1!==t.end,t.proxyErrors=!!t.proxyErrors,i?t.end&&e.end():(this[A].push(t.proxyErrors?new F(this,e,t):new B(this,e,t)),this[j]?U(()=>this[w]()):this[w]()),e}unpipe(e){const t=this[A].find(t=>t.dest===e);t&&(1===this[A].length?(this[I]&&0===this[M]&&(this[I]=!1),this[A]=[]):this[A].splice(this[A].indexOf(t),1),t.unpipe())}addListener(e,t){return this.on(e,t)}on(e,t){const n=super.on(e,t);if("data"===e)this[q]=!1,this[M]++,this[A].length||this[I]||this[w]();else if("readable"===e&&0!==this[E])super.emit("readable");else if((e=>"end"===e||"finish"===e||"prefinish"===e)(e)&&this[p])super.emit(e),this.removeAllListeners(e);else if("error"===e&&this[m]){const e=t;this[j]?U(()=>e.call(this,this[m])):e.call(this,this[m])}return n}removeListener(e,t){return this.off(e,t)}off(e,t){const n=super.off(e,t);return"data"===e&&(this[M]=this.listeners("data").length,0!==this[M]||this[q]||this[A].length||(this[I]=!1)),n}removeAllListeners(e){const t=super.removeAllListeners(e);return"data"!==e&&void 0!==e||(this[M]=0,this[q]||this[A].length||(this[I]=!1)),t}get emittedEnd(){return this[p]}[l](){this[u]||this[p]||this[k]||0!==this[S].length||!this[o]||(this[u]=!0,this.emit("end"),this.emit("prefinish"),this.emit("finish"),this[h]&&this.emit("close"),this[u]=!1)}emit(e,...t){const n=t[0];if("error"!==e&&"close"!==e&&e!==k&&this[k])return!1;if("data"===e)return!(!this[z]&&!n)&&(this[j]?(U(()=>this[C](n)),!0):this[C](n));if("end"===e)return this[R]();if("close"===e){if(this[h]=!0,!this[p]&&!this[k])return!1;const e=super.emit("close");return this.removeAllListeners("close"),e}if("error"===e){this[m]=n,super.emit(N,n);const e=!(this[L]&&!this.listeners("error").length)&&super.emit("error",n);return this[l](),e}if("resume"===e){const e=super.emit("resume");return this[l](),e}if("finish"===e||"prefinish"===e){const t=super.emit(e);return this.removeAllListeners(e),t}const i=super.emit(e,...t);return this[l](),i}[C](e){for(const t of this[A])!1===t.dest.write(e)&&this.pause();const t=!this[q]&&super.emit("data",e);return this[l](),t}[R](){return!this[p]&&(this[p]=!0,this.readable=!1,this[j]?(U(()=>this[O]()),!0):this[O]())}[O](){if(this[v]){const e=this[v].end();if(e){for(const t of this[A])t.dest.write(e);this[q]||super.emit("data",e)}}for(const e of this[A])e.end();const e=super.emit("end");return this.removeAllListeners("end"),e}async collect(){const e=Object.assign([],{dataLength:0});this[z]||(e.dataLength=0);const t=this.promise();return this.on("data",t=>{e.push(t),this[z]||(e.dataLength+=t.length)}),await t,e}async concat(){if(this[z])throw new Error("cannot concat in objectMode");const e=await this.collect();return this[b]?e.join(""):Buffer.concat(e,e.dataLength)}async promise(){return new Promise((e,t)=>{this.on(k,()=>t(new Error("stream destroyed"))),this.on("error",e=>t(e)),this.on("end",()=>e())})}[Symbol.asyncIterator](){this[q]=!1;let e=!1;const t=async()=>(this.pause(),e=!0,{value:void 0,done:!0});return{next:()=>{if(e)return t();const n=this.read();if(null!==n)return Promise.resolve({done:!1,value:n});if(this[o])return t();let i,s;const a=e=>{this.off("data",r),this.off("end",c),this.off(k,d),t(),s(e)},r=e=>{this.off("error",a),this.off("end",c),this.off(k,d),this.pause(),i({value:e,done:!!this[o]})},c=()=>{this.off("error",a),this.off("data",r),this.off(k,d),t(),i({done:!0,value:void 0})},d=()=>a(new Error("stream destroyed"));return new Promise((e,t)=>{s=t,i=e,this.once(k,d),this.once("error",a),this.once("end",c),this.once("data",r)})},throw:t,return:t,[Symbol.asyncIterator](){return this},[Symbol.asyncDispose]:async()=>{}}}[Symbol.iterator](){this[q]=!1;let e=!1;const t=()=>(this.pause(),this.off(N,t),this.off(k,t),this.off("end",t),e=!0,{done:!0,value:void 0});return this.once("end",t),this.once(N,t),this.once(k,t),{next:()=>{if(e)return t();const n=this.read();return null===n?t():{done:!1,value:n}},throw:t,return:t,[Symbol.iterator](){return this},[Symbol.dispose]:()=>{}}}destroy(e){return this[k]?(e?this.emit("error",e):this.emit(k),this):(this[k]=!0,this[q]=!0,this[S].length=0,this[E]=0,"function"!=typeof this.close||this[h]||this.close(),e?this.emit("error",e):this.emit(k),this)}static get isStream(){return e.isStream}}e.Minipass=H}(se)),se),{Readable:g}=nn(),{computeSyncThreshold:f,isStream:y,isGzip:b,isDeflate:v,intoAsyncIterator:I,isWebReadableStream:x,isFetchResponse:w,webStreamToNodeReadable:S,unwrapFetchResponse:A,createPeekTransform:E}=function(){if($t)return Ut;$t=1;const{Readable:e}=r,{availableParallelism:t}=m,{Transform:n}=nn();return Ut={computeSyncThreshold:function(e=t()){const n=65536>>3*(Math.min(e,4)-1);return Math.min(Math.max(n,4096),65536)},isZstd:function(e){return"object"==typeof e&&null!==e&&e.length>3&&40===e[0]&&181===e[1]&&47===e[2]&&253===e[3]},isGzip:function(e){return"object"==typeof e&&null!==e&&e.length>2&&31===e[0]&&139===e[1]&&8===e[2]},isDeflate:function(e){return"object"==typeof e&&null!==e&&e.length>1&&8==(15&e[0])&&!(128&e[0])&&((e[0]<<8)+e[1])%31==0},isStream:function(e){return null!==e&&"object"==typeof e&&"function"==typeof e.pipe},intoAsyncIterator:async function*(e){if("object"==typeof e){if(Buffer.isBuffer(e))return void(yield e);if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))return void(yield Buffer.from(e));if(Symbol.iterator in e){for(const t of e)yield t;return}if(Symbol.asyncIterator in e){for await(const t of e)yield t;return}}yield e},isWebReadableStream:function(e){return e instanceof ReadableStream},isFetchResponse:function(e){return e instanceof Response},webStreamToNodeReadable:function(t){return e.fromWeb(t)},unwrapFetchResponse:function(e,t){e.code(t.status);for(const[n,i]of t.headers)e.header(n,i);return t.body},createPeekTransform:function(e,t=10){const i=[];let s=0,a=null,o=null;const r=new n({transform:(e,n,o)=>null!==a?a.write(e,n,o):(s+=e.length,i.push(e),s<t?o():void p(o)),flush(e){o=e,null!==a?a.end():p(t=>{t?(o=null,e(t)):a.end()})}});function c(e){r.push(e)}function d(e){r.destroy(e)}function l(){o&&o(),a.off("data",c),a.off("error",d),a.off("end",l),a=null,o=null,r.push(null)}function p(n){const s=Buffer.concat(i);try{a=e(s.subarray(0,t)),a.on("data",c),a.on("error",d),a.on("end",l),a.write(s,n),i.length=0}catch(e){n(e)}}return r}},Ut}(),_=f(),T=ce("FST_CP_ERR_INVALID_CONTENT_ENCODING","Unsupported Content-Encoding: %s",415),z=ce("FST_CP_ERR_INVALID_CONTENT","Could not decompress the request payload using the provided encoding",400);function k(e,t,n){const i=R(t),s=P(t);t.encodings&&t.encodings.length<1?n(new Error("The `encodings` option array must have at least 1 item.")):t.requestEncodings&&t.requestEncodings.length<1?n(new Error("The `requestEncodings` option array must have at least 1 item.")):i.encodings.length<1?n(new Error("None of the passed `encodings` were supported — compression not possible.")):s.encodings.length<1?n(new Error("None of the passed `requestEncodings` were supported — request decompression not possible.")):!s.forceEncoding||s.encodings.includes(s.forceEncoding)?(e.decorateReply("compress",null),e.addHook("onRoute",e=>{if(void 0!==e.compress){if("object"==typeof e.compress){D(0,Object.assign({},i,R(e.compress)),e)}else if(!1!==e.compress)throw new Error("Unknown value for route compress configuration")}else i.global?D(0,i,e):D(0,i,e,!0);if(void 0!==e.decompress){if("object"==typeof e.decompress){L(0,Object.assign({},s,P(e.decompress)),e)}else if(!1!==e.decompress)throw new Error("Unknown value for route decompress configuration")}else s.global&&L(0,s,e)}),n()):n(new Error(`Unsupported decompression encoding ${t.forceRequestEncoding}.`))}const N=/^text\/(?!event-stream)|(?:\+|\/)json(?:;|$)|(?:\+|\/)text(?:;|$)|(?:\+|\/)xml(?:;|$)|octet-stream(?:;|$)/u,C={params:{[e.constants.BROTLI_PARAM_QUALITY]:4}};function R(t){if(!t)return;const n={global:"boolean"==typeof t.globalCompression?t.globalCompression:"boolean"!=typeof t.global||t.global};n.removeContentLengthHeader="boolean"!=typeof t.removeContentLengthHeader||t.removeContentLengthHeader,n.brotliOptions={...C,...t.brotliOptions},n.zlibOptions=t.zlibOptions,n.onUnsupportedEncoding=t.onUnsupportedEncoding,n.inflateIfDeflated=!0===t.inflateIfDeflated,n.threshold="number"==typeof t.threshold?t.threshold:1024,n.syncThreshold="number"==typeof t.syncThreshold?t.syncThreshold:_,n.compressibleTypes=t.customTypes instanceof RegExp?t.customTypes.test.bind(t.customTypes):"function"==typeof t.customTypes?t.customTypes:N.test.bind(N),n.compressStream={br:()=>((t.zlib||e).createBrotliCompress||e.createBrotliCompress)(n.brotliOptions),gzip:()=>((t.zlib||e).createGzip||e.createGzip)(n.zlibOptions),deflate:()=>((t.zlib||e).createDeflate||e.createDeflate)(n.zlibOptions)},"function"==typeof((t.zlib||e).createZstdCompress||e.createZstdCompress)&&(n.compressStream.zstd=()=>((t.zlib||e).createZstdCompress||e.createZstdCompress)(n.zlibOptions)),n.compressSync={};for(const[e,i,s,a]of[["br","createBrotliCompress","brotliCompressSync",n.brotliOptions],["gzip","createGzip","gzipSync",n.zlibOptions],["deflate","createDeflate","deflateSync",n.zlibOptions],["zstd","createZstdCompress","zstdCompressSync",n.zlibOptions]]){const o=O(t.zlib,i,s,a);void 0!==o&&(n.compressSync[e]=o)}n.uncompressStream={br:()=>((t.zlib||e).createBrotliDecompress||e.createBrotliDecompress)(n.brotliOptions),gzip:()=>((t.zlib||e).createGunzip||e.createGunzip)(n.zlibOptions),deflate:()=>((t.zlib||e).createInflate||e.createInflate)(n.zlibOptions)},"function"==typeof((t.zlib||e).createZstdDecompress||e.createZstdDecompress)&&(n.uncompressStream.zstd=()=>((t.zlib||e).createZstdDecompress||e.createZstdDecompress)(n.zlibOptions));const i=["br","gzip","deflate","identity"];return"function"==typeof e.createZstdCompress&&i.unshift("zstd"),n.encodings=Array.isArray(t.encodings)?i.filter(e=>t.encodings.includes(e)).sort((e,n)=>t.encodings.indexOf(e)-t.encodings.indexOf(n)):i,n}function O(t,n,i,s){let a;if(null!=t&&"function"==typeof t[i])a=t[i];else{if(null!=t&&"function"==typeof t[n]||"function"!=typeof e[i])return;a=e[i]}return e=>a(e,s)}function j(e,t,n,i,s){if(e.syncThreshold<=0||s>e.syncThreshold)return null;const a=e.compressSync[n];if(void 0===a)return null;if("string"!=typeof i&&!Buffer.isBuffer(i))return null;if(!1===e.removeContentLengthHeader&&void 0!==t.getHeader("content-length"))return null;const o=Buffer.isBuffer(i)?i:Buffer.from(i);return 0!==Y(o)?o:a(o)}function P(t){if(!t)return;const n=t.zlib||e,i={global:"boolean"==typeof t.globalDecompression?t.globalDecompression:"boolean"!=typeof t.global||t.global,onUnsupportedRequestEncoding:t.onUnsupportedRequestEncoding,onInvalidRequestPayload:t.onInvalidRequestPayload,decompressStream:{br:n.createBrotliDecompress||e.createBrotliDecompress,gzip:n.createGunzip||e.createGunzip,deflate:n.createInflate||e.createInflate},encodings:[],forceEncoding:null};"function"==typeof(n.createZstdDecompress||e.createZstdDecompress)&&(i.decompressStream.zstd=n.createZstdDecompress||e.createZstdDecompress);const s=["br","gzip","deflate","identity"];return"function"==typeof e.createZstdCompress&&s.unshift("zstd"),i.encodings=Array.isArray(t.requestEncodings)?s.filter(e=>t.requestEncodings.includes(e)).sort((e,n)=>t.requestEncodings.indexOf(e)-t.requestEncodings.indexOf(n)):s,t.forceRequestEncoding&&(i.forceEncoding=t.forceRequestEncoding,i.encodings.includes(t.forceRequestEncoding)&&(i.encodings=[t.forceRequestEncoding])),i}function D(e,t,n,s){Array.isArray(n.onRequest)?n.onRequest.push(o):"function"==typeof n.onRequest?n.onRequest=[n.onRequest,o]:n.onRequest=[o];const a=function(e){return function(t){if(null==t)return void this.send(new Error("Internal server error"));if(w(t)){if(null===t.body)return this.send(t);t=A(this,t)}let n,s;const a=void 0!==this.request.headers["x-no-compression"]||!1===G(this.getHeader("Content-Type")||"application/json",e.compressibleTypes)||null==(s=H(e.encodings,this.request))||"identity"===s;if(null==s&&null!=e.onUnsupportedEncoding){const t=this.request.headers["accept-encoding"];let n;try{n=e.onUnsupportedEncoding(t,this.request,this)}catch(e){n=e}return this.send(n)}if(a)return e.inflateIfDeflated&&y(n=ae(t,this.serialize.bind(this)))&&(void 0===s?this.removeHeader("Content-Encoding"):this.header("Content-Encoding","identity"),i(n,t=re(e.uncompressStream),q.bind(this))),this.send(t);if("function"!=typeof t.pipe&&(x(t)?t=S(t):Buffer.isBuffer(t)||"string"==typeof t||(t=this.serialize(t))),"function"!=typeof t.pipe){const n=Buffer.byteLength(t);if(n<e.threshold)return this.send(t);let i=null;try{i=j(e,this,s,t,n)}catch(e){return this.send(e)}if(null!==i)return M(this),this.header("Content-Encoding",s),this.header("Content-Length",i.length),this.send(i);t=g.from(I(t))}return M(this),this.header("Content-Encoding",s),e.removeContentLengthHeader&&this.removeHeader("content-length"),n=oe(e.compressStream,s),i(t,n,q.bind(this)),this.send(n)}}(t);function o(e,t,n){t.compress=a,n()}function r(e,n,s,a){if(w(s)&&(s=A(n,s)),null==s)return a(null,s);const o=n.getHeader("Content-Encoding");if(o&&"identity"!==o)return a(null,s);let r,c;const d=void 0!==e.headers["x-no-compression"]||206===n.statusCode||void 0!==n.getHeader("Content-Range")||!1===G(n.getHeader("Content-Type")||"application/json",t.compressibleTypes)||null==(c=H(t.encodings,e))||"identity"===c;if(null==c&&null!=t.onUnsupportedEncoding){const i=e.headers["accept-encoding"];try{return a(null,t.onUnsupportedEncoding(i,n.request,n))}catch(e){return a(e)}}if(d)return t.inflateIfDeflated&&y(r=ae(s))&&(void 0===c?n.removeHeader("Content-Encoding"):n.header("Content-Encoding","identity"),i(r,s=re(t.uncompressStream),q.bind(n))),a(null,s);if("function"!=typeof s.pipe)if(x(s))s=S(s);else{const e=Buffer.byteLength(s);if(e<t.threshold)return a();let i=null;try{i=j(t,n,c,s,e)}catch(e){return a(e)}if(null!==i)return M(n),n.header("Content-Encoding",c),n.header("Content-Length",i.length),a(null,i);s=g.from(I(s))}M(n),n.header("Content-Encoding",c),t.removeContentLengthHeader&&n.removeHeader("content-length"),r=oe(t.compressStream,c),i(s,r,q.bind(n)),a(null,r)}s||(Array.isArray(n.onSend)?n.onSend.push(r):"function"==typeof n.onSend?n.onSend=[n.onSend,r]:n.onSend=[r])}function L(e,t,n){function s(e,n,s,a){let o=t.forceEncoding;if(o||(o=e.headers["content-encoding"]),!o)return a(null,s);if(!t.encodings.includes(o)){let n;if(t.onUnsupportedRequestEncoding)try{n=t.onUnsupportedRequestEncoding(o,e)}catch{n=void 0}return n||(n=new T(o)),a(n)}if("identity"===o)return a(null,s);const r=t.decompressStream[o]();r.receivedEncodedLength=0,r.on("error",B.bind(this,e,t,o)),r.pause(),s.on("data",U.bind(r)),s.on("end",$),i(s,r,()=>{}),a(null,r)}Array.isArray(n.preParsing)?n.preParsing.unshift(s):"function"==typeof n.preParsing?n.preParsing=[s,n.preParsing]:n.preParsing=[s]}function M(e){if(e.hasHeader("Vary")){const t=e.getHeader("Vary"),n=Array.isArray(t)?t:[t];n.some(e=>e.includes("accept-encoding"))||e.header("Vary",n.concat("accept-encoding").join(", "))}else e.header("Vary","accept-encoding")}function q(e){e&&"ERR_STREAM_PREMATURE_CLOSE"!==e.code&&"premature close"!==e.message&&this.log.error(e)}function U(e){this.receivedEncodedLength+=e.length}function $(){this.removeListener("data",U),this.removeListener("end",$)}function B(e,t,n,i){let s;if(this.log.debug(`compress: invalid request payload - ${i}`),t.onInvalidRequestPayload)try{s=t.onInvalidRequestPayload(n,e,i)}catch{s=void 0}s||(s=new z),i.decompressError=i,Object.assign(i,s)}const F=/\*|x-gzip/gu;function H(e,t){let n=t.headers["accept-encoding"];return null!=n?(n=n.toLowerCase().replace(F,"gzip"),p.negotiate(n,e)):void 0}function G(e,t){if(t(e))return!0;const n=u[e.split(";",1)[0].trim().toLowerCase()];return void 0!==n&&!0===n.compressible}function Y(e){return b(e)?1:v(e)?2:0}function ae(e,t){if(y(e))return e;let n=e,i=e;return ArrayBuffer.isView(e)?n=i=Buffer.from(e.buffer,e.byteOffset,e.byteLength):t&&"string"!=typeof e&&(n=i=t(e)),Buffer.isBuffer(n)?0===Y(n)?i:g.from(I(i)):i}function oe(e,t){return E(function(n){switch(Y(n)){case 1:case 2:return new h}return e[t]()})}function re(e,t){return t>=0||(t=3),E(function(n){if(t<0)throw new Error("Maximum recursion reached");switch(Y(n)){case 1:return s(e.gzip(),re(e,t-1));case 2:return s(e.deflate(),re(e,t-1))}return new h})}function ce(e,i,s){function a(t){Error.captureStackTrace(this,a),this.name="FastifyCompressError",this.code=e,this.message=t?n(i,t):i,this.statusCode=s}return e=e.toUpperCase(),a.prototype[Symbol.toStringTag]="Error",a.prototype.toString=function(){return`${this.name} [${this.code}]: ${this.message}`},t(a,Error),a}return V.exports=l(k,{fastify:"5.x",name:"@fastify/compress"}),V.exports.default=k,V.exports.fastifyCompress=k,V.exports}(),an=$(sn);const on={perMessageDeflate:{threshold:256,serverNoContextTakeover:!0,clientNoContextTakeover:!0,concurrencyLimit:4,zlibDeflateOptions:{level:1}}};function rn(e){return e.readyState===(e.OPEN??1)}function cn(e){const t=Buffer.isBuffer(e)?e.toString("utf8"):"string"==typeof e?e:"";if(Buffer.byteLength(t,"utf8")<=123)return t;let n="";for(const e of t){const t=`${n}${e}`;if(Buffer.byteLength(t,"utf8")>123)break;n=t}return n}function dn(e){if("number"==typeof e&&Number.isInteger(e))return e>=3e3&&e<=4999||e>=1e3&&e<=1014&&1004!==e&&1005!==e&&1006!==e?e:void 0}function ln(e,t,n){e.close(dn(t),cn(n)||void 0)}function pn(e,t,n,i){if(rn(e))for(const e of t.splice(0))if(i(e),!n(e))return}function un(e,t,n={}){const i=n.pendingFrameLimit??256,s=n.maxFrameBytes??8388608,a=n.maxTotalBytes??1073741824,o=n.maxBufferedBytes??16777216;let r=!1,c=rn(t);const d=[],l=[];let p,u=0,m=0,h=0;const g=e=>Buffer.isBuffer(e)||e instanceof ArrayBuffer||ArrayBuffer.isView(e)?e.byteLength:Buffer.byteLength("string"==typeof e?e:String(e),"utf8"),f=(i,o)=>{const r=g(o);return h+=r,n.onFrame?.(i,r),!(r>s||h>a)||(ln(e,1009,"WebSocket bridge traffic limit exceeded."),ln(t,1009,"WebSocket bridge traffic limit exceeded."),!1)},y=()=>{p&&(clearTimeout(p),p=void 0)},b=(n,i)=>{const s=i.bytes;if((n.bufferedAmount??0)+s>o)return ln(e,1013,"WebSocket bridge consumer is too slow."),ln(t,1013,"WebSocket bridge consumer is too slow."),!1;try{return function(e,t){e.send(t.data,{binary:t.isBinary,compress:!1})}(n,i),!0}catch{return ln(e,1011,"WebSocket bridge send failed."),ln(t,1011,"WebSocket bridge send failed."),!1}},v=(n,s,a)=>{if(s.length>=i)return ln(e,1011,"WebSocket bridge pending frame limit exceeded."),void ln(t,1011,"WebSocket bridge pending frame limit exceeded.");const r="upstream"===n?u:m;if((("upstream"===n?t:e).bufferedAmount??0)+r+a.bytes>o)return ln(e,1013,"WebSocket bridge consumer is too slow."),void ln(t,1013,"WebSocket bridge consumer is too slow.");s.push(a),"upstream"===n?u+=a.bytes:m+=a.bytes};return n.upstreamOpenTimeoutMs&&!c&&(p=setTimeout(()=>{c||r||(ln(e,1011,"Upstream websocket did not open."),ln(t))},n.upstreamOpenTimeoutMs)),e.on("open",()=>pn(e,l,t=>b(e,t),e=>{m-=e.bytes})),t.on("open",()=>{y(),c=!0,n.onUpstreamOpen?.(),pn(t,d,e=>b(t,e),e=>{u-=e.bytes})}),e.on("message",(e,n=!1)=>{if(!f("client-to-upstream",e))return;const i={data:e,isBinary:Boolean(n),bytes:g(e)};rn(t)?b(t,i):v("upstream",d,i)}),t.on("message",(t,n=!1)=>{if(!f("upstream-to-client",t))return;const i={data:t,isBinary:Boolean(n),bytes:g(t)};rn(e)?b(e,i):v("client",l,i)}),t.on("close",(t,i)=>{y(),n.onUpstreamClose?.(t,i),(c||r||!n.onUpstreamCloseBeforeOpen?.())&&ln(e,t,i)}),t.on("error",t=>{n.onUpstreamError?.(t),(c||r||!n.onUpstreamErrorBeforeOpen?.(t))&&ln(e)}),e.on("close",(e,i)=>{y(),r=!0,n.onClientClose?.(e,i),ln(t,e,i)}),e.on("error",e=>{y(),r=!0,n.onClientError?.(e),ln(t,1011,"WebSocket bridge client failed.")}),{close:(n,i)=>{y(),ln(t,n,i),ln(e,n,i)}}}const mn=new Set(["authorization","cookie"]),hn=20971520,gn=512e3,fn=gn,yn=hn,bn=41943040,vn=262144,In="ai.sessions",xn="ai-session.snapshot",wn="ai-session.patch",Sn="ai-session.removed",An="ai-session.message-delta",En="ai-session.timeline-item",_n="ai-session.unread.updated",Tn=f.z.string().trim().min(1).max(80),zn=f.z.enum(["app-session","ai-session"]),kn=f.z.enum(["image","file"]),Nn={scopeType:f.z.enum(["session","create-request"]),scopeId:f.z.string().trim().min(1).max(160),kind:kn,name:f.z.string().trim().min(1).max(240),mime:f.z.string().trim().min(1).max(120)},Cn=f.z.object({...Nn,size:f.z.coerce.number().int().positive().max(hn)}).strict(),Rn=f.z.string().regex(/^cia_[a-f0-9]{24}$/),On=f.z.object({attachmentId:Rn,...Nn,size:f.z.number().int().positive().max(hn)}).strict();f.z.object({offset:f.z.coerce.number().int().nonnegative()}).strict();const jn=f.z.object({attachmentId:Rn,offset:f.z.number().int().nonnegative()}),Pn=f.z.object({id:Rn,kind:kn,name:f.z.string().trim().min(1).max(240),mime:f.z.string().trim().min(1).max(120),size:f.z.number().int().positive().max(hn),expiresAt:f.z.string().datetime()});function Dn(e){return["image/bmp","image/gif","image/jpeg","image/png","image/webp"].includes(e.split(";",1)[0].trim().toLowerCase())}const Ln=f.z.object({id:f.z.string().trim().min(1).max(120),kind:kn,name:f.z.string().trim().min(1).max(240),mime:f.z.string().trim().min(1).max(120),size:f.z.number().int().min(0).max(Number.MAX_SAFE_INTEGER)}),Mn=f.z.enum(["available","expired","missing"]),qn=Ln.extend({contentState:Mn.default("available")}).strict(),Un=f.z.object({id:f.z.string().trim().min(1).max(240),text:f.z.string(),attachments:f.z.array(qn).max(6).default([])}).strict(),$n=f.z.enum(["running","waiting","idle","failed"]),Bn=f.z.object({instanceId:f.z.string().trim().min(1).max(160),sessionId:f.z.string().trim().min(1).max(120),unread:f.z.boolean(),sessionUpdatedAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}).strict(),Fn=f.z.enum(["thinking","tool","editing","approval","responding","unknown"]),Hn=f.z.object({id:f.z.string().trim().min(1).max(240).optional(),kind:f.z.string().trim().min(1).max(80).optional(),name:f.z.string().trim().min(1).max(120),inputPreview:f.z.string().trim().max(500).optional(),startedAt:f.z.string().datetime().optional()}).strict(),Gn=f.z.enum(["running","completed","failed","waiting"]),Wn=f.z.object({id:f.z.string().trim().min(1).max(240),turnId:f.z.string().trim().min(1).max(240)}).strict(),Vn=Wn.extend({type:f.z.literal("user-message"),text:f.z.string(),attachments:f.z.array(qn).max(6).optional()}).strict(),Kn=Wn.extend({type:f.z.literal("ai-message"),text:f.z.string()}).strict(),Yn=Wn.extend({type:f.z.literal("activity"),activityKind:f.z.string().trim().min(1).max(120),title:f.z.string().trim().min(1).max(240),status:Gn.optional(),summary:f.z.string().max(4e3).optional(),input:f.z.string().max(1e5).optional(),output:f.z.string().max(1e6).optional(),paths:f.z.array(f.z.string().trim().min(1).max(4096)).max(500).optional(),exitCode:f.z.number().int().optional(),durationMs:f.z.number().int().nonnegative().optional()}).strict(),Xn=f.z.discriminatedUnion("type",[Vn,Kn,Yn]),Jn=f.z.object({sessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().min(1).max(240),items:f.z.array(Xn),generatedAt:f.z.string().datetime()}).strict(),Qn=f.z.object({sessionId:f.z.string().trim().min(1).max(120),turnId:f.z.string().trim().min(1).max(240),items:f.z.array(Xn),generatedAt:f.z.string().datetime()}).strict(),Zn=f.z.enum(["pending-init","running","interrupted","completed","errored","shutdown","not-found"]),ei=f.z.enum(["started","interacted","interrupted"]),ti=f.z.object({threadId:f.z.string().trim().min(1).max(240),path:f.z.string().trim().max(4096).optional(),status:Zn,activity:ei.optional(),message:f.z.string().trim().max(1e3).optional(),updatedAt:f.z.string().datetime()}).strict(),ni=f.z.object({toolCalls:f.z.number().int().min(0).default(0),edits:f.z.number().int().min(0).default(0),approvals:f.z.number().int().min(0).default(0)}).strict().default({toolCalls:0,edits:0,approvals:0}),ii=f.z.object({send:f.z.boolean().optional(),interrupt:f.z.boolean().optional(),approval:f.z.boolean().optional(),fork:f.z.boolean().optional(),openApp:f.z.boolean().optional(),close:f.z.boolean().optional()}).strict(),si=f.z.object({kind:f.z.literal("fork"),parentProviderSessionId:f.z.string().trim().min(1).max(240),throughTurnId:f.z.string().trim().min(1).max(240).optional()}).strict(),ai=f.z.union([Ln.extend({source:f.z.object({type:f.z.literal("inline"),encoding:f.z.literal("base64"),data:f.z.string().min(1).max(31457280)}).strict()}).strict().superRefine((e,t)=>{const n="image"===e.kind?hn:gn;(e.size<=0||("file"===e.kind?e.size>=n:e.size>n))&&t.addIssue({code:f.z.ZodIssueCode.custom,path:["size"],message:`Inline ${e.kind} must be between 1 byte and ${n} bytes.`})}),Ln.extend({source:f.z.object({type:f.z.literal("runtime-path"),path:f.z.string().trim().min(1).max(4096)}).strict()}).strict()]),oi=Ln.extend({sourceType:f.z.enum(["inline","runtime-path"])}).strict(),ri=f.z.union([f.z.object({id:f.z.string().trim().min(1).max(120),kind:kn.optional(),source:f.z.object({type:f.z.literal("upload-ref")}).strict().default({type:"upload-ref"})}).strict(),f.z.object({id:f.z.string().trim().min(1).max(120),kind:kn,name:f.z.string().trim().min(1).max(240),mime:f.z.string().trim().min(1).max(120),size:f.z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),source:f.z.object({type:f.z.literal("runtime-path"),path:f.z.string().trim().min(1).max(4096)}).strict()}).strict()]),ci=f.z.enum(["auto","queue","steer","immediate"]),di=f.z.enum(["ask","auto-review","full-access"]),li=f.z.enum(["review","rename","goal","compact"]),pi=f.z.object({command:li,argument:f.z.string().trim().max(4e3).optional()}).strict().superRefine((e,t)=>{"rename"!==e.command||e.argument||t.addIssue({code:"custom",path:["argument"],message:"Rename requires a thread name."}),"review"!==e.command&&"compact"!==e.command||!e.argument||t.addIssue({code:"custom",path:["argument"],message:`${e.command} does not accept an argument.`})}),ui=f.z.object({command:li,value:f.z.string().max(4e3).optional(),turnId:f.z.string().trim().min(1).max(240).optional()}).strict();f.z.enum(["skill","app","plugin"]);const mi=f.z.object({name:f.z.string().trim().min(1).max(240),path:f.z.string().trim().min(1).max(4096)}),hi=f.z.discriminatedUnion("kind",[mi.extend({kind:f.z.literal("skill"),path:f.z.string().trim().min(1).max(4096).refine(e=>e.startsWith("/"),"Skill paths must be absolute.")}).strict(),mi.extend({kind:f.z.literal("app"),path:f.z.string().trim().min(7).max(4096).regex(/^app:\/\/[^\s/]+$/,"App paths must use app://<id>.")}).strict(),mi.extend({kind:f.z.literal("plugin"),path:f.z.string().trim().min(10).max(4096).regex(/^plugin:\/\/[^\s/]+$/,"Plugin paths must use plugin://<id>.")}).strict()]),gi=f.z.array(hi).max(20).default([]),fi=f.z.enum(["plugin","skill","file","directory","app"]),yi=f.z.object({kind:fi,name:f.z.string().trim().min(1).max(240),description:f.z.string().trim().max(1e3).optional(),path:f.z.string().trim().min(1).max(4096),icon:f.z.string().trim().max(4096).optional()}).strict().superRefine((e,t)=>{"skill"!==e.kind||e.path.startsWith("/")||t.addIssue({code:"custom",path:["path"],message:"Skill paths must be absolute."}),"app"!==e.kind||/^app:\/\/[^\s/]+$/.test(e.path)||t.addIssue({code:"custom",path:["path"],message:"App paths must use app://<id>."}),"plugin"!==e.kind||/^plugin:\/\/[^\s/]+$/.test(e.path)||t.addIssue({code:"custom",path:["path"],message:"Plugin paths must use plugin://<id>."}),"file"!==e.kind&&"directory"!==e.kind||!e.path.startsWith("/")&&!e.path.split(/[\\/]+/).includes("..")||t.addIssue({code:"custom",path:["path"],message:"File and directory paths must be relative to the session cwd."})}),bi=f.z.object({category:f.z.enum(["skills","plugins","apps","files"]),code:f.z.string().trim().min(1).max(160),message:f.z.string().trim().min(1).max(2e3)}).strict(),vi=f.z.object({sessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().min(1).max(240),cwd:f.z.string().trim().min(1).max(4096),candidates:f.z.array(yi).max(1e3).default([]),diagnostics:f.z.array(bi).max(20).default([])}).strict(),Ii=f.z.object({query:f.z.string().trim().max(240).default("")}).strict(),xi=f.z.object({sessionId:f.z.string().trim().min(1).max(120),cwd:f.z.string().trim().min(1).max(4096),query:f.z.string().trim().max(240),requestId:f.z.string().trim().min(1).max(160),candidates:f.z.array(yi.refine(e=>"file"===e.kind||"directory"===e.kind,"File search only returns files and directories.")).max(200).default([]),complete:f.z.boolean().default(!1)}).strict(),wi=f.z.object({message:f.z.string().trim().min(1).max(2e4),mode:ci.optional(),permissionMode:di.optional()}),Si=wi.extend({attachments:f.z.array(ai).max(6).default([]),references:gi}).strict().superRefine((e,t)=>{e.attachments.reduce((e,t)=>e+("inline"===t.source.type?t.size:0),0)>bn&&t.addIssue({code:f.z.ZodIssueCode.custom,path:["attachments"],message:"Inline attachments must be 41943040 bytes or less in total."})}),Ai=wi.extend({attachments:f.z.array(ri).max(6).default([]),references:gi}).strict(),Ei=f.z.object({type:f.z.literal("runtime-path"),path:f.z.string().trim().min(1).max(4096).refine(e=>e.startsWith("/")||/^[A-Za-z]:[\\/]/.test(e),"Runtime paths must be absolute in the target controlled instance.")}).strict(),_i=Si.extend({agent:Tn,cwd:Ei,cwdFolderId:f.z.string().trim().min(1).max(120).optional(),clientRequestId:f.z.string().trim().min(1).max(160)}).strict(),Ti=f.z.object({mode:f.z.enum(["current-folder","worktree"]),branch:f.z.string().trim().min(1).max(1024)}).strict(),zi=Ai.extend({agent:Tn,cwdFolderId:f.z.string().trim().min(1).max(120).optional(),gitSelection:Ti.optional(),clientRequestId:f.z.string().trim().min(1).max(160)}).strict(),ki=f.z.object({disposition:f.z.enum(["created","already-created"]),aiSessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().min(1).max(240),creationSource:f.z.literal("ai-session")}).strict(),Ni=f.z.object({mode:f.z.enum(["current","managed-worktree"]).default("current")}).strict().default({mode:"current"}),Ci=f.z.object({clientRequestId:f.z.string().trim().min(1).max(160),throughTurnId:f.z.string().trim().min(1).max(240).optional(),workspace:Ni.optional().default({mode:"current"})}).strict(),Ri=f.z.object({disposition:f.z.enum(["created","already-created"]),aiSessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().min(1).max(240),creationSource:f.z.literal("ai-session")}).strict(),Oi=f.z.object({clientRequestId:f.z.string().trim().min(1).max(160)}).strict(),ji=f.z.object({disposition:f.z.enum(["opened","already-open"]),aiSessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().min(1).max(240),appSessionId:f.z.string().trim().min(1).max(120),creationSource:zn}).strict(),Pi=f.z.object({clientRequestId:f.z.string().trim().min(1).max(160)}).strict(),Di=f.z.object({disposition:f.z.enum(["closed","already-closed"]),aiSessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().min(1).max(240),creationSource:zn}).strict();f.z.object({code:f.z.enum(["invalid-request","not-found","unsupported","provider-unavailable","materialization-failed","open-app-failed","close-failed","conflict"]),message:f.z.string().trim().min(1).max(4e3),retryable:f.z.boolean().default(!1),aiSessionId:f.z.string().trim().min(1).max(120).optional(),providerSessionId:f.z.string().trim().min(1).max(240).optional()}).strict();const Li=f.z.object({decision:f.z.enum(["allow","deny","skip"])}).strict(),Mi=f.z.object({expectedRevision:f.z.number().int().min(0),queueIds:f.z.array(f.z.string().trim().min(1).max(120)).max(100)}).strict(),qi=f.z.object({expectedRevision:f.z.number().int().min(0),message:f.z.string().trim().min(1).max(2e4)}).strict();f.z.object({code:f.z.string().trim().min(1).max(160),message:f.z.string(),instanceId:f.z.string().trim().min(1).max(160).optional(),nodeId:f.z.string().trim().min(1).max(160).optional(),route:f.z.string().trim().min(1).max(4096).optional()}).strict();const Ui=f.z.object({id:f.z.string().trim().min(1).max(120),messageId:f.z.string().trim().min(1).max(240).optional(),message:f.z.string().trim().min(1).max(2e4),attachments:f.z.array(oi).max(6).default([]),references:gi,permissionMode:di.optional(),status:f.z.enum(["queued","sending","failed"]).default("queued"),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime(),error:f.z.string().trim().max(4e3).optional()}).strict(),$i=f.z.object({revision:f.z.number().int().min(0).default(0),pendingCount:f.z.number().int().min(0).default(0),items:f.z.array(Ui).max(100).default([])}).strict().default({revision:0,pendingCount:0,items:[]}),Bi=f.z.enum(["control","realtime","adapter-snapshot","transcript-tail","transcript-scan","process-scan","app-session"]),Fi=f.z.object({id:f.z.string().trim().min(1).max(240),status:f.z.enum(["running","completed"]),startedAt:f.z.string().datetime().optional(),completedAt:f.z.string().datetime().optional()}).strict(),Hi=f.z.object({id:f.z.string().trim().min(1).max(240),providerTurnId:f.z.string().trim().max(240).optional(),source:Bi.optional(),userPrompt:f.z.string().trim().optional(),userMessages:f.z.array(Un).max(100).optional(),status:f.z.enum(["queued","running","waiting","completed","failed"]).default("running"),phase:Fn.optional(),summary:f.z.string().trim().max(1e3).optional(),lastMessage:f.z.string().trim().optional(),lastMessageItemId:f.z.string().trim().max(240).optional(),contextCompactions:f.z.array(Fi).max(20).optional(),revision:f.z.number().int().min(0).default(0),sourcePriority:f.z.number().int().min(0).max(100).optional(),snapshotVersion:f.z.number().int().min(0).optional(),observedAt:f.z.string().datetime().optional(),startedAt:f.z.string().datetime().optional(),updatedAt:f.z.string().datetime().optional(),completedAt:f.z.string().datetime().optional()}).strict(),Gi=Hi.pick({id:!0,providerTurnId:!0,userPrompt:!0,userMessages:!0,status:!0,phase:!0,summary:!0,lastMessage:!0,contextCompactions:!0,startedAt:!0,updatedAt:!0,completedAt:!0}).strict(),Wi=f.z.object({id:f.z.string().trim().min(1).max(120),agent:Tn,creationSource:zn.default("app-session"),appSessionId:f.z.string().trim().max(120).optional(),appId:f.z.string().trim().max(120).optional(),providerSessionId:f.z.string().trim().max(240).optional(),lineage:si.optional(),providerMeta:f.z.record(f.z.string(),f.z.unknown()).optional(),appBindingKeys:f.z.array(f.z.string().trim().min(1).max(240)).max(20).optional(),actions:ii.optional(),activeTurnId:f.z.string().trim().max(240).optional(),title:f.z.string().trim().max(240).optional(),cwd:f.z.string().trim().max(4096).optional(),cwdFolderId:f.z.string().trim().min(1).max(120).optional(),userPrompt:f.z.string().trim().optional(),turns:f.z.array(Hi).max(50).optional(),status:$n.default("running"),phase:Fn.default("unknown"),summary:f.z.string().trim().max(1e3).optional(),lastMessage:f.z.string().trim().optional(),lastMessageItemId:f.z.string().trim().max(240).optional(),currentTool:Hn.optional(),toolCallsSinceLastMessage:f.z.number().int().min(0).default(0),subAgents:f.z.array(ti).max(50).default([]),transcriptPath:f.z.string().trim().max(4096).optional(),transcriptSize:f.z.number().int().min(0).optional(),startedAt:f.z.string().datetime(),updatedAt:f.z.string().datetime(),completedAt:f.z.string().datetime().optional(),error:f.z.string().trim().max(4e3).optional(),counters:ni,queue:$i}).strict(),Vi=Wi.pick({id:!0,appBindingKeys:!0,cwd:!0,error:!0,providerMeta:!0,queue:!0,subAgents:!0}).strict(),Ki=Hi.pick({id:!0,providerTurnId:!0,status:!0,phase:!0,revision:!0,startedAt:!0,updatedAt:!0,completedAt:!0}).extend({bodyRevision:f.z.string().trim().min(1).max(64)}).strict(),Yi=f.z.object({sessionId:f.z.string().trim().min(1).max(120),revision:f.z.string().trim().min(1).max(64),turns:f.z.array(Ki).max(50)}).strict(),Xi=f.z.object({sessionId:f.z.string().trim().min(1).max(120),revision:f.z.string().trim().min(1).max(64),turn:Hi}).strict(),Ji=f.z.object({session:Wi,provider:f.z.string().trim().min(1).max(80),action:f.z.enum(["send","queue","steer","interrupt","approval"]),decision:f.z.enum(["allow","deny","skip"]).optional(),turnId:f.z.string().trim().min(1).max(240).optional(),providerTurnId:f.z.string().trim().min(1).max(240).optional(),queueId:f.z.string().trim().min(1).max(120).optional()}).strict(),Qi=Ji.omit({session:!0}).extend({sessionId:f.z.string().trim().min(1).max(120),messageId:f.z.string().trim().min(1).max(240).optional()}).strict(),Zi=f.z.union([Qi,Ji.transform(function(e){const t=e.session.turns?.at(-1),n=(e.queueId?e.session.queue?.items.find(t=>t.id===e.queueId)?.messageId:void 0)||("send"===e.action||"queue"===e.action||"steer"===e.action?t?.userMessages?.at(-1)?.id:void 0);return Qi.parse({sessionId:e.session.id,provider:e.provider,action:e.action,...e.decision?{decision:e.decision}:{},...e.turnId||e.session.activeTurnId||t?.id?{turnId:e.turnId||e.session.activeTurnId||t?.id}:{},...e.providerTurnId||t?.providerTurnId?{providerTurnId:e.providerTurnId||t?.providerTurnId}:{},...e.queueId?{queueId:e.queueId}:{},...n?{messageId:n}:{}})})]),es=500,ts=f.z.object({id:f.z.string().trim().min(1).max(120),agent:Tn,creationSource:zn,providerSessionId:f.z.string().trim().min(1).max(240),lineage:si.optional(),title:f.z.string().trim().max(240).optional(),userPrompt:f.z.string().trim().optional(),lastMessage:f.z.string().trim().optional(),cwd:f.z.string().trim().min(1).max(4096),cwdFolderId:f.z.string().trim().min(1).max(120).optional(),lastActiveAt:f.z.string().datetime(),archivedAt:f.z.string().datetime()}).strict();f.z.object({schemaVersion:f.z.literal(1).default(1),items:f.z.array(ts).max(es).default([])}).strict();const ns=f.z.object({items:f.z.array(ts).max(es).default([])}).strict(),is=f.z.object({item:ts,turns:f.z.array(Gi).max(50).default([])}).strict(),ss=f.z.object({disposition:f.z.enum(["resumed","already-open"]),aiSessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().min(1).max(240),appSessionId:f.z.string().trim().min(1).max(120).optional(),creationSource:zn}).strict(),as=Hi.omit({userMessages:!0}),os=Wi.pick({id:!0,agent:!0,creationSource:!0,appSessionId:!0,appId:!0,providerSessionId:!0,lineage:!0,providerMeta:!0,appBindingKeys:!0,actions:!0,activeTurnId:!0,title:!0,cwd:!0,cwdFolderId:!0,userPrompt:!0,turns:!0,status:!0,phase:!0,summary:!0,lastMessage:!0,lastMessageItemId:!0,currentTool:!0,toolCallsSinceLastMessage:!0,subAgents:!0,queue:!0,startedAt:!0,updatedAt:!0,error:!0}).extend({turns:f.z.array(as).max(50).optional(),detailRevision:f.z.string().trim().min(1).max(64).optional(),turnsRevision:f.z.string().trim().min(1).max(64).optional(),turnCount:f.z.number().int().min(0).optional(),subAgentCount:f.z.number().int().min(0).optional(),lastUserMessageAt:f.z.string().datetime().optional()}).strict(),rs=f.z.object({runningCount:f.z.number().int().min(0).default(0),waitingCount:f.z.number().int().min(0).default(0),staleCount:f.z.number().int().min(0).default(0),sessions:f.z.array(os).default([]),updatedAt:f.z.string().datetime()}).strict(),cs=f.z.object({streamId:f.z.string().trim().min(1).max(240),revision:f.z.number().int().min(0),lastEventAt:f.z.string().datetime(),snapshot:rs}).strict(),ds=rs.pick({runningCount:!0,waitingCount:!0,staleCount:!0,updatedAt:!0}).extend({idleCount:f.z.number().int().min(0).default(0),problemCount:f.z.number().int().min(0).default(0),revision:f.z.number().int().min(0).optional()});function ls(e,t={}){const n=e.sessions.filter(e=>"idle"===e.status).length,i=e.sessions.filter(e=>"failed"===e.status).length;return ds.parse({runningCount:e.runningCount,waitingCount:e.waitingCount,staleCount:e.staleCount,idleCount:n,problemCount:i,updatedAt:e.updatedAt,revision:t.revision})}const ps=f.z.enum(["provider-event","app-session-created","app-session-updated","app-session-deleted","discovery-scan","control-action","heartbeat-sync","startup"]),us=f.z.object({streamId:f.z.string().trim().min(1).max(240),instanceId:f.z.string().trim().min(1).max(160),nodeId:f.z.string().trim().min(1).max(160).optional(),revision:f.z.number().int().min(0),previousRevision:f.z.number().int().min(0).optional(),traceId:f.z.string().trim().min(1).max(160),generatedAt:f.z.string().datetime(),reason:ps}).strict(),ms=f.z.object({meta:us,snapshot:rs}).strict(),hs=f.z.object({meta:us,upserted:f.z.array(os).default([]),removed:f.z.array(f.z.string().trim().min(1).max(120)).default([])}).strict(),gs=f.z.object({meta:us,sessionIds:f.z.array(f.z.string().trim().min(1).max(120)).default([]),expiresAt:f.z.string().datetime()}).strict(),fs=f.z.object({instanceId:f.z.string().trim().min(1).max(160),nodeId:f.z.string().trim().min(1).max(160).optional(),sessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().min(1).max(240).optional(),turnId:f.z.string().trim().min(1).max(240),itemId:f.z.string().trim().min(1).max(240),delta:f.z.string().min(1),generatedAt:f.z.string().datetime()}).strict(),ys=fs.omit({instanceId:!0,nodeId:!0,providerSessionId:!0}).strict(),bs=f.z.object({instanceId:f.z.string().trim().min(1).max(160),nodeId:f.z.string().trim().min(1).max(160).optional(),sessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().min(1).max(240),item:Xn,generatedAt:f.z.string().datetime()}).strict(),vs=f.z.object({streamId:f.z.string().trim().min(1).max(240),instanceId:f.z.string().trim().min(1).max(160),sinceRevision:f.z.number().int().min(0),latestRevision:f.z.number().int().min(0),earliestRetainedRevision:f.z.number().int().min(0),syncRequired:f.z.boolean().default(!1),events:f.z.array(f.z.discriminatedUnion("type",[f.z.object({type:f.z.literal(xn),payload:ms}).strict(),f.z.object({type:f.z.literal(wn),payload:hs}).strict(),f.z.object({type:f.z.literal(Sn),payload:gs}).strict()])).default([])}).strict(),Is=f.z.object({source:Bi,sourcePriority:f.z.number().int().min(0).max(100).optional(),observedAt:f.z.string().datetime().optional(),snapshotVersion:f.z.number().int().min(0).optional()}).strict(),xs=Is.extend({type:f.z.literal("snapshot"),agent:f.z.string().trim().min(1).max(80),creationSource:zn.optional(),appSessionId:f.z.string().trim().max(120).optional(),appId:f.z.string().trim().max(120).optional(),providerSessionId:f.z.string().trim().max(240).optional(),lineage:si.optional(),providerMeta:f.z.record(f.z.string(),f.z.unknown()).optional(),appBindingKeys:f.z.array(f.z.string().trim().min(1).max(240)).max(20).optional(),actions:ii.optional(),title:f.z.string().trim().max(240).optional(),cwd:f.z.string().trim().max(4096).optional(),cwdFolderId:f.z.string().trim().min(1).max(120).optional(),activeTurnId:f.z.string().trim().max(240).optional(),userPrompt:f.z.string().trim().optional(),turns:f.z.array(Hi).max(50).optional(),status:$n.optional(),phase:Fn.optional(),summary:f.z.string().trim().max(1e3).optional(),lastMessage:f.z.string().trim().optional(),lastMessageItemId:f.z.string().trim().max(240).optional(),error:f.z.string().trim().max(4e3).optional(),currentTool:Hn.optional(),toolCallsSinceLastMessage:f.z.number().int().min(0).optional(),subAgents:f.z.array(ti).max(50).optional(),transcriptPath:f.z.string().trim().max(4096).optional(),transcriptSize:f.z.number().int().min(0).optional(),replaceActivity:f.z.boolean().optional()}).strict(),ws=Is.extend({type:f.z.literal("event"),sessionId:f.z.string().trim().min(1).max(120),kind:f.z.enum(["lifecycle","send-ack","turn-started","user-message","assistant-message","approval-requested","turn-completed","session-error","tool-activity","sub-agent-activity","context-compaction"]),activeTurnId:f.z.string().trim().max(240).optional(),providerTurnId:f.z.string().trim().max(240).optional(),userPrompt:f.z.string().trim().optional(),userMessage:Un.optional(),text:f.z.string().optional(),itemId:f.z.string().trim().max(240).optional(),status:$n.optional(),phase:Fn.optional(),summary:f.z.string().trim().max(1e3).optional(),error:f.z.string().trim().max(4e3).optional(),currentTool:Hn.nullable().optional(),toolCallsSinceLastMessage:f.z.number().int().min(0).optional(),subAgents:f.z.array(ti).max(50).optional(),contextCompaction:Fi.optional(),counters:f.z.object({toolCalls:f.z.number().int().min(0).optional(),edits:f.z.number().int().min(0).optional(),approvals:f.z.number().int().min(0).optional()}).strict().optional()}).strict().superRefine((e,t)=>{if("session-error"!==e.kind||e.error||t.addIssue({code:"custom",path:["error"],message:"session-error events require error"}),"context-compaction"===e.kind?e.contextCompaction||t.addIssue({code:"custom",path:["contextCompaction"],message:"context-compaction events require contextCompaction"}):void 0!==e.contextCompaction&&t.addIssue({code:"custom",path:["contextCompaction"],message:"contextCompaction is only valid for context-compaction events"}),"send-ack"!==e.kind&&"user-message"!==e.kind&&void 0!==e.userMessage&&t.addIssue({code:"custom",path:["userMessage"],message:"userMessage is only valid for send-ack and user-message events"}),"sub-agent-activity"===e.kind?e.subAgents||t.addIssue({code:"custom",path:["subAgents"],message:"sub-agent-activity events require subAgents"}):void 0!==e.subAgents&&t.addIssue({code:"custom",path:["subAgents"],message:"subAgents is only valid for sub-agent-activity events"}),"tool-activity"!==e.kind)return void 0!==e.currentTool&&t.addIssue({code:"custom",path:["currentTool"],message:"currentTool is only valid for tool-activity events"}),void(void 0!==e.toolCallsSinceLastMessage&&t.addIssue({code:"custom",path:["toolCallsSinceLastMessage"],message:"toolCallsSinceLastMessage is only valid for tool-activity events"}));"currentTool"in e||t.addIssue({code:"custom",path:["currentTool"],message:"tool-activity events require currentTool"}),void 0===e.toolCallsSinceLastMessage&&t.addIssue({code:"custom",path:["toolCallsSinceLastMessage"],message:"tool-activity events require toolCallsSinceLastMessage"})});f.z.discriminatedUnion("type",[xs,ws]);const Ss=f.z.object({type:f.z.literal("snapshot"),data:f.z.string(),pendingEscape:f.z.string(),cols:f.z.number().int().positive(),rows:f.z.number().int().positive()}).passthrough(),As="app-session.snapshot",Es="app-session.patch",_s="app-session.removed",Ts=f.z.enum(["created","starting","running","stopping","stopped","exited","failed","closed","terminated","unknown"]),zs=f.z.enum(["tty","vnc","web"]);f.z.object({mode:zs,url:f.z.string().trim().min(1).max(4096),token:f.z.string().trim().min(1).max(512),expiresAt:f.z.string().datetime()}).strict(),f.z.object({revoked:f.z.boolean()}).strict();const ks=new Set(["stopped","failed","exited","closed","terminated"]),Ns=f.z.object({type:f.z.enum(["app-session","provider-session","adapter-key"]),id:f.z.string().trim().min(1).max(240),agent:f.z.string().trim().min(1).max(80).optional(),adapter:f.z.string().trim().min(1).max(80).optional(),key:f.z.string().trim().min(1).max(240).optional()}).strict(),Cs=f.z.record(f.z.string(),f.z.unknown()).and(f.z.object({id:f.z.string().trim().min(1).max(160),appId:f.z.string().trim().min(1).max(160).optional(),title:f.z.string().trim().max(240).optional(),kind:f.z.string().trim().max(80).optional(),status:Ts.default("unknown"),bindings:f.z.array(Ns).max(40).default([]),workspace:f.z.object({cwd:f.z.string().trim().max(4096).optional()}).strict().optional(),createdAt:f.z.string().datetime().optional(),updatedAt:f.z.string().datetime().optional()})),Rs=f.z.object({runningCount:f.z.number().int().min(0).default(0),problemCount:f.z.number().int().min(0).default(0),sessions:f.z.array(Cs).default([]),updatedAt:f.z.string().datetime()}).strict(),Os=f.z.object({streamId:f.z.string().trim().min(1).max(240),revision:f.z.number().int().min(0),lastEventAt:f.z.string().datetime(),snapshot:Rs}).strict();Rs.pick({runningCount:!0,problemCount:!0,updatedAt:!0}).extend({revision:f.z.number().int().min(0).optional()});const js=f.z.enum(["app-session-created","app-session-updated","app-session-deleted","app-session-recovered","control-action","heartbeat-sync","startup"]),Ps=f.z.object({streamId:f.z.string().trim().min(1).max(240),instanceId:f.z.string().trim().min(1).max(160),nodeId:f.z.string().trim().min(1).max(160).optional(),revision:f.z.number().int().min(0),previousRevision:f.z.number().int().min(0).optional(),traceId:f.z.string().trim().min(1).max(160),generatedAt:f.z.string().datetime(),reason:js}).strict(),Ds=f.z.object({meta:Ps,snapshot:Rs}).strict(),Ls=f.z.object({meta:Ps,session:Cs}).strict(),Ms=f.z.object({meta:Ps,sessionId:f.z.string().trim().min(1).max(160),tombstone:Cs.optional(),expiresAt:f.z.string().datetime().optional()}).strict(),qs=f.z.object({streamId:f.z.string().trim().min(1).max(240),instanceId:f.z.string().trim().min(1).max(160),sinceRevision:f.z.number().int().min(0),latestRevision:f.z.number().int().min(0),earliestRetainedRevision:f.z.number().int().min(0),syncRequired:f.z.boolean().default(!1),events:f.z.array(f.z.discriminatedUnion("type",[f.z.object({type:f.z.literal(As),payload:Ds}).strict(),f.z.object({type:f.z.literal(Es),payload:Ls}).strict(),f.z.object({type:f.z.literal(_s),payload:Ms}).strict()])).default([])}).strict();function Us(e,t=(new Date).toISOString()){const n=e.map(e=>Bs(e));return Rs.parse({runningCount:n.filter(e=>"running"===e.status).length,problemCount:n.filter(e=>"failed"===e.status).length,sessions:n,updatedAt:t})}function $s(e,t=(new Date).toISOString()){return Us(e.filter(e=>Hs("string"==typeof e.status?e.status:void 0)),t)}function Bs(e){const t=Fs("string"==typeof e.status?e.status:void 0),n="string"==typeof e.id?e.id:"",i=function(e){const t=Xs(e.workspace),n=Xs(e.tty),i=Xs(e.launch),s=Xs(e.ai),a=Xs(s.claude),o=Js(t.cwd)||Js(n.cwd)||Js(a.cwd)||Js(i.cwd);return o?{cwd:o}:void 0}(e),{workspace:s,...a}=e;return Cs.parse({...a,status:t,bindings:Ys([...(o=e.bindings,Array.isArray(o)?o.flatMap(e=>{const t=Ns.safeParse(e);return t.success?[t.data]:[]}):[]),...n?[{type:"app-session",id:n}]:[],...Vs(e)]),...i?{workspace:i}:{}});var o}function Fs(e){const t=(e||"unknown").trim().toLowerCase();return"ended"===t?"closed":"terminating"===t?"stopping":Ts.options.includes(t)?t:"unknown"}function Hs(e){return!ks.has(Fs(e))}function Gs(e){return"tty"===e.kind?"tty":"gui"===e.kind?"vnc":"web"===e.kind?"web":void 0}function Ws(e){return"app-session"===e.type?`app:${e.id}`:"provider-session"===e.type?`provider:${e.agent||""}:${e.id}`:`adapter:${e.adapter||""}:${e.key||e.id}`}function Vs(e){const t=Xs(e.ai),n=Xs(t.claude),i=Xs(t.appServer),s=Xs(e.launch),a=[],o=Js(Xs(s.aiSessionResume).providerSessionId),r="codex"===e.appId||"claude"===e.appId||"opencode"===e.appId?e.appId:void 0;r&&o&&a.push({type:"provider-session",agent:r,id:o});const c=Js(n.short);c&&a.push({type:"adapter-key",adapter:"claude",agent:"claude",id:`short:${c}`,key:`short:${c}`});const d=Js(n.providerSessionId);d&&a.push({type:"provider-session",agent:"claude",id:d});const l=Array.isArray(t.threadIds)?t.threadIds.filter(e=>"string"==typeof e&&Boolean(e.trim())):[],p=Js(t.activeThreadId);for(const e of[...new Set([p,...l].filter(Boolean))])a.push({type:"provider-session",agent:"codex",id:e});const u=Js(i.socketPath);return u&&a.push({type:"adapter-key",adapter:"codex-app-server",agent:"codex",id:`socket:${u}`,key:`socket:${u}`}),a}function Ks(e){const t="string"==typeof e.id?e.id:"",n=Xs(e.ai),i=Js(Xs(n.claude).short);return[t?`app:${t}`:"",i?`claude-short:${i}`:""]}function Ys(e){const t=new Map;for(const n of e)t.set(Ws(n),n);return[...t.values()]}function Xs(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function Js(e){return"string"==typeof e&&e.trim()?e.trim():""}function Qs(e=(new Date).toISOString()){return Rs.parse({runningCount:0,problemCount:0,sessions:[],updatedAt:e})}const Zs=f.z.string().trim().min(3).max(160).regex(/^[a-z][a-z0-9_-]*$/),ea=f.z.string().datetime(),ta=f.z.string().regex(/^sha256:[A-Za-z0-9_-]{43}$/),na=f.z.string().min(32).max(4096),ia=f.z.strictObject({default:f.z.string().trim().min(1).max(160),translations:f.z.record(f.z.string().regex(/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/),f.z.string().trim().min(1).max(160)).default({})});function sa(e){return Array.isArray(e)?`[${e.map(sa).join(",")}]`:e&&"object"==typeof e?`{${Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${sa(t)}`).join(",")}}`:JSON.stringify(e)}const aa="2026-08-10",oa="2026-08-10",ra="2026-08-10",ca=Object.freeze({AccountApi:"task-handoff:official-account-api",Binding:"task-handoff:control-plane-binding",CoordinatorControl:"task-handoff:coordinator-control",RelayAllocation:"task-handoff:relay-allocation",RelayClientAttach:"task-handoff:relay-client-attach",RelayControlPlaneAttach:"task-handoff:relay-control-plane-attach",RelayRevocation:"task-handoff:relay-revocation",ControlPlaneAccess:"task-handoff:control-plane-access"});f.z.strictObject({protocolVersion:f.z.literal("2026-08-10"),audience:f.z.literal(ca.AccountApi)});const da=f.z.string().email().max(320).transform(e=>e.trim().toLowerCase()),la=f.z.enum(["pending-verification","active","disabled","pending-deletion"]);f.z.strictObject({id:Zs,email:da,emailVerified:f.z.boolean(),hasPassword:f.z.boolean().optional(),totpEnabled:f.z.boolean().optional(),displayName:ia.optional(),status:la,createdAt:ea}),f.z.strictObject({id:Zs,kind:f.z.enum(["browser","mobile"]),deviceName:f.z.string().trim().min(1).max(160),platform:f.z.string().trim().min(1).max(80).optional(),createdAt:ea,lastSeenAt:ea.optional(),expiresAt:ea,revokedAt:ea.optional()}),f.z.union([f.z.object({code:na,state:f.z.string().min(1).max(4096).optional(),redirectUri:f.z.string().url(),expiresAt:ea}),f.z.object({authorizationUrl:f.z.string().url(),expiresAt:ea})]),f.z.object({tokenType:f.z.literal("Bearer"),accessToken:na,accessExpiresAt:ea,refreshCredential:na,accountId:Zs,deviceSessionId:Zs}),f.z.strictObject({enrollmentToken:na,secret:na,algorithm:f.z.literal("SHA1"),digits:f.z.literal(6),periodSeconds:f.z.literal(30),otpauthUri:f.z.string().url().startsWith("otpauth://totp/"),expiresAt:ea});const pa=f.z.strictObject({controlPlaneId:Zs,algorithm:f.z.literal("Ed25519"),publicKey:f.z.string().regex(/^[A-Za-z0-9_-]{43}$/),fingerprint:ta});f.z.strictObject({protocolVersion:f.z.literal(aa),audience:f.z.literal(ca.Binding),challengeId:Zs,challenge:na,serviceOrigin:f.z.string().url(),identity:pa,nonce:f.z.string().min(16).max(256),initiatingAdminSessionId:Zs,issuedAt:ea,expiresAt:ea}),f.z.strictObject({code:f.z.enum(["CONTROL_PLANE_ALREADY_BOUND","REVISION_CONFLICT","REVOCATION_PENDING","IDENTITY_CLONE_CONFLICT"]),controlPlaneId:Zs,expectedRevision:f.z.number().int().nonnegative().optional(),actualRevision:f.z.number().int().nonnegative().optional(),retryable:f.z.boolean()});const ua=f.z.strictObject({bindingId:Zs.optional(),controlPlaneId:Zs,displayName:ia,publicKeyFingerprint:ta,bindingRevision:f.z.number().int().positive(),remoteAccess:f.z.enum(["enabled","disabled","revocation-pending"]),leaseExpiresAt:ea.optional(),lastConnectedAt:ea.optional(),relayUsageBytes:f.z.number().int().nonnegative(),relayQuotaBytes:f.z.number().int().nonnegative().optional(),versionWarning:f.z.string().trim().min(1).max(500).optional(),errorCode:f.z.string().trim().min(1).max(160).optional()}),ma=f.z.enum(["interactive","stream","bulk"]),ha=f.z.object({type:f.z.literal("tty-snapshot"),streamId:f.z.string().trim().min(1).optional(),data:f.z.string(),pendingEscape:f.z.string(),cols:f.z.number().int().positive(),rows:f.z.number().int().positive()}).passthrough(),ga=f.z.strictObject({protocolVersion:f.z.literal(oa),audience:f.z.literal(ca.CoordinatorControl),connectionId:Zs,processInstanceId:Zs,controlPlaneId:Zs,publicKey:f.z.string().regex(/^[A-Za-z0-9_-]{43}$/),publicKeyFingerprint:ta,bindingId:Zs.optional(),bindingRevision:f.z.number().int().positive().optional(),epoch:f.z.number().int().nonnegative(),capabilities:f.z.array(f.z.enum(["request","stream","websocket"])).min(1),issuedAt:ea,expiresAt:ea}).superRefine((e,t)=>{Boolean(e.bindingId)!==Boolean(e.bindingRevision)&&t.addIssue({code:"custom",message:"binding id and revision must be supplied together"})});ga.safeExtend({signature:na}),f.z.strictObject({connectionId:Zs,controlPlaneId:Zs,bindingRevision:f.z.number().int().positive(),epoch:f.z.number().int().nonnegative(),relayId:Zs,relayRegion:f.z.string().trim().min(1).max(80),issuedAt:ea,expiresAt:ea});const fa=f.z.strictObject({protocolVersion:f.z.literal(oa),audience:f.z.literal(ca.ControlPlaneAccess),ticketId:Zs,accountId:Zs,deviceSessionId:Zs,controlPlaneId:Zs,bindingId:Zs,bindingRevision:f.z.number().int().positive(),targetPublicKeyFingerprint:ta,nonce:f.z.string().min(16).max(256),trafficClasses:f.z.array(ma).min(1),issuedAt:ea,expiresAt:ea,signature:na});f.z.strictObject({audience:f.z.literal(ca.ControlPlaneAccess),accountId:Zs,deviceSessionId:Zs,controlPlaneId:Zs,bindingId:Zs,bindingRevision:f.z.number().int().positive(),authenticatedAt:ea,expiresAt:ea,signature:na});const ya=f.z.enum(["client","control-plane"]),ba=f.z.strictObject({protocolVersion:f.z.literal(ra),audience:f.z.enum([ca.RelayClientAttach,ca.RelayControlPlaneAttach]),allocationId:Zs,relayId:Zs,role:ya,controlPlaneId:Zs,accountId:Zs,deviceSessionId:Zs,bindingId:Zs,ticketId:Zs,bindingRevision:f.z.number().int().positive(),trafficClass:ma,nonce:f.z.string().min(16).max(256),issuedAt:ea,expiresAt:ea,signature:na}).superRefine((e,t)=>{const n="client"===e.role?ca.RelayClientAttach:ca.RelayControlPlaneAttach;e.audience!==n&&t.addIssue({code:"custom",path:["audience"],message:`audience must match ${e.role} role`})});f.z.object({allocationId:Zs,relayId:Zs,relayRegion:f.z.string().trim().min(1).max(80),relayUrl:f.z.string().url(),clientAttach:ba,expiresAt:ea}),f.z.strictObject({channelId:Zs,allocationId:Zs,controlPlaneId:Zs,bindingRevision:f.z.number().int().positive(),trafficClass:ma,state:f.z.enum(["waiting-for-peer","handshaking","open","closing","closed"]),clientAttached:f.z.boolean(),controlPlaneAttached:f.z.boolean(),openedAt:ea.optional(),leaseExpiresAt:ea}),f.z.strictObject({protocolVersion:f.z.literal(ra),channelId:Zs,sequence:f.z.number().int().nonnegative(),kind:f.z.enum(["handshake","data","cancel","window-update","close"]),ciphertext:f.z.string().max(1398102).optional(),creditBytes:f.z.number().int().positive().optional()}),f.z.strictObject({channelId:Zs,code:f.z.enum(["normal","expired","revoked","quota-exceeded","idle-timeout","slow-consumer","protocol-error","peer-disconnected"]),retryable:f.z.boolean()}),f.z.strictObject({protocolVersion:f.z.literal(ra),audience:f.z.literal(ca.RelayRevocation),revocationId:Zs,relayId:Zs.optional(),allocationId:Zs.optional(),accountId:Zs.optional(),deviceSessionId:Zs.optional(),bindingId:Zs.optional(),issuedAt:ea,expiresAt:ea,signature:na}).refine(e=>[e.allocationId,e.accountId,e.deviceSessionId,e.bindingId].some(Boolean),"revocation target is required"),f.z.strictObject({data:f.z.strictObject({protocolVersion:f.z.literal(aa),items:f.z.array(ua)})}),Object.keys(ua.shape);const va=f.z.object({ticketId:f.z.string().trim().min(3).max(160),deviceSessionId:f.z.string().trim().min(3).max(160),clientEphemeralPublicKey:f.z.string().regex(/^[A-Za-z0-9_-]{43}$/)});function Ia(){return Object.assign(new Error("End-to-end handshake is invalid."),{code:"E2E_HANDSHAKE_INVALID"})}f.z.object({serverEphemeralPublicKey:f.z.string().regex(/^[A-Za-z0-9_-]{43}$/),transcript:f.z.string().regex(/^[A-Za-z0-9_-]{43}$/),signature:f.z.string().regex(/^[A-Za-z0-9_-]{86}$/)});const xa=f.z.union([f.z.object({type:f.z.literal("schedule"),scheduleKind:f.z.literal("interval").default("interval"),intervalMs:f.z.number().int().min(1e3)}).strict(),f.z.object({type:f.z.literal("schedule"),scheduleKind:f.z.literal("daily"),timeOfDay:f.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/),timezone:f.z.string().trim().min(1).max(120)}).strict(),f.z.object({type:f.z.literal("schedule"),scheduleKind:f.z.literal("weekly"),weekdays:f.z.array(f.z.number().int().min(0).max(6)).min(1).max(7),timeOfDay:f.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/),timezone:f.z.string().trim().min(1).max(120)}).strict()]),wa=f.z.union([xa,f.z.object({type:f.z.literal("file-change"),roots:f.z.array(f.z.string().trim().min(1).max(4096)).min(1).max(50),globs:f.z.array(f.z.string().trim().min(1).max(500)).min(1).max(100),ignore:f.z.array(f.z.string().trim().min(1).max(500)).max(100).optional(),debounceMs:f.z.number().int().min(100).max(6e4).default(1500)}).strict(),f.z.object({type:f.z.literal("ai-session"),agent:f.z.string().trim().min(1).max(80).optional(),statuses:f.z.array(f.z.enum(["running","waiting","idle","failed"])).max(20).optional(),phases:f.z.array(f.z.enum(["thinking","tool","editing","approval","responding","unknown"])).max(20).optional()}).strict()]),Sa=f.z.object({promptTemplate:f.z.string().trim().min(1).max(2e4)}).strict(),Aa=f.z.object({cooldownMs:f.z.number().int().min(0).max(864e5).optional(),maxConcurrentRuns:f.z.number().int().min(1).max(20).default(1),whenBusy:f.z.enum(["skip","queue"]).default("skip")}).strict(),Ea=f.z.object({configHash:f.z.string().trim().min(8).max(80),name:f.z.string().trim().min(1).max(160),description:f.z.string().trim().max(1e3).optional(),source:wa,action:Sa,policy:Aa.default({maxConcurrentRuns:1,whenBusy:"skip"}),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}).strict(),_a=f.z.object({type:f.z.literal("ai-session"),aiSessionId:f.z.string().trim().min(1).max(160)}).strict(),Ta=f.z.object({configHash:f.z.string().trim().min(8).max(80),deploymentId:f.z.string().trim().min(1).max(240).optional(),instanceId:f.z.string().trim().min(1).max(160),origin:f.z.enum(["control-plane","controlled-instance"]).default("controlled-instance"),enabled:f.z.boolean().default(!0),target:_a,localName:f.z.string().trim().min(1).max(160).optional(),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}).strict(),za=f.z.object({configHash:f.z.string().trim().min(8).max(80),deploymentId:f.z.string().trim().min(1).max(240).optional(),instanceId:f.z.string().trim().min(1).max(160),status:f.z.enum(["idle","running","disabled","error"]).default("idle"),lastTriggeredAt:f.z.string().datetime().optional(),lastCompletedAt:f.z.string().datetime().optional(),lastSkippedAt:f.z.string().datetime().optional(),lastError:f.z.string().trim().max(4e3).optional(),runCount:f.z.number().int().min(0).default(0),skippedCount:f.z.number().int().min(0).default(0)}).strict(),ka=f.z.object({id:f.z.string().trim().min(1).max(160),configHash:f.z.string().trim().min(8).max(80),deploymentId:f.z.string().trim().min(1).max(240).optional(),instanceId:f.z.string().trim().min(1).max(160),eventType:f.z.enum(["manual","schedule","file-change","ai-session"]),status:f.z.enum(["started","completed","failed","skipped"]),target:_a,promptPreview:f.z.string().trim().max(500),eventSummary:f.z.string().trim().max(1e3).optional(),error:f.z.string().trim().max(4e3).optional(),startedAt:f.z.string().datetime(),completedAt:f.z.string().datetime().optional()}).strict();f.z.object({schemaVersion:f.z.literal(1).default(1),configs:f.z.array(Ea).default([]),deployments:f.z.array(Ta).default([]),runtime:f.z.array(za).default([]),recentRuns:f.z.array(ka).default([])}).strict();const Na=f.z.object({instanceId:f.z.string().trim().min(1).max(160),instanceName:f.z.string().trim().min(1).max(160),deployment:Ta,runtime:za.optional()}).strip(),Ca=ka.extend({instanceName:f.z.string().trim().min(1).max(160).optional()}).strip(),Ra=f.z.object({configHash:f.z.string().trim().min(8).max(80),config:Ea,deploymentCount:f.z.number().int().min(0),enabledCount:f.z.number().int().min(0),runningCount:f.z.number().int().min(0),errorCount:f.z.number().int().min(0),ownedByControlPlane:f.z.boolean(),controlPlaneDeploymentCount:f.z.number().int().min(0),deployments:f.z.array(Na),recentRuns:f.z.array(Ca)}).strip(),Oa=f.z.object({updatedAt:f.z.string().datetime(),triggers:f.z.array(Ra)}).strip();function ja(e){const t=La({source:e.source,action:e.action,policy:Aa.parse(e.policy||{})});return`trg_${function(e){const t=(new TextEncoder).encode(e),n=64*Math.ceil((t.length+9)/64),i=new Uint8Array(n);i.set(t),i[t.length]=128;const s=new DataView(i.buffer),a=8*t.length;s.setUint32(n-8,Math.floor(a/4294967296)),s.setUint32(n-4,a>>>0);const o=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),r=new Uint32Array(64);for(let e=0;e<n;e+=64){for(let t=0;t<16;t+=1)r[t]=s.getUint32(e+4*t);for(let e=16;e<64;e+=1){const t=r[e-15],n=r[e-2],i=Da(t,7)^Da(t,18)^t>>>3,s=Da(n,17)^Da(n,19)^n>>>10;r[e]=r[e-16]+i+r[e-7]+s>>>0}let[t,n,i,a,c,d,l,p]=o;for(let e=0;e<64;e+=1){const s=p+(Da(c,6)^Da(c,11)^Da(c,25))+(c&d^~c&l)+Pa[e]+r[e]>>>0,o=t&n^t&i^n&i;p=l,l=d,d=c,c=a+s>>>0,a=i,i=n,n=t,t=s+((Da(t,2)^Da(t,13)^Da(t,22))+o>>>0)>>>0}o[0]=o[0]+t>>>0,o[1]=o[1]+n>>>0,o[2]=o[2]+i>>>0,o[3]=o[3]+a>>>0,o[4]=o[4]+c>>>0,o[5]=o[5]+d>>>0,o[6]=o[6]+l>>>0,o[7]=o[7]+p>>>0}return[...o].map(e=>e.toString(16).padStart(8,"0")).join("")}(JSON.stringify(t)).slice(0,24)}`}f.z.object({name:Ea.shape.name,description:Ea.shape.description,source:wa,action:Sa,policy:Aa.partial().optional()}).strict(),f.z.object({scope:f.z.enum(["node","instance"]),nodeId:f.z.string().trim().min(1).max(160).optional(),instanceId:f.z.string().trim().min(1).max(160).optional(),code:f.z.string().trim().min(1).max(160),message:f.z.string().trim().min(1).max(4e3)}).strip();const Pa=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];function Da(e,t){return e>>>t|e<<32-t}function La(e){return Array.isArray(e)?e.map(La):e&&"object"==typeof e?Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>[e,La(t)])):e}const Ma="2026-08-01",qa=f.z.string().regex(/^\d{4}-\d{2}-\d{2}$/,"Proxy protocol version must use YYYY-MM-DD format."),Ua=f.z.string().trim().min(1).max(160).regex(/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/),$a=f.z.string().datetime(),Ba=f.z.string().trim().min(32).max(4096),Fa=Ua,Ha=f.z.string().trim().max(2048).transform((e,t)=>{try{return function(e){const t=new URL(e.trim());if("https:"!==t.protocol||t.username||t.password||"/"!==t.pathname||t.search||t.hash)throw new Error("Proxy origin must be an HTTPS origin without credentials, path, query, or fragment.");return t.origin}(e)}catch(e){return t.addIssue({code:"custom",message:e instanceof Error?e.message:String(e)}),f.z.NEVER}}),Ga=f.z.string().trim().min(1).max(4096).transform((e,t)=>{try{return function(e){const t=e.trim();if(!t.startsWith("/")||t.startsWith("//")||t.includes("\\")||/%25/i.test(t))throw new Error("Proxy route must be a single-encoded node-agent relative route.");const n=t.split("?",1)[0];let i,s;try{i=n.split("/").map(e=>decodeURIComponent(e))}catch{throw new Error("Proxy route contains invalid percent encoding.")}if(i.some(e=>".."===e||"."===e))throw new Error("Proxy route cannot traverse outside the node-agent API.");try{s=new URL(t,"https://node-agent.invalid")}catch{throw new Error("Proxy route is invalid.")}if("https://node-agent.invalid"!==s.origin||s.username||s.password)throw new Error("Proxy route cannot select an absolute upstream URL.");return`${s.pathname}${s.search}`}(e)}catch(e){return t.addIssue({code:"custom",message:e instanceof Error?e.message:String(e)}),f.z.NEVER}}),Wa=new Set(["accept","accept-language","authorization","content-type","if-match","if-none-match","range","x-request-id","x-task-handoff-trace-id"]),Va=new Set(["cache-control","content-disposition","content-language","content-length","content-range","content-type","etag","last-modified","server-timing","x-request-id","x-task-handoff-trace-id"]),Ka="x-task-handoff-proxy-protocol-version",Ya="x-task-handoff-proxy-source-control-plane-id",Xa="x-task-handoff-proxy-binding-key-id",Ja="x-task-handoff-proxy-credential",Qa={ProtocolUnsupported:"CONTROL_PLANE_PROXY_PROTOCOL_UNSUPPORTED",InviteInvalid:"CONTROL_PLANE_PROXY_INVITE_INVALID",InviteExpired:"CONTROL_PLANE_PROXY_INVITE_EXPIRED",InviteConsumed:"CONTROL_PLANE_PROXY_INVITE_CONSUMED",InviteRevoked:"CONTROL_PLANE_PROXY_INVITE_REVOKED",TargetUnavailable:"CONTROL_PLANE_PROXY_TARGET_UNAVAILABLE",TargetMismatch:"CONTROL_PLANE_PROXY_TARGET_MISMATCH",BindingUnknown:"CONTROL_PLANE_PROXY_BINDING_UNKNOWN",BindingRevoked:"CONTROL_PLANE_PROXY_BINDING_REVOKED",BindingIdentityConflict:"CONTROL_PLANE_PROXY_BINDING_IDENTITY_CONFLICT",AuthenticationFailed:"CONTROL_PLANE_PROXY_AUTHENTICATION_FAILED",RouteInvalid:"CONTROL_PLANE_PROXY_ROUTE_INVALID",HeaderInvalid:"CONTROL_PLANE_PROXY_HEADER_INVALID",ResourceLimit:"CONTROL_PLANE_PROXY_RESOURCE_LIMIT",SnapshotRequired:"CONTROL_PLANE_PROXY_SNAPSHOT_REQUIRED",Unavailable:"CONTROL_PLANE_PROXY_UNAVAILABLE",TransportFailed:"CONTROL_PLANE_PROXY_TRANSPORT_FAILED"},Za=f.z.enum(Object.values(Qa)),eo=f.z.object({code:Za,message:f.z.string().trim().min(1).max(2048),retryable:f.z.boolean(),details:f.z.record(f.z.string(),f.z.unknown()).optional()}).strict(),to=f.z.enum(["active","revoked"]),no=f.z.object({id:Ua,targetNodeId:Ua,status:to,createdBy:Ua,expiresAt:$a,revokedAt:$a.optional(),createdAt:$a,updatedAt:$a}).strict(),io=f.z.object({targetNodeId:Ua,expiresInSeconds:f.z.number().int().min(60).max(3600).default(600)}).strict(),so=f.z.object({invite:no,token:f.z.string().trim().min(24).max(512),proxyOrigin:Ha,protocolVersion:qa}).strict(),ao=f.z.enum(["active","revoked"]),oo=f.z.object({id:Ua,claimId:Ua,sourceControlPlaneId:Ua,targetNodeId:Ua,bindingKeyId:Ua,status:ao,revision:f.z.number().int().positive(),lastError:eo.optional(),revokedAt:$a.optional(),createdAt:$a,updatedAt:$a}).strict(),ro=f.z.object({protocolVersion:qa,inviteToken:f.z.string().trim().min(24).max(512).optional(),claimId:Ua,sourceControlPlaneId:Ua,targetNodeId:Ua.optional(),bindingKeyId:Ua,credential:Ba}).strict(),co=f.z.object({sourceControlPlaneId:Ua,bindingKeyId:Ua,credential:Ba}).strict(),lo=f.z.object({id:Ua,name:f.z.string().trim().min(1).max(160),status:f.z.enum(["unknown","online","offline","degraded"]),health:f.z.enum(["unknown","ok","degraded","failed"]),lastSeenAt:$a.optional(),capabilities:f.z.record(f.z.string(),f.z.unknown()).default({})}).strict(),po=f.z.object({protocolVersion:qa,binding:oo,streamId:Ua,revision:f.z.number().int().nonnegative(),observedAt:$a,target:lo}).strict(),uo=f.z.object({type:f.z.literal("control-plane-proxy.event"),protocolVersion:qa,streamId:Ua,bindingId:Ua,sourceControlPlaneId:Ua,targetNodeId:Ua,revision:f.z.number().int().positive(),source:f.z.object({id:f.z.string().trim().min(1).max(512),seq:f.z.number().int().nonnegative()}).strict(),target:lo,event:f.z.object({type:f.z.string().trim().min(1).max(240),topic:f.z.string().trim().min(1).max(240),createdAt:$a}).strict()}).strict(),mo=f.z.object({type:f.z.literal("control-plane-proxy.events.ready"),protocolVersion:qa,streamId:Ua,bindingId:Ua,sourceControlPlaneId:Ua,targetNodeId:Ua,latestRevision:f.z.number().int().nonnegative(),earliestRetainedRevision:f.z.number().int().nonnegative()}).strict(),ho=f.z.object({type:f.z.literal("control-plane-proxy.snapshot-required"),protocolVersion:qa,streamId:Ua,bindingId:Ua,sourceControlPlaneId:Ua,targetNodeId:Ua,sinceRevision:f.z.number().int().nonnegative(),latestRevision:f.z.number().int().nonnegative(),earliestRetainedRevision:f.z.number().int().nonnegative(),error:eo}).strict(),go=f.z.discriminatedUnion("type",[uo,mo,ho]),fo=f.z.object({protocolVersion:qa,binding:oo,target:po.shape.target}).strict(),yo=f.z.object({id:Ua,claimId:Ua,proxyOrigin:Ha,requestedName:f.z.string().trim().min(1).max(160).optional(),sourceControlPlaneId:Ua,targetNodeId:Ua.optional(),bindingKeyId:Ua,credential:Ba,status:f.z.enum(["pending","compensation-required"]),createdAt:$a,updatedAt:$a,expiresAt:$a}).strict();yo.omit({credential:!0});const bo=f.z.object({id:Ua,nodeId:Ua,proxyOrigin:Ha,proxyBindingId:Ua,targetNodeId:Ua,sourceControlPlaneId:Ua,bindingKeyId:Ua,credential:Ba,createdAt:$a,updatedAt:$a}).strict(),vo=f.z.string().trim().min(1).max(120),Io=f.z.object({agent:vo,actions:f.z.object({create:f.z.boolean().default(!1),send:f.z.boolean().default(!1),queue:f.z.boolean().default(!1),steer:f.z.boolean().default(!1),interrupt:f.z.boolean().default(!1),archive:f.z.boolean().default(!1),delete:f.z.boolean().default(!1),fork:f.z.boolean().default(!1),approvalDecisions:f.z.array(f.z.enum(["allow","deny","skip"])).max(3).default([])}).passthrough(),timeline:f.z.object({sessionRead:f.z.boolean().default(!1),turnRead:f.z.boolean().default(!1),liveItems:f.z.boolean().default(!1)}).passthrough()}).passthrough(),xo=f.z.array(Io).max(100).default([]),wo="2026-08-23",So=new Set(["2026-08-01","2026-08-16","2026-08-17","2026-08-20",wo]),Ao=f.z.string().regex(/^\d{4}-\d{2}-\d{2}$/,"Protocol version must use YYYY-MM-DD format."),Eo=f.z.string().trim().min(1).max(120);function _o(){return{features:{appRuntime:!1,tty:!1,gui:!1,browser:!1,screenshots:!1,logs:!1,aiSessionWorkspaceSelection:!1,aiSessionPersistenceSettings:!1,gitCliCredentialBroker:!1,gitCredentialProxy:!1,aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]},aiSessionConversationAttachments:{metadataAgents:[],contentAgents:[],uploadAgents:[],retentionSettings:!1,fileSizeLimitSettings:!1},aiSessionProviders:[]}}}const To=f.z.object({sessionReadAgents:f.z.array(Eo).max(100).default([]),turnReadAgents:f.z.array(Eo).max(100).default([]),liveItemAgents:f.z.array(Eo).max(100).default([])}).passthrough(),zo=f.z.object({metadataAgents:f.z.array(Eo).max(100).default([]),contentAgents:f.z.array(Eo).max(100).default([]),uploadAgents:f.z.array(Eo).max(100).default([]),retentionSettings:f.z.boolean().default(!1),fileSizeLimitSettings:f.z.boolean().default(!1)}).passthrough(),ko=f.z.object({appRuntime:f.z.boolean().default(!1),tty:f.z.boolean().default(!1),gui:f.z.boolean().default(!1),browser:f.z.boolean().default(!1),screenshots:f.z.boolean().default(!1),logs:f.z.boolean().default(!1),aiSessionWorkspaceSelection:f.z.boolean().default(!1),aiSessionPersistenceSettings:f.z.boolean().default(!1),gitCliCredentialBroker:f.z.boolean().optional(),gitCredentialProxy:f.z.boolean().optional(),aiSessionTimeline:To.default(function(){return{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}}),aiSessionConversationAttachments:zo.optional(),aiSessionProviders:xo.optional()}).passthrough(),No=f.z.object({features:ko.default(function(){return{appRuntime:!1,tty:!1,gui:!1,browser:!1,screenshots:!1,logs:!1,aiSessionWorkspaceSelection:!1,aiSessionPersistenceSettings:!1,gitCliCredentialBroker:!1,gitCredentialProxy:!1,aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]},aiSessionConversationAttachments:{metadataAgents:[],contentAgents:[],uploadAgents:[],retentionSettings:!1,fileSizeLimitSettings:!1},aiSessionProviders:[]}})}).passthrough();function Co(e){const t={features:{appRuntime:!1,tty:!1,gui:!1,browser:!1,screenshots:!1,logs:!1,aiSessionWorkspaceSelection:!1,aiSessionPersistenceSettings:!1,gitCliCredentialBroker:!1,gitCredentialProxy:!1,aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]},aiSessionConversationAttachments:{metadataAgents:[],contentAgents:[],uploadAgents:[],retentionSettings:!1,fileSizeLimitSettings:!1},aiSessionProviders:[]}};if(!e||"object"!=typeof e||Array.isArray(e))return t;const n=e,i=n.features;if(!i||"object"!=typeof i||Array.isArray(i))return t;const s=i,a={appRuntime:!1,tty:!1,gui:!1,browser:!1,screenshots:!1,logs:!1,aiSessionWorkspaceSelection:!1,aiSessionPersistenceSettings:!1,gitCliCredentialBroker:!1,gitCredentialProxy:!1,aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]},aiSessionConversationAttachments:{metadataAgents:[],contentAgents:[],uploadAgents:[],retentionSettings:!1,fileSizeLimitSettings:!1},aiSessionProviders:[]};for(const e of["appRuntime","tty","gui","browser","screenshots","logs","aiSessionWorkspaceSelection","aiSessionPersistenceSettings","gitCliCredentialBroker","gitCredentialProxy"]){const t=f.z.boolean().safeParse(s[e]);t.success&&(a[e]=t.data)}const o=To.safeParse(s.aiSessionTimeline);o.success&&(a.aiSessionTimeline=o.data);const r=zo.safeParse(s.aiSessionConversationAttachments);r.success&&(a.aiSessionConversationAttachments=r.data);const c=xo.safeParse(s.aiSessionProviders);return c.success&&(a.aiSessionProviders=c.data),No.parse({...n,features:{...s,...a}})}function Ro(e){return Co(e).features.gitCredentialProxy}function Oo(e,t){const n=function(e){return Co(e).features.aiSessionTimeline}(e);return"session-read"===t?n.sessionReadAgents:"turn-read"===t?n.turnReadAgents:n.liveItemAgents}const jo=f.z.string().trim().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/),Po=f.z.string().datetime(),Do=f.z.record(f.z.string(),f.z.string()).default({}),Lo=f.z.record(f.z.string(),f.z.string()).default({});function Mo(e){if(null!=e){if("string"==typeof e)return{encoding:"utf8",data:e};if(Buffer.isBuffer(e))return{encoding:"base64",data:e.toString("base64")};if(e instanceof ArrayBuffer)return{encoding:"base64",data:Buffer.from(e).toString("base64")};if(ArrayBuffer.isView(e))return{encoding:"base64",data:Buffer.from(e.buffer,e.byteOffset,e.byteLength).toString("base64")};throw new TypeError("Node tunnel request body must be a string or binary buffer.")}}f.z.object({encoding:f.z.enum(["utf8","base64"]),data:f.z.string()}).strict().superRefine((e,t)=>{"base64"===e.encoding&&Buffer.from(e.data,"base64").toString("base64")!==e.data&&t.addIssue({code:"custom",path:["data"],message:"Node tunnel binary body must use canonical base64 encoding."})});const qo=/^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$/,Uo=/^sha256:([a-fA-F0-9]{64})$/,$o=/^(?:localhost|[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?)(?::[1-9][0-9]{0,4})?$/,Bo=/^[a-z0-9]+(?:(?:[._]|__|-+)[a-z0-9]+)*$/;function Fo(e){const t=e.trim();if(!t||t.length>512||t.includes("://")||/\s/.test(t))throw new Error("Docker image reference must not contain a URL scheme or whitespace.");const n=t.indexOf("@");if(-1!==n&&n!==t.lastIndexOf("@"))throw new Error("Docker image reference contains more than one digest separator.");const i=-1===n?void 0:t.slice(n+1),s=-1===n?t:t.slice(0,n),a=i?Uo.exec(i):void 0;if(i&&!a)throw new Error("Docker image digest must use sha256 followed by 64 hexadecimal characters.");const o=s.lastIndexOf("/"),r=s.lastIndexOf(":"),c=r>o,d=c?s.slice(r+1):void 0,l=c?s.slice(0,r):s;if(d&&!qo.test(d))throw new Error("Docker image tag is invalid.");if(!d&&!a)throw new Error("Docker image reference must include an explicit tag or sha256 digest.");const p=l.split("/");if(!p.length||p.some(e=>!e))throw new Error("Docker image repository path is invalid.");const u=p.length>1&&(p[0].includes(".")||p[0].includes(":")||"localhost"===p[0]),m=u?p.slice(1):p;if(u&&!$o.test(p[0].toLowerCase()))throw new Error("Docker image registry host or port is invalid.");if(!m.length||m.some(e=>!Bo.test(e)))throw new Error("Docker image repository names must be lowercase and use valid separators.");const h=p.map((e,t)=>u&&0===t?e.toLowerCase():e).join("/"),g=a?`sha256:${a[1].toLowerCase()}`:void 0;return`${h}${d?`:${d}`:""}${g?`@${g}`:""}`}function Ho(e){const t=Fo(e),n=t.indexOf("@"),i=-1===n?void 0:t.slice(n+1),s=-1===n?t:t.slice(0,n),a=s.lastIndexOf("/"),o=s.lastIndexOf(":"),r=o>a;return{reference:t,repository:r?s.slice(0,o):s,tag:r?s.slice(o+1):void 0,digest:i}}const Go=f.z.string().trim().min(1).max(512).transform((e,t)=>{try{return Fo(e)}catch(e){return t.addIssue({code:"custom",message:e instanceof Error?e.message:String(e)}),f.z.NEVER}}),Wo=f.z.string().trim().transform((e,t)=>{const n=Uo.exec(e);return n?`sha256:${n[1].toLowerCase()}`:(t.addIssue({code:"custom",message:"Docker image digest must use sha256 followed by 64 hexadecimal characters."}),f.z.NEVER)}),Vo=f.z.object({codexModelHash:jo.nullable().optional(),claudeModelHash:jo.nullable().optional(),opencodeModelHash:jo.nullable().optional()}).strict().default({}),Ko=f.z.object({imageId:jo,tag:f.z.string().trim().min(1).max(128).regex(qo).optional()}).strict(),Yo=f.z.discriminatedUnion("type",[f.z.object({type:f.z.literal("image"),imageSelection:Ko}).strict(),f.z.object({type:f.z.literal("template"),environmentTemplateId:jo}).strict()]),Xo=f.z.enum(["creating","ready","failed","deleting"]),Jo=f.z.enum(["linux","darwin","win32","freebsd","openbsd","aix","sunos","unknown"]),Qo=f.z.enum(["x64","arm64","arm","ia32","ppc64","s390x","riscv64","unknown"]),Zo=f.z.object({code:f.z.string().trim().min(1).max(120),message:f.z.string().trim().min(1).max(2048),phase:f.z.enum(["validate","commit","inspect","security-check","persist","delete","recovery"]).optional()}).strict(),er=f.z.object({templateId:jo,nodeId:jo,imageId:Wo,name:f.z.string().trim().min(1).max(160),platform:Jo,architecture:Qo}).strict(),tr=f.z.enum(["data","agent-home","workspace"]),nr=f.z.object({deleteVolumes:f.z.boolean()}).strict(),ir=f.z.object({role:tr,name:f.z.string().trim().min(1).max(255),mountPath:f.z.string().trim().startsWith("/").max(4096),status:f.z.enum(["deleted","retained","missing","failed"]),error:f.z.object({code:f.z.string().trim().min(1).max(120),message:f.z.string().trim().min(1).max(2048)}).strict().optional()}).strict(),sr=f.z.object({instanceId:jo,containerDeleted:f.z.boolean(),completed:f.z.boolean(),deletedVolumes:f.z.array(ir),retainedVolumes:f.z.array(ir),volumeResults:f.z.array(ir)}).strict(),ar={img_default:"market_taskhandoff_browser",img_codex:"market_taskhandoff_codex",img_ai:"market_taskhandoff_ai"};function or(e,t){if(e&&"object"==typeof e&&!Array.isArray(e)){const t=e;return{imageId:"string"==typeof t.imageId&&ar[t.imageId]||t.imageId,..."string"==typeof t.tag?{tag:t.tag}:{}}}if("string"==typeof t)return{imageId:ar[t]||t}}function rr(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e,{defaultImageId:n,defaultRuntimeId:i,...s}=t;return{...s,source:yd(t.source),defaultImageSelection:or(t.defaultImageSelection,n)}}const cr=f.z.object({id:jo,name:f.z.string().trim().min(1).max(120),kind:f.z.enum(["tty","gui","web"]),source:f.z.enum(["builtin","custom"]),availability:f.z.enum(["available","missing-dependency"]),capabilities:f.z.object({automation:f.z.enum(["cdp"]).optional(),supportsCwdSelection:f.z.boolean().default(!1)}).strict().default({supportsCwdSelection:!1}),diagnosticCode:f.z.enum(["APP_EXECUTABLE_NOT_FOUND"]).optional()}).strict(),dr=f.z.object({code:f.z.enum(["APP_CATALOG_INVALID"]),message:f.z.string().trim().min(1).max(500)}).strict(),lr=f.z.object({items:f.z.array(cr).max(256),observedAt:Po,issues:f.z.array(dr).max(32).default([])}).strict(),pr=f.z.object({id:jo,name:f.z.string().trim().min(1).max(160),sourceInstanceId:jo,nodeId:jo,imageId:Wo.optional(),internalTag:f.z.string().trim().min(1).max(512).optional(),platform:Jo.optional(),architecture:Qo.optional(),sizeBytes:f.z.number().int().nonnegative().optional(),status:Xo,error:Zo.optional(),createdAt:Po,updatedAt:Po}).strict().superRefine((e,t)=>{if("ready"===e.status)for(const n of["imageId","internalTag","platform","architecture","sizeBytes"])void 0===e[n]&&t.addIssue({code:"custom",path:[n],message:`Ready environment template requires ${n}.`});"failed"!==e.status||e.error||t.addIssue({code:"custom",path:["error"],message:"Failed environment template requires an error diagnostic."})}),ur=f.z.enum(["apt","dnf","brew","npm"]),mr=f.z.enum(["user","passwordless-sudo","root"]),hr=f.z.object({platform:Jo,arch:Qo,installers:f.z.array(ur).max(8),privilege:mr,installerAccess:f.z.object({npmGlobalWritable:f.z.boolean().optional()}).strict().optional()}).strict(),gr=f.z.enum(["installed","not-installed","broken","unsupported"]),fr=f.z.enum(["recipe","bundled","external","none"]),yr=f.z.object({code:f.z.enum(["BUNDLED","EXTERNALLY_MANAGED","ALREADY_INSTALLED","NOT_INSTALLED","UNSUPPORTED_PLATFORM","INSTALLER_UNAVAILABLE","INSTALLER_NOT_WRITABLE","INSUFFICIENT_PRIVILEGE","OPERATION_IN_PROGRESS"]),message:f.z.string().trim().min(1).max(500)}).strict(),br=f.z.object({id:jo,name:f.z.string().trim().min(1).max(120),kind:f.z.enum(["tty","gui","web"]),description:f.z.string().trim().max(500).optional(),state:gr,managementSource:fr,version:f.z.string().trim().max(120).optional(),canInstall:f.z.boolean(),canUninstall:f.z.boolean(),installReason:yr.optional(),uninstallReason:yr.optional(),activeJobId:jo.optional()}).strict(),vr=f.z.enum(["install","uninstall"]),Ir=f.z.enum(["queued","running","succeeded","failed","cancelled","interrupted"]),xr=f.z.object({current:f.z.number().finite().nonnegative().optional(),total:f.z.number().finite().positive().optional(),unit:f.z.string().trim().min(1).max(40).optional()}).strict().refine(e=>void 0===e.total||void 0===e.current||e.current<=e.total,{message:"Progress current must not exceed total.",path:["current"]}),wr=f.z.object({executable:f.z.string().trim().min(1).max(4096),args:f.z.array(f.z.string().max(4096)).max(128)}).strict(),Sr=f.z.object({code:f.z.string().trim().min(1).max(120).regex(/^[a-z0-9][a-z0-9._-]*$/),message:f.z.string().trim().min(1).max(4096),retryable:f.z.boolean(),sessionIds:f.z.array(jo).max(64).optional()}).strict(),Ar=f.z.object({id:jo,requestId:jo.optional(),appId:jo,operation:vr,state:Ir,phase:f.z.string().trim().min(1).max(120).optional(),progress:xr.optional(),command:wr.optional(),logTail:f.z.string().max(32768).optional(),logTruncated:f.z.boolean().optional(),error:Sr.optional(),requestedAt:Po,startedAt:Po.optional(),finishedAt:Po.optional(),updatedAt:Po}).strict(),Er=f.z.object({streamId:jo,sequence:f.z.number().int().nonnegative(),capabilities:hr,apps:f.z.array(br).max(256),activeJobs:f.z.array(Ar).max(256),recentJobs:f.z.array(Ar).max(256),observedAt:Po}).strict(),_r=f.z.object({requestId:jo.optional()}).strict(),Tr=f.z.object({job:Ar}).strict();f.z.object({type:f.z.literal("app-management"),streamId:jo,sequence:f.z.number().int().nonnegative(),observedAt:Po,job:Ar.optional(),snapshot:Er.optional()}).strict().refine(e=>void 0!==e.job||void 0!==e.snapshot,{message:"An app management event requires a job or snapshot."});const zr=f.z.object({component:f.z.enum(["control-plane","node-agent","controlled-instance"]),packageName:f.z.string().trim().max(160).optional(),packageVersion:f.z.string().trim().max(80).optional(),protocolVersion:Ao.optional(),buildId:f.z.string().trim().max(160).optional(),builtAt:f.z.string().trim().max(120).optional(),gitCommit:f.z.string().trim().max(120).optional(),imageRef:f.z.string().trim().max(512).optional(),imageDigest:f.z.string().trim().max(240).optional()}).strict(),kr=f.z.object({data:f.z.object({ok:f.z.literal(!0),role:f.z.literal("control-plane"),protocolVersion:Ao,build:zr.extend({component:f.z.literal("control-plane"),packageVersion:f.z.string().trim().min(1).max(80)}).loose(),serverTime:Po}).loose()}).loose(),Nr=f.z.enum(["stable","beta","alpha"]),Cr=f.z.object({packageName:f.z.literal("@task-handoff/controlled-instance"),version:f.z.string().trim().min(1).max(80),platform:f.z.string().trim().min(1).max(40),arch:f.z.string().trim().min(1).max(40),formatVersion:f.z.number().int().positive(),launcherAbi:f.z.number().int().positive(),entrypoint:f.z.string().trim().min(1).max(512),sha256:f.z.string().regex(/^[a-f0-9]{64}$/)}).strict(),Rr=f.z.object({code:f.z.enum(["INSTANCE_RUNTIME_VERSION_MISMATCH","INSTANCE_RUNTIME_ARTIFACT_UNAVAILABLE","INSTANCE_RUNTIME_ARTIFACT_INVALID","INSTANCE_RUNTIME_INSTALL_FAILED","INSTANCE_RUNTIME_RESTART_FAILED","INSTANCE_RUNTIME_VERIFICATION_FAILED","INSTANCE_BASE_RUNTIME_INCOMPATIBLE","NODE_UPDATE_PREFLIGHT_FAILED","NODE_UPDATE_FAILED","LEGACY_INSTANCE_UPDATE_RETIRED"]),message:f.z.string().trim().min(1).max(4096),expectedVersion:f.z.string().trim().min(1).max(80).optional(),actualVersion:f.z.string().trim().min(1).max(80).optional(),retryable:f.z.boolean().default(!1)}).strict(),Or=f.z.object({desiredVersion:f.z.string().trim().min(1).max(80),actualVersion:f.z.string().trim().min(1).max(80).optional(),phase:f.z.enum(["pending","draining","installing","restarting","verifying","matched","failed"]),attempt:f.z.number().int().nonnegative().default(0),lastAttemptAt:Po.optional(),matchedAt:Po.optional(),error:Rr.optional()}).strict(),jr=f.z.object({runningInstanceCount:f.z.number().int().nonnegative(),stoppedInstanceCount:f.z.number().int().nonnegative(),activeInstanceCount:f.z.number().int().nonnegative(),restartInstanceCount:f.z.number().int().nonnegative(),runningInstanceIds:f.z.array(jo).max(1024).default([]),stoppedInstanceIds:f.z.array(jo).max(1024).default([]),activeInstanceIds:f.z.array(jo).max(1024).default([])}).strict(),Pr=f.z.object({phase:f.z.enum(["queued","updating-node","restarting-node","converging-instances","succeeded","degraded","failed"]),desiredVersion:f.z.string().trim().min(1).max(80),nodeVersion:f.z.string().trim().min(1).max(80).optional(),expectedInstanceIds:f.z.array(jo).max(1024).default([]),expectedInstanceCount:f.z.number().int().nonnegative(),matchedInstanceCount:f.z.number().int().nonnegative(),pendingInstanceCount:f.z.number().int().nonnegative(),failedInstanceCount:f.z.number().int().nonnegative(),deferredInstanceCount:f.z.number().int().nonnegative().default(0)}).strict(),Dr=f.z.object({channel:Nr.default("stable")}).strict(),Lr=f.z.object({source:f.z.literal("npm"),channel:Nr,currentVersion:f.z.string().trim().max(240).optional(),availableVersion:f.z.string().trim().min(1).max(240),artifactRef:f.z.string().trim().min(1).max(512).optional(),runtimeArtifacts:f.z.array(Cr).default([]),impact:jr,updateAvailable:f.z.boolean(),supported:f.z.boolean().default(!0),reason:f.z.string().trim().max(2048).optional(),checkedAt:Po,preflightToken:f.z.string().trim().min(16).max(240).optional()}).strict(),Mr=f.z.object({id:jo,nodeId:jo,source:f.z.literal("npm"),channel:Nr,fromVersion:f.z.string().trim().max(240).optional(),toVersion:f.z.string().trim().min(1).max(240),artifactRef:f.z.string().trim().min(1).max(512).optional(),runtimeArtifacts:f.z.array(Cr).default([]),impact:jr,rollout:Pr,status:f.z.enum(["queued","updating-node","restarting-node","converging-instances","succeeded","degraded","failed"]),error:Rr.optional(),startedAt:Po.optional(),completedAt:Po.optional(),createdAt:Po,updatedAt:Po}).strict(),qr=f.z.object({channel:Nr,targetVersion:f.z.string().trim().min(1).max(240),preflightToken:f.z.string().trim().min(16).max(240)}).strict(),Ur=f.z.object({type:f.z.enum(["branch","tag"]),name:f.z.string().trim().min(1).max(240)}).strict(),$r=f.z.object({type:f.z.literal("commit"),commit:f.z.string().trim().regex(/^[0-9a-fA-F]{4,64}$/,"commit must be a hexadecimal Git object id")}).strict(),Br=f.z.discriminatedUnion("type",[Ur,$r]),Fr=f.z.object({type:f.z.enum(["none","ssh-key","https-token"]).default("none"),secretId:f.z.string().trim().min(1).max(120).optional()}).strict(),Hr=f.z.object({depth:f.z.number().int().positive().max(1e5).optional(),submodules:f.z.boolean().default(!1),lfs:f.z.boolean().default(!1),subdirectory:f.z.string().trim().max(240).refine(e=>!e.startsWith("/")&&!e.split("/").some(e=>".."===e),"subdirectory must be a relative path within the repository").transform(e=>e.split("/").filter(e=>e&&"."!==e).join("/")).default("")}).strict();f.z.object({id:jo,name:f.z.string().trim().min(1).max(160),url:f.z.string().trim().min(1).max(2048),provider:f.z.string().trim().max(80).optional(),ref:Br.default({type:"branch",name:"main"}),auth:Fr.default({type:"none"}),clone:Hr.default({submodules:!1,lfs:!1,subdirectory:""}),defaultImageSelection:Ko.optional(),labels:Do,createdAt:Po,updatedAt:Po}).strict();const Gr=f.z.object({id:jo,nodeId:jo,name:f.z.string().trim().min(1).max(160),path:f.z.string().trim().min(1).max(4096),defaultImageSelection:Ko.optional(),labels:Do,createdAt:Po,updatedAt:Po}).strict(),Wr=f.z.discriminatedUnion("type",[f.z.object({type:f.z.literal("git-repository"),repositoryId:jo.optional(),url:f.z.string().trim().min(1).max(2048),provider:f.z.string().trim().max(80).optional(),ref:Br.default({type:"branch",name:"main"}),auth:Fr.default({type:"none"}),clone:Hr.default({submodules:!1,lfs:!1,subdirectory:""})}).strict(),f.z.object({type:f.z.literal("git-template"),url:f.z.string().trim().min(1).max(2048),templateId:f.z.string().trim().min(1).max(120).optional(),ref:Br.default({type:"branch",name:"main"}),auth:Fr.default({type:"none"}),clone:Hr.default({submodules:!1,lfs:!1,subdirectory:""})}).strict(),f.z.object({type:f.z.literal("local-folder"),localFolderId:jo.optional(),path:f.z.string().trim().min(1).max(4096),ownerNodeId:jo.optional()}).strict()]);function Vr(e){const t=Wr.parse(e);return"local-folder"===t.type?t:Wr.parse({...t,auth:{type:"none"}})}const Kr=f.z.object({mode:f.z.enum(["local-bind","git-clone","empty-volume","persistent-volume"]),path:f.z.string().trim().min(1).max(4096).default("/workspace"),volumeName:f.z.string().trim().max(240).optional(),readOnly:f.z.boolean().default(!1)}).strict(),Yr=f.z.enum(["codex","claude","opencode"]),Xr=f.z.object({id:jo,name:f.z.string().trim().min(1).max(160),source:Wr,defaultImageSelection:Ko.optional(),defaultNodeId:jo.optional(),workspacePolicy:Kr,labels:Do,createdAt:Po,updatedAt:Po}).strict(),Jr=f.z.object({id:jo,name:f.z.string().trim().min(1).max(160),endpoint:f.z.string().trim().min(1).max(2048),key:f.z.string().trim().min(1).max(4096),model:f.z.string().trim().min(1).max(240),app:Yr,enabled:f.z.boolean().default(!0),order:f.z.number().int().min(0).max(1e6).default(0),labels:Do,createdAt:Po,updatedAt:Po}).strict(),Qr=Jr.omit({key:!0}).extend({keyPreview:f.z.string().trim().min(1).max(160),keySet:f.z.boolean()}).strict(),Zr=Qr.extend({referenceCount:f.z.number().int().min(0)}).strict(),ec=f.z.object({instanceId:jo,codexModelHash:jo.optional(),claudeModelHash:jo.optional(),opencodeModelHash:jo.optional(),updatedAt:Po}).strict(),tc=f.z.discriminatedUnion("type",[f.z.object({type:f.z.literal("control-plane"),name:Jr.shape.name,enabled:Jr.shape.enabled,order:Jr.shape.order}).strict(),f.z.object({type:f.z.literal("node"),nodeId:jo,name:Jr.shape.name,enabled:Jr.shape.enabled,order:Jr.shape.order,referenceCount:f.z.number().int().min(0)}).strict()]),nc=f.z.object({id:jo,model:Qr,locations:f.z.array(tc).min(1),referenceCount:f.z.number().int().min(0).default(0)}).strict(),ic=f.z.object({nodeId:jo,code:f.z.string().trim().min(1).max(120),message:f.z.string().trim().min(1).max(2e3)}).strict(),sc=f.z.object({models:f.z.array(nc),nodeDiagnostics:f.z.array(ic).default([]),updatedAt:Po}).strict();function ac(e){const t={app:Yr.parse(e.app),endpoint:Jr.shape.endpoint.parse(e.endpoint),key:Jr.shape.key.parse(e.key),model:Jr.shape.model.parse(e.model)};return`mdl_${i.createHash("sha256").update(JSON.stringify(t)).digest("hex")}`}Jr.omit({id:!0,createdAt:!0,updatedAt:!0}).strict().partial().strict(),f.z.object({modelSelection:Vo,codexModelHash:jo.optional(),claudeModelHash:jo.optional(),opencodeModelHash:jo.optional()}).strict();const oc=f.z.enum(["market","custom"]),rc=f.z.enum(["active","deprecated","yanked"]),cc=f.z.discriminatedUnion("kind",[f.z.object({kind:f.z.literal("builtin"),key:f.z.string().trim().min(1).max(120)}).strict(),f.z.object({kind:f.z.literal("remote"),url:f.z.string().trim().url().max(2048),mediaType:f.z.enum(["image/png","image/jpeg","image/webp"]).optional(),digest:Wo.optional()}).strict()]),dc={kind:"builtin",key:"default-image-cover"},lc=f.z.array(f.z.string().trim().min(1).max(80)).default([]),pc=f.z.array(f.z.string().trim().min(1).max(120)).default([]),uc=f.z.record(f.z.string().trim().min(2).max(35),f.z.string().trim().min(1).max(4096)),mc=f.z.object({os:f.z.string().trim().min(1).max(40),architecture:f.z.string().trim().min(1).max(40),digest:Wo.optional(),downloadSizeBytes:f.z.number().int().positive().optional(),unpackedSizeBytes:f.z.number().int().positive().optional()}).strict(),hc=f.z.object({name:f.z.string().trim().min(1).max(128).regex(qo),version:f.z.string().trim().min(1).max(160).optional(),reference:Go,manifestDigest:Wo.optional(),publishedAt:Po.optional(),platforms:f.z.array(mc).default([]),status:rc.default("active")}).strict(),gc=f.z.object({id:jo,publisher:f.z.string().trim().min(1).max(160),slug:f.z.string().trim().min(1).max(160),name:f.z.string().trim().min(1).max(160),description:f.z.string().trim().min(1).max(4096),localizedDescriptions:uc.optional(),cover:cc.optional(),repository:f.z.string().trim().min(1).max(512),defaultTag:f.z.string().trim().min(1).max(128).regex(qo),tags:f.z.array(hc).min(1),capabilities:lc,optionalApps:pc,defaultEnv:Lo,labels:Do,status:rc.default("active")}).strict().superRefine((e,t)=>{e.tags.some(t=>t.name===e.defaultTag)||t.addIssue({code:"custom",path:["defaultTag"],message:"Market defaultTag must identify one of the image tags."})}),fc=f.z.object({protocolVersion:Ao,catalogId:jo,revision:f.z.string().trim().min(1).max(240),source:f.z.enum(["embedded","remote","cache"]),generatedAt:Po,expiresAt:Po.optional(),items:f.z.array(gc)}).strict(),yc=f.z.object({source:f.z.enum(["embedded","remote","cache"]),state:f.z.enum(["ready","refreshing","stale","failed"]),revision:f.z.string().trim().min(1).max(240),updatedAt:Po,error:f.z.string().trim().max(4096).optional()}).strict(),bc=f.z.object({id:jo,origin:f.z.literal("custom"),name:f.z.string().trim().min(1).max(160),description:f.z.string().trim().max(4096).optional(),localizedDescriptions:uc.optional(),cover:cc.optional(),reference:Go,repository:f.z.string().trim().min(1).max(512),tag:f.z.string().trim().min(1).max(128).regex(qo).optional(),pullPolicy:f.z.literal("if-not-present").default("if-not-present"),capabilities:lc,optionalApps:pc,defaultEnv:Lo,labels:Do,createdAt:Po,updatedAt:Po}).strict(),vc=f.z.object({name:f.z.string().trim().min(1).max(128).regex(qo),version:f.z.string().trim().min(1).max(160).optional(),reference:Go,manifestDigest:Wo.optional(),status:rc}).strict(),Ic=f.z.object({id:jo,origin:oc,name:f.z.string().trim().min(1).max(160),description:f.z.string().trim().max(4096).optional(),localizedDescriptions:uc.optional(),cover:cc,repository:f.z.string().trim().min(1).max(512),tag:f.z.string().trim().min(1).max(128).regex(qo).optional(),availableTags:f.z.array(vc),reference:Go,digest:Wo.optional(),downloadSizeBytes:f.z.number().int().positive().optional(),unpackedSizeBytes:f.z.number().int().positive().optional(),capabilities:lc,optionalApps:pc,defaultEnv:Lo,labels:Do,readOnly:f.z.boolean(),lifecycleStatus:rc.optional(),market:f.z.object({catalogId:jo,catalogRevision:f.z.string().trim().min(1).max(240),publisher:f.z.string().trim().min(1).max(160),version:f.z.string().trim().min(1).max(160).optional()}).strict().optional()}).strict(),xc=f.z.object({id:jo,origin:oc,name:f.z.string().trim().min(1).max(160),description:f.z.string().trim().max(4096).optional(),localizedDescriptions:uc.optional(),cover:cc.optional(),repository:f.z.string().trim().min(1).max(512),tag:f.z.string().trim().min(1).max(128).regex(qo).optional(),requestedReference:Go,resolvedDigest:Wo.optional(),resolvedReference:Go.optional(),downloadSizeBytes:f.z.number().int().positive().optional(),pullPolicy:f.z.literal("if-not-present").default("if-not-present"),capabilities:lc,optionalApps:pc,defaultEnv:Lo,labels:Do,market:f.z.object({catalogId:jo,catalogRevision:f.z.string().trim().min(1).max(240),publisher:f.z.string().trim().min(1).max(160),version:f.z.string().trim().min(1).max(160).optional()}).strict().optional(),createdAt:Po,updatedAt:Po}).strict(),wc=f.z.object({phase:f.z.enum(["checking-image","pulling-image","resolving-image","ready","failed"]),requestedReference:Go,generation:f.z.number().int().nonnegative().default(0),error:f.z.string().trim().max(4096).optional(),startedAt:Po,updatedAt:Po}).strict(),Sc="image.pull.terminal.output",Ac="image.pull.terminal.finished",Ec=f.z.object({instanceId:jo,generation:f.z.number().int().nonnegative(),requestedReference:Go,sequence:f.z.number().int().nonnegative(),observedAt:Po}).strict(),_c=Ec.extend({data:f.z.string().min(1).max(65536),replay:f.z.boolean().optional()}).strict(),Tc=Ec.extend({outcome:f.z.enum(["succeeded","failed"])}).strict(),zc=Ec.extend({status:f.z.enum(["connecting","pulling","extracting","complete","failed"]),layers:f.z.object({total:f.z.number().int().nonnegative(),completed:f.z.number().int().nonnegative(),downloaded:f.z.number().int().nonnegative(),downloading:f.z.number().int().nonnegative(),extracting:f.z.number().int().nonnegative()}).strict(),bytes:f.z.object({current:f.z.number().finite().nonnegative(),total:f.z.number().finite().positive()}).strict().optional(),percent:f.z.number().finite().min(0).max(100).optional(),message:f.z.string().trim().min(1).max(500),terminalTail:f.z.string().max(262144).optional(),terminalTruncated:f.z.boolean().optional()}).strict();function kc(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e,i=new Set(["id","origin","name","description","localizedDescriptions","cover","reference","repository","tag","image","registry","pullPolicy","capabilities","optionalApps","defaultEnv","labels","createdAt","updatedAt"]);for(const e of Object.keys(n))i.has(e)||t?.({imageId:"string"==typeof n.id?n.id:void 0,field:e});const s="string"==typeof n.id?n.id:void 0,a="string"==typeof n.image?n.image:void 0;void 0!==a&&t?.({imageId:s,field:"image"}),Object.prototype.hasOwnProperty.call(n,"registry")&&t?.({imageId:s,field:"registry"});let o,r="string"==typeof n.reference?n.reference:a;if(r)try{r=Fo(r)}catch{if(!r.includes("@")&&r.lastIndexOf(":")<=r.lastIndexOf("/"))try{r=Fo(`${r}:latest`),t?.({imageId:s,field:"reference:implicit-latest"})}catch{}}try{o=r?Ho(r):void 0}catch{}return{id:n.id,origin:"custom",name:n.name,description:n.description,localizedDescriptions:n.localizedDescriptions,cover:bd(n.cover,["kind","key","url","mediaType","digest"]),reference:o?.reference??r,repository:o?.repository??n.repository,tag:o?.tag??n.tag,pullPolicy:n.pullPolicy??"if-not-present",capabilities:n.capabilities,optionalApps:n.optionalApps,defaultEnv:n.defaultEnv,labels:n.labels,createdAt:n.createdAt,updatedAt:n.updatedAt}}const Nc=f.z.discriminatedUnion("kind",[f.z.object({kind:f.z.literal("direct")}).strict(),f.z.object({kind:f.z.literal("control-plane-proxy"),proxyId:jo,proxyBindingId:jo,targetNodeId:jo}).strict()]),Cc=f.z.object({pingRttMs:f.z.number().nonnegative().optional(),pingRttP95Ms:f.z.number().nonnegative().optional(),consecutiveReconnects:f.z.number().int().nonnegative(),nextRetryAt:Po.optional()}).strict();f.z.object({nodeId:jo,inviteId:jo.optional()}).strict();const Rc=f.z.discriminatedUnion("status",[f.z.object({id:jo,status:f.z.literal("pending")}).strict(),f.z.object({id:jo,status:f.z.literal("completed"),nodeId:jo}).strict()]),Oc=f.z.object({reachability:f.z.enum(["unknown","reachable","unreachable"]),bindingStatus:f.z.enum(["unknown","active","revoked"]),bindingRevision:f.z.number().int().positive().optional(),streamId:f.z.string().trim().min(1).max(160).optional(),revision:f.z.number().int().nonnegative().optional(),observedAt:Po.optional(),target:lo.optional(),lastError:eo.optional(),updatedAt:Po}).strict(),jc=f.z.object({id:jo,name:f.z.string().trim().min(1).max(160),connectionMode:f.z.enum(["local-ipc","local-loopback","direct-http","reverse-wss","control-plane-proxy"]).default("direct-http"),connectionPath:Nc.default({kind:"direct"}),connectionEnabled:f.z.boolean().default(!0),auth:f.z.object({mode:f.z.enum(["local-static-key","paired-hmac","proxy-binding"]).default("local-static-key"),keyId:jo.optional(),secret:f.z.string().trim().max(4096).optional(),pairedAt:Po.optional(),pairing:f.z.object({status:f.z.enum(["pending","paired","expired"]).default("pending"),joinToken:f.z.string().trim().max(4096).optional(),expiresAt:Po.optional()}).strict().optional()}).strict().default({mode:"local-static-key"}),endpoint:f.z.string().trim().max(2048).optional(),controlEndpoint:f.z.string().trim().max(2048).optional(),containerEndpoint:f.z.string().trim().max(2048).optional(),publicWebBase:f.z.string().trim().max(2048).optional(),status:f.z.enum(["unknown","online","offline","degraded"]).default("unknown"),health:f.z.enum(["unknown","ok","degraded","failed"]).default("unknown"),capabilities:f.z.record(f.z.string(),f.z.unknown()).default({}),proxyState:Oc.optional(),appInventory:lr.optional(),labels:Do,lastSeenAt:Po.optional(),createdAt:Po,updatedAt:Po}).strict().superRefine((e,t)=>{"control-plane-proxy"===e.connectionPath.kind&&"control-plane-proxy"!==e.connectionMode&&t.addIssue({code:"custom",path:["connectionPath"],message:"Control-plane proxy paths require control-plane-proxy connection mode."}),"control-plane-proxy"===e.connectionMode&&"control-plane-proxy"!==e.connectionPath.kind&&t.addIssue({code:"custom",path:["connectionPath"],message:"Control-plane proxy nodes require a control-plane-proxy connection path."})}),Pc=f.z.object({nodeId:jo,status:f.z.enum(["unknown","online","offline","degraded"]),health:f.z.enum(["unknown","ok","degraded","failed"]),lastSeenAt:Po.nullable(),connectionPhase:f.z.enum(["connecting","handshaking","healthy","reconnecting","suspect","offline"]).nullable(),connectionDiagnostics:Cc.nullable(),proxyState:Oc.nullable()}).strict(),Dc=f.z.object({id:jo,nodeId:jo,name:f.z.string().trim().min(1).max(160),type:f.z.enum(["docker","kubernetes","local"]),status:f.z.enum(["unknown","online","offline","degraded"]).default("unknown"),accessStrategy:f.z.enum(["node-proxy","direct-port","kubernetes-ingress","kubernetes-port-forward"]).default("node-proxy"),capabilities:f.z.record(f.z.string(),f.z.unknown()).default({}),labels:Do,createdAt:Po,updatedAt:Po}).strict(),Lc=f.z.object({instanceId:jo,runtimeKind:f.z.literal("docker"),state:f.z.enum(["pending","available","stopped","unavailable"]),sampledAt:Po,cpu:f.z.object({usagePercent:f.z.number().nonnegative()}).strict().optional(),memory:f.z.object({usageBytes:f.z.number().nonnegative(),limitBytes:f.z.number().nonnegative().optional(),usagePercent:f.z.number().nonnegative().optional()}).strict().optional(),network:f.z.object({rxBytes:f.z.number().nonnegative(),txBytes:f.z.number().nonnegative()}).strict().optional(),blockIo:f.z.object({readBytes:f.z.number().nonnegative(),writeBytes:f.z.number().nonnegative()}).strict().optional(),pids:f.z.number().int().nonnegative().optional(),error:f.z.string().trim().max(2048).optional()}).strict(),Mc=f.z.object({registry:f.z.boolean().default(!1),runtimeBroker:f.z.boolean().default(!1),workspaceProvisioning:f.z.object({docker:f.z.boolean().default(!1),kubernetes:f.z.boolean().default(!1),local:f.z.boolean().default(!1)}).strip().default({docker:!1,kubernetes:!1,local:!1})}).strip(),qc=f.z.object({modelEndpointProbe:f.z.boolean().optional(),aiSessionHistoryLimit:f.z.boolean().optional(),aiSessionAttachmentRetention:f.z.boolean().optional(),aiSessionFileAttachmentLimit:f.z.boolean().optional(),folderPlaces:f.z.boolean().optional(),localFolderNameUpdate:f.z.boolean().optional(),managedGitCredentials:Mc.optional()}).strip();function Uc(e){const t=qc.safeParse(e),n=t.success?t.data:{};return{...n,managedGitCredentials:Mc.parse(n.managedGitCredentials||{})}}function $c(e){return Uc(e).managedGitCredentials.registry}function Bc(e){return Uc(e).managedGitCredentials.runtimeBroker}function Fc(e){return!0===qc.safeParse(e).data?.aiSessionFileAttachmentLimit}const Hc=f.z.object({status:f.z.enum(["healthy","congested","recovering"]),activeOutputs:f.z.number().int().nonnegative(),bufferedBytes:f.z.number().int().nonnegative(),peakBufferedBytes:f.z.number().int().nonnegative(),coalescedEvents:f.z.number().int().nonnegative(),oversizedEvents:f.z.number().int().nonnegative().optional(),peakEventBytes:f.z.number().int().nonnegative().optional(),congestedSince:Po.optional(),lastCongestedAt:Po.optional()}).strip(),Gc=f.z.object({ok:f.z.boolean().optional(),role:f.z.string().optional(),nodeId:jo.optional(),platform:Jo.optional(),arch:Qo.optional(),protocolVersion:Ao.optional(),capabilities:qc.optional(),build:zr.strip().optional(),process:f.z.object({pid:f.z.number().int().positive(),startIdentity:f.z.string().trim().min(1).optional()}).strip().optional(),listener:f.z.object({host:f.z.string().trim().min(1),port:f.z.number().int().min(1).max(65535)}).strip().optional(),instanceProxy:f.z.object({requests:f.z.number().int().nonnegative(),active:f.z.number().int().nonnegative(),completed:f.z.number().int().nonnegative(),aborted:f.z.number().int().nonnegative(),limitRejected:f.z.number().int().nonnegative(),responseBytes:f.z.number().nonnegative(),totalDurationMs:f.z.number().nonnegative(),maxResponseBytes:f.z.number().int().nonnegative()}).partial().strip().optional(),eventTransport:Hc.optional(),serverTime:Po.optional()}).strip(),Wc=f.z.object({bindScope:f.z.enum(["loopback","all-ipv4"]),port:f.z.number().int().min(1).max(65535)}).strict().extend({host:f.z.enum(["127.0.0.1","0.0.0.0"]),status:f.z.enum(["listening","error"]),source:f.z.enum(["bootstrap","persisted"]),error:f.z.string().trim().max(2048).optional()}).strict(),Vc=f.z.object({nodeId:jo,joinToken:f.z.string().trim().min(1),expiresAt:Po}).passthrough(),Kc=f.z.object({nodeId:jo,keyId:jo,secret:f.z.string().regex(/^[A-Za-z0-9_-]{32,128}$/),pairedAt:Po}).strict(),Yc=f.z.object({id:jo,keyId:jo,name:f.z.string().trim().min(1).max(160).optional(),pairedAt:Po,updatedAt:Po,current:f.z.boolean()}).passthrough(),Xc=f.z.object({keyId:jo,revoked:f.z.literal(!0),revokedAt:Po}).strict(),Jc=f.z.object({id:jo,pairingKeyId:jo,url:f.z.string().trim().min(1).max(2048),name:f.z.string().trim().min(1).max(160).optional(),enabled:f.z.boolean(),createdAt:Po,updatedAt:Po,status:f.z.enum(["disabled","connecting","connected","reconnecting","failed"]),pingRttMs:f.z.number().nonnegative().optional(),pingRttP95Ms:f.z.number().nonnegative().optional(),consecutiveReconnects:f.z.number().int().nonnegative().optional(),nextRetryAt:Po.optional(),lastConnectedAt:Po.optional(),lastDisconnectedAt:Po.optional(),error:f.z.string().optional()}).passthrough(),Qc=f.z.object({pairing:Yc,connection:f.z.object({id:jo,pairingKeyId:jo,url:f.z.string().trim().min(1).max(2048),name:f.z.string().trim().min(1).max(160).optional(),enabled:f.z.boolean(),createdAt:Po,updatedAt:Po}).passthrough(),tunnel:f.z.object({status:f.z.enum(["disabled","saved","connecting","connected","failed"]),error:f.z.string().trim().max(2048).optional()}).passthrough()}).passthrough(),Zc=f.z.object({deleted:f.z.boolean().optional()}).passthrough(),ed=f.z.object({repository:f.z.string().trim().optional(),tag:f.z.string().trim().optional(),id:f.z.string().trim(),createdSince:f.z.string().trim().optional(),size:f.z.string().trim().optional(),sizeBytes:f.z.number().int().nonnegative().optional(),reference:f.z.string().trim().min(1),repoDigests:f.z.array(f.z.string().trim().min(1).max(512)).default([])}).passthrough(),td=f.z.object({image:Ic,status:f.z.enum(["available","pull-required","unknown"]),localImage:ed.optional(),localSizeBytes:f.z.number().int().nonnegative().optional(),downloadSizeBytes:f.z.number().int().positive().optional(),unpackedSizeBytes:f.z.number().int().positive().optional(),error:f.z.string().trim().max(2048).optional()}).strict(),nd=f.z.lazy(()=>f.z.object({name:f.z.string().trim().min(1),path:f.z.string().trim().min(1).max(4096),children:f.z.array(nd)}).passthrough()),id=f.z.object({kind:f.z.enum(["home","root"]),name:f.z.string().trim().min(1),path:f.z.string().trim().min(1).max(4096)}).passthrough(),sd=f.z.object({status:f.z.number().int().min(100).max(599).optional(),headers:f.z.record(f.z.string(),f.z.string()).optional(),bodyBase64:f.z.string().optional()}).passthrough(),ad=f.z.object({strategy:f.z.enum(["node-proxy","direct-port","kubernetes-ingress","kubernetes-port-forward"]).default("node-proxy"),web:f.z.string().trim().max(2048).optional(),api:f.z.string().trim().max(2048).optional(),vnc:f.z.string().trim().max(2048).optional(),tty:f.z.string().trim().max(2048).optional(),logs:f.z.string().trim().max(2048).optional(),status:f.z.enum(["unknown","reachable","endpoint-unreachable"]).default("unknown")}).strict(),od=f.z.object({...ad.shape}).strict(),rd=f.z.object({strategy:f.z.enum(["control-plane-proxy","direct-port","node-proxy","kubernetes-ingress","kubernetes-port-forward"]).default("control-plane-proxy"),web:f.z.string().trim().max(2048).optional(),api:f.z.string().trim().max(2048).optional(),ws:f.z.string().trim().max(2048).optional(),status:f.z.enum(["unknown","reachable","endpoint-unreachable"]).default("unknown")}).strict().default({strategy:"control-plane-proxy",status:"unknown"}),cd=f.z.object({mode:f.z.enum(["local-bind","git-clone","empty-volume","persistent-volume"]).optional(),status:f.z.enum(["unknown","pending","ready","failed"]).default("unknown"),path:f.z.string().trim().max(4096).optional(),resolvedCommit:f.z.string().trim().max(120).optional(),error:f.z.string().trim().max(2048).optional()}).passthrough(),dd=f.z.object({id:jo,name:f.z.string().trim().min(1).max(160),projectId:jo.optional(),source:Wr,sourceSnapshot:f.z.record(f.z.string(),f.z.unknown()).default({}),modelSelection:Vo,nodeId:jo,runtimeId:jo,imageSelection:Ko.optional(),environmentSource:Yo.optional(),environmentTemplateOrigin:er.optional(),imageSnapshot:xc.optional(),imageProvisioning:wc.optional(),stateRevision:f.z.number().int().min(0).default(0),processIncarnationId:f.z.string().trim().min(1).max(120).optional(),status:f.z.enum(["created","provisioning","starting","registering","registered","running","stopping","stopped","deleting","failed","unhealthy"]).default("created"),health:f.z.enum(["unknown","ok","degraded","failed"]).default("unknown"),connectionStatus:f.z.enum(["unknown","online","offline","endpoint-unreachable"]).default("unknown"),agentStatus:f.z.enum(["unknown","online","offline"]).default("unknown"),targetStatus:f.z.enum(["unknown","reachable","endpoint-unreachable"]).default("unknown"),uiAccessStatus:f.z.enum(["unknown","reachable","endpoint-unreachable"]).default("unknown"),controlMode:f.z.enum(["standalone","controlled"]).default("controlled"),protocolVersion:Ao.optional(),instanceVersion:f.z.string().trim().max(80).optional(),build:zr.optional(),runtimeVersion:Or.optional(),ready:f.z.boolean().default(!1),capabilities:No.default(_o),appInventory:lr.optional(),config:f.z.object({autoImportAgentConfigs:f.z.boolean().default(!0),defaultCodexPermissionMode:di.default("ask"),aiSessionHistoryLimit:f.z.number().int().min(1).max(es).default(50),aiSessionAttachmentRetentionDays:f.z.number().int().min(0).max(365).default(30),aiSessionMaxFileAttachmentBytes:f.z.number().int().positive().max(yn).default(fn)}).strict().default({autoImportAgentConfigs:!0,defaultCodexPermissionMode:"ask",aiSessionHistoryLimit:50,aiSessionAttachmentRetentionDays:30,aiSessionMaxFileAttachmentBytes:fn}),workspace:cd.default({status:"unknown"}),target:ad.default({strategy:"direct-port",status:"unknown"}),access:rd,apps:f.z.object({runningCount:f.z.number().int().min(0).default(0),problemCount:f.z.number().int().min(0).default(0),updatedAt:Po.optional(),revision:f.z.number().int().min(0).optional()}).strict().default({runningCount:0,problemCount:0}),aiSessions:rs.default(()=>({runningCount:0,waitingCount:0,staleCount:0,sessions:[],updatedAt:(new Date).toISOString()})),triggers:f.z.object({enabledCount:f.z.number().int().min(0).default(0),runningCount:f.z.number().int().min(0).default(0),errorCount:f.z.number().int().min(0).default(0),configs:f.z.array(f.z.object({configHash:f.z.string().trim().min(1),config:Ea,deployments:f.z.array(Ta).default([]),runtime:f.z.array(za).default([])}).strict()).default([]),recentRuns:f.z.array(ka).default([])}).strict().optional(),runtime:f.z.object({kind:f.z.string().trim().max(80).optional(),containerName:f.z.string().trim().max(240).optional(),containerId:f.z.string().trim().max(240).optional(),workspacePath:f.z.string().trim().max(4096).optional(),pid:f.z.number().int().positive().optional(),port:f.z.number().int().positive().max(65535).optional(),labels:f.z.record(f.z.string(),f.z.string()).default({})}).strict().default({labels:{}}),registrationToken:f.z.string().trim().min(1).max(240).optional(),lastHeartbeatAt:Po.optional(),createdAt:Po,updatedAt:Po}).strict(),ld=f.z.union([dd.transform(e=>({instance:e,gitWorkspaceProvisioningOperationId:void 0})),f.z.object({instance:dd,gitWorkspaceProvisioningOperationId:jo.optional()}).strict()]),pd=f.z.preprocess(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e;return t.instance&&"object"==typeof t.instance&&!Array.isArray(t.instance)?{instance:hd(t.instance),..."string"==typeof t.gitWorkspaceProvisioningOperationId?{gitWorkspaceProvisioningOperationId:t.gitWorkspaceProvisioningOperationId}:{}}:hd(t)},ld),ud="instance.lifecycle.snapshot",md=f.z.object({instanceId:dd.shape.id,revision:f.z.number().int().min(0),updatedAt:Po,status:dd.shape.status.unwrap(),health:dd.shape.health.unwrap(),connectionStatus:dd.shape.connectionStatus.unwrap(),accessStatus:f.z.enum(["reachable","endpoint-unreachable"]),imageProvisioning:wc.optional(),workspace:cd,runtime:dd.shape.runtime.unwrap(),runtimeVersion:Or.optional(),ready:f.z.boolean(),lastHeartbeatAt:Po.optional()}).strict();function hd(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e,i=new Set(Object.keys(dd.shape)),s={};for(const[e,t]of Object.entries(n))i.has(e)&&(s[e]=t);if(n.capabilities&&"object"==typeof n.capabilities&&!Array.isArray(n.capabilities)){const e={...n.capabilities};Object.prototype.hasOwnProperty.call(e,"apps")&&delete e.apps,s.capabilities=Co(e)}else s.capabilities=Co(void 0);s.appInventory=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e;Object.keys(t).some(e=>!["observedAt","items","issues"].includes(e));const n={observedAt:t.observedAt,items:Array.isArray(t.items)?t.items.map(e=>{e&&"object"==typeof e&&!Array.isArray(e)&&Object.keys(e).some(e=>!["id","name","kind","source","availability","capabilities","diagnosticCode"].includes(e));const t=bd(e,["id","name","kind","source","availability","diagnosticCode"]);return!t||"object"!=typeof t||Array.isArray(t)?t:{...t,capabilities:bd(e.capabilities,["automation","supportsCwdSelection"])}}):t.items,issues:Array.isArray(t.issues)?t.issues.map(e=>bd(e,["code","message"])):t.issues},i=lr.safeParse(n);return i.success?i.data:void 0}(n.appInventory,"string"==typeof n.id&&n.id),s.source=yd(n.source,0,"string"==typeof n.id&&n.id),s.sourceSnapshot=n.sourceSnapshot&&"object"==typeof n.sourceSnapshot&&!Array.isArray(n.sourceSnapshot)?n.sourceSnapshot:{},s.build=gd(zr,n.build,0,0,"string"==typeof n.id&&n.id),s.aiSessions=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e,n=Array.isArray(t.sessions)?t.sessions.flatMap((e,t)=>{const n=gd(os,e);return n?[n]:[]}):[],i={runningCount:"number"==typeof t.runningCount&&Number.isInteger(t.runningCount)&&t.runningCount>=0?t.runningCount:0,waitingCount:"number"==typeof t.waitingCount&&Number.isInteger(t.waitingCount)&&t.waitingCount>=0?t.waitingCount:0,staleCount:"number"==typeof t.staleCount&&Number.isInteger(t.staleCount)&&t.staleCount>=0?t.staleCount:0,sessions:n,updatedAt:Po.safeParse(t.updatedAt).success?t.updatedAt:(new Date).toISOString()};return Object.keys(t).some(e=>!["runningCount","waitingCount","staleCount","sessions","updatedAt"].includes(e)),rs.parse(i)}(n.aiSessions,"string"==typeof n.id&&n.id),s.triggers=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e;Object.keys(t).some(e=>!["enabledCount","runningCount","errorCount","configs","recentRuns"].includes(e));const n=(e,t,n)=>Array.isArray(e)?e.flatMap((e,n)=>{const i=gd(t,e);return i?[i]:[]}):[],i=Array.isArray(t.configs)?t.configs.flatMap((e,t)=>{if(!e||"object"!=typeof e||Array.isArray(e))return[];const i=e;Object.keys(i).some(e=>!["configHash","config","deployments","runtime"].includes(e));const s=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e,n=bd(t,["configHash","name","description","createdAt","updatedAt"]);if(t.source&&"object"==typeof t.source&&!Array.isArray(t.source)){const e=t.source,i="schedule"===e.type?"interval"===e.scheduleKind?["type","scheduleKind","intervalMs"]:"daily"===e.scheduleKind?["type","scheduleKind","timeOfDay","timezone"]:["type","scheduleKind","weekdays","timeOfDay","timezone"]:"file-change"===e.type?["type","roots","globs","ignore","debounceMs"]:["type","agent","statuses","phases"];n.source=bd(e,i)}return n.action=bd(t.action,["promptTemplate"]),n.policy=bd(t.policy,["cooldownMs","maxConcurrentRuns","whenBusy"]),gd(Ea,n)}(i.config);return"string"==typeof i.configHash&&s?[{configHash:i.configHash,config:s,deployments:n(i.deployments,Ta),runtime:n(i.runtime,za)}]:[]}):[];return{enabledCount:"number"==typeof t.enabledCount&&Number.isInteger(t.enabledCount)&&t.enabledCount>=0?t.enabledCount:0,runningCount:"number"==typeof t.runningCount&&Number.isInteger(t.runningCount)&&t.runningCount>=0?t.runningCount:0,errorCount:"number"==typeof t.errorCount&&Number.isInteger(t.errorCount)&&t.errorCount>=0?t.errorCount:0,configs:i,recentRuns:n(t.recentRuns,ka)}}(n.triggers,"string"==typeof n.id&&n.id),s.apps=gd(dd.shape.apps.unwrap(),bd(n.apps,["runningCount","problemCount","updatedAt","revision"]),0,0,"string"==typeof n.id&&n.id)||{runningCount:0,problemCount:0},s.config=gd(dd.shape.config.unwrap(),bd(n.config,["autoImportAgentConfigs","defaultCodexPermissionMode","aiSessionHistoryLimit","aiSessionAttachmentRetentionDays","aiSessionMaxFileAttachmentBytes"]),0,0,"string"==typeof n.id&&n.id)||{autoImportAgentConfigs:!0,defaultCodexPermissionMode:"ask",aiSessionHistoryLimit:50,aiSessionAttachmentRetentionDays:30,aiSessionMaxFileAttachmentBytes:fn},s.modelSelection=gd(Vo.unwrap(),bd(n.modelSelection,["codexModelHash","claudeModelHash","opencodeModelHash"]),0,0,"string"==typeof n.id&&n.id)||{},s.imageSnapshot=function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e,i=kc(n),{reference:s,...a}=i,o=n.requestedReference??s;let r;try{r="string"==typeof o?Ho(o):void 0}catch{}const c={img_default:"market_taskhandoff_browser",img_codex:"market_taskhandoff_codex",img_ai:"market_taskhandoff_ai"},d="string"==typeof n.id?n.id:"string"==typeof t?t:void 0,l="market"===n.origin||d&&c[d]?"market":"custom";return void 0!==n.image||n.reference,{...a,id:d&&c[d]?c[d]:d,origin:l,repository:r?.repository??n.repository,tag:r?.tag??n.tag,requestedReference:r?.reference??o,resolvedDigest:n.resolvedDigest,resolvedReference:n.resolvedReference,downloadSizeBytes:n.downloadSizeBytes,market:"market"===l?bd(n.market,["catalogId","catalogRevision","publisher","version"])??{catalogId:"task_handoff_embedded",catalogRevision:"legacy",publisher:"task-handoff"}:void 0}}(n.imageSnapshot,n.imageId,"string"==typeof n.id&&n.id);const a="string"==typeof n.imageId?{img_default:"market_taskhandoff_browser",img_codex:"market_taskhandoff_codex",img_ai:"market_taskhandoff_ai"}[n.imageId]||n.imageId:void 0,o=bd(n.imageSelection,["imageId","tag"]);s.imageSelection=o||(a?{imageId:a,tag:s.imageSnapshot?.tag}:void 0),s.imageProvisioning=gd(wc,bd(n.imageProvisioning,["phase","requestedReference","generation","error","startedAt","updatedAt"]),0,0,"string"==typeof n.id&&n.id),s.runtimeVersion=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e,n=e=>{if("string"!=typeof e)return;const t=e.trim();return t&&t.length<=80?t:void 0},i=n(t.desiredVersion);if(!i)return;const s=new Set(Or.shape.phase.options),a="string"==typeof t.phase?t.phase:"pending",o=s.has(a)?a:{idle:"pending",queued:"pending",checking:"pending",downloading:"installing",updating:"installing",completed:"matched",succeeded:"matched",ready:"matched",error:"failed"}[a]||"pending";let r;if(t.error&&"object"==typeof t.error&&!Array.isArray(t.error)){const e=t.error,i="string"==typeof e.message?e.message.trim().slice(0,4096):"";if(i){const t=new Set(Rr.shape.code.options),s="string"==typeof e.code&&t.has(e.code)?e.code:"INSTANCE_RUNTIME_INSTALL_FAILED";e.code;const a=n(e.expectedVersion),o=n(e.actualVersion);r={code:s,message:i,...a?{expectedVersion:a}:{},...o?{actualVersion:o}:{},retryable:!0===e.retryable}}}"string"==typeof t.error&&t.error.trim()&&(r={code:"INSTANCE_RUNTIME_INSTALL_FAILED",message:t.error.trim().slice(0,4096),expectedVersion:i,...n(t.actualVersion)?{actualVersion:n(t.actualVersion)}:{},retryable:!1});const c=n(t.actualVersion),d=Po.safeParse(t.lastAttemptAt),l=Po.safeParse(t.matchedAt);return void 0!==t.lastAttemptAt&&d.success,void 0!==t.matchedAt&&l.success,{desiredVersion:i,...c?{actualVersion:c}:{},phase:o,attempt:"number"==typeof t.attempt&&Number.isInteger(t.attempt)&&t.attempt>=0?t.attempt:0,...d.success?{lastAttemptAt:d.data}:{},...l.success?{matchedAt:l.data}:{},...r?{error:r}:{}}}(n.runtimeVersion,"string"==typeof n.id&&n.id),s.workspace=gd(cd,n.workspace,0,0,"string"==typeof n.id&&n.id)||{status:"unknown"},s.environmentSource=gd(Yo,n.environmentSource,0,0,"string"==typeof n.id&&n.id),s.environmentTemplateOrigin=gd(er,n.environmentTemplateOrigin,0,0,"string"==typeof n.id&&n.id),s.runtime=gd(dd.shape.runtime.unwrap(),n.runtime,0,0,"string"==typeof n.id&&n.id)||{labels:{}},s.target=gd(ad,bd(n.target??n.endpoints,["strategy","web","api","vnc","tty","logs","status"]),0,0,"string"==typeof n.id&&n.id)||{strategy:"direct-port",status:"unknown"},s.access=gd(rd,bd(n.access,["strategy","web","api","ws","status"]),0,0,"string"==typeof n.id&&n.id)||{strategy:"control-plane-proxy",status:"unknown"};for(const[e,t]of Object.entries(dd.shape))Object.prototype.hasOwnProperty.call(s,e)&&!t.safeParse(s[e]).success&&t.safeParse(void 0).success&&delete s[e];return s}function gd(e,t,n,i,s){if(!t||"object"!=typeof t||Array.isArray(t))return;let a=structuredClone(t);for(let t=0;t<20;t+=1){const t=e.safeParse(a);if(t.success)return t.data;let n=!1;for(const e of t.error.issues){if("unrecognized_keys"!==e.code)continue;const t=fd(a,e.path);if(t&&"object"==typeof t&&!Array.isArray(t))for(const i of e.keys)Object.prototype.hasOwnProperty.call(t,i)&&(delete t[i],n=!0)}if(!n){const n=structuredClone(a);let i=!1;for(const e of t.error.issues){if(!e.path.length||"string"!=typeof e.path.at(-1))continue;const t=fd(n,e.path.slice(0,-1)),s=e.path.at(-1);t&&"object"==typeof t&&!Array.isArray(t)&&Object.prototype.hasOwnProperty.call(t,s)&&(delete t[s],i=!0)}if(i){const t=e.safeParse(n);if(t.success)return t.data}break}}}function fd(e,t){let n=e;for(const e of t){if(!n||"object"!=typeof n)return;n=n[e]}return n}function yd(e,t,n){if(!e||"object"!=typeof e||Array.isArray(e))return e;const i=e,s=i.type,a=Wr.options.find(e=>e.shape.type.value===s);if(!a)return e;const o="local-folder"===s?["type","localFolderId","path","ownerNodeId"]:"git-template"===s?["type","url","templateId","ref","auth","clone"]:["type","repositoryId","url","provider","ref","auth","clone"],r=bd(i,o);if("local-folder"!==s){const e=function(e){const t=e&&"object"==typeof e&&!Array.isArray(e)?e:void 0,n=Br.safeParse(bd(t,["type","name","commit"]));if(n.success)return n.data;const i="string"==typeof t?.commit?t.commit.trim():"",s="string"==typeof t?.name?t.name.trim():"",a=i?Br.safeParse({type:"commit",commit:i}):s?Br.safeParse({type:"tag"===t?.type?"tag":"branch",name:s}):Br.safeParse({type:"branch",name:"main"});return a.success?a.data:void 0}(i.ref),t=gd(Fr,bd(i.auth,["type","secretId"])),n=gd(Hr,bd(i.clone,["depth","submodules","lfs","subdirectory"]));e?r.ref=e:delete r.ref,t?r.auth=t:delete r.auth,n?r.clone=n:delete r.clone}const c=gd(a,r);return c?(Object.keys(i).some(e=>!o.includes(e)),c):r}function bd(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e;return Object.fromEntries(t.filter(e=>Object.prototype.hasOwnProperty.call(n,e)).map(e=>[e,n[e]]))}f.z.object({instanceId:jo.optional(),projectId:jo.optional(),source:Wr.optional(),nodeId:jo.optional(),runtimeId:jo.optional(),imageSelection:Ko.optional(),instanceVersion:f.z.string().trim().max(80).optional(),protocolVersion:Ao,build:zr.optional(),controlMode:f.z.enum(["standalone","controlled"]).default("controlled"),capabilities:No.default(_o),appInventory:lr.optional(),target:od.optional(),workspace:cd.default({status:"unknown"}),registrationToken:f.z.string().trim().max(240).optional(),processIncarnationId:f.z.string().trim().min(1).max(120).optional()}).strict().superRefine((e,t)=>{So.has(e.protocolVersion)&&!e.appInventory&&t.addIssue({code:"custom",path:["appInventory"],message:"Current protocol register payload requires appInventory."})}),f.z.object({status:dd.shape.status.optional(),health:dd.shape.health.optional(),protocolVersion:Ao,build:zr.optional(),capabilities:dd.shape.capabilities.optional(),appInventory:lr.optional(),apps:dd.shape.apps.optional(),aiSessions:dd.shape.aiSessions.optional(),triggers:dd.shape.triggers.optional(),workspace:cd.optional(),target:od.optional(),processIncarnationId:f.z.string().trim().min(1).max(120).optional()}).strict().superRefine((e,t)=>{So.has(e.protocolVersion)&&!e.appInventory&&t.addIssue({code:"custom",path:["appInventory"],message:"Current protocol heartbeat payload requires appInventory."})});const vd=f.z.enum(["web","telegram","wechat","dingding","lark"]),Id=f.z.object({id:jo,channel:vd,name:f.z.string().trim().min(1).max(160),enabled:f.z.boolean().default(!1),token:f.z.string().trim().max(4096).optional(),defaultChatId:f.z.string().trim().max(240).optional(),allowedUserIds:f.z.array(f.z.string().trim().min(1).max(240)).default([]),pollIntervalMs:f.z.number().int().positive().max(6e4).default(3e3),settings:f.z.record(f.z.string(),f.z.unknown()).default({}),createdAt:Po,updatedAt:Po}).strict(),xd=f.z.object({id:jo,channel:vd,bridgeId:jo.optional(),chatSessionId:f.z.string().trim().min(1).max(240),userId:f.z.string().trim().max(240).optional(),activeProjectId:jo.optional(),activeInstanceId:jo.optional(),activeAiSessionId:f.z.string().trim().min(1).max(120).optional(),lastUsedAt:Po,createdAt:Po,updatedAt:Po}).strict(),wd=f.z.object({source:f.z.object({type:f.z.literal("chat-gateway").default("chat-gateway"),channel:vd,bridgeId:jo.optional(),chatSessionId:f.z.string().trim().min(1).max(240),userId:f.z.string().trim().max(240).optional()}).strict(),message:f.z.object({text:f.z.string().trim().max(2e4).default(""),attachments:f.z.array(ai).max(6).default([])}).strict().superRefine((e,t)=>{e.attachments.reduce((e,t)=>e+("inline"===t.source.type?t.size:0),0)>bn&&t.addIssue({code:f.z.ZodIssueCode.custom,path:["attachments"],message:"Inline attachments must be 41943040 bytes or less in total."})}),target:f.z.object({instanceId:jo,aiSessionId:f.z.string().trim().min(1).max(120)}).strict().optional()}).strict(),Sd=f.z.object({id:jo,instanceId:jo,projectId:jo.optional(),aiSessionId:f.z.string().trim().min(1).max(120),providerSessionId:f.z.string().trim().max(240).optional(),result:f.z.string().default(""),timeoutMs:f.z.number().positive().optional(),source:f.z.string().trim().max(120).optional(),kind:f.z.enum(["task","approval"]).default("task"),status:f.z.enum(["pending","unreachable"]).default("pending"),error:f.z.string().trim().max(2048).optional(),lastSeenAt:Po}).strict();function Ad(e){return!1!==e.ready&&(!e.runtimeVersion||["matched","failed"].includes(e.runtimeVersion.phase))}const Ed=6048e5;function _d(e,n){const i=t.resolve(e),s=t.resolve(i,n);if(t.dirname(s)!==i||t.basename(s)!==n)throw new Error(`Retention entry is not a direct child of its managed root: ${n}`);return s}function Td(e){if(n.existsSync(e)){const t=n.lstatSync(e);if(!t.isDirectory()||t.isSymbolicLink())throw new Error(`Managed persistence path must be a real directory: ${e}`)}n.mkdirSync(e,{recursive:!0,mode:448}),n.chmodSync(e,448)}const zd="2026-08-25",kd=f.z.object({v:f.z.literal(1),type:f.z.literal("ping"),sentAt:f.z.string().datetime()}).strict();function Nd(e){return e.startsWith("ai-session.")||e.startsWith("ai.session.")?"ai.sessions":e.startsWith("app-session.")?"app.sessions":e.startsWith("app.management")?"apps":e.startsWith("trigger.")?"triggers":e.startsWith("instance.")?"instances":e.startsWith("node.")?"nodes":e.startsWith("project.")?"projects":e.startsWith("model.")?"models":e.startsWith("image.")?"images":e.startsWith("market.")?"market":"system"}f.z.object({v:f.z.literal(1),type:f.z.literal("pong"),sentAt:f.z.string().datetime(),receivedAt:f.z.string().datetime()}).strict();const Cd=f.z.object({replaySince:f.z.string().datetime().optional(),messageDeltas:f.z.object({allInstances:f.z.boolean().default(!1),instanceIds:f.z.array(f.z.string().trim().min(1).max(160)).max(1e3).default([])}).default({allInstances:!1,instanceIds:[]}),timelineAllSessions:f.z.boolean().default(!1),timelineSessions:f.z.array(f.z.object({instanceId:f.z.string().trim().min(1).max(160),sessionId:f.z.string().trim().min(1).max(120)})).max(1e3).default([])});function Rd(e,t){if(!e)return!0;if("ai-session.message-delta"!==t.type&&"ai-session.timeline-item"!==t.type)return!0;const n=t.payload&&"object"==typeof t.payload&&!Array.isArray(t.payload)?t.payload:{},i=String(n.instanceId||t.scope?.instanceId||"");return"ai-session.message-delta"===t.type?e.messageDeltas.allInstances||e.messageDeltas.instanceIds.includes(i):e.timelineAllSessions||e.timelineSessions.some(e=>e.instanceId===i&&e.sessionId===n.sessionId)}const Od=f.z.enum(["ai.sessions","app.sessions"]),jd=f.z.object({topic:Od,instanceId:f.z.string().trim().min(1).max(160),streamId:f.z.string().trim().min(1).max(240),latestRevision:f.z.number().int().min(0),earliestRetainedRevision:f.z.number().int().min(0)}).strict(),Pd=f.z.object({protocolVersion:f.z.literal(1),streams:f.z.array(jd)}).strict(),Dd={project:"projects",node:"nodes",runtime:"runtimes",template:"templates",instance:"instances","app-session":"app-sessions","ai-session":"ai-sessions","trigger-template":"triggers","trigger-deployment":"triggers",repository:"repositories",attachment:"attachments",image:"images",model:"models",user:"users",role:"roles","identity-provider":"identity-providers","user-session":"users","identity-approval":"users","user-audit":"users","chat-bridge":"chat-bridges","control-plane-settings":"settings",secret:"secrets","public-directory":"public-directory"},Ld=new Set(["instance","app-session","ai-session"]);function Md(e,t){return"all"===e.kind||e.nodeIds.includes(t)}function qd(e,t,n,i){return t&&"inherit-node-scope"!==t.kind?t.instanceIds.includes(n):Md(e,i)}function Ud(e,t,n){const i=function(e,t){const n=Dd[t];return"manage-secrets"===e?"secrets:manage":"manage-settings"===e?"settings:manage":"manage-members"===e?"users:manage":"manage-node-auth"===e?"secrets:manage":"trigger-template"===t&&"read"!==e?"settings:manage":"interactive-access"===e||"proxy"===e?Ld.has(t)?`${n}:interactive`:void 0:"read"===e?`${n}:read`:`${n}:manage`}(t,n.type);return Boolean(i&&e.permissionIds.includes(i))}function $d(e,t,n){if(!function(e,t,n){return"system"===e.type||("chat-bridge"===e.type?function(e,t){return"ai-session"===t.type?["read","send-message","approve","interrupt"].includes(e):"instance"===t.type?["read","start","stop","restart"].includes(e):"read"===e}(t,n):"cloud-account"===e.type?function(e,t){return!["user","role","identity-provider","user-session","identity-approval","user-audit","control-plane-settings","secret","chat-bridge"].includes(t.type)&&("node"===t.type?"read"===e:"read"===e||"image"!==t.type&&"public-directory"!==t.type&&["create","update","delete","start","stop","restart","proxy","interactive-access","send-message","approve","interrupt","read-file-content"].includes(e))}(t,n):Ud(e,t,n))}(e,t,n))throw Fd(t,n)}function Bd(e,t,n,i){if(!Ud(e,t,n))throw Fd(t,n);if(!function(e,t){return"global-public"===t.kind||"global-shared"===t.kind||"global-admin"===t.kind||("node"===t.kind?Md(e.nodeScope,t.nodeId):qd(e.nodeScope,e.instanceScope,t.instanceId,t.nodeId))}(e,i))throw Object.assign(new Error("The requested resource is not visible."),{statusCode:404,code:"CONTROL_PLANE_RESOURCE_NOT_VISIBLE"})}function Fd(e,t){return Object.assign(new Error(`Actor is not allowed to ${e} ${t.type}${t.id?` ${t.id}`:""}.`),{statusCode:403,code:"CONTROL_PLANE_FORBIDDEN"})}function Hd(){return(new Date).toISOString()}function Gd(e,t=448){n.mkdirSync(e,{recursive:!0,mode:t}),n.chmodSync(e,t)}function Wd(e,i,s={}){const a=s.directoryMode??448,o=s.fileMode??384;Gd(t.dirname(e),a),y.sync(e,`${JSON.stringify(i,null,2)}\n`,{encoding:"utf8",mode:o}),n.chmodSync(e,o)}function Vd(e,t){console.warn(JSON.stringify({message:e,...t}))}function Kd(e){return e&&"object"==typeof e&&"issues"in e?{issues:e.issues}:{error:e instanceof Error?e.message:String(e)}}function Yd(e,t){const i=t.logger||Vd;let s;try{s=JSON.parse(n.readFileSync(e,"utf8"))}catch(t){return void i("stored JSON could not be read",{filePath:e,...Kd(t)})}if(!t.schema)return s;const a=t.sanitize?t.sanitize(s):s,o=t.schema.safeParse(a);if(o.success)return o.data;const r="strip"in t.schema&&"function"==typeof t.schema.strip?t.schema.strip().safeParse(a):void 0;if(r?.success)return i("unknown stored fields were ignored",{filePath:e,issues:o.error.issues}),r.data;i("stored record failed validation and was isolated",{filePath:e,issues:o.error.issues})}function Xd(e){return`${e}_${i.randomUUID().replace(/-/g,"").slice(0,20)}`}function Jd(){return i.randomBytes(24).toString("base64url")}class Qd{directory;options;permissionsInitialized=!1;constructor(e,t={}){this.directory=e,this.options=t}init(){if(this.permissionsInitialized&&n.existsSync(this.directory))return;Gd(this.directory,this.options.directoryMode??448);const e=this.options.fileMode??384;for(const i of n.readdirSync(this.directory).filter(e=>e.endsWith(".json")))n.chmodSync(t.join(this.directory,i),e);this.permissionsInitialized=!0}filePath(e){return t.join(this.directory,`${e}.json`)}list(){return this.init(),n.readdirSync(this.directory).filter(e=>e.endsWith(".json")).sort().flatMap(e=>{const n=Yd(t.join(this.directory,e),this.options);return n?[n]:[]})}get(e){this.init();const t=this.filePath(e);return n.existsSync(t)?Yd(t,this.options):void 0}put(e){const t=this.options.sanitize?this.options.sanitize(e):e,n=this.options.schema?this.options.schema.parse(t):t;return Wd(this.filePath(n.id),n,this.options),n}patch(e,t){const n=this.get(e);if(!n)return;const i={...n,...t,id:n.id,createdAt:n.createdAt,updatedAt:(new Date).toISOString()};return this.put(i)}delete(e){const t=this.filePath(e);return!!n.existsSync(t)&&(n.unlinkSync(t),!0)}}class Zd{filePathValue;defaults;options;constructor(e,t,n={}){this.filePathValue=e,this.defaults=t,this.options=n}init(){Gd(t.dirname(this.filePathValue),this.options.directoryMode??448),n.existsSync(this.filePathValue)?n.chmodSync(this.filePathValue,this.options.fileMode??384):this.put(this.defaults())}get(){return this.init(),n.existsSync(this.filePathValue)?Yd(this.filePathValue,this.options)??this.defaults():this.defaults()}put(e){const t=this.options.sanitize?this.options.sanitize(e):e,n=this.options.schema?this.options.schema.parse(t):t;return Wd(this.filePathValue,n,this.options),n}}const el=f.z.object({sub:f.z.string().trim().min(1).max(500),email:f.z.string().email().optional(),email_verified:f.z.boolean().optional(),name:f.z.string().trim().min(1).max(160).optional(),preferred_username:f.z.string().trim().min(1).max(160).optional()}).passthrough(),tl=f.z.object({id:f.z.union([f.z.number().int().positive(),f.z.string().trim().regex(/^\d+$/)]),login:f.z.string().trim().min(1).max(160),name:f.z.string().trim().min(1).max(160).nullable().optional(),email:f.z.string().email().nullable().optional()}).passthrough(),nl={oidc:{kind:"oidc",identityKind:"oidc",normalizeClaims(e){const t=el.parse(e);return{subject:t.sub,...t.email&&!0===t.email_verified?{verifiedEmail:t.email}:{},...t.name||t.preferred_username?{displayName:t.name||t.preferred_username}:{}}}},github:{kind:"github",identityKind:"oauth",normalizeClaims(e){const t=tl.parse(e);return{subject:String(t.id),...t.email?{verifiedEmail:t.email}:{},displayName:t.name||t.login}}}};function il(e){const t=nl[e];if(!t)throw Object.assign(new Error(`Unsupported external identity provider adapter: ${e}`),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_UNSUPPORTED",statusCode:400});return t}const sl=f.z.object({issuer:f.z.string().url(),authorization_endpoint:f.z.string().url(),token_endpoint:f.z.string().url(),jwks_uri:f.z.string().url()}).passthrough(),al=f.z.object({iss:f.z.string().url(),sub:f.z.string().trim().min(1).max(500),aud:f.z.union([f.z.string().trim().min(1),f.z.array(f.z.string().trim().min(1)).min(1)]),exp:f.z.number().int().positive(),iat:f.z.number().int().positive().optional(),nonce:f.z.string().trim().min(1),email:f.z.string().email().optional(),email_verified:f.z.boolean().optional(),name:f.z.string().trim().min(1).max(160).optional(),preferred_username:f.z.string().trim().min(1).max(160).optional()}).passthrough();function ol(e){return JSON.parse(Buffer.from(e,"base64url").toString("utf8"))}function rl(e=32){return i.randomBytes(e).toString("base64url")}function cl(e){return i.createHash("sha256").update(e).digest("base64url")}function dl(e){return new URLSearchParams(e).toString()}class ll{flows=new Map;fetchImplementation;users;sessions;providers;constructor(e,t,n,i={}){this.users=e,this.sessions=t,this.providers=n,this.fetchImplementation=i.fetch||fetch}async begin(e,t="web"){this.pruneFlows();const n=await this.users.store.providers.get(e);if(!n||"enabled"!==n.status)throw Object.assign(new Error("Identity provider is unavailable."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_UNAVAILABLE",statusCode:404});const i={providerId:e,state:rl(),nonce:rl(),codeVerifier:rl(48),expiresAt:Date.now()+6e5,clientType:t};return this.flows.set(i.state,i),{authorizationUrl:"oidc"===n.kind?await this.oidcAuthorizationUrl(n,i):this.githubAuthorizationUrl(n,i),expiresAt:new Date(i.expiresAt).toISOString()}}async callback(e){const t=f.z.object({state:f.z.string().trim().min(32),code:f.z.string().trim().min(1)}).strict().parse(e),n=this.flows.get(t.state);if(this.flows.delete(t.state),!n||n.expiresAt<=Date.now())throw Object.assign(new Error("External login callback is invalid or expired."),{code:"AUTH_EXTERNAL_FLOW_INVALID",statusCode:401});const i=await this.users.store.providers.get(n.providerId);if(!i||"enabled"!==i.status)throw Object.assign(new Error("Identity provider is unavailable."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_UNAVAILABLE",statusCode:401});const s="oidc"===i.kind?await this.exchangeOidc(i,n,t.code):await this.exchangeGitHub(i,n,t.code),a=await this.users.store.identities.findByProviderSubject(i.id,s.subject);if(a)return{kind:"session",...await this.sessions.createSessionForIdentity(a.id,n.clientType)};if("existing-only"===i.loginPolicy)throw Object.assign(new Error("External identity is not bound to a Control Plane user."),{code:"AUTH_EXTERNAL_IDENTITY_NOT_BOUND",statusCode:403});const o=await this.users.store.approvals.findActivePending(i.id,s.subject,Hd());if(o)return{kind:"pending-approval",approvalId:o.id,expiresAt:o.expiresAt};const r=Hd(),c=await this.users.store.approvals.put({id:Xd("identity_approval"),providerId:i.id,subject:s.subject,verifiedEmail:s.verifiedEmail,displayName:s.displayName,status:"pending",expiresAt:new Date(Date.now()+864e5).toISOString(),createdAt:r,updatedAt:r});return{kind:"pending-approval",approvalId:c.id,expiresAt:c.expiresAt}}async oidcAuthorizationUrl(e,t){const n=await this.discovery(e.issuer),i=new URL(n.authorization_endpoint);return i.search=new URLSearchParams({response_type:"code",client_id:e.clientId,redirect_uri:e.callbackUrl,scope:"openid profile email",state:t.state,nonce:t.nonce,code_challenge:cl(t.codeVerifier),code_challenge_method:"S256"}).toString(),i.toString()}githubAuthorizationUrl(e,t){const n=new URL("https://github.com/login/oauth/authorize");return n.search=new URLSearchParams({client_id:e.clientId,redirect_uri:e.callbackUrl,scope:"read:user user:email",state:t.state,code_challenge:cl(t.codeVerifier),code_challenge_method:"S256"}).toString(),n.toString()}async exchangeOidc(e,t,n){const s=await this.discovery(e.issuer),a=await this.fetchImplementation(s.token_endpoint,{method:"POST",headers:{accept:"application/json","content-type":"application/x-www-form-urlencoded"},body:dl({grant_type:"authorization_code",code:n,redirect_uri:e.callbackUrl,client_id:e.clientId,client_secret:await this.providers.clientSecret(e.id),code_verifier:t.codeVerifier})});if(!a.ok)throw Object.assign(new Error("OIDC token exchange failed."),{code:"AUTH_EXTERNAL_TOKEN_EXCHANGE_FAILED",statusCode:401});const o=f.z.object({id_token:f.z.string().trim().min(1)}).passthrough().parse(await a.json()),r=await this.fetchImplementation(s.jwks_uri,{headers:{accept:"application/json"}});if(!r.ok)throw Object.assign(new Error("OIDC signing keys are unavailable."),{code:"AUTH_EXTERNAL_KEYS_UNAVAILABLE",statusCode:401});const c=function(e){const[t,n,s]=e.token.split(".");if(!t||!n||!s)throw new Error("OIDC ID token is malformed.");const a=f.z.object({alg:f.z.enum(["RS256","ES256"]),kid:f.z.string().trim().min(1)}).passthrough().parse(ol(t)),o=f.z.object({keys:f.z.array(f.z.record(f.z.string(),f.z.unknown()))}).passthrough().parse(e.jwks).keys.find(e=>e.kid===a.kid);if(!o)throw new Error("OIDC ID token signing key was not found.");const r=i.createPublicKey({key:o,format:"jwk"});if(!i.verify("sha256",Buffer.from(`${t}.${n}`),{key:r,..."ES256"===a.alg?{dsaEncoding:"ieee-p1363"}:{}},Buffer.from(s,"base64url")))throw new Error("OIDC ID token signature is invalid.");const c=al.parse(ol(n)),d=e.issuer.replace(/\/$/,"");if(c.iss.replace(/\/$/,"")!==d)throw new Error("OIDC ID token issuer is invalid.");if(!(Array.isArray(c.aud)?c.aud:[c.aud]).includes(e.clientId))throw new Error("OIDC ID token audience is invalid.");if(c.nonce!==e.nonce)throw new Error("OIDC ID token nonce is invalid.");const l=Math.floor((e.now??Date.now())/1e3);if(c.exp<=l)throw new Error("OIDC ID token is expired.");return c}({token:o.id_token,jwks:await r.json(),issuer:e.issuer,clientId:e.clientId,nonce:t.nonce});return il("oidc").normalizeClaims(c)}async exchangeGitHub(e,t,n){const i=await this.fetchImplementation("https://github.com/login/oauth/access_token",{method:"POST",headers:{accept:"application/json","content-type":"application/x-www-form-urlencoded"},body:dl({client_id:e.clientId,client_secret:await this.providers.clientSecret(e.id),code:n,redirect_uri:e.callbackUrl,code_verifier:t.codeVerifier})});if(!i.ok)throw Object.assign(new Error("GitHub token exchange failed."),{code:"AUTH_EXTERNAL_TOKEN_EXCHANGE_FAILED",statusCode:401});const{access_token:s}=f.z.object({access_token:f.z.string().trim().min(1)}).passthrough().parse(await i.json()),a=await this.fetchImplementation("https://api.github.com/user",{headers:{accept:"application/vnd.github+json",authorization:`Bearer ${s}`}});if(!a.ok)throw Object.assign(new Error("GitHub identity lookup failed."),{code:"AUTH_EXTERNAL_IDENTITY_LOOKUP_FAILED",statusCode:401});const o=await a.json(),r=await this.fetchImplementation("https://api.github.com/user/emails",{headers:{accept:"application/vnd.github+json",authorization:`Bearer ${s}`}});if(r.ok){const e=f.z.array(f.z.object({email:f.z.string().email(),primary:f.z.boolean(),verified:f.z.boolean()}).passthrough()).safeParse(await r.json()),t=e.success?e.data.find(e=>e.primary&&e.verified):void 0;t&&(o.email=t.email)}return il("github").normalizeClaims(o)}async discovery(e){const t=e.replace(/\/$/,""),n=await this.fetchImplementation(`${t}/.well-known/openid-configuration`,{headers:{accept:"application/json"}});if(!n.ok)throw Object.assign(new Error("OIDC discovery failed."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_UNAVAILABLE",statusCode:401});const i=sl.parse(await n.json());if(i.issuer.replace(/\/$/,"")!==t)throw Object.assign(new Error("OIDC issuer mismatch."),{code:"AUTH_EXTERNAL_ISSUER_MISMATCH",statusCode:401});return i}pruneFlows(){const e=Date.now();for(const[t,n]of this.flows)n.expiresAt<=e&&this.flows.delete(t)}}function pl(e,t){let n=fl(t);for(let t=0;t<100;t+=1){const t=e.safeParse(n);if(t.success)return t;const i=ml(t.error.issues);let s=!1;for(const e of i){const t=gl(n,e.path);if(t&&"object"==typeof t&&!Array.isArray(t))for(const n of e.keys)Object.prototype.hasOwnProperty.call(t,n)&&(delete t[n],s=!0)}if(!s)return t}return e.safeParse(n)}function ul(e,t){const n=pl(e,t);if(!n.success)throw n.error;return n.data}function ml(e,t=[]){const n=[];for(const i of e){if("unrecognized_keys"===i.code){n.push({code:"unrecognized_keys",keys:i.keys,path:[...t,...i.path]});continue}if("invalid_union"!==i.code||!Array.isArray(i.errors))continue;const e=i.errors.filter(e=>Array.isArray(e));if(!e.length)continue;const s=e.reduce((e,t)=>hl(t)<hl(e)?t:e);n.push(...ml(s,[...t,...i.path]))}return n}function hl(e){return e.reduce((e,t)=>{if("unrecognized_keys"===t.code)return e;if("invalid_union"!==t.code||!Array.isArray(t.errors))return e+1;const n=t.errors.filter(e=>Array.isArray(e));return e+(n.length?Math.min(...n.map(hl)):1)},0)}function gl(e,t){let n=e;for(const e of t){if(!n||"object"!=typeof n)return;n=n[e]}return n}function fl(e){return Array.isArray(e)?e.map(fl):e&&"object"==typeof e?Object.getPrototypeOf(e)!==Object.prototype&&null!==Object.getPrototypeOf(e)?e:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,fl(t)])):e}const yl=["users:read","users:manage","roles:read","roles:manage","identity-providers:read","identity-providers:manage","nodes:read","nodes:manage","projects:read","projects:manage","runtimes:read","runtimes:manage","templates:read","templates:manage","instances:read","instances:manage","instances:interactive","app-sessions:read","app-sessions:manage","app-sessions:interactive","ai-sessions:read","ai-sessions:manage","ai-sessions:interactive","triggers:read","triggers:manage","repositories:read","repositories:manage","attachments:read","attachments:manage","images:read","images:manage","models:read","models:manage","settings:read","settings:manage","secrets:manage","chat-bridges:read","chat-bridges:manage","public-directory:read"],bl=f.z.enum(yl),vl=f.z.enum(["active","disabled","archived"]),Il=f.z.enum(["local-password","oidc","oauth"]),xl=f.z.enum(["active","archived"]),wl=f.z.enum(["oidc","github"]),Sl=f.z.enum(["enabled","disabled"]),Al=f.z.enum(["existing-only","admin-approved-create"]),El=f.z.enum(["pending","approved","rejected","expired"]),_l=f.z.discriminatedUnion("kind",[f.z.object({kind:f.z.literal("all")}).strict(),f.z.object({kind:f.z.literal("selected"),nodeIds:f.z.array(f.z.string().trim().min(1)).max(1e4)}).strict()]),Tl=f.z.discriminatedUnion("kind",[f.z.object({kind:f.z.literal("inherit-node-scope")}).strict(),f.z.object({kind:f.z.literal("selected"),instanceIds:f.z.array(f.z.string().trim().min(1)).max(1e4)}).strict()]),zl=f.z.object({id:bl,resource:f.z.string().trim().min(1).max(80),action:f.z.string().trim().min(1).max(80),nodeScoped:f.z.boolean(),name:f.z.string().trim().min(1).max(160),translationKey:f.z.string().trim().min(1).max(200).optional(),description:f.z.string().trim().min(1).max(500).optional()}).strict(),kl=new Set(["users","roles","identity-providers","settings","secrets","chat-bridges","public-directory"]),Nl=yl.map(e=>{const[t,n]=e.split(":");return zl.parse({id:e,resource:t,action:n,nodeScoped:!kl.has(t),name:e,translationKey:`settings.userAccess.permissionLabels.${t}.${n}`})}),Cl=f.z.object({id:f.z.string().trim().min(1),displayName:f.z.string().trim().min(1).max(160),primaryUsername:f.z.string().trim().min(1).max(80).optional(),status:vl,createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime(),lastLoginAt:f.z.string().datetime().optional()}).strict(),Rl=f.z.string().trim().min(1).max(80).regex(/^[a-zA-Z0-9_.@-]+$/),Ol=f.z.object({displayName:f.z.string().trim().min(1).max(160).optional(),username:Rl.optional(),status:vl.optional()}).strict().refine(e=>Object.values(e).some(e=>void 0!==e),{message:"At least one user field must be updated."}),jl=f.z.object({id:f.z.string().trim().min(1),userId:f.z.string().trim().min(1),kind:Il,providerId:f.z.string().trim().min(1).optional(),loginName:f.z.string().trim().min(1).max(160).optional(),subject:f.z.string().trim().min(1).max(500).optional(),verifiedEmail:f.z.string().email().optional(),requiresPasswordChange:f.z.boolean().optional(),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime(),lastUsedAt:f.z.string().datetime().optional()}).strict().superRefine((e,t)=>{"local-password"!==e.kind||e.loginName||t.addIssue({code:"custom",path:["loginName"],message:"Local password identities require loginName."}),"local-password"===e.kind||e.providerId&&e.subject||t.addIssue({code:"custom",path:["providerId"],message:"External identities require providerId and subject."})}),Pl=f.z.object({id:f.z.string().trim().min(1),userId:f.z.string().trim().min(1),identityId:f.z.string().trim().min(1),clientType:f.z.enum(["web","mobile"]),createdAt:f.z.string().datetime(),expiresAt:f.z.string().datetime(),lastSeenAt:f.z.string().datetime().optional(),current:f.z.boolean().optional()}).strict(),Dl=f.z.object({id:f.z.string().trim().min(1),name:f.z.string().trim().min(1).max(120),description:f.z.string().trim().max(500).optional(),system:f.z.boolean(),status:xl,permissionIds:f.z.array(bl).max(yl.length),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}).strict(),Ll=f.z.object({userId:f.z.string().trim().min(1),roleIds:f.z.array(f.z.string().trim().min(1)).min(1).max(100),nodeScope:_l,instanceScope:Tl.default({kind:"inherit-node-scope"}),authorizationRevision:f.z.number().int().positive(),updatedAt:f.z.string().datetime()}).strict(),Ml=Cl.extend({identities:f.z.array(jl),accessGrant:Ll}).strict(),ql=f.z.object({userId:f.z.string().trim().min(1),identityId:f.z.string().trim().min(1),roleIds:f.z.array(f.z.string().trim().min(1)).min(1).max(100),permissionIds:f.z.array(bl).max(yl.length),nodeScope:_l,instanceScope:Tl.default({kind:"inherit-node-scope"}),authorizationRevision:f.z.number().int().positive()}).strict(),Ul=f.z.object({id:f.z.string().trim().min(1),name:f.z.string().trim().min(1).max(120),kind:wl,status:Sl,loginPolicy:Al,issuer:f.z.string().url().optional(),clientId:f.z.string().trim().min(1).max(500),callbackUrl:f.z.string().url(),clientSecretConfigured:f.z.boolean(),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}).strict().superRefine((e,t)=>{"oidc"!==e.kind||e.issuer||t.addIssue({code:"custom",path:["issuer"],message:"OIDC providers require issuer."})});f.z.object({id:f.z.string().trim().min(1),providerId:f.z.string().trim().min(1),subject:f.z.string().trim().min(1).max(500),verifiedEmail:f.z.string().email().optional(),displayName:f.z.string().trim().min(1).max(160).optional(),status:El,expiresAt:f.z.string().datetime(),decidedAt:f.z.string().datetime().optional(),decidedByUserId:f.z.string().trim().min(1).optional(),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}).strict();const $l=f.z.object({userManagement:f.z.object({users:f.z.literal(!0),identities:f.z.literal(!0),sessions:f.z.literal(!0)}).strict(),authentication:f.z.object({externalIdentity:f.z.object({oidc:f.z.boolean(),oauthAdapters:f.z.array(wl).max(20)}).strict().optional()}).strict(),authorization:f.z.object({customRoles:f.z.boolean(),nodeScopes:f.z.literal(!0),instanceScopes:f.z.literal(!0).optional(),authorizationRevisions:f.z.literal(!0)}).strict()}).strict(),Bl=f.z.object({authentication:f.z.enum(["required","disabled"]),aiSessions:f.z.boolean(),nodes:f.z.boolean(),instanceBoard:f.z.boolean(),triggers:f.z.boolean().optional(),accessManagement:$l.optional()}).strict(),Fl=f.z.object({version:f.z.literal(1),kind:f.z.literal("control-plane"),controlPlaneId:f.z.string().trim().min(1).max(160),publicKey:f.z.object({algorithm:f.z.literal("Ed25519"),encoding:f.z.literal("base64url"),value:f.z.string().regex(/^[A-Za-z0-9_-]{43}$/),fingerprint:f.z.string().regex(/^sha256:[A-Za-z0-9_-]{43}$/)}).strict(),capabilities:Bl,protocolVersion:f.z.string().regex(/^\d{4}-\d{2}-\d{2}$/),issuedAt:f.z.string().datetime(),expiresAt:f.z.string().datetime()}).strict(),Hl=f.z.object({data:f.z.object({payload:Fl,signature:f.z.string().regex(/^[A-Za-z0-9_-]{86}$/)}).strict()}).strict(),Gl=f.z.object({id:f.z.string().trim().min(8).max(160),name:f.z.string().trim().min(1).max(160),platform:f.z.enum(["ios","android"]),appVersion:f.z.string().trim().min(1).max(80).optional()}).strict();f.z.object({username:f.z.string().trim().min(1).max(80),password:f.z.string().min(1).max(4096),device:Gl}).strict();const Wl=Pl.extend({device:Gl,user:Cl}).strict();f.z.enum(["CONTROL_PLANE_FORBIDDEN","CONTROL_PLANE_AUTH_REQUIRED","AUTH_PASSWORD_CHANGE_REQUIRED","CONTROL_PLANE_USER_DISABLED","CONTROL_PLANE_AUTHORIZATION_REVISION_CONFLICT","CONTROL_PLANE_LAST_ACTIVE_ADMIN","CONTROL_PLANE_USERNAME_CONFLICT","CONTROL_PLANE_EXTERNAL_IDENTITY_CONFLICT","CONTROL_PLANE_IDENTITY_PROVIDER_NAMESPACE_IMMUTABLE","CONTROL_PLANE_IDENTITY_PROVIDER_UNAVAILABLE","USER_STORE_REINITIALIZATION_REQUIRED"]),f.z.object({data:f.z.object({sessionToken:f.z.string().trim().min(32),session:Wl,authorization:ql}).strict()}).strict(),f.z.object({data:f.z.array(Wl)}).strict(),f.z.object({data:f.z.object({revoked:f.z.boolean()}).strict()}).strict();const Vl=f.z.object({version:f.z.literal(1),key:f.z.string().regex(/^[A-Za-z0-9_-]{43}$/)}).strict();class Kl{keyFile;constructor(e){this.keyFile=new Zd(e,()=>({version:1,key:i.randomBytes(32).toString("base64url")}),{schema:Vl,directoryMode:448,fileMode:384})}init(){this.keyFile.init()}seal(e){const t=Buffer.from(this.keyFile.get().key,"base64url"),n=i.randomBytes(12),s=i.createCipheriv("aes-256-gcm",t,n),a=Buffer.concat([s.update(e,"utf8"),s.final()]);return["v1",n.toString("base64url"),a.toString("base64url"),s.getAuthTag().toString("base64url")].join(".")}open(e){const[t,n,s,a]=e.split(".");if("v1"!==t||!n||!s||!a)throw new Error("Unsupported encrypted secret envelope.");const o=Buffer.from(this.keyFile.get().key,"base64url"),r=i.createDecipheriv("aes-256-gcm",o,Buffer.from(n,"base64url"));return r.setAuthTag(Buffer.from(a,"base64url")),Buffer.concat([r.update(Buffer.from(s,"base64url")),r.final()]).toString("utf8")}}const Yl=f.z.object({name:f.z.string().trim().min(1).max(120),kind:f.z.enum(["oidc","github"]),status:f.z.enum(["enabled","disabled"]).optional(),loginPolicy:f.z.enum(["existing-only","admin-approved-create"]).optional(),issuer:f.z.string().url().optional(),clientId:f.z.string().trim().min(1).max(500),clientSecret:f.z.string().min(1).max(1e4),callbackUrl:f.z.string().url()}).strict().superRefine((e,t)=>{"oidc"!==e.kind||e.issuer||t.addIssue({code:"custom",path:["issuer"],message:"OIDC provider requires issuer."})}),Xl=f.z.object({name:f.z.string().trim().min(1).max(120).optional(),kind:f.z.enum(["oidc","github"]).optional(),status:f.z.enum(["enabled","disabled"]).optional(),loginPolicy:f.z.enum(["existing-only","admin-approved-create"]).optional(),issuer:f.z.string().url().optional(),clientId:f.z.string().trim().min(1).max(500).optional(),clientSecret:f.z.string().min(1).max(1e4).optional(),callbackUrl:f.z.string().url().optional()}).strict().refine(e=>Object.values(e).some(e=>void 0!==e),{message:"At least one provider field must be updated."});function Jl(e,t){return"github"===e?"github":`oidc:${new URL(t).toString().replace(/\/$/,"")}`}class Ql{users;secrets;fetchImplementation;constructor(e,t,n={}){this.users=t,this.secrets=new Kl(e.identityProviderEncryptionKeyPath),this.fetchImplementation=n.fetch||fetch}init(){this.secrets.init()}async list(){return(await this.users.store.providers.list()).map(e=>this.publicProvider(e))}async create(e){const t=Yl.parse(e);il(t.kind),await this.validateConfiguration(t);const n=Hd();return this.publicProvider(await this.users.store.providers.put({id:Xd("idp"),name:t.name,kind:t.kind,status:t.status||"disabled",loginPolicy:t.loginPolicy||"existing-only",issuer:t.issuer,clientId:t.clientId,clientSecretCiphertext:this.secrets.seal(t.clientSecret),callbackUrl:t.callbackUrl,createdAt:n,updatedAt:n}))}async update(e,t){const n=Xl.parse(t),i=await this.users.store.providers.get(e);if(!i)throw Object.assign(new Error("Identity provider was not found."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_NOT_FOUND",statusCode:404});const s=n.kind||i.kind,a=void 0===n.issuer?i.issuer:n.issuer;if("oidc"===s&&!a)throw Object.assign(new Error("OIDC provider requires issuer."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_ISSUER_REQUIRED",statusCode:400});il(s),await this.assertIdentityNamespaceChangeAllowed(i,s,a,this.users.store);const{clientSecret:o,...r}=n;return await this.validateConfiguration({name:r.name||i.name,kind:s,status:r.status||i.status,loginPolicy:r.loginPolicy||i.loginPolicy,issuer:a,clientId:r.clientId||i.clientId,clientSecret:o||await this.clientSecret(e),callbackUrl:r.callbackUrl||i.callbackUrl}),this.users.store.transaction(async t=>{const i=await t.providers.get(e);if(!i)throw Object.assign(new Error("Identity provider was not found."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_NOT_FOUND",statusCode:404});const s=n.kind||i.kind,a=void 0===n.issuer?i.issuer:n.issuer;return await this.assertIdentityNamespaceChangeAllowed(i,s,a,t),await this.users.assertProviderStatusChangeAllowed(e,r.status||i.status,t),this.publicProvider(await t.providers.put({...i,...r,kind:s,issuer:a,clientSecretCiphertext:o?this.secrets.seal(o):i.clientSecretCiphertext,updatedAt:Hd()}))})}async remove(e){if(!await this.users.store.providers.get(e))return!1;if(await this.users.store.identities.existsForProvider(e))throw Object.assign(new Error("Identity provider is referenced by login identities."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_IN_USE",statusCode:409});return this.users.store.providers.delete(e)}async clientSecret(e){const t=await this.users.store.providers.get(e);if(!t)throw Object.assign(new Error("Identity provider was not found."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_NOT_FOUND",statusCode:404});return this.secrets.open(t.clientSecretCiphertext)}async validateConfiguration(e){if("oidc"!==e.kind)return;const t=e.issuer.replace(/\/$/,""),n=await this.fetchImplementation(`${t}/.well-known/openid-configuration`,{headers:{accept:"application/json"}});if(!n.ok)throw Object.assign(new Error("OIDC discovery failed."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_UNAVAILABLE",statusCode:400});if(f.z.object({issuer:f.z.string().url(),authorization_endpoint:f.z.string().url(),token_endpoint:f.z.string().url(),jwks_uri:f.z.string().url()}).passthrough().parse(await n.json()).issuer.replace(/\/$/,"")!==t)throw Object.assign(new Error("OIDC discovery issuer does not match configured issuer."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_ISSUER_MISMATCH",statusCode:400})}async assertIdentityNamespaceChangeAllowed(e,t,n,i){if(Jl(e.kind,e.issuer)!==Jl(t,n)&&(await i.identities.existsForProvider(e.id)||await i.approvals.hasActivePendingForProvider(e.id,Hd())))throw Object.assign(new Error("Identity provider kind and issuer cannot change while identities or pending approvals reference it."),{code:"CONTROL_PLANE_IDENTITY_PROVIDER_NAMESPACE_IMMUTABLE",statusCode:409})}publicProvider(e){return Ul.parse({id:e.id,name:e.name,kind:e.kind,status:e.status,loginPolicy:e.loginPolicy,issuer:e.issuer,clientId:e.clientId,callbackUrl:e.callbackUrl,clientSecretConfigured:Boolean(e.clientSecretCiphertext),createdAt:e.createdAt,updatedAt:e.updatedAt})}}const Zl=o.promisify(i.scrypt);function ep(e){return e.trim().toLocaleLowerCase("en-US")}async function tp(e){const t=i.randomBytes(16).toString("base64url");return`scrypt$${t}$${(await Zl(e,t,64)).toString("base64url")}`}async function np(e,t){const[n,s,a]=t.split("$");if("scrypt"!==n||!s||!a)return!1;const o=await Zl(e,s,64),r=Buffer.from(a,"base64url");return r.length===o.length&&i.timingSafeEqual(r,o)}const ip=f.z.object({username:f.z.string().trim().min(1).max(80),password:f.z.string().min(1).max(4096)}).strict(),sp={windowMs:9e5,maxFailuresPerSource:20,maxFailuresPerUsername:10,maxConcurrent:4};class ap{sourceFailures=new Map;usernameFailures=new Map;options;concurrent=0;constructor(e){this.options=e}begin(e,t){const n=Date.now();if(this.assertAvailable(this.sourceFailures,e,this.options.maxFailuresPerSource,n),this.assertAvailable(this.usernameFailures,t,this.options.maxFailuresPerUsername,n),this.concurrent>=this.options.maxConcurrent)throw this.error();this.concurrent+=1}finish(){this.concurrent=Math.max(0,this.concurrent-1)}failure(e,t){const n=Date.now();this.current(this.sourceFailures,e,n).push(n),this.current(this.usernameFailures,t,n).push(n)}current(e,t,n){const i=(e.get(t)||[]).filter(e=>e>n-this.options.windowMs);return e.set(t,i),i}assertAvailable(e,t,n,i){const s=this.current(e,t,i);if(s.length>=n)throw this.error(s[0]+this.options.windowMs-i)}error(e=1e3){return Object.assign(new Error("Too many failed sign-in attempts. Try again later."),{code:"AUTH_LOGIN_RATE_LIMITED",statusCode:429,retryAfterSeconds:Math.max(1,Math.ceil(e/1e3))})}}function op(e){return i.createHash("sha256").update(e).digest("base64url")}class rp{passwordUpdates=new Set;limiter;sessionActivity=new Map;users;nextSessionActivityPruneAt=0;constructor(e,t={}){this.users=e,this.limiter=new ap({...sp,...t})}async loginLocal(e,t={}){const n=ip.parse(e),i=ep(n.username),s=t.sourceId?.trim()||"unknown";this.limiter.begin(s,i);try{const e=await this.users.store.identities.findByLoginName(i),a=!!e&&await np(n.password,e.passwordHash||"");if(!e||!a)throw this.limiter.failure(s,i),Object.assign(new Error("Invalid username or password."),{code:"AUTH_LOGIN_FAILED",statusCode:401});const o=await this.users.store.users.get(e.userId);if(!o||"active"!==o.status)throw this.limiter.failure(s,i),Object.assign(new Error("Invalid username or password."),{code:"AUTH_LOGIN_FAILED",statusCode:401});const r=Hd();return this.createSessionForIdentity(e.id,t.clientType||"web",t.device,{loginAt:r})}finally{this.limiter.finish()}}async createSessionForIdentity(e,t,n,i={}){const s=n?Gl.parse(n):void 0;if("mobile"===t&&!s)throw Object.assign(new Error("Mobile sessions require device metadata."),{code:"AUTH_MOBILE_DEVICE_REQUIRED",statusCode:400});const a=Hd(),o=Jd(),r=await this.users.store.transaction(async n=>{const r=await n.identities.get(e);if(!r)throw Object.assign(new Error("Login identity was not found."),{code:"CONTROL_PLANE_IDENTITY_NOT_FOUND",statusCode:404});if("mobile"===t&&!0===r.requiresPasswordChange)throw Object.assign(new Error("Change the temporary password in the Control Plane before signing in on mobile."),{code:"AUTH_PASSWORD_CHANGE_REQUIRED",statusCode:403});const c=await this.users.authorization(r.userId,n);if(i.loginAt){const e=await n.users.get(r.userId);await n.users.put({...e,lastLoginAt:i.loginAt,updatedAt:i.loginAt}),await n.identities.put({...r,lastUsedAt:i.loginAt,updatedAt:i.loginAt})}return{record:await n.sessions.put({id:Xd("mobile"===t?"msess":"sess"),userId:r.userId,identityId:e,authorizationRevision:c.authorizationRevision,tokenHash:op(o),expiresAt:new Date(Date.now()+12096e5).toISOString(),createdAt:a,updatedAt:a,clientType:t,...s?{device:s}:{}}),identity:r,authorization:c}}),{record:c,identity:d,authorization:l}=r;return this.trackSessionActivity(c,a),{sessionToken:`${c.id}.${o}`,expiresAt:c.expiresAt,session:await this.publicSession(c.id),user:await this.users.detail(d.userId),authorization:ql.parse({...l,identityId:e}),requiresPasswordChange:!0===d.requiresPasswordChange}}async changeLocalPassword(e,t){const n=f.z.object({currentPassword:f.z.string().min(1).max(4096),newPassword:f.z.string().min(8).max(4096)}).strict().parse(t),i=await this.resolve(e,"web");if(!i)throw Object.assign(new Error("Sign in to change the password."),{code:"CONTROL_PLANE_AUTH_REQUIRED",statusCode:401});if(this.passwordUpdates.has(i.user.id))throw Object.assign(new Error("A password update is already in progress for this account."),{code:"AUTH_CREDENTIAL_UPDATE_IN_PROGRESS",statusCode:409});this.passwordUpdates.add(i.user.id);try{const e=await this.users.store.identities.get(i.session.identityId);if(!e||"local-password"!==e.kind||!await np(n.currentPassword,e.passwordHash||""))throw Object.assign(new Error("The current password is incorrect."),{code:"AUTH_CURRENT_PASSWORD_INVALID",statusCode:400});if(await np(n.newPassword,e.passwordHash||""))throw Object.assign(new Error("The new password must be different from the current password."),{code:"AUTH_PASSWORD_UNCHANGED",statusCode:400});return await this.users.resetLocalPassword(e.userId,n.newPassword,!1),this.createSessionForIdentity(e.id,"web")}finally{this.passwordUpdates.delete(i.user.id)}}async resolve(e,t){const[n,i]=e?.split(".")||[];if(!n||!i)return;const s=await this.users.store.sessions.get(n),a=Hd();if(!s)return void this.sessionActivity.delete(n);if(s.expiresAt<=a)return void this.sessionActivity.delete(n);if(t&&s.clientType!==t||s.tokenHash!==op(i))return;let o;try{o=await this.users.authorization(s.userId)}catch{return await this.users.store.sessions.delete(s.id),void this.sessionActivity.delete(s.id)}return o.authorizationRevision!==s.authorizationRevision?(await this.users.store.sessions.delete(s.id),void this.sessionActivity.delete(s.id)):(this.trackSessionActivity(s,a),{session:{...s,lastSeenAt:a},user:await this.users.detail(s.userId),authorization:ql.parse({...o,identityId:s.identityId}),requiresPasswordChange:!0===(await this.users.store.identities.get(s.identityId))?.requiresPasswordChange})}async currentSession(e,t="web"){const n=await this.resolve(e,t);return{authenticated:Boolean(n),user:n?.user,authorization:n?.authorization,requiresPasswordChange:!0===n?.requiresPasswordChange}}async listSessions(e,t=e){if(e!==t&&!(await this.users.authorization(e)).permissionIds.includes("users:manage"))throw Object.assign(new Error("Session management is forbidden."),{code:"CONTROL_PLANE_FORBIDDEN",statusCode:403});const n=(await this.users.store.sessions.listByUser(t)).filter(e=>e.expiresAt>Hd());return Promise.all(n.map(e=>this.publicSession(e.id)))}async listMobileSessions(e){const t=(await this.users.store.sessions.listByUser(e)).filter(e=>"mobile"===e.clientType&&e.expiresAt>Hd());return Promise.all(t.map(async e=>({...await this.publicSession(e.id),device:e.device,user:await this.users.detail(e.userId)})))}async revokeSession(e,t){const n=await this.users.store.sessions.get(t);if(!n)return this.sessionActivity.delete(t),!1;if(n.userId!==e&&!(await this.users.authorization(e)).permissionIds.includes("users:manage"))throw Object.assign(new Error("Session management is forbidden."),{code:"CONTROL_PLANE_FORBIDDEN",statusCode:403});const i=await this.users.store.sessions.delete(t);return i&&this.sessionActivity.delete(t),i}async logout(e){const t=e?.split(".")[0];return t&&(await this.users.store.sessions.delete(t),this.sessionActivity.delete(t)),{ok:!0}}async publicSession(e){const t=await this.users.store.sessions.get(e);if(!t)throw Object.assign(new Error("Session was not found."),{code:"CONTROL_PLANE_SESSION_NOT_FOUND",statusCode:404});return Pl.parse({id:t.id,userId:t.userId,identityId:t.identityId,clientType:t.clientType,createdAt:t.createdAt,expiresAt:t.expiresAt,lastSeenAt:this.sessionActivity.get(t.id)?.lastSeenAt||t.lastSeenAt||t.createdAt})}trackSessionActivity(e,t){const n=Date.parse(t);if(n>=this.nextSessionActivityPruneAt){for(const[e,t]of this.sessionActivity)Date.parse(t.expiresAt)<=n&&this.sessionActivity.delete(e);this.nextSessionActivityPruneAt=n+36e5}this.sessionActivity.set(e.id,{expiresAt:e.expiresAt,lastSeenAt:t})}}const cp=f.z.object({dialect:f.z.literal("sqlite").default("sqlite"),path:f.z.string().trim().min(1).optional()}).strict(),dp=f.z.object({dialect:f.z.literal("postgresql"),connectionString:f.z.string().trim().url(),schema:f.z.string().trim().regex(/^[a-zA-Z_][a-zA-Z0-9_]*$/).default("public")}).strict(),lp=f.z.discriminatedUnion("dialect",[cp,dp]);const pp="import_v0.0.21_auth_json",up=f.z.object({id:f.z.string().trim().min(1),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}),mp=up.extend({username:f.z.string().trim().min(1).max(80).regex(/^[a-zA-Z0-9_.@-]+$/),passwordHash:f.z.string().trim().min(1),role:f.z.enum(["viewer","operator","admin"]),lastLoginAt:f.z.string().datetime().optional()}).strip(),hp=up.extend({userId:f.z.string().trim().min(1),tokenHash:f.z.string().trim().min(1),expiresAt:f.z.string().datetime(),lastSeenAt:f.z.string().datetime().optional(),clientType:f.z.enum(["web","mobile"]).default("web"),device:Gl.optional()}).strip().refine(e=>"mobile"!==e.clientType||Boolean(e.device),{path:["device"],message:"Mobile sessions require device metadata."}),gp=up.extend({subject:f.z.object({type:f.z.literal("local-user"),userId:f.z.string().trim().min(1)}).strip(),role:f.z.enum(["viewer","operator","admin"]),nodeScope:_l,status:f.z.enum(["active","disabled"]),authorizationRevision:f.z.number().int().positive()}).strip();function fp(e){return n.existsSync(e)?n.readdirSync(e).filter(e=>e.endsWith(".json")).sort():[]}function yp(e,i){return fp(e).map(s=>{const a=t.join(e,s);let o;try{o=JSON.parse(n.readFileSync(a,"utf8"))}catch(e){throw bp(`Cannot read ${a}: ${e instanceof Error?e.message:String(e)}`)}const r=i.safeParse(o);if(!r.success)throw bp(`Invalid v0.0.21 record ${a}: ${f.z.prettifyError(r.error)}`);if(s!==`${r.data.id}.json`)throw bp(`Legacy record filename does not match id: ${a}.`);return r.data})}function bp(e){return Object.assign(new Error(e),{code:"CONTROL_PLANE_LEGACY_AUTH_IMPORT_FAILED",recovery:"Fix or restore the v0.0.21 auth JSON files, then restart. The source files were not modified."})}function vp(e){return`identity_legacy_${i.createHash("sha256").update(e).digest("hex").slice(0,20)}`}function Ip(e){return fp(e.authUsersDir).length>0||fp(e.authSessionsDir).length>0||fp(e.authMembershipsDir).length>0}const xp="role_admin",wp=yl.filter(e=>e.endsWith(":read")),Sp=["users:","roles:","identity-providers:","settings:","secrets:","chat-bridges:"],Ap=yl.filter(e=>!Sp.some(t=>e.startsWith(t)));function Ep(e,t,n){const i=Hd();return{id:e,name:t,system:!0,status:"active",permissionIds:[...n],createdAt:i,updatedAt:i}}class _p{repositoryValue;stateValue;paths;database;constructor(e,t={}){this.paths=e,this.database=t.database}get users(){return this.repository().users}get identities(){return this.repository().identities}get roles(){return this.repository().roles}get grants(){return this.repository().grants}get sessions(){return this.repository().sessions}get providers(){return this.repository().providers}get approvals(){return this.repository().approvals}get audit(){return this.repository().audit}async init(){if(this.repositoryValue)return this.state();this.repositoryValue=await async function(e,n){const i=function(e,n){const i=n?.dialect||process.env.TASK_HANDOFF_CONTROL_PLANE_DATABASE_DIALECT||"sqlite";if("postgresql"===i)return lp.parse(n||{dialect:i,connectionString:process.env.TASK_HANDOFF_CONTROL_PLANE_DATABASE_URL,schema:process.env.TASK_HANDOFF_CONTROL_PLANE_DATABASE_SCHEMA});if("sqlite"!==i)throw Object.assign(new Error(`Unsupported Control Plane database dialect: ${i}.`),{code:"CONTROL_PLANE_DATABASE_DIALECT_UNSUPPORTED"});const s=cp.parse(n||{dialect:"sqlite",path:process.env.TASK_HANDOFF_CONTROL_PLANE_SQLITE_PATH});return{...s,path:t.resolve(s.path||e.databasePath)}}(e,n);if("postgresql"===i.dialect){const{createPostgresqlUserRepository:e}=await Promise.resolve().then(function(){return dA});return e(i)}const{createSqliteUserRepository:s}=await Promise.resolve().then(function(){return NA});return s(i.path)}(this.paths,this.database);try{Ip(this.paths)&&await this.repositoryValue.transaction(async e=>{await this.ensureSystemRoles(e),await async function(e,t){const n=yp(t.authUsersDir,mp),s=yp(t.authSessionsDir,hp),a=yp(t.authMembershipsDir,gp),o=function(e,t,n){return i.createHash("sha256").update(JSON.stringify({users:e,sessions:t,memberships:n})).digest("hex")}(n,s,a),r=await e.migration(pp);if(r){if(r.checksum!==o)throw bp("Legacy auth JSON changed after it was imported.");return{imported:!1,users:Number(r.details.users||0),sessions:Number(r.details.sessions||0),memberships:Number(r.details.memberships||0)}}const c=new Set(n.map(e=>e.id));if(c.size!==n.length)throw bp("Legacy auth data contains duplicate user ids.");const d=n.map(e=>ep(e.username));if(new Set(d).size!==d.length)throw bp("Legacy auth data contains usernames that collide after normalization.");const l=new Map;for(const e of a){const t=e.subject.userId;if(!c.has(t))throw bp(`Legacy membership ${e.id} references missing user ${t}.`);if(l.has(t))throw bp(`Legacy auth data contains multiple memberships for user ${t}.`);l.set(t,e)}const p=s.map(e=>e.tokenHash);if(new Set(p).size!==p.length)throw bp("Legacy auth data contains duplicate session token hashes.");for(const e of s)if(!c.has(e.userId))throw bp(`Legacy session ${e.id} references missing user ${e.userId}.`);if((await Promise.all([e.users.list(),e.identities.list(),e.grants.list(),e.sessions.list()])).some(e=>e.length>0))throw bp("The SQL user store is not empty; refusing to merge legacy auth JSON automatically.");try{await e.transaction(async e=>{for(const t of n){const n=l.get(t.id);await e.users.put({id:t.id,displayName:t.username,status:"disabled"===n?.status?"disabled":"active",lastLoginAt:t.lastLoginAt,createdAt:t.createdAt,updatedAt:t.updatedAt}),await e.identities.put({id:vp(t.id),userId:t.id,kind:"local-password",normalizedLoginName:ep(t.username),passwordHash:t.passwordHash,requiresPasswordChange:!1,lastUsedAt:t.lastLoginAt,createdAt:t.createdAt,updatedAt:t.updatedAt}),await e.grants.put({userId:t.id,roleIds:[`role_${n?.role||t.role}`],nodeScope:n?.nodeScope||{kind:"all"},instanceScope:{kind:"inherit-node-scope"},authorizationRevision:n?.authorizationRevision||1,createdAt:t.createdAt,updatedAt:t.updatedAt})}const t=(new Date).toISOString();for(const n of s.filter(e=>e.expiresAt>t)){const t=l.get(n.userId)?.authorizationRevision||1;await e.sessions.put({...n,identityId:vp(n.userId),authorizationRevision:t})}const i=n.map(e=>e.createdAt).sort()[0]||t;await e.putMetadata({schemaVersion:1,initializedAt:i}),await e.putMigration({id:pp,checksum:o,appliedAt:t,details:{sourceVersion:a.length?"v0.0.24":"v0.0.21",users:n.length,sessions:s.length,memberships:a.length}})})}catch(e){if("CONTROL_PLANE_LEGACY_AUTH_IMPORT_FAILED"===e.code)throw e;throw bp(`v0.0.21 import transaction failed: ${e instanceof Error?e.message:String(e)}`)}return{imported:!0,users:n.length,sessions:s.length,memberships:a.length}}(e,this.paths)});const e=await this.repositoryValue.metadata(),t={initialized:Boolean(e.initializedAt),legacyDataPresent:Ip(this.paths),databaseDialect:this.repositoryValue.dialect};return this.stateValue=t,t.initialized&&await this.ensureSystemRoles(),t}catch(e){throw await this.close(),e}}state(){if(!this.stateValue)throw Object.assign(new Error("Control Plane user database is not initialized."),{code:"CONTROL_PLANE_DATABASE_NOT_INITIALIZED"});return this.stateValue}async initializeForBootstrap(){await this.repository().transaction(async e=>{const t=await e.metadata();t.initializedAt||await e.putMetadata({...t,initializedAt:Hd()}),await this.ensureSystemRoles(e)}),this.stateValue={...this.state(),initialized:!0}}transaction(e){return this.repository().transaction(e)}async close(){const e=this.repositoryValue;this.repositoryValue=void 0,this.stateValue=void 0,await(e?.close())}repository(){if(!this.repositoryValue)throw Object.assign(new Error("Control Plane user database is not initialized."),{code:"CONTROL_PLANE_DATABASE_NOT_INITIALIZED"});return this.repositoryValue}async ensureSystemRoles(e=this.repository()){const t=[Ep(xp,"Admin",yl),Ep("role_operator","Operator",Ap),Ep("role_viewer","Viewer",wp)];for(const n of t){const t=await e.roles.get(n.id);await e.roles.put(t?{...n,createdAt:t.createdAt,updatedAt:t.permissionIds.join("\0")===n.permissionIds.join("\0")?t.updatedAt:n.updatedAt}:n)}}}const Tp=Rl,zp=f.z.string().min(8).max(4096),kp=_l,Np=Tl,Cp=f.z.object({username:Tp,password:zp,displayName:f.z.string().trim().min(1).max(160).optional()}).strict(),Rp=Cp.extend({roleIds:f.z.array(f.z.string().trim().min(1)).min(1).max(100),nodeScope:kp,instanceScope:Np.optional(),requirePasswordChange:f.z.boolean().optional()}).strict(),Op=f.z.object({roleIds:f.z.array(f.z.string().trim().min(1)).min(1).max(100),nodeScope:kp,instanceScope:Np.optional(),expectedAuthorizationRevision:f.z.number().int().positive()}).strict(),jp=f.z.object({name:f.z.string().trim().min(1).max(120),description:f.z.string().trim().max(500).optional(),permissionIds:f.z.array(bl).min(1)}).strict(),Pp=f.z.object({name:f.z.string().trim().min(1).max(120).optional(),description:f.z.string().trim().max(500).optional(),permissionIds:f.z.array(bl).min(1).optional()}).strict().refine(e=>Object.values(e).some(e=>void 0!==e),{message:"At least one role field must be updated."}),Dp=f.z.object({username:Tp,password:zp,userId:f.z.string().trim().min(1).optional(),targetUsername:Tp.optional()}).strict().refine(e=>!(e.userId&&e.targetUsername),{message:"Select an account by either userId or targetUsername, not both."}),Lp=f.z.object({displayName:f.z.string().trim().min(1).max(160).optional(),roleIds:f.z.array(f.z.string().trim().min(1)).min(1).max(100),nodeScope:kp,instanceScope:Np.optional()}).strict();function Mp(e,t){return Object.assign(new Error(t),{code:e,statusCode:409})}function qp(e){return Object.assign(new Error(`${e} was not found.`),{code:`CONTROL_PLANE_${e.toUpperCase()}_NOT_FOUND`,statusCode:404})}function Up(e){return"all"===e.kind?{kind:"all"}:{kind:"selected",nodeIds:[...new Set(e.nodeIds.map(e=>e.trim()).filter(Boolean))].sort()}}function $p(e){return"inherit-node-scope"===e.kind?{kind:"inherit-node-scope"}:{kind:"selected",instanceIds:[...new Set(e.instanceIds.map(e=>e.trim()).filter(Boolean))].sort()}}class Bp{store;bootstrapInProgress=!1;initPromise;constructor(e,t={}){this.store=new _p(e,t)}init(){return this.initPromise||(this.initPromise=this.store.init().catch(e=>{throw this.initPromise=void 0,e})),this.initPromise}async state(){const e=this.store.state();return{...e,requiresBootstrap:!e.initialized||0===(await this.store.users.list()).length}}async bootstrapAdmin(e){if(await this.init(),this.bootstrapInProgress)throw Mp("AUTH_BOOTSTRAP_IN_PROGRESS","Control Plane admin initialization is already in progress.");const t=Cp.parse(e);if(this.store.state().initialized&&(await this.store.users.list()).length>0)throw Mp("AUTH_BOOTSTRAP_ALREADY_DONE","Control Plane user store is already initialized.");let n,i;this.bootstrapInProgress=!0;try{await this.store.initializeForBootstrap();const e=await this.createLocalUserInternal({...t,roleIds:[xp],nodeScope:{kind:"all"},instanceScope:{kind:"inherit-node-scope"}});return n=e.user.id,i=e.identity.id,await this.detail(e.user.id)}catch(e){throw n&&(await this.store.grants.delete(n),await this.store.users.delete(n)),i&&await this.store.identities.delete(i),e}finally{this.bootstrapInProgress=!1}}async list(e={}){const t=e.search?.trim().toLocaleLowerCase("en-US"),[n,i]=await Promise.all([this.store.users.list(),this.store.identities.list()]),s=new Map(i.filter(e=>"local-password"===e.kind).map(e=>[e.userId,e]));return n.filter(t=>e.includeArchived||"archived"!==t.status).filter(e=>!t||e.displayName.toLocaleLowerCase("en-US").includes(t)||s.get(e.id)?.normalizedLoginName?.includes(t)).sort((e,t)=>e.displayName.localeCompare(t.displayName)).map(e=>this.publicUser(e,s.get(e.id)))}async detail(e){const t=await this.requireUser(e),[n,i]=await Promise.all([this.store.identities.listByUser(e),this.store.grants.get(e)]);if(!i)throw Mp("CONTROL_PLANE_USER_ACCESS_REQUIRED","User has no access grant.");const s=n.map(e=>this.publicIdentity(e));return Ml.parse({...this.publicUser(t,n.find(e=>"local-password"===e.kind)),identities:s,accessGrant:{userId:i.userId,roleIds:i.roleIds,nodeScope:i.nodeScope,instanceScope:i.instanceScope,authorizationRevision:i.authorizationRevision,updatedAt:i.updatedAt}})}async createLocalUser(e){const t=Rp.parse(e),n=await this.createLocalUserInternal(t);return this.detail(n.user.id)}async updateUser(e,t){const n=Ol.parse(t);return await this.store.transaction(async t=>{const i=await this.requireUser(e,t),s=Hd();if(void 0!==n.username){const i=await this.localIdentity(e,t);if(!i)throw qp("identity");const a=ep(n.username),o=await t.identities.findByLoginName(a);if(o&&o.id!==i.id)throw Mp("CONTROL_PLANE_USERNAME_CONFLICT","A Control Plane user already uses that username.");await t.identities.put({...i,normalizedLoginName:a,updatedAt:s})}const a={...i,...void 0===n.displayName?{}:{displayName:n.displayName},...void 0===n.status?{}:{status:n.status,archivedAt:"archived"===n.status?Hd():void 0},updatedAt:s};await this.assertLoginCapableAdminRemains(t,{userStatus:{userId:e,status:a.status}}),await t.users.put(a),void 0!==n.status&&n.status!==i.status&&await this.bumpAuthorizationRevisionIn(t,e)}),this.detail(e)}async setAccess(e,t){const n=Op.parse(t);return await this.store.transaction(async t=>{await this.requireUser(e,t);const i=await t.grants.get(e);if(!i)throw Mp("CONTROL_PLANE_USER_ACCESS_REQUIRED","User has no access grant.");if(i.authorizationRevision!==n.expectedAuthorizationRevision)throw Mp("CONTROL_PLANE_AUTHORIZATION_REVISION_CONFLICT","User authorization changed before this update was applied.");await this.assertActiveRoles(n.roleIds,t),await this.assertLoginCapableAdminRemains(t,{roleIds:{userId:e,roleIds:n.roleIds}}),await t.grants.put({...i,roleIds:[...new Set(n.roleIds)].sort(),nodeScope:Up(n.nodeScope),instanceScope:n.instanceScope?$p(n.instanceScope):i.instanceScope,authorizationRevision:i.authorizationRevision+1,updatedAt:Hd()}),await this.revokeSessionsIn(t,e)}),this.detail(e)}async authorization(e,t){const n=t||this.store;if("active"!==(await this.requireUser(e,t)).status)throw Object.assign(new Error("User is not active."),{code:"CONTROL_PLANE_USER_DISABLED",statusCode:403});const i=await n.grants.get(e);if(!i)throw Mp("CONTROL_PLANE_USER_ACCESS_REQUIRED","User has no access grant.");const s=(await Promise.all(i.roleIds.map(e=>n.roles.get(e)))).filter(e=>Boolean(e&&"active"===e.status));if(s.length!==i.roleIds.length)throw Mp("CONTROL_PLANE_ROLE_INACTIVE","User access references an unavailable role.");const a=[...new Set(s.flatMap(e=>e.permissionIds))].sort();return{userId:e,roleIds:i.roleIds,permissionIds:a,nodeScope:i.nodeScope,instanceScope:i.instanceScope,authorizationRevision:i.authorizationRevision}}async resetLocalPassword(e,t,n=!0){zp.parse(t);const i=await tp(t);let s="";return await this.store.transaction(async t=>{await this.requireUser(e,t);const a=await this.localIdentity(e,t);if(!a)throw qp("identity");s=a.id,await t.identities.put({...a,passwordHash:i,requiresPasswordChange:n,updatedAt:Hd()}),await this.bumpAuthorizationRevisionIn(t,e)}),this.publicIdentity(await this.store.identities.get(s))}async recoverLocalCredentials(e){const t=Dp.parse(e),n=ep(t.username),i=await tp(t.password);let s="";return await this.store.transaction(async e=>{const a=await e.users.list(),o=t.userId?a.find(e=>e.id===t.userId):t.targetUsername?(await Promise.all(a.map(async t=>({user:t,identity:await this.localIdentity(t.id,e)})))).find(({identity:e})=>e?.normalizedLoginName===ep(t.targetUsername))?.user:1===a.length?a[0]:void 0;if(!o&&(t.userId||t.targetUsername))throw qp("user");if(!o)throw Mp("AUTH_ACCOUNT_AMBIGUOUS","The account to recover is ambiguous.");const r=await e.identities.findByLoginName(n);if(r&&r.userId!==o.id)throw Mp("CONTROL_PLANE_USERNAME_CONFLICT","A Control Plane user already uses that username.");const c=await this.localIdentity(o.id,e);if(!c)throw qp("identity");s=o.id,await e.identities.put({...c,normalizedLoginName:n,passwordHash:i,requiresPasswordChange:!1,updatedAt:Hd()}),await this.bumpAuthorizationRevisionIn(e,o.id)}),this.detail(s)}async unbindExternalIdentity(e,t){return await this.store.transaction(async n=>{const i=await this.requireUser(e,n),s=await n.identities.get(t);if(!s||s.userId!==e)throw qp("identity");if("local-password"===s.kind)throw Mp("CONTROL_PLANE_LOCAL_IDENTITY_IMMUTABLE","Local password identities cannot be unbound.");const a={removedIdentityId:t};if(await this.assertLoginCapableAdminRemains(n,a),"active"===i.status&&!await this.hasLoginCapableIdentity(e,n,a))throw Mp("CONTROL_PLANE_LAST_LOGIN_IDENTITY","An active user must retain at least one login identity.");await n.identities.delete(t),await this.bumpAuthorizationRevisionIn(n,e)}),{unbound:!0}}async approveExternalIdentity(e,t,n){if(!(await this.authorization(e)).permissionIds.includes("users:manage"))throw Object.assign(new Error("User management is forbidden."),{code:"CONTROL_PLANE_FORBIDDEN",statusCode:403});const i=Lp.parse(n);await this.assertActiveRoles(i.roleIds);const s=await this.store.approvals.get(t);if(!s||"pending"!==s.status||s.expiresAt<=Hd())throw Mp("CONTROL_PLANE_EXTERNAL_IDENTITY_APPROVAL_INVALID","External identity approval is invalid or expired.");const a=await this.store.providers.get(s.providerId);if(!a||"enabled"!==a.status)throw qp("identity_provider");if(await this.store.identities.findByProviderSubject(s.providerId,s.subject))throw Mp("CONTROL_PLANE_EXTERNAL_IDENTITY_CONFLICT","External identity is already bound to a user.");const o=Hd(),r={id:Xd("user"),displayName:i.displayName||s.displayName||s.verifiedEmail||"External user",status:"active",createdAt:o,updatedAt:o},c={id:Xd("identity"),userId:r.id,kind:"oidc"===a.kind?"oidc":"oauth",providerId:a.id,subject:s.subject,verifiedEmail:s.verifiedEmail,createdAt:o,updatedAt:o};return await this.store.transaction(async n=>{const a=await n.approvals.get(t);if(!a||"pending"!==a.status||a.expiresAt<=Hd())throw Mp("CONTROL_PLANE_EXTERNAL_IDENTITY_APPROVAL_INVALID","External identity approval is invalid or expired.");if(await n.identities.findByProviderSubject(s.providerId,s.subject))throw Mp("CONTROL_PLANE_EXTERNAL_IDENTITY_CONFLICT","External identity is already bound to a user.");await this.assertActiveRoles(i.roleIds,n),await n.users.put(r),await n.identities.put(c),await n.grants.put({userId:r.id,roleIds:[...new Set(i.roleIds)].sort(),nodeScope:Up(i.nodeScope),instanceScope:$p(i.instanceScope||{kind:"inherit-node-scope"}),authorizationRevision:1,createdAt:o,updatedAt:o}),await n.approvals.put({...a,status:"approved",decidedAt:o,decidedByUserId:e,updatedAt:o})}),this.detail(r.id)}async rejectExternalIdentity(e,t){if(!(await this.authorization(e)).permissionIds.includes("users:manage"))throw Object.assign(new Error("User management is forbidden."),{code:"CONTROL_PLANE_FORBIDDEN",statusCode:403});const n=Hd();return await this.store.transaction(async i=>{const s=await i.approvals.get(t);if(!s||"pending"!==s.status)throw qp("external_identity_approval");await i.approvals.put({...s,status:"rejected",decidedAt:n,decidedByUserId:e,updatedAt:n})}),{rejected:!0}}async createRole(e){const t=jp.parse(e),n=Hd();return this.store.transaction(async e=>{if((await e.roles.list()).some(e=>e.name.toLocaleLowerCase("en-US")===t.name.toLocaleLowerCase("en-US")&&"active"===e.status))throw Mp("CONTROL_PLANE_ROLE_NAME_CONFLICT","An active role already uses that name.");return Dl.parse(await e.roles.put({id:Xd("role"),name:t.name,description:t.description,system:!1,status:"active",permissionIds:[...new Set(t.permissionIds)].sort(),createdAt:n,updatedAt:n}))})}async updateRole(e,t){const n=Pp.parse(t),i=await this.store.transaction(async t=>{const i=await t.roles.get(e);if(!i)throw qp("role");if(i.system)throw Mp("CONTROL_PLANE_SYSTEM_ROLE_IMMUTABLE","System roles cannot be edited.");if(n.name&&(await t.roles.list()).some(t=>t.id!==e&&"active"===t.status&&t.name.toLocaleLowerCase("en-US")===n.name.toLocaleLowerCase("en-US")))throw Mp("CONTROL_PLANE_ROLE_NAME_CONFLICT","An active role already uses that name.");const s=await t.roles.put({...i,...void 0===n.name?{}:{name:n.name},...void 0===n.description?{}:{description:n.description},...void 0===n.permissionIds?{}:{permissionIds:[...new Set(n.permissionIds)].sort()},updatedAt:Hd()});for(const n of await t.grants.listByRole(e))await t.grants.put({...n,authorizationRevision:n.authorizationRevision+1,updatedAt:Hd()}),await this.revokeSessionsIn(t,n.userId);return s});return Dl.parse(i)}async archiveRole(e){return this.store.transaction(async t=>{const n=await t.roles.get(e);if(!n)throw qp("role");if(n.system)throw Mp("CONTROL_PLANE_SYSTEM_ROLE_IMMUTABLE","System roles cannot be archived.");if((await t.grants.listByRole(e)).length>0)throw Mp("CONTROL_PLANE_ROLE_IN_USE","Role is assigned to one or more users.");return Dl.parse(await t.roles.put({...n,status:"archived",updatedAt:Hd()}))})}async revokeSessions(e){return this.store.transaction(t=>this.revokeSessionsIn(t,e))}async removeInstanceFromAccessScopes(e){return this.store.transaction(async t=>{const n=[];for(const i of await t.grants.list())"selected"===i.instanceScope.kind&&i.instanceScope.instanceIds.includes(e)&&(await t.grants.put({...i,instanceScope:{kind:"selected",instanceIds:i.instanceScope.instanceIds.filter(t=>t!==e)},authorizationRevision:i.authorizationRevision+1,updatedAt:Hd()}),await this.revokeSessionsIn(t,i.userId),n.push(i.userId));return n})}async revokeSessionsIn(e,t){let n=0;for(const i of await e.sessions.listByUser(t))await e.sessions.delete(i.id)&&(n+=1);return n}async bumpAuthorizationRevisionIn(e,t){const n=await e.grants.get(t);if(!n)throw Mp("CONTROL_PLANE_USER_ACCESS_REQUIRED","User has no access grant.");await e.grants.put({...n,authorizationRevision:n.authorizationRevision+1,updatedAt:Hd()}),await this.revokeSessionsIn(e,t)}async createLocalUserInternal(e){const t=ep(e.username),n=Hd(),i={id:Xd("user"),displayName:e.displayName||e.username,status:"active",createdAt:n,updatedAt:n},s={id:Xd("identity"),userId:i.id,kind:"local-password",normalizedLoginName:t,passwordHash:await tp(e.password),requiresPasswordChange:e.requirePasswordChange||!1,createdAt:n,updatedAt:n};return this.store.transaction(async a=>{if(await a.identities.findByLoginName(t))throw Mp("CONTROL_PLANE_USERNAME_CONFLICT","A Control Plane user already uses that username.");return await this.assertActiveRoles(e.roleIds,a),await a.users.put(i),await a.identities.put(s),await a.grants.put({userId:i.id,roleIds:[...new Set(e.roleIds)].sort(),nodeScope:Up(e.nodeScope),instanceScope:$p(e.instanceScope||{kind:"inherit-node-scope"}),authorizationRevision:1,createdAt:n,updatedAt:n}),{user:i,identity:s}})}async requireUser(e,t){const n=await(t?.users||this.store.users).get(e);if(!n)throw qp("user");return n}async localIdentity(e,t){return(await(t?.identities||this.store.identities).listByUser(e)).find(e=>"local-password"===e.kind)}publicUser(e,t){return Cl.parse({id:e.id,displayName:e.displayName,primaryUsername:t?.normalizedLoginName,status:e.status,createdAt:e.createdAt,updatedAt:e.updatedAt,lastLoginAt:e.lastLoginAt})}publicIdentity(e){return jl.parse({id:e.id,userId:e.userId,kind:e.kind,providerId:e.providerId,loginName:e.normalizedLoginName,subject:e.subject,verifiedEmail:e.verifiedEmail,requiresPasswordChange:e.requiresPasswordChange,createdAt:e.createdAt,updatedAt:e.updatedAt,lastUsedAt:e.lastUsedAt})}async assertActiveRoles(e,t){const n=[...new Set(e)];if(n.length!==e.length)throw Mp("CONTROL_PLANE_ROLE_DUPLICATE","Role assignments must be unique.");for(const e of n){const n=await(t?.roles||this.store.roles).get(e);if(!n||"active"!==n.status)throw qp("role")}}async assertProviderStatusChangeAllowed(e,t,n){"enabled"!==t&&await this.assertLoginCapableAdminRemains(n||this.store,{providerStatus:{providerId:e,status:t}})}async assertLoginCapableAdminRemains(e,t={}){let n=!1;for(const i of await e.users.list()){if("active"!==(t.userStatus?.userId===i.id?t.userStatus.status:i.status))continue;const s=await e.grants.get(i.id),a=t.roleIds?.userId===i.id?t.roleIds.roleIds:s?.roleIds;if(!0===a?.includes(xp)&&await this.hasLoginCapableIdentity(i.id,e,t)){n=!0;break}}if(!n)throw Mp("CONTROL_PLANE_LAST_ACTIVE_ADMIN","At least one active login-capable Admin must remain.")}async hasLoginCapableIdentity(e,t,n){for(const i of await t.identities.listByUser(e)){if(i.id===n.removedIdentityId)continue;if("local-password"===i.kind)return!0;const e=await t.providers.get(i.providerId||"");if("enabled"===(n.providerStatus?.providerId===e?.id?n.providerStatus.status:e?.status))return!0}return!1}async roleSummaries(){return(await this.store.roles.list()).map(e=>Dl.parse(e))}}const Fp="task_handoff_cp_session",Hp=f.z.enum(["disabled","password"]);class Gp{mode;users;sessions;identityProviders;external;onUserAuthorizationChanged;constructor(e,t={}){this.mode=Hp.parse(t.mode||process.env.TASK_HANDOFF_CONTROL_PLANE_AUTH_MODE||"disabled"),this.users=new Bp(e,{database:t.database}),this.sessions=new rp(this.users,t.loginRateLimit),this.identityProviders=new Ql(e,this.users),this.external=new ll(this.users,this.sessions,this.identityProviders),this.onUserAuthorizationChanged=t.onUserAuthorizationChanged}async init(){this.enabled()&&(await this.users.init(),this.identityProviders.init())}close(){return this.users.store.close()}enabled(){return"password"===this.mode}async state(){return this.enabled()?{mode:this.mode,enabled:!0,requiresBootstrap:(await this.users.state()).requiresBootstrap}:{mode:this.mode,enabled:!1,requiresBootstrap:!1}}async bootstrapAdmin(e){return this.assertEnabled(),this.users.bootstrapAdmin(e)}async login(e,t={}){return this.assertEnabled(),this.sessions.loginLocal(e,{sourceId:t.sourceId,clientType:"web"})}async loginMobile(e,t={}){this.assertEnabled();const n=f.z.object({username:f.z.string().trim().min(1).max(80),password:f.z.string().min(1).max(4096),device:f.z.custom()}).strict().parse(e),i=await this.sessions.loginLocal({username:n.username,password:n.password},{sourceId:t.sourceId,clientType:"mobile",device:n.device});return{sessionToken:i.sessionToken,session:{...i.session,device:n.device,user:i.user},authorization:i.authorization}}changePassword(e,t){return this.sessions.changeLocalPassword(e,t)}async currentSession(e,t="web"){const n=this.enabled()?await this.sessions.currentSession(e,t):{authenticated:!0};return{...await this.state(),...n}}async currentAccess(e,t){return(await this.sessions.resolve(e,t))?.authorization}async authorizationForSessionToken(e,t){const n=await this.sessions.resolve(e,t);if(n)return{type:"user",userId:n.authorization.userId,identityId:n.authorization.identityId,roleIds:n.authorization.roleIds,permissionIds:n.authorization.permissionIds,nodeScope:n.authorization.nodeScope,instanceScope:n.authorization.instanceScope,authorizationRevision:n.authorization.authorizationRevision,requiresPasswordChange:n.requiresPasswordChange}}logout(e){return this.sessions.logout(e)}async mobileSessions(e){const t=await this.sessions.resolve(e);return t?this.sessions.listMobileSessions(t.user.id):void 0}async revokeMobileSession(e,t){const n=await this.sessions.resolve(e);return n?this.sessions.revokeSession(n.user.id,t):void 0}async assertAppAccessAuthorization(e){const t=await this.users.authorization(e.userId);if(t.authorizationRevision!==e.authorizationRevision)throw Object.assign(new Error("The app access authorization has changed."),{code:"CONTROL_PLANE_AUTHORIZATION_REVISION_CONFLICT",statusCode:401});Bd({...t},"interactive-access",{type:"app-session"},{kind:"instance-derived",instanceId:e.instanceId,nodeId:e.nodeId})}async notifyAuthorizationChanged(e){const[t,n]=await Promise.all([this.users.store.users.get(e),this.users.store.grants.get(e)]);t&&n&&this.onUserAuthorizationChanged?.({userId:e,authorizationRevision:n.authorizationRevision,status:t.status})}assertEnabled(){if(!this.enabled())throw Object.assign(new Error("Control Plane authentication is disabled."),{code:"AUTH_DISABLED",statusCode:400})}}const Wp=f.z.enum(["import","export"]),Vp=f.z.object({id:f.z.string().trim().min(1).max(120),label:f.z.string().trim().min(1).max(120),directoryName:f.z.string().trim().min(1).max(120)}).strict(),Kp=f.z.object({direction:Wp,programIds:f.z.array(f.z.string().trim().min(1).max(120)).min(1).max(20).refine(e=>new Set(e).size===e.length,"Config sync program ids must be unique."),workspaceFolder:f.z.string().trim().min(1).max(1e3)}).strict(),Yp=f.z.object({import:f.z.string().trim().min(1).max(1e3).default("."),export:f.z.string().trim().min(1).max(1e3).default(".")}).strict(),Xp=f.z.object({programs:f.z.array(Vp),preferences:Yp}).strict(),Jp=f.z.object({id:f.z.string().trim().min(1).max(120),type:f.z.enum(["file","dir"]),projectPath:f.z.string().trim().min(1).max(1e3),containerPath:f.z.string().trim().min(1).max(1e3),source:f.z.string().trim().min(1).max(4096),target:f.z.string().trim().min(1).max(4096),status:f.z.enum(["copied","skipped_missing_source","failed"]),error:f.z.string().trim().max(4096).optional()}).strict(),Qp=f.z.object({preset:f.z.object({id:f.z.string().trim().min(1).max(120),label:f.z.string().trim().min(1).max(120),projectRoot:f.z.string().trim().min(1).max(1e3)}).strict(),direction:Wp,items:f.z.array(Jp).max(100)}).strict(),Zp=f.z.object({direction:Wp,workspaceFolder:f.z.string().trim().min(1).max(1e3),programs:f.z.array(Qp).min(1).max(20)}).strict(),eu="x-task-handoff-trace-id";function tu(e,t){return`${e};dur=${(Number.isFinite(t)?Math.max(0,t):0).toFixed(1)}`}function nu(...e){return e.map(e=>String(e||"").trim()).filter(Boolean).join(", ")}const iu=f.z.string().trim().min(1).max(160).regex(/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/),su=f.z.string().datetime(),au=f.z.string().trim().min(1).max(255).refine(e=>!(/[\u0000-\u001f\u007f ~^:?*[\\]/.test(e)||e.includes("..")||e.endsWith(".")||e.endsWith("/")),"Invalid Git name."),ou=f.z.string().min(1).max(4096).refine(e=>!(e.includes("\0")||e.startsWith("/")||e.startsWith("\\")||/^[a-zA-Z]:[\\/]/.test(e))&&e.split("/").every(e=>e.length>0&&"."!==e&&".."!==e&&".git"!==e),"Path must be a safe repository-relative path."),ru=f.z.enum(["ai-session","app-session"]),cu=f.z.enum(["available","session-not-found","session-inactive","cwd-missing","cwd-inaccessible","git-unavailable","not-worktree"]),du=f.z.enum(["branch","detached","unborn"]),lu=f.z.enum(["review-changes","resolve-conflicts","publish-branch","push","pull","diverged","up-to-date"]),pu=f.z.enum(["conflict","staged","unstaged","untracked"]),uu=f.z.enum(["added","modified","deleted","renamed","copied","type-changed","unmerged","untracked"]),mu=f.z.object({state:du,oid:f.z.string().regex(/^[0-9a-f]{40,64}$/).optional(),branch:f.z.string().min(1).max(1024).optional()}).strict(),hu=f.z.object({ref:f.z.string().min(1).max(2048),remote:au,branch:f.z.string().min(1).max(1024),ahead:f.z.number().int().nonnegative(),behind:f.z.number().int().nonnegative()}).strict(),gu=f.z.object({id:iu,isCurrent:f.z.boolean(),isMain:f.z.boolean(),managed:f.z.boolean(),head:mu,dirty:f.z.boolean(),locked:f.z.boolean(),lockReason:f.z.string().max(1e3).optional(),prunable:f.z.boolean(),activeAiSessionIds:f.z.array(iu).max(256).default([]),activeAppSessionIds:f.z.array(iu).max(256).default([])}).strict(),fu=f.z.enum(["main-worktree","external-worktree","outside-workspace-roots","dirty","locked","prunable","session-occupied","path-inaccessible"]),yu=gu.extend({canCreateAiSession:f.z.boolean(),canRemove:f.z.boolean(),createAiSessionBlockers:f.z.array(fu).max(16).default([]),removeBlockers:f.z.array(fu).max(16).default([])}).strict(),bu=f.z.object({repositoryId:iu,repositoryContextId:iu,snapshotId:iu,items:f.z.array(yu).max(1e4)}).strict(),vu=f.z.object({conflicts:f.z.number().int().nonnegative(),staged:f.z.number().int().nonnegative(),unstaged:f.z.number().int().nonnegative(),untracked:f.z.number().int().nonnegative()}).strict(),Iu=f.z.object({name:au,fetchUrl:f.z.string().max(4096).optional(),pushUrl:f.z.string().max(4096).optional()}).strict(),xu=f.z.object({availability:cu,sessionKind:ru,sessionId:iu,observedAt:su,snapshotId:iu.optional(),repositoryId:iu.optional(),repositoryContextId:iu.optional(),repositoryRoot:f.z.string().min(1).max(4096).optional(),displayName:f.z.string().trim().min(1).max(255).optional(),cwdRelativePath:f.z.string().max(4096).optional(),head:mu.optional(),upstream:hu.optional(),currentWorktree:gu.optional(),changes:vu.optional(),remotes:f.z.array(Iu).max(128).optional(),primaryAction:lu.optional()}).strict(),wu=f.z.enum(["directory","file","symlink","submodule","nested-repository","special"]),Su=f.z.object({executable:f.z.boolean(),gitMode:f.z.enum(["100644","100755","120000","160000"]).optional()}).strict(),Au=f.z.object({name:f.z.string().min(1).max(1024),path:ou,kind:wu,traversable:f.z.boolean(),editable:f.z.boolean(),size:f.z.number().int().nonnegative().optional(),mode:Su.optional()}).strict();f.z.object({path:f.z.string().max(4096),entries:f.z.array(Au).max(1e4),snapshotId:iu}).strict();const Eu=f.z.string().min(16).max(160).regex(/^[a-zA-Z0-9_.:-]+$/),_u=f.z.object({path:ou,content:f.z.string(),byteLength:f.z.number().int().nonnegative(),version:Eu,mode:Su}).strict(),Tu=f.z.object({path:ou,oldPath:ou.optional(),scope:pu,status:uu,version:Eu,binary:f.z.boolean().default(!1)}).strict(),zu=f.z.object({snapshotId:iu,summary:vu,entries:f.z.array(Tu).max(1e5)}).strict();f.z.object({file:_u.optional(),snapshotId:iu,context:xu,changes:zu}).strict();const ku=f.z.object({kind:f.z.enum(["metadata","hunk","context","addition","deletion"]),content:f.z.string(),oldLine:f.z.number().int().positive().optional(),newLine:f.z.number().int().positive().optional(),oldStart:f.z.number().int().nonnegative().optional(),oldCount:f.z.number().int().nonnegative().optional(),newStart:f.z.number().int().nonnegative().optional(),newCount:f.z.number().int().nonnegative().optional(),heading:f.z.string().optional(),hunkId:f.z.string().min(1).max(200).optional()}).strict();f.z.object({path:ou,oldPath:ou.optional(),scope:pu,binary:f.z.boolean(),complete:f.z.boolean(),truncated:f.z.boolean(),byteLimit:f.z.number().int().positive(),content:f.z.string(),lines:f.z.array(ku).max(2e5),contextGaps:f.z.array(f.z.object({gapId:f.z.string().min(1).max(500),beforeHunkId:f.z.string().min(1).max(200).optional(),afterHunkId:f.z.string().min(1).max(200).optional(),lines:f.z.array(ku).max(6e3),startLineCount:f.z.number().int().nonnegative().max(3e3),hasMore:f.z.boolean()}).strict()).max(2e4),version:Eu,snapshotId:iu}).strict();const Nu=f.z.object({name:f.z.string().min(1).max(1024),oid:f.z.string().regex(/^[0-9a-f]{40,64}$/),kind:f.z.enum(["local","remote-tracking"]),current:f.z.boolean(),upstream:f.z.string().min(1).max(2048).optional(),ahead:f.z.number().int().nonnegative().optional(),behind:f.z.number().int().nonnegative().optional(),checkedOutWorktreeIds:f.z.array(iu).max(256).default([])}).strict(),Cu=f.z.object({snapshotId:iu,branches:f.z.array(Nu).max(1e5)}).strict();f.z.object({snapshotId:iu,context:xu,branches:Cu}).strict(),f.z.object({ok:f.z.literal(!0),snapshotId:iu,context:xu,changes:zu.optional(),commitOid:f.z.string().regex(/^[0-9a-f]{40,64}$/).optional()}).strict();const Ru=f.z.enum(["REPOSITORY_REQUEST_INVALID","REPOSITORY_SESSION_NOT_FOUND","REPOSITORY_SESSION_INACTIVE","REPOSITORY_CWD_MISSING","REPOSITORY_CWD_INACCESSIBLE","REPOSITORY_GIT_UNAVAILABLE","REPOSITORY_NOT_WORKTREE","REPOSITORY_PATH_INVALID","REPOSITORY_PATH_FORBIDDEN","REPOSITORY_FILE_NOT_FOUND","REPOSITORY_FILE_EXISTS","REPOSITORY_FILE_UNSUPPORTED","REPOSITORY_FILE_TOO_LARGE","REPOSITORY_FILE_BINARY","REPOSITORY_FILE_STALE","REPOSITORY_STATE_STALE","REPOSITORY_WORKTREE_NOT_FOUND","REPOSITORY_WORKTREE_OCCUPIED","REPOSITORY_WORKTREE_UNSAFE","REPOSITORY_BRANCH_INVALID","REPOSITORY_BRANCH_OCCUPIED","REPOSITORY_BRANCH_UNMERGED","REPOSITORY_CONFLICT","REPOSITORY_DIRTY","REPOSITORY_NOTHING_TO_COMMIT","REPOSITORY_IDENTITY_MISSING","REPOSITORY_HOOK_FAILED","REPOSITORY_SIGNING_FAILED","REPOSITORY_AUTHENTICATION_FAILED","REPOSITORY_CREDENTIAL_MISSING","REPOSITORY_CREDENTIAL_AMBIGUOUS","REPOSITORY_REMOTE_UNSUPPORTED","REPOSITORY_HOST_KEY_REQUIRED","REPOSITORY_AUTHENTICATION_REJECTED","REPOSITORY_NON_FAST_FORWARD","REPOSITORY_UPSTREAM_MISSING","REPOSITORY_COMMAND_TIMEOUT","REPOSITORY_OUTPUT_LIMIT","REPOSITORY_OPERATION_ABORTED","REPOSITORY_OPERATION_FAILED"]);f.z.object({ok:f.z.literal(!1),error:f.z.object({code:Ru,message:f.z.string().trim().min(1).max(2e3),retryable:f.z.boolean(),details:f.z.record(f.z.string(),f.z.union([f.z.string(),f.z.number(),f.z.boolean()])).optional()}).strict()}).strict();const Ou=f.z.object({expectedSnapshotId:iu}).strict(),ju=f.z.object({path:ou,expectedVersion:Eu}).strict();f.z.object({path:ou,content:f.z.string().max(4194304),expectedAbsent:f.z.literal(!0),expectedSnapshotId:iu}).strict(),f.z.object({path:ou,content:f.z.string().max(4194304),expectedVersion:Eu,expectedSnapshotId:iu}).strict(),f.z.object({path:ou,destination:ou,expectedVersion:Eu,expectedDestinationAbsent:f.z.literal(!0),expectedSnapshotId:iu}).strict(),f.z.object({path:ou,expectedVersion:Eu,expectedSnapshotId:iu,confirm:f.z.literal(!0)}).strict(),Ou.extend({paths:f.z.array(ju).min(1).max(1e3)}).strict(),Ou.extend({paths:f.z.array(ju).min(1).max(1e3)}).strict(),Ou.extend({paths:f.z.array(ju).min(1).max(1e3),confirm:f.z.literal(!0)}).strict(),Ou.extend({paths:f.z.array(ju).min(1).max(1e3),confirm:f.z.literal(!0)}).strict(),Ou.extend({message:f.z.string().trim().min(1).max(65536)}).strict();const Pu=f.z.discriminatedUnion("mode",[f.z.object({mode:f.z.literal("new-branch"),branchName:au,startRef:f.z.string().trim().min(1).max(2048),expectedSnapshotId:iu}).strict(),f.z.object({mode:f.z.literal("existing-branch"),branchName:au,expectedSnapshotId:iu}).strict()]);Ou.extend({worktreeId:iu,confirm:f.z.literal(!0)}).strict(),f.z.object({worktreeId:iu,worktrees:bu}).strict(),f.z.object({removedWorktreeId:iu,branchRetained:f.z.boolean(),worktrees:bu}).strict();const Du=f.z.discriminatedUnion("type",[f.z.object({type:f.z.literal("current")}).strict(),f.z.object({type:f.z.literal("worktree"),repositoryContextId:iu,worktreeId:iu}).strict()]);f.z.object({agent:f.z.enum(["codex","claude","opencode"]),workspaceSelection:Du,message:f.z.string().trim().min(1).max(2e4),clientRequestId:iu,permissionMode:f.z.enum(["ask","auto-review","full-access"]).optional()}).strict(),f.z.object({agent:f.z.enum(["codex","claude","opencode"]),worktree:Pu,message:f.z.string().trim().min(1).max(2e4),clientRequestId:iu,permissionMode:f.z.enum(["ask","auto-review","full-access"]).optional()}).strict(),f.z.object({aiSessionId:iu,providerSessionId:f.z.string().trim().min(1).max(240),worktreeId:iu,disposition:f.z.literal("started")}).strict();const Lu=f.z.object({name:f.z.string().min(1).max(1024),kind:f.z.enum(["branch","head"]).default("branch"),current:f.z.boolean(),currentFolderSelectable:f.z.boolean(),worktreeSelectable:f.z.boolean(),worktreeCheckout:f.z.enum(["attached","detached"]).default("attached"),currentFolderReason:f.z.enum(["dirty","session-occupied","branch-occupied"]).optional(),worktreeReason:f.z.enum(["current-branch","branch-occupied","worktree-unavailable"]).optional()}).strict(),Mu=f.z.object({availability:cu,currentBranch:f.z.string().min(1).max(1024).optional(),dirty:f.z.boolean().default(!1),branches:f.z.array(Lu).max(1e5).default([])}).strict();f.z.object({cwd:Ei}).strict();const qu=Ti;function Uu(e){return{id:e.id,providerTurnId:e.providerTurnId,status:e.status,phase:e.phase,revision:e.revision,startedAt:e.startedAt,updatedAt:e.updatedAt,completedAt:e.completedAt,bodyRevision:$u(e)}}function $u(e){return i.createHash("sha256").update(JSON.stringify(e)).digest("base64url").slice(0,22)}_i.extend({gitSelection:qu}).strict(),zi.extend({cwd:Ei,gitSelection:qu}).strict(),Ou.extend({name:au}).strict(),Ou.extend({branch:f.z.string().trim().min(1).max(2048)}).strict(),Ou.extend({name:au,remoteTrackingRef:f.z.string().trim().min(1).max(2048)}).strict(),Ou.extend({name:au,confirm:f.z.literal(!0)}).strict(),Ou.extend({remote:au}).strict(),Ou.extend({remote:au,sourceBranch:au,targetBranch:au,setUpstream:f.z.boolean(),confirmSetUpstream:f.z.boolean().optional()}).strict().refine(e=>!e.setUpstream||!0===e.confirmSetUpstream,{message:"Setting an upstream requires explicit confirmation.",path:["confirmSetUpstream"]}),Ou.extend({remote:au,sourceBranch:au,targetBranch:au}).strict();class Bu{options;resumeSnapshotRefreshFailures=0;lastResumeSnapshotRefreshFailure;constructor(e){this.options=e}async resolveApproval(e,t,n){return ul(Zi,await this.post(e,Gu(t,"approval"),{decision:n}))}async listHistory(e,t){const n=t?.length?`?agents=${encodeURIComponent(t.join(","))}`:"";return ul(ns,await this.get(e,`/ai-sessions/history${n}`))}async historyDetail(e,t){return ul(is,await this.get(e,`/ai-sessions/history/${encodeURIComponent(t)}`))}async detail(e,t){const n=await this.get(e,`/ai-sessions/${encodeURIComponent(t)}`),i=Vi.safeParse(n);return i.success?i.data:(s=ul(Wi,n),Vi.parse({id:s.id,appBindingKeys:s.appBindingKeys,cwd:s.cwd,error:s.error,providerMeta:s.providerMeta,queue:s.queue,subAgents:s.subAgents}));var s}async turnIndex(e,t){try{return ul(Yi,await this.get(e,`${Gu(t,"turns")}?projection=index`))}catch(n){if(!Wu(n))throw n;const i=await this.legacyStatus(e,t);return Yi.parse({sessionId:i.id,revision:`legacy:${i.updatedAt}`,turns:(i.turns||[]).filter(e=>e.userPrompt?.trim()||e.lastMessage?.trim()||e.summary?.trim()||e.contextCompactions?.length).map(Uu)})}}async turnBody(e,t,n){try{return ul(Xi,await this.get(e,`${Gu(t,"turns")}/${encodeURIComponent(n)}`))}catch(i){if(!Wu(i))throw i;const s=await this.legacyStatus(e,t),a=(s.turns||[]).find(e=>e.id===n||e.providerTurnId===n);if(!a)throw new Error(`AI session Turn ${n} was not found.`);return Xi.parse({sessionId:s.id,revision:$u(a),turn:a})}}async legacyStatus(e,t){return ul(Wi,await this.get(e,`/ai-sessions/${encodeURIComponent(t)}`))}async timeline(e,t){const n=await this.options.requireInstance(e);if(!function(e){return Oo(e.capabilities,"session-read").length>0}(n))throw function(){const e=new Error("The controlled instance does not support AI session Timeline reads.");return Object.assign(e,{statusCode:409,code:"AI_SESSION_TIMELINE_UNSUPPORTED"}),e}();return ul(Jn,await this.options.request(n,Gu(t,"timeline"),{method:"GET"}))}async turnTimeline(e,t,n){const i=await this.options.requireInstance(e);if(!function(e){return Oo(e.capabilities,"turn-read").length>0}(i))throw function(){const e=new Error("The controlled instance does not support per-turn AI session Timeline reads.");return Object.assign(e,{statusCode:409,code:"AI_SESSION_TURN_TIMELINE_UNSUPPORTED"}),e}();return ul(Qn,await this.options.request(i,`${Gu(t,"turns")}/${encodeURIComponent(n)}/timeline`,{method:"GET"}))}async resume(e,t){return ul(ss,await this.post(e,Gu(t,"resume"),{}))}async create(e,t){Ku((t.attachments||[]).filter(e=>"upload-ref"!==e.source.type));const n=await this.options.requireInstance(e),i=Fu(n);if(t.gitSelection&&!i)throw Hu();const s=t.permissionMode||("codex"===t.agent?n.config.defaultCodexPermissionMode:void 0),a=t.gitSelection?"/repository/ai-session-workspace/create":"/ai-sessions",{cwdFolderId:o,...r}=t;return ul(ki,await this.options.request(n,a,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({...r,...i&&o?{cwdFolderId:o}:{},...s?{permissionMode:s}:{}})}))}async inspectWorkspace(e,t){const n=await this.options.requireInstance(e);if(!Fu(n))throw Hu();return ul(Mu,await this.options.request(n,"/repository/ai-session-workspace/inspect",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({cwd:t})}))}async fork(e,t,n){return ul(Ri,await this.post(e,Gu(t,"fork"),n))}async openApp(e,t,n){return ul(ji,await this.post(e,Gu(t,"open-app"),{clientRequestId:n}))}async close(e,t,n){return ul(Di,await this.post(e,Gu(t,"close"),{clientRequestId:n}))}diagnostics(){return{resumeSnapshotRefreshFailures:this.resumeSnapshotRefreshFailures,lastResumeSnapshotRefreshFailure:this.lastResumeSnapshotRefreshFailure}}async sendMessage(e,t,n,i,s=[],a=[],o,r){const c=s.filter(e=>"upload-ref"!==e.source.type);Ku(c);const d=await this.options.requireInstance(e);s.some(e=>"runtime-path"===e.source.type)&&function(e,t){if(!e.some(e=>"runtime-path"===e.source.type)||"local"===t)return;const n=new Error("Runtime path attachments are currently available only for Local Runtime instances.");throw Object.assign(n,{statusCode:400,code:"AI_SESSION_RUNTIME_PATH_UNSUPPORTED"}),n}(c,(await this.options.requireRuntime(d.nodeId,d.runtimeId)).type);const l=d.aiSessions.sessions.find(e=>e.id===t),p=o||("codex"===l?.agent?d.config.defaultCodexPermissionMode:void 0);return ul(Zi,await this.options.request(d,Gu(t,"messages"),{method:"POST",headers:{"content-type":"application/json",...r?.traceId?{[eu]:r.traceId}:{}},body:JSON.stringify({message:n,...i?{mode:i}:{},...s.length?{attachments:s}:{},...a.length?{references:a}:{},...p?{permissionMode:p}:{}})},r?.onTiming))}async mentionCatalog(e,t){return ul(vi,await this.get(e,Gu(t,"mentions")))}async searchMentionFiles(e,t,n){return ul(xi,await this.post(e,Gu(t,"mentions/files"),{query:n}))}async executeCommand(e,t,n){return ul(ui,await this.post(e,Gu(t,"commands"),n))}async queue(e,t){return ul($i,await this.get(e,Gu(t,"queue")))}async steerQueuedMessage(e,t,n){return ul(Zi,await this.post(e,Vu(t,n,"steer"),{}))}async retryQueuedMessage(e,t,n){return ul(Wi,await this.post(e,Vu(t,n,"retry"),{}))}async removeQueuedMessage(e,t,n){const i=await this.options.requireInstance(e);return ul(Wi,await this.options.request(i,Vu(t,n),{method:"DELETE"}))}async editQueuedMessage(e,t,n,i){const s=qi.parse(i);return ul(Wi,await this.patch(e,Vu(t,n),s))}async reorderQueuedMessages(e,t,n){const i=Mi.parse(n);return ul(Wi,await this.patch(e,Gu(t,"queue/reorder"),i))}async interrupt(e,t){return ul(Zi,await this.post(e,Gu(t,"interrupt"),{}))}async get(e,t){return this.options.request(await this.options.requireInstance(e),t)}async post(e,t,n){return this.options.request(await this.options.requireInstance(e),t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}async patch(e,t,n){return this.options.request(await this.options.requireInstance(e),t,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}}function Fu(e){return Co(e.capabilities).features.aiSessionWorkspaceSelection}function Hu(){const e=new Error("The controlled instance does not support AI session workspace selection.");return Object.assign(e,{statusCode:409,code:"AI_SESSION_WORKSPACE_SELECTION_UNSUPPORTED"}),e}function Gu(e,t){return`/ai-sessions/${encodeURIComponent(e)}/${t}`}function Wu(e){if(e instanceof f.z.ZodError)return!0;if(!e||"object"!=typeof e)return!1;const t=e;return 404===(t.statusCode??t.status)&&"AI_SESSION_NOT_FOUND"!==t.code&&"AI_SESSION_TURN_NOT_FOUND"!==t.code}function Vu(e,t,n){return`${Gu(e,"queue")}/${encodeURIComponent(t)}${n?`/${n}`:""}`}function Ku(e){if(e.reduce((e,t)=>e+("inline"===t.source.type?t.size:0),0)<=bn)return;const t=new Error("Inline attachments must be 41943040 bytes or less in total.");throw Object.assign(t,{statusCode:400,code:"AI_SESSION_ATTACHMENTS_TOO_LARGE"}),t}class Yu{requestImpl;logger;constructor(e){this.requestImpl=e.request,this.logger=e.logger}async request(e,t,n={}){const i=n.method||"GET";let s,a;try{s=await this.requestImpl(e,t,n)}catch(n){throw this.logger?.warn?.({nodeId:e.id,route:t,method:i,error:n instanceof Error?n.message:String(n),errorCode:"NODE_AGENT_TRANSPORT_FAILED"},"node agent transport failed"),n}try{a=await s.json()}catch(n){this.logger?.warn?.({nodeId:e.id,route:t,method:i,statusCode:s.status,error:n instanceof Error?n.message:String(n),errorCode:"NODE_AGENT_RESPONSE_INVALID_JSON"},"node agent response was not valid json");const a=new Error(`Node agent ${e.id} returned invalid JSON for ${t}.`);throw Object.assign(a,{statusCode:502,code:"NODE_AGENT_RESPONSE_INVALID_JSON",nodeId:e.id,route:t}),a}if(!s.ok){const n=new Error(a.error?.message||`Node agent request failed with HTTP ${s.status}`);throw Object.assign(n,{statusCode:s.status,code:a.error?.code||"NODE_AGENT_REQUEST_FAILED",nodeId:e.id,route:t}),this.logger?.warn?.({nodeId:e.id,route:t,method:i,statusCode:s.status,errorCode:a.error?.code||"NODE_AGENT_REQUEST_FAILED",error:n.message},"node agent request failed"),n}return this.logger?.info?.({nodeId:e.id,route:t,method:i,statusCode:s.status},"node agent request ok"),a.data??a}async requestSchema(e,t,n,i={}){return this.parse(e,t,n,await this.request(e,t,i),i.method||"GET")}parse(e,t,n,i,s="GET"){const a=pl(n,i);if(a.success)return a.data;this.logger?.warn?.({nodeId:e.id,route:t,method:s,errorCode:"NODE_AGENT_PROTOCOL_INVALID",issues:a.error.issues},"node agent protocol response did not match schema");const o=new Error(`Node agent ${e.id} returned invalid protocol data for ${t}.`);throw Object.assign(o,{statusCode:502,code:"NODE_AGENT_PROTOCOL_INVALID",nodeId:e.id,route:t,issues:a.error.issues}),o}}const Xu=f.z.string().trim().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/),Ju=f.z.string().datetime(),Qu=f.z.number().int().nonnegative(),Zu=f.z.enum(["https-token","ssh-key"]),em=f.z.enum(["operation-only","instance-retained"]),tm=f.z.enum(["enabled","disabled"]),nm=f.z.enum(["pending","synced","deferred","revoking","revoked"]),im=f.z.object({scheme:f.z.enum(["https","ssh"]),host:f.z.string().trim().min(1).max(253),port:f.z.number().int().min(1).max(65535).optional(),pathPrefix:f.z.string().min(1).max(2048).default("/")}).strict();function sm(e){throw new Error(`Invalid Git credential scope: ${e}`)}function am(e){const t=e.trim().replace(/^\[|\]$/g,"");(!t||t.includes("*")||/[/?#@\s]/.test(t))&&sm("host is invalid");try{const e=new URL(t.includes(":")?`http://[${t}]/`:`http://${t}/`).hostname.replace(/^\[|\]$/g,"").toLowerCase();return(!e||e.length>253||e.includes("*"))&&sm("host is invalid"),e}catch{sm("host is invalid")}}function om(e){try{return decodeURIComponent(e)}catch{sm("path contains invalid percent encoding")}}function rm(e){const t=e?.trim()||"/";(t.includes("?")||t.includes("#")||t.includes("\\")||t.includes("\0"))&&sm("path contains an unsupported delimiter");const n=(t.startsWith("/")?t:`/${t}`).split("/").filter(Boolean);for(const e of n){const t=om(e);("."===t||".."===t||t.includes("/")||t.includes("\\")||t.includes("\0"))&&sm("path contains an unsafe segment")}return 0===n.length?"/":`/${n.join("/")}/`}function cm(e){const t=im.parse(e),n="https"===t.scheme?443:22;return im.parse({scheme:t.scheme,host:am(t.host),...void 0===t.port||t.port===n?{}:{port:t.port},pathPrefix:rm(t.pathPrefix)})}function dm(e){return rm(e.replace(/\.git\/?$/,""))}const lm=f.z.object({id:Xu,name:f.z.string().trim().min(1).max(160),kind:Zu,scope:im,secretSet:f.z.literal(!0),status:tm,revision:Qu,createdAt:Ju,updatedAt:Ju}).strict(),pm=f.z.object({kind:f.z.literal("https-token"),username:f.z.string().trim().min(1).max(240),token:f.z.string().min(1).max(8192)}).strict(),um=f.z.object({kind:f.z.literal("ssh-key"),privateKey:f.z.string().min(1).max(131072),passphrase:f.z.string().max(8192).optional(),pinnedKnownHosts:f.z.string().min(1).max(131072)}).strict(),mm=f.z.discriminatedUnion("kind",[pm,um]),hm=f.z.object({name:f.z.string().trim().min(1).max(160),scope:im,secret:mm}).strict().superRefine((e,t)=>{"https"===e.scope.scheme!=("https-token"===e.secret.kind)&&t.addIssue({code:"custom",path:["scope","scheme"],message:"Credential kind must match the remote scheme."});try{cm(e.scope)}catch(e){t.addIssue({code:"custom",path:["scope"],message:e instanceof Error?e.message:"Invalid Git scope."})}}),gm=f.z.object({name:f.z.string().trim().min(1).max(160).optional(),scope:im.optional(),secret:mm.optional(),status:tm.optional()}).strict().refine(e=>Object.keys(e).length>0,"At least one credential field must be updated.");f.z.object({items:f.z.array(lm).max(1e4)}).strict();const fm=f.z.object({instanceId:Xu,credentialId:Xu,credentialRevision:Qu,assignmentRevision:Qu,status:nm,authorizedAt:Ju,updatedAt:Ju}).strict(),ym=f.z.object({credential:lm,secret:mm}).strict().superRefine((e,t)=>{e.credential.kind!==e.secret.kind&&t.addIssue({code:"custom",path:["secret","kind"],message:"Credential payload kind mismatch."})}),bm=f.z.object({instanceId:Xu,generation:Qu,credentialIds:f.z.array(Xu).max(256).transform(e=>[...new Set(e)].sort()),updatedAt:Ju}).strict();f.z.object({remoteUrl:f.z.string().trim().min(1).max(4096)}).strict(),f.z.discriminatedUnion("status",[f.z.object({status:f.z.literal("ok"),username:f.z.string().min(1).max(240),password:f.z.string().min(1).max(8192)}).strict(),f.z.object({status:f.z.enum(["none","ambiguous","unsupported","missing-host-key","rejected"])}).strict()]),f.z.object({remoteUrl:f.z.string().trim().min(1).max(4096)}).strict(),f.z.discriminatedUnion("status",[f.z.object({status:f.z.literal("ok"),invocationId:Xu,publicIdentity:f.z.string().min(1).max(131072),pinnedKnownHosts:f.z.string().min(1).max(131072)}).strict(),f.z.object({status:f.z.enum(["none","ambiguous","unsupported","missing-host-key","rejected"])}).strict()]),f.z.object({invocationId:Xu,frame:f.z.string().min(1).max(1048576)}).strict(),f.z.object({frame:f.z.string().min(1).max(1048576)}).strict();const vm=f.z.object({operationId:Xu,retention:em,payload:ym}).strict(),Im=f.z.object({operationId:Xu,instanceId:Xu,remoteUrl:f.z.string().trim().min(1).max(4096),ref:f.z.discriminatedUnion("type",[f.z.object({type:f.z.enum(["branch","tag"]),name:f.z.string().trim().min(1).max(240)}).strict(),f.z.object({type:f.z.literal("commit"),commit:f.z.string().trim().regex(/^[0-9a-fA-F]{4,64}$/,"commit must be a hexadecimal Git object id")}).strict()]),clone:f.z.object({depth:f.z.number().int().positive().max(1e5).optional(),submodules:f.z.boolean().default(!1),lfs:f.z.boolean().default(!1),subdirectory:f.z.string().trim().max(240).refine(e=>!e.startsWith("/")&&!e.split("/").some(e=>".."===e),"subdirectory must be a relative path within the repository").transform(e=>e.split("/").filter(e=>e&&"."!==e).join("/")).default("")}).strict(),credentials:f.z.array(vm).max(256).default([])}).strict();function xm(e,t){let n;try{n=function(e){const t=e.trim();if(t&&!t.includes("\0")||sm("remote is empty or invalid"),/^https?:\/\//i.test(t)||/^ssh:\/\//i.test(t)){let e;rm(t.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]+/i,"").split(/[?#]/,1)[0]||"/");try{e=new URL(t)}catch{sm("remote URL is invalid")}"https:"!==e.protocol&&"ssh:"!==e.protocol&&sm("remote scheme is unsupported"),(e.password||"https:"===e.protocol&&e.username)&&sm("HTTPS userinfo is forbidden"),(e.search||e.hash)&&sm("query and fragment are forbidden");const n="https:"===e.protocol?"https":"ssh",i=e.port?Number(e.port):void 0;return{...cm({scheme:n,host:e.hostname,port:i,pathPrefix:dm(e.pathname)}),original:t}}/^[a-z][a-z0-9+.-]*:\/\//i.test(t)&&sm("remote scheme is unsupported");const n=/^(?:([^@/:\s]+)@)?([^/:\s]+):(.+)$/.exec(t);n||sm("remote must use HTTPS, ssh://, or scp-like SSH syntax");const[,,i,s]=n;return(s.includes("?")||s.includes("#"))&&sm("query and fragment are forbidden"),{...cm({scheme:"ssh",host:i,pathPrefix:dm(s)}),original:t}}(e)}catch(e){return{status:"unsupported",reason:e instanceof Error?e.message:"Unsupported Git remote."}}const i=t.filter(e=>"enabled"===e.status).filter(e=>"https"===n.scheme==("https-token"===e.kind)).filter(e=>function(e,t){const n=cm(e);return n.scheme===t.scheme&&n.host===t.host&&n.port===t.port&&("/"===n.pathPrefix||t.pathPrefix.startsWith(n.pathPrefix))}(e.scope,n)).map(e=>({candidate:e,specificity:cm(e.scope).pathPrefix.length}));if(0===i.length)return{status:"none",remote:n};const s=Math.max(...i.map(e=>e.specificity)),a=i.filter(e=>e.specificity===s).map(e=>e.candidate);if(a.length>1)return{status:"ambiguous",remote:n,credentialIds:a.map(e=>e.id).sort()};const o=a[0];return"ssh-key"===o.kind&&!0!==o.pinnedKnownHosts?{status:"missing-host-key",remote:n,credentialId:o.id}:{status:"unique",remote:n,credential:o}}class wm{client;fleetRequestTimeoutMs;fleetSnapshotFreshMs;fleetRetryBaseMs;fleetRetryMaxMs;onFleetStateChanged;runtimeSnapshots=new Map;instanceSnapshots=new Map;modelSnapshots=new Map;fleetRefreshes=new Map;fleetRevisions=new Map;fleetRetryAttempts=new Map;fleetRetryTimers=new Map;disposed=!1;constructor(e,t={}){this.client=e,this.fleetRequestTimeoutMs=Number.isFinite(t.fleetRequestTimeoutMs)&&Number(t.fleetRequestTimeoutMs)>0?Number(t.fleetRequestTimeoutMs):2e3,this.fleetSnapshotFreshMs=Number.isFinite(t.fleetSnapshotFreshMs)&&Number(t.fleetSnapshotFreshMs)>=0?Number(t.fleetSnapshotFreshMs):15e3,this.fleetRetryBaseMs=Number.isFinite(t.fleetRetryBaseMs)&&Number(t.fleetRetryBaseMs)>0?Number(t.fleetRetryBaseMs):1e3,this.fleetRetryMaxMs=Number.isFinite(t.fleetRetryMaxMs)&&Number(t.fleetRetryMaxMs)>=this.fleetRetryBaseMs?Number(t.fleetRetryMaxMs):Math.max(3e4,this.fleetRetryBaseMs),this.onFleetStateChanged=t.onFleetStateChanged}request(e,t,n={}){return this.client.request(e,t,n)}forgetNode(e){this.runtimeSnapshots.delete(e),this.instanceSnapshots.delete(e),this.modelSnapshots.delete(e);for(const t of["runtimes","instances","models"])this.resetFleetRetry(`${t}:${e}`)}dispose(){this.disposed=!0;for(const e of this.fleetRetryTimers.values())clearTimeout(e);this.fleetRetryTimers.clear(),this.fleetRetryAttempts.clear()}health(e){return this.client.requestSchema(e,"/health",Gc)}checkUpdate(e,t){return this.client.requestSchema(e,"/updates/check",Lr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}applyUpdate(e,t){return this.client.requestSchema(e,"/updates/apply",Mr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}listUpdateJobs(e){return this.client.requestSchema(e,"/updates/jobs",f.z.array(Mr))}getExternalListener(e){return this.client.requestSchema(e,"/settings/external-listener",Wc)}updateExternalListener(e,t){return this.client.requestSchema(e,"/settings/external-listener",Wc,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}deployGitCredential(e,t){return this.client.requestSchema(e,`/git-credentials/${encodeURIComponent(t.credential.id)}`,lm,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}removeGitCredential(e,t){return this.client.requestSchema(e,`/git-credentials/${encodeURIComponent(t)}`,f.z.object({deleted:f.z.boolean()}).strip(),{method:"DELETE"})}replaceGitCredentialAuthorizations(e,t){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t.instanceId)}/git-credential-authorizations`,bm,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}createPairingInvite(e,t={}){return this.client.requestSchema(e,"/pairing/invites",Vc,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t&&"object"==typeof t?t:{})})}createControlPlaneConnection(e,t){return this.client.requestSchema(e,"/control-plane-connections",Qc,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}listControlPlanePairings(e){return this.client.requestSchema(e,"/control-plane-pairings",f.z.array(Yc))}deleteControlPlanePairing(e,t){return this.client.requestSchema(e,`/control-plane-pairings/${encodeURIComponent(t)}`,Zc,{method:"DELETE"})}listControlPlaneConnections(e){return this.client.requestSchema(e,"/control-plane-connections",f.z.array(Jc))}deleteControlPlaneConnection(e,t){return this.client.requestSchema(e,`/control-plane-connections/${encodeURIComponent(t)}`,Zc,{method:"DELETE"})}listDockerImages(e){return this.client.requestSchema(e,"/docker/images",f.z.array(ed))}listFolderTree(e,t={}){const n=new URLSearchParams;t.path&&n.set("path",t.path),void 0!==t.depth&&n.set("depth",String(t.depth));const i=n.toString();return this.client.requestSchema(e,"/folders/tree"+(i?`?${i}`:""),f.z.array(nd))}listFolderPlaces(e){return this.client.requestSchema(e,"/folders/places",f.z.array(id))}listLocalFolders(e,t={}){return this.client.requestSchema(e,"/local-folders",f.z.array(Gr),t)}createLocalFolder(e,t){return this.client.requestSchema(e,"/local-folders",Gr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}updateLocalFolder(e,t,n){return this.client.requestSchema(e,`/local-folders/${encodeURIComponent(t)}`,Gr,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}async requireLocalFolder(e,t){const n=(await this.listLocalFolders(e)).find(e=>e.id===t);if(!n){const n=new Error(`Local folder ${t} was not found on node ${e.id}.`);throw Object.assign(n,{statusCode:404,code:"NODE_LOCAL_FOLDER_NOT_FOUND",nodeId:e.id,route:"/local-folders"}),n}return n}listRuntimes(e,t={}){return this.client.requestSchema(e,"/runtimes",f.z.array(Dc),t)}async createRuntime(e,t){const n=await this.client.requestSchema(e,"/runtimes",Dc,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)});return this.invalidateFleetResource(e,"runtimes"),n}async updateRuntime(e,t,n){const i=`/runtimes/${encodeURIComponent(t)}`,s=await this.client.requestSchema(e,i,Dc,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(n)});return this.invalidateFleetResource(e,"runtimes"),s}async checkRuntime(e,t){const n=`/runtimes/${encodeURIComponent(t)}/check`,i=await this.client.requestSchema(e,n,Dc,{method:"POST"});return this.invalidateFleetResource(e,"runtimes"),i}async deleteRuntime(e,t){const n=await this.client.requestSchema(e,`/runtimes/${encodeURIComponent(t)}`,Zc,{method:"DELETE"});return this.invalidateFleetResource(e,"runtimes"),n}deleteLocalFolder(e,t){return this.client.requestSchema(e,`/local-folders/${encodeURIComponent(t)}`,Zc,{method:"DELETE"})}listModels(e,t={}){return this.client.requestSchema(e,"/models",f.z.array(Zr),t)}async createModel(e,t){const n=await this.client.requestSchema(e,"/models",Zr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)});return this.invalidateFleetResource(e,"models"),n}async deployModel(e,t,n){const i=await this.client.requestSchema(e,`/models/${encodeURIComponent(t)}/deploy`,Zr,{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(n)});return this.invalidateFleetResource(e,"models"),i}async updateModel(e,t,n){const i=await this.client.requestSchema(e,`/models/${encodeURIComponent(t)}`,Zr,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(n)});return this.invalidateFleetResource(e,"models"),i}async deleteModel(e,t){const n=await this.client.requestSchema(e,`/models/${encodeURIComponent(t)}`,Zc,{method:"DELETE"});return this.invalidateFleetResource(e,"models"),n}discoverModels(e,t){return this.client.requestSchema(e,"/models/discover",f.z.object({models:f.z.array(f.z.object({id:f.z.string(),ownedBy:f.z.string().optional()}).strict()),latencyMs:f.z.number().nonnegative()}).strict(),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}testModel(e,t){return this.client.requestSchema(e,"/models/test",f.z.object({success:f.z.literal(!0),latencyMs:f.z.number().nonnegative()}).strict(),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)})}async assignInstanceModels(e,t,n){const i=await this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/model-assignment`,f.z.object({assignment:ec,instance:dd}).strict(),{method:"PUT",headers:{"content-type":"application/json"},body:JSON.stringify(n)});return this.upsertInstanceSnapshot(e,i.instance),i}async listFleetModels(e,t={}){return await this.refreshFleetModels(e,t,!0),this.readFleetModels(e)}async listFleetRuntimes(e,t={}){return await this.refreshFleetRuntimes(e,t,!0),this.readFleetRuntimes(e)}readFleetModels(e){const t=this.readFleetSnapshots(e,"models",this.modelSnapshots);return{...t,items:t.items.map(({nodeId:e,item:t})=>({nodeId:e,model:t}))}}readFleetRuntimes(e){const t=this.readFleetSnapshots(e,"runtimes",this.runtimeSnapshots);return{...t,items:t.items.map(({item:e})=>e)}}readFleetInstances(e){const t=this.readFleetSnapshots(e,"instances",this.instanceSnapshots);return{...t,items:t.items.map(({item:e})=>e)}}refreshFleetModels(e,t={},n=!1){return this.refreshFleetSnapshots(e,"models","/models",t,this.modelSnapshots,async(e,t)=>({items:await this.listModels(e,t),nodeErrors:[]}),n)}refreshFleetRuntimes(e,t={},n=!1){return this.refreshFleetSnapshots(e,"runtimes","/runtimes",t,this.runtimeSnapshots,async(e,t)=>({items:await this.listRuntimes(e,t),nodeErrors:[]}),n)}refreshFleetInstances(e,t={},n=!1){return this.refreshFleetSnapshots(e,"instances","/instances",t,this.instanceSnapshots,(e,t)=>this.loadInstancesWithDiagnostics(e,t),n)}listInstances(e,t={}){return this.listInstancesWithDiagnostics(e,t).then(e=>e.items)}async listInstancesWithDiagnostics(e,t={}){const n=await this.loadInstancesWithDiagnostics(e,t);return this.setTargetedSnapshot(e,"instances",this.instanceSnapshots,n),n}async loadInstancesWithDiagnostics(e,t={}){return this.client.requestSchema(e,"/instances",f.z.array(f.z.unknown()),t).then(t=>t.reduce((t,n)=>{const i=this.normalizeInstance(e,n);return i.instance&&t.items.push(i.instance),i.error&&t.nodeErrors.push(i.error),t},{items:[],nodeErrors:[]}))}instanceFromSnapshot(e,t){for(const n of e){const e=this.instanceSnapshots.get(n.id);if(!e||e.connectionKey!==this.fleetConnectionKey(n))continue;const i=e.items.find(e=>e.id===t);if(i)return i}}async createInstance(e,t){const n=await this.client.requestSchema(e,"/instances",dd,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)});return this.upsertInstanceSnapshot(e,n),n}async updateInstance(e,t,n){const i=await this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}`,dd,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify(n)});return this.upsertInstanceSnapshot(e,i),i}async deleteInstance(e,t,n){const i=await this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/delete`,sr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)});return this.removeInstanceSnapshot(e,t),i}listEnvironmentTemplates(e,t={}){return this.client.requestSchema(e,"/environment-templates",f.z.array(pr),t)}getEnvironmentTemplate(e,t,n={}){return this.client.requestSchema(e,`/environment-templates/${encodeURIComponent(t)}`,pr,n)}createEnvironmentTemplate(e,t,n){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/environment-templates`,pr,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}deleteEnvironmentTemplate(e,t){return this.client.requestSchema(e,`/environment-templates/${encodeURIComponent(t)}`,f.z.object({deleted:f.z.boolean(),templateId:pr.shape.id}).strict(),{method:"DELETE"})}async startInstance(e,t,n={}){const i=await this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/start`,pd,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)});return this.upsertInstanceSnapshot(e,i.instance),i}async retryInstanceImageProvisioning(e,t){const n=await this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/image-provisioning/retry`,dd,{method:"POST"});return this.upsertInstanceSnapshot(e,n),n}async stopInstance(e,t){const n=await this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/stop`,dd,{method:"POST"});return this.upsertInstanceSnapshot(e,n),n}async restartInstance(e,t,n={}){const i=await this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/restart`,pd,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)});return this.upsertInstanceSnapshot(e,i.instance),i}instanceResourceMetrics(e,t){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/metrics`,Lc)}proxyRawInstance(e,t,n){return this.client.requestSchema(e,`/instances/${encodeURIComponent(t)}/proxy/raw`,sd,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)})}async listFleetInstances(e,t={}){return await this.refreshFleetInstances(e,t,!0),this.readFleetInstances(e)}readFleetSnapshots(e,t,n){this.reconcileFleetConnections(e,t,n);const i={items:[],nodeErrors:[],nodeStates:[]};for(const s of e){const e=n.get(s.id);if(!e){i.nodeStates.push({nodeId:s.id,resource:t,phase:"uninitialized",revision:this.fleetRevisions.get(`${t}:${s.id}`)});continue}i.items.push(...e.items.map(e=>({nodeId:s.id,item:e})));const a=this.publicFleetState(s.id,t,e);i.nodeStates.push(a),e.error&&i.nodeErrors.push(e.error)}return i}async refreshFleetSnapshots(e,t,n,i,s,a,o){this.reconcileFleetConnections(e,t,s),await Promise.all(e.map(e=>this.refreshFleetNode(e,t,n,i,s,a,o)))}refreshFleetNode(e,t,n,i,s,a,o){if(this.disposed)return Promise.resolve();const r=`${t}:${e.id}`,c=this.fleetRefreshes.get(r);if(c)return c;if(!o&&this.fleetRetryTimers.has(r))return Promise.resolve();o&&this.clearFleetRetry(r);const d=this.fleetConnectionKey(e),l=s.get(e.id),p=l?.connectionKey===d?l:void 0,u="ready"===p?.phase&&void 0!==p.updatedAt&&Date.now()-Date.parse(p.updatedAt)<this.fleetSnapshotFreshMs;if(!o&&u)return Promise.resolve();const m=l?.connectionKey===d&&Boolean(l.error)&&("error"===l.phase||"stale"===l.phase),h=this.nextFleetRevision(e.id,t),g={connectionKey:d,items:l?.connectionKey===d?[...l.items]:[],phase:m?l.phase:"ready"===p?.phase?"ready":p?.updatedAt?"stale":"loading",revision:h,updatedAt:l?.connectionKey===d?l.updatedAt:void 0,error:m?l.error:void 0};s.set(e.id,g),m||p&&this.sameFleetState(t,p,g)||this.emitFleetState(e.id,t,g,{contentChanged:!1});const f=(async()=>{try{this.requireFleetNodeReady(e,n);const o=await this.withFleetDeadline(e,n,i,t=>a(e,t));if(s.get(e.id)?.revision!==h)return;const c=o.nodeErrors[0],l={connectionKey:d,items:[...o.items],phase:c?"stale":"ready",revision:h,updatedAt:(new Date).toISOString(),error:c};s.set(e.id,l);const u=!p||!this.sameFleetItems(t,p,l);if(c)return this.sameFleetState(t,g,l)||this.emitFleetState(e.id,t,l,{contentChanged:u}),void this.scheduleFleetRetry(r,()=>this.refreshFleetNode(e,t,n,{},s,a,!0));this.resetFleetRetry(r),p&&this.sameFleetState(t,p,l)||this.emitFleetState(e.id,t,l,{contentChanged:u})}catch(i){if(s.get(e.id)?.revision!==h)return;const o=function(e,t,n,i){const s=i&&"object"==typeof i?i:{};return{nodeId:e.id,route:"string"==typeof s.route?s.route:t,method:"GET",code:"string"==typeof s.code?s.code:"NODE_AGENT_REQUEST_FAILED",message:i instanceof Error?i.message:String(i),statusCode:"number"==typeof s.statusCode?s.statusCode:void 0,issues:Array.isArray(s.issues)?s.issues:void 0}}(e,n,0,i),c={...g,phase:g.updatedAt?"stale":"error",error:o};s.set(e.id,c),this.sameFleetState(t,g,c)||this.emitFleetState(e.id,t,c,{contentChanged:!1}),this.scheduleFleetRetry(r,()=>this.refreshFleetNode(e,t,n,{},s,a,!0))}})().finally(()=>{this.fleetRefreshes.get(r)===f&&this.fleetRefreshes.delete(r)});return this.fleetRefreshes.set(r,f),f}reconcileFleetConnections(e,t,n){for(const i of e){const e=n.get(i.id);e&&e.connectionKey!==this.fleetConnectionKey(i)&&(n.delete(i.id),this.resetFleetRetry(`${t}:${i.id}`))}}invalidateFleetResource(e,t){const n="instances"===t?this.instanceSnapshots:"runtimes"===t?this.runtimeSnapshots:this.modelSnapshots;n.get(e.id)&&(this.resetFleetRetry(`${t}:${e.id}`),n.delete(e.id),this.onFleetStateChanged?.({nodeId:e.id,resource:t,phase:"uninitialized",revision:this.nextFleetRevision(e.id,t),contentChanged:!0}))}publicFleetState(e,t,n){const i=n.error?{nodeId:n.error.nodeId,route:n.error.route,method:n.error.method,code:n.error.code,message:n.error.message,...void 0!==n.error.statusCode?{statusCode:n.error.statusCode}:{},...n.error.issues?{issues:n.error.issues.map(e=>({path:e.path.map(e=>"symbol"==typeof e?String(e):e),message:e.message}))}:{}}:void 0;return{nodeId:e,resource:t,phase:n.phase,revision:n.revision,...n.updatedAt?{updatedAt:n.updatedAt}:{},...i?{error:i}:{}}}emitFleetState(e,t,n,i={}){this.onFleetStateChanged?.({...this.publicFleetState(e,t,n),...void 0===i.contentChanged?{}:{contentChanged:i.contentChanged}})}sameFleetItems(e,t,n){return JSON.stringify(this.fleetItemsForComparison(e,t.items))===JSON.stringify(this.fleetItemsForComparison(e,n.items))}fleetItemsForComparison(e,t){return"instances"!==e?t:t.map(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return e;const{stateRevision:t,updatedAt:n,lastHeartbeatAt:i,aiSessions:s,appInventory:a,...o}=e,r=a&&"object"==typeof a&&!Array.isArray(a)?(({observedAt:e,...t})=>t)(a):a;return{...o,...r?{appInventory:r}:{}}})}sameFleetState(e,t,n){const i=t=>({phase:t.phase,items:this.fleetItemsForComparison(e,t.items),error:t.error&&{code:t.error.code,message:t.error.message,statusCode:t.error.statusCode,route:t.error.route,method:t.error.method,issues:t.error.issues}});return JSON.stringify(i(t))===JSON.stringify(i(n))}scheduleFleetRetry(e,t){if(this.disposed||this.fleetRetryTimers.has(e))return;const n=(this.fleetRetryAttempts.get(e)||0)+1;this.fleetRetryAttempts.set(e,n);const i=Math.min(this.fleetRetryMaxMs,this.fleetRetryBaseMs*2**Math.min(n-1,10)),s=setTimeout(()=>{this.fleetRetryTimers.delete(e),this.disposed||t()},i);s.unref?.(),this.fleetRetryTimers.set(e,s)}clearFleetRetry(e){const t=this.fleetRetryTimers.get(e);t&&clearTimeout(t),this.fleetRetryTimers.delete(e)}resetFleetRetry(e){this.clearFleetRetry(e),this.fleetRetryAttempts.delete(e)}setTargetedSnapshot(e,t,n,i){const s=n.get(e.id),a={connectionKey:this.fleetConnectionKey(e),items:[...i.items],phase:i.nodeErrors.length?"stale":"ready",revision:this.nextFleetRevision(e.id,t),updatedAt:(new Date).toISOString(),error:i.nodeErrors[0]};n.set(e.id,a),this.emitFleetState(e.id,t,a,{contentChanged:!s||s.connectionKey!==a.connectionKey||!this.sameFleetItems(t,s,a)})}nextFleetRevision(e,t){const n=`${t}:${e}`,i=(this.fleetRevisions.get(n)||0)+1;return this.fleetRevisions.set(n,i),i}fleetConnectionKey(e){return JSON.stringify([e.id,e.connectionMode,e.controlEndpoint,e.endpoint,e.auth.mode,e.auth.keyId])}upsertInstanceSnapshot(e,t){const n=this.instanceSnapshots.get(e.id),i=this.fleetConnectionKey(e);if(!n||n.connectionKey!==i)return;const s=n.items;n.items=[...n.items.filter(e=>e.id!==t.id),t],n.phase="ready",n.revision=this.nextFleetRevision(e.id,"instances"),n.updatedAt=(new Date).toISOString(),n.error=void 0,this.emitFleetState(e.id,"instances",n,{contentChanged:!this.sameFleetItems("instances",{...n,items:s},n)})}removeInstanceSnapshot(e,t){const n=this.instanceSnapshots.get(e.id);if(!n||n.connectionKey!==this.fleetConnectionKey(e))return;const i=n.items;n.items=n.items.filter(e=>e.id!==t),n.phase="ready",n.revision=this.nextFleetRevision(e.id,"instances"),n.updatedAt=(new Date).toISOString(),n.error=void 0,this.emitFleetState(e.id,"instances",n,{contentChanged:JSON.stringify(i)!==JSON.stringify(n.items)})}requireFleetNodeReady(e,t){const n=e.connectionPhase,i="reverse-wss"!==e.connectionMode&&"control-plane-proxy"!==e.connectionMode;if(!n||"healthy"===n||i)return;const s=new Error(`Node agent ${e.id} is ${n}; serving its latest fleet snapshot.`);throw Object.assign(s,{code:"NODE_AGENT_CONNECTION_PENDING",nodeId:e.id,route:t}),s}async withFleetDeadline(e,t,n,i){const s=new AbortController,a=Object.assign(new Error(`Node agent ${e.id} did not return ${t} before the fleet aggregation deadline.`),{code:"NODE_AGENT_FLEET_TIMEOUT",nodeId:e.id,route:t}),o=new Promise((e,t)=>{const n=()=>t(s.signal.reason||a);s.signal.aborted?n():s.signal.addEventListener("abort",n,{once:!0})}),r=()=>s.abort(n.signal?.reason);n.signal?.aborted?r():n.signal?.addEventListener("abort",r,{once:!0});const c=setTimeout(()=>s.abort(a),this.fleetRequestTimeoutMs);c.unref?.();try{return await Promise.race([i({...n,signal:s.signal}),o])}finally{clearTimeout(c),n.signal?.removeEventListener("abort",r)}}normalizeInstance(e,t){const n=(i=t,dd.safeParse(hd(i)));var i;if(n.success)return n.data.protocolVersion&&n.data.protocolVersion!==wo?(this.client.logger?.warn?.({nodeId:e.id,instanceId:n.data.id,expectedProtocolVersion:wo,actualProtocolVersion:n.data.protocolVersion,errorCode:"PROTOCOL_VERSION_MISMATCH"},"node instance protocol version mismatch"),{instance:n.data}):{instance:n.data};const s=t&&"object"==typeof t?t:{},a="string"==typeof s.id?s.id:void 0;return this.client.logger?.warn?.({nodeId:e.id,instanceId:a,errorCode:"NODE_INSTANCE_PAYLOAD_INVALID",issues:n.error.issues.map(e=>({path:e.path.join("."),message:e.message}))},"node instance payload invalid"),{error:{nodeId:e.id,route:"/instances",method:"GET",code:"NODE_INSTANCE_PAYLOAD_INVALID",message:a?`Node instance ${a} payload is invalid.`:"Node instance payload is invalid.",statusCode:502,issues:n.error.issues}}}}const Sm="TASK_HANDOFF_NODE_AGENT_V1",Am=6e4,Em="/api/node-tunnel";function _m(e,t){if("paired-hmac"===e.auth.mode&&e.auth.secret){if(!e.auth.keyId){const t=new Error(`Node ${e.id} paired-HMAC auth is missing keyId.`);throw Object.assign(t,{statusCode:500,code:"NODE_AGENT_REMOTE_KEY_ID_MISSING"}),t}return function(e){const t=e.timestamp||(new Date).toISOString(),n=e.nonce||i.randomBytes(18).toString("base64url"),s=Tm(e.body||""),a=zm(e.secret,{keyId:e.keyId,method:e.method,pathWithQuery:e.pathWithQuery,timestamp:t,nonce:n,bodySha256:s});return{"x-taskhandoff-node-id":e.nodeId,"x-taskhandoff-key-id":e.keyId,"x-taskhandoff-timestamp":t,"x-taskhandoff-nonce":n,"x-taskhandoff-body-sha256":s,"x-taskhandoff-signature":a}}({nodeId:e.id,keyId:e.auth.keyId,secret:e.auth.secret,method:t.method,pathWithQuery:t.pathWithQuery,body:t.body})}const n="local-ipc"!==e.connectionMode&&"local-loopback"!==e.connectionMode||"local-static-key"!==e.auth.mode?void 0:e.auth.secret;return n?{authorization:`Bearer ${n}`}:{}}function Tm(e=""){return i.createHash("sha256").update(e).digest("hex")}function zm(e,t){return i.createHmac("sha256",e).update(function(e){return[Sm,e.keyId,e.method.toUpperCase(),e.pathWithQuery,e.timestamp,e.nonce,e.bodySha256].join("\n")}(t)).digest("hex")}function km(e){if(e.startsWith("ipc://"))return decodeURIComponent(e.slice(6))}function Nm(e,t=process.platform){if(!function(e,t=process.platform){if("win32"===t)return e.startsWith("\\\\.\\pipe\\");const i=n.statSync(e),s=process.getuid?.();return void 0===s||i.uid===s}(e,t)){const e=new Error("Local node agent IPC socket is not owned by the current user.");throw Object.assign(e,{statusCode:403,code:"NODE_AGENT_IPC_OWNER_INVALID"}),e}}function Cm(e,t){return Number.isFinite(e)&&Number(e)>0?Number(e):t}function Rm(e,t){const n=AbortSignal.timeout(t);return e?AbortSignal.any([e,n]):n}async function Om(e,t,n,i={}){const s=km(t);return s?(Nm(s),async function(e,t,n={}){const i=n.method||"GET",s="string"==typeof n.body||n.body instanceof Buffer?n.body:void 0===n.body||null===n.body?void 0:String(n.body),a=new Headers(n.headers||{});return void 0===s||a.has("content-length")||a.set("content-length",String(Buffer.byteLength(s))),new Promise((o,c)=>{const d=v.request({socketPath:e,method:i,path:`/api/node-agent${t}`,headers:Object.fromEntries(a.entries())},e=>{const t=e.statusCode||500;o(new Response("HEAD"!==i&&204!==t&&205!==t&&304!==t?r.Readable.toWeb(e):null,{status:t,headers:e.headers}))});d.on("error",c);const l=()=>d.destroy(new DOMException("The operation was aborted.","AbortError"));n.signal?.aborted?l():n.signal?.addEventListener("abort",l,{once:!0}),d.once("close",()=>n.signal?.removeEventListener("abort",l)),void 0!==s&&d.write(s),d.end()})}(s,n,i)):e(`${t.replace(/\/$/,"")}/api/node-agent${n}`,i)}function jm(e){const t=e.controlEndpoint||e.endpoint;if(!t){const e=new Error("Node agent direct HTTP mode requires an endpoint.");throw Object.assign(e,{statusCode:400,code:"NODE_AGENT_ENDPOINT_REQUIRED"}),e}return t}function Pm(e,t,n,i){const s=jm(e),a=km(s),o=`/api/node-agent${t}`;if(a)return Nm(a),function(e,t,n,i={}){const s=`/api/node-agent${t}`,a={createConnection:()=>I.connect(e),headers:{host:"task-handoff-node-agent.local",...i}};return n&&(Array.isArray(n)?n.length>0:n.trim().length>0)?new b.WebSocket(`ws://task-handoff-node-agent.local${s}`,n,a):new b.WebSocket(`ws://task-handoff-node-agent.local${s}`,a)}(a,t,n,i);const r=new URL(o,s.replace(/\/$/,""));return r.protocol="https:"===r.protocol?"wss:":"ws:",n?new b.WebSocket(r.toString(),n,{headers:i}):new b.WebSocket(r.toString(),{headers:i})}function Dm(e,t,n){const i=new Headers(n),s=_m(e,t);for(const[e,t]of Object.entries(s))"authorization"===e&&i.has(e)||i.set(e,t);return Object.fromEntries(i.entries())}function Lm(e=fetch,t={}){const n=t.openWebSocket||Pm,i=Cm(t.requestTimeoutMs,3e4),s=Cm(t.streamHeaderTimeoutMs,3e4),a=Cm(t.websocketOpenTimeoutMs,1e4);return{request:async(t,n,s={})=>{const a=jm(t),o=s.method||"GET",r="string"==typeof s.body||s.body instanceof Buffer?s.body:void 0===s.body||null===s.body?void 0:String(s.body),c=Dm(t,{method:o,pathWithQuery:`/api/node-agent${n}`,body:r||""},s.headers);return Om(e,a,n,{...s,body:r,headers:c,signal:Rm(s.signal,i)})},requestStream:async(t,n,i={})=>{const a=jm(t),o=i.method||"GET",r="string"==typeof i.body||i.body instanceof Buffer?i.body:void 0===i.body||null===i.body?void 0:String(i.body),c=Dm(t,{method:o,pathWithQuery:`/api/node-agent${n}`,body:r||""},i.headers),d=new AbortController,l=i.signal?AbortSignal.any([i.signal,d.signal]):d.signal;return async function(t,s,o){const d=setTimeout(()=>o.abort(Object.assign(new Error("Node agent response header timed out."),{code:"NODE_AGENT_RESPONSE_HEADER_TIMEOUT"})),s);d.unref?.();try{return await Om(e,a,n,{...i,body:r,headers:c,signal:l})}finally{clearTimeout(d)}}(0,s,d)},proxyWebSocket(e,t,i,s,o={}){const r=Dm(e,{method:"GET",pathWithQuery:`/api/node-agent${i}`},o),c=n(e,i,s,r);let d,l=!1;return c.on("open",()=>{if(!l||c.readyState!==(c.OPEN??1))return;const e=d;d=void 0,l=!1,c.send(e)}),un(t,c,{upstreamOpenTimeoutMs:a,onUpstreamError:()=>t.close(1011,"Instance websocket proxy failed."),onUpstreamErrorBeforeOpen:()=>!0}),{send:e=>{c.readyState!==(c.OPEN??1)?(d=e,l=!0):c.send(e)},ping:()=>{const e=c.ping;if(!e)throw new Error("Direct node-agent websocket does not support ping.");e.call(c)},onPong:e=>c.on("pong",e)}}}}class Mm{direct;tunnel;proxy;constructor(e){this.direct=e.direct,this.tunnel=e.tunnel,this.proxy=e.proxy}setTunnel(e){this.tunnel=e}setProxy(e){this.proxy=e}resolve(e){if(!1===e.connectionEnabled){const e=new Error("Node agent connection is disabled locally.");throw Object.assign(e,{statusCode:409,code:"NODE_AGENT_CONNECTION_DISABLED"}),e}if("control-plane-proxy"===e.connectionMode){if(!this.proxy){const e=new Error("Control-plane proxy transport is not available.");throw Object.assign(e,{statusCode:503,code:"CONTROL_PLANE_PROXY_TRANSPORT_UNAVAILABLE"}),e}return this.proxy}if("reverse-wss"!==e.connectionMode)return this.direct;if(!this.tunnel){const e=new Error("Reverse node agent transport is not available.");throw Object.assign(e,{statusCode:503,code:"NODE_AGENT_REVERSE_TRANSPORT_UNAVAILABLE"}),e}return this.tunnel}}function qm(e,t,n,i){const s=new Error(e,void 0===i?void 0:{cause:i});return Object.assign(s,{code:t,statusCode:n,retryable:n>=500}),s}function Um(e,t){if("control-plane-proxy"!==e.connectionPath.kind)throw qm("Control-plane proxy transport requires a proxy connection path.","CONTROL_PLANE_PROXY_CONFIGURATION_INVALID",400);const n=t(e);if(!n)throw qm("Control-plane proxy credential is missing.","CONTROL_PLANE_PROXY_CREDENTIAL_REQUIRED",503);if(n.nodeId!==e.id||n.proxyBindingId!==e.connectionPath.proxyBindingId||n.targetNodeId!==e.connectionPath.targetNodeId)throw qm("Control-plane proxy credential does not match the node connection identity.","CONTROL_PLANE_PROXY_CREDENTIAL_MISMATCH",409);return n}function $m(e,t){const n=new Headers(t);n.set(Ka,Ma),n.set(Ya,e.sourceControlPlaneId),n.set(Xa,e.bindingKeyId),n.set(Ja,e.credential);const s=Fa.safeParse(n.get("x-request-id"));return n.set("x-request-id",s.success?s.data:`proxy_request_${i.randomUUID().replace(/-/g,"")}`),Object.fromEntries(n.entries())}function Bm(e){const t=Ga.safeParse(e);if(t.success)return t.data;const n=qm("Control-plane proxy route is invalid.",Qa.RouteInvalid,400);throw Object.assign(n,{issues:t.error.issues}),n}function Fm(e,t,n){return t?new b.WebSocket(e,t,{headers:n}):new b.WebSocket(e,{headers:n})}class Hm{credentialForNode;fetchImpl;openWebSocket;constructor(e){this.credentialForNode=e.credentialForNode,this.fetchImpl=e.fetchImpl||fetch,this.openWebSocket=e.openWebSocket||Fm}async fetch(e,t,n={}){const i=Um(e,this.credentialForNode),s=function(e,t){const n=new URL(Bm(t),"https://node-agent.invalid"),i=new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}/http${n.pathname}`,e.proxyOrigin);return i.search=n.search,i}(i,t);try{return await this.fetchImpl(s,{...n,headers:$m(i,n.headers)})}catch(e){if(function(e){return e instanceof Error&&("AbortError"===e.name||"ABORT_ERR"===e.code)}(e))throw e;throw qm(`Trusted control-plane proxy ${i.proxyOrigin} is unavailable.`,"CONTROL_PLANE_PROXY_UNAVAILABLE",503,e)}}request(e,t,n={}){return this.fetch(e,t,n)}requestStream(e,t,n={}){return this.fetch(e,t,n)}proxyWebSocket(e,t,n,i,s={}){const a=Um(e,this.credentialForNode),o=this.openWebSocket(function(e,t){const n=new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}/websocket`,e.proxyOrigin);return n.protocol="wss:",n.searchParams.set("route",Bm(t)),n}(a,n).toString(),i,$m(a,s));let r,c=!1;return o.on("open",()=>{if(!c||o.readyState!==(o.OPEN??1))return;const e=r;r=void 0,c=!1,o.send(e)}),un(t,o,{onUpstreamError:()=>t.close(1011,"Control-plane proxy websocket failed."),onUpstreamErrorBeforeOpen:()=>!0}),{send:e=>{o.readyState!==(o.OPEN??1)?(r=e,c=!0):o.send(e)},ping:()=>{const e=o.ping;if(!e)throw new Error("Control-plane proxy websocket does not support ping.");e.call(o)},onPong:e=>o.on("pong",e)}}}const Gm=new Set(Object.keys(yo.shape)),Wm=new Set(Object.keys(bo.shape));function Vm(e,t,n){if(!e||"object"!=typeof e||Array.isArray(e))return e;const i=e,s=Object.keys(i).filter(e=>!t.has(e));return s.length&&n?.(s),Object.fromEntries([...t].filter(e=>e in i).map(e=>[e,i[e]]))}function Km(e){const{credential:t,...n}=e;return n}class Ym{pendingClaims;nodeCredentials;identity;constructor(e,t){this.pendingClaims=new Qd(e.pendingClaimsDir,{schema:yo,sanitize:e=>function(e){return Vm(e,Gm,e=>t?.("unknown stored pending proxy claim fields were ignored",{fields:e}))}(e),logger:t,directoryMode:448,fileMode:384}),this.nodeCredentials=new Qd(e.nodeCredentialsDir,{schema:bo,sanitize:e=>function(e){return Vm(e,Wm,e=>t?.("unknown stored proxy node credential fields were ignored",{fields:e}))}(e),logger:t,directoryMode:448,fileMode:384}),this.identity=new Zd(e.identityPath,()=>({controlPlaneId:Xd("control_plane")}),{schema:f.z.object({controlPlaneId:f.z.string().trim().min(1).max(160)}).strip(),logger:t,directoryMode:448,fileMode:384})}init(e=Date.now()){return this.pendingClaims.init(),this.nodeCredentials.init(),this.identity.init(),this.gcPendingClaims(e)}controlPlaneId(){return this.identity.get().controlPlaneId}pendingClaimByClaimId(e){return this.pendingClaims.list().find(t=>t.claimId===e)}pendingClaimByReference(e){return this.pendingClaims.get(e)||this.pendingClaimByClaimId(e)}putPendingClaim(e){const t=this.pendingClaimByClaimId(e.claimId);if(!t)return this.pendingClaims.put(e);if(t.proxyOrigin!==e.proxyOrigin||t.requestedName!==e.requestedName||t.sourceControlPlaneId!==e.sourceControlPlaneId||t.targetNodeId!==e.targetNodeId||t.bindingKeyId!==e.bindingKeyId||t.credential!==e.credential){const e=new Error("Pending proxy claim identity conflicts with an existing claim.");throw Object.assign(e,{code:"CONTROL_PLANE_PROXY_BINDING_IDENTITY_CONFLICT",statusCode:409}),e}return t}publicPendingClaims(){return this.pendingClaims.list().map(Km)}nodeCredential(e){return this.nodeCredentials.list().find(t=>t.nodeId===e)}putNodeCredential(e){const t=this.nodeCredential(e.nodeId);if(t&&(t.proxyOrigin!==e.proxyOrigin||t.proxyBindingId!==e.proxyBindingId||t.targetNodeId!==e.targetNodeId||t.sourceControlPlaneId!==e.sourceControlPlaneId||t.bindingKeyId!==e.bindingKeyId||t.credential!==e.credential)){const e=new Error("Proxy node credential conflicts with the existing node identity.");throw Object.assign(e,{code:"CONTROL_PLANE_PROXY_NODE_IDENTITY_CONFLICT",statusCode:409}),e}return t||this.nodeCredentials.put(e)}deleteNodeCredential(e){const t=this.nodeCredential(e);return!!t&&this.nodeCredentials.delete(t.id)}gcNodeCredentials(e){const t=[];for(const n of this.nodeCredentials.list())e(n)||(this.nodeCredentials.delete(n.id),t.push(n.id));return t}promotePendingClaim(e,t){const n=this.pendingClaimByClaimId(e);if(!n)return;if(n.proxyOrigin!==t.proxyOrigin||n.sourceControlPlaneId!==t.sourceControlPlaneId||void 0!==n.targetNodeId&&n.targetNodeId!==t.targetNodeId||n.bindingKeyId!==t.bindingKeyId||n.credential!==t.credential){const e=new Error("Proxy node credential does not match the pending claim identity.");throw Object.assign(e,{code:"CONTROL_PLANE_PROXY_BINDING_IDENTITY_CONFLICT",statusCode:409}),e}const i=this.putNodeCredential(t);return this.pendingClaims.delete(n.id),i}markCompensationRequired(e){const t=this.pendingClaimByClaimId(e);if(t)return this.pendingClaims.patch(t.id,{status:"compensation-required"})}cancelPendingClaim(e,t){const n=this.pendingClaimByClaimId(e);return n?t?(this.pendingClaims.patch(n.id,{status:"compensation-required"}),{deleted:!1,compensationRequired:!0}):{deleted:this.pendingClaims.delete(n.id),compensationRequired:!1}:{deleted:!1,compensationRequired:!1}}completePendingClaimCompensation(e){const t=this.pendingClaimByClaimId(e);return!(!t||"compensation-required"!==t.status)&&this.pendingClaims.delete(t.id)}forceDeletePendingClaim(e){const t=this.pendingClaimByReference(e);return!!t&&this.pendingClaims.delete(t.id)}gcPendingClaims(e=Date.now()){const t=[];for(const n of this.pendingClaims.list()){if("compensation-required"===n.status)continue;const i=Date.parse(n.expiresAt);!Number.isFinite(i)||i>e||(this.pendingClaims.delete(n.id),t.push(n.id))}return t}}const Xm=f.z.string().trim().min(1).max(120).regex(/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/),Jm=f.z.string().datetime(),Qm=f.z.object({sessionReadAgents:f.z.array(f.z.string().trim().min(1).max(120)).max(100).default([]),turnReadAgents:f.z.array(f.z.string().trim().min(1).max(120)).max(100).default([]),liveItemAgents:f.z.array(f.z.string().trim().min(1).max(120)).max(100).default([])}).passthrough();const Zm=f.z.object({metadataAgents:f.z.array(f.z.string().trim().min(1).max(120)).max(100).default([]),contentAgents:f.z.array(f.z.string().trim().min(1).max(120)).max(100).default([]),uploadAgents:f.z.array(f.z.string().trim().min(1).max(120)).max(100).default([]),retentionSettings:f.z.boolean().default(!1)}).passthrough(),eh=f.z.object({aiSessionTimeline:Qm.default(function(){return{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}}),aiSessionConversationAttachments:Zm.optional(),aiSessionProviders:xo.optional()}).passthrough(),th=f.z.enum(["connecting","handshaking","healthy","reconnecting","suspect","offline"]),nh=f.z.enum(["start","stop","restart","retry-image"]);f.z.object({instanceId:Xm,revision:f.z.number().int().nonnegative(),updatedAt:Jm,status:f.z.enum(["created","provisioning","starting","registering","registered","running","stopping","stopped","deleting","failed","unhealthy"]),health:f.z.enum(["unknown","ok","degraded","failed"]),connectionStatus:f.z.enum(["unknown","online","offline","endpoint-unreachable"]),ready:f.z.boolean(),lastHeartbeatAt:Jm.optional()}).strip();const ih=f.z.object({code:f.z.string().trim().min(1).max(120),message:f.z.string().trim().min(1).max(2048)}).strict(),sh=f.z.enum(["instances","runtimes","models"]),ah=f.z.enum(["uninitialized","loading","ready","stale","error"]),oh=f.z.object({nodeId:Xm,resource:sh,phase:ah,revision:f.z.number().int().nonnegative().optional(),updatedAt:Jm.optional(),error:f.z.object({nodeId:Xm,route:f.z.string().trim().min(1).max(500),method:f.z.string().trim().min(1).max(20),code:f.z.string().trim().min(1).max(120),message:f.z.string().trim().min(1).max(4096),statusCode:f.z.number().int().optional(),issues:f.z.array(f.z.object({path:f.z.array(f.z.union([f.z.string(),f.z.number()])).optional(),message:f.z.string()}).passthrough()).optional()}).passthrough().optional()}).strict();oh.extend({contentChanged:f.z.boolean().optional()}).strict(),f.z.object({nodeStates:f.z.array(oh).default([])}).passthrough();const rh=f.z.object({id:Xm,name:f.z.string().trim().min(1).max(160),status:f.z.enum(["unknown","online","offline","degraded"]),health:f.z.enum(["unknown","ok","degraded","failed"]),connectionMode:f.z.enum(["local-ipc","local-loopback","direct-http","reverse-wss","control-plane-proxy"]),connectionPhase:th.optional(),lastSeenAt:Jm.optional(),observedAt:Jm,capabilities:f.z.array(f.z.string().trim().min(1).max(120)).max(256),error:ih.optional()}).strict();f.z.array(rh);const ch=f.z.object({id:f.z.string().trim().min(1).max(120),name:f.z.string().trim().min(1).max(120),kind:f.z.enum(["tty","gui","web"]),supportsCwdSelection:f.z.boolean()}).strict(),dh=f.z.object({id:Xm,name:f.z.string().trim().min(1).max(160),nodeId:Xm,status:f.z.enum(["created","provisioning","starting","registering","registered","running","stopping","stopped","deleting","failed","unhealthy"]),health:f.z.enum(["unknown","ok","degraded","failed"]),connectionStatus:f.z.enum(["unknown","online","offline","endpoint-unreachable"]),ready:f.z.boolean(),capabilities:eh.default({aiSessionTimeline:{sessionReadAgents:[],turnReadAgents:[],liveItemAgents:[]}}),config:f.z.object({defaultCodexPermissionMode:di.default("ask"),aiSessionMaxFileAttachmentBytes:f.z.number().int().positive().default(fn)}).strict().default({defaultCodexPermissionMode:"ask",aiSessionMaxFileAttachmentBytes:fn}),lastHeartbeatAt:Jm.optional(),heartbeatAgeMs:f.z.number().int().nonnegative().optional(),observedAt:Jm,runtime:f.z.object({id:Xm,name:f.z.string().trim().min(1).max(160).optional(),type:f.z.enum(["docker","kubernetes","local"]).optional()}).strict(),workspace:f.z.object({status:f.z.enum(["unknown","pending","ready","failed"]),path:f.z.string().trim().max(4096).optional()}).strict(),protocol:f.z.object({version:f.z.string().optional(),compatible:f.z.boolean(),warning:f.z.string().trim().min(1).max(500).optional()}).strict(),aiSessions:ds,availableActions:f.z.array(nh).max(4).default([]),availableApps:f.z.array(ch).max(256).default([]),availableAgents:f.z.array(ch).max(256),error:ih.optional()}).strict();function lh(e){if(!e||"object"!=typeof e)return;const t=e,n=zr.safeParse(t.build),i=Jo.safeParse(t.platform),s=Qo.safeParse(t.arch),a=qc.safeParse(t.capabilities);return{..."boolean"==typeof t.ok?{ok:t.ok}:{},..."string"==typeof t.role?{role:t.role}:{},..."string"==typeof t.nodeId?{nodeId:t.nodeId}:{},..."string"==typeof t.protocolVersion?{protocolVersion:t.protocolVersion}:{},...i.success?{platform:i.data}:{},...s.success?{arch:s.data}:{},...a.success?{capabilities:a.data}:{},...n.success?{build:n.data}:{},..."string"==typeof t.serverTime?{serverTime:t.serverTime}:{}}}function ph(e){const{agent:t,...n}=e.capabilities,{secret:i,...s}=e.auth,a=s.pairing?{...s.pairing,joinToken:void 0}:void 0,o=lh(t);return{...e,auth:a?{...s,pairing:a}:s,capabilities:o?{...n,agent:o}:n}}function uh(e){return"local-folder"===e.type?{mode:"local-bind",path:"/workspace",readOnly:!1}:{mode:"git-clone",path:"/workspace",readOnly:!1}}function mh(e){return function(e){const{registrationToken:t,target:n,agentStatus:i,targetStatus:s,uiAccessStatus:a,...o}=e;return o}(function(e){const t=`/instances/${encodeURIComponent(e.id)}`,n={strategy:"control-plane-proxy",web:`${t}/`,api:`${t}/api`,ws:`${t}/api`,status:"online"===e.connectionStatus||"online"===e.agentStatus?"reachable":"endpoint-unreachable"};return{...e,access:n}}(e))}function hh(e){const{key:t,...n}=e;return{...n,keyPreview:(i=e.key,i.length<=8?"set":`${i.slice(0,4)}...${i.slice(-4)}`),keySet:!0};var i}function gh(e){return e?e instanceof Headers?Object.fromEntries(e.entries()):Array.isArray(e)?Object.fromEntries(e.map(([e,t])=>[e,t])):Object.fromEntries(Object.entries(e).map(([e,t])=>[e,String(t)])):{}}function fh(e){const t=String(e||"").split(":");if(3===t.length&&"ai"===t[1]&&t[0]&&t[2])return{instanceId:t[0],aiSessionId:t[2]}}function yh(e){return e instanceof Error?e.message:String(e)}function bh(e,t){const n=new Error(t);throw Object.assign(n,{statusCode:404,code:e}),n}f.z.array(dh);const vh=f.z.object({proxyOrigin:Ha,inviteToken:f.z.string().trim().min(24).max(512),name:f.z.string().trim().min(1).max(160).optional()}).strict(),Ih=f.z.object({data:f.z.object({binding:oo,closed:f.z.object({abortedRequests:f.z.number().int().nonnegative(),closedSockets:f.z.number().int().nonnegative()}).strict()}).strict()}).strict();class xh{claimOperations=new Map;options;constructor(e){this.options=e}listPendingClaims(){return this.options.privateStore.publicPendingClaims()}async claimNode(e){const t=vh.parse(e),n=Hd(),i=Xd("proxy_claim"),s={id:i,claimId:i,proxyOrigin:t.proxyOrigin,...t.name?{requestedName:t.name}:{},sourceControlPlaneId:this.options.privateStore.controlPlaneId(),bindingKeyId:Xd("proxy_key"),credential:Jd(),status:"pending",createdAt:n,updatedAt:n,expiresAt:new Date(Date.now()+864e5).toISOString()};return this.options.privateStore.putPendingClaim(s),this.withClaimLock(s.claimId,()=>this.completeClaim(s,t.inviteToken))}async resumeClaim(e){const t=this.options.privateStore.pendingClaimByReference(e);return t||bh("CONTROL_PLANE_PROXY_CLAIM_NOT_FOUND",`Proxy claim ${e} was not found.`),this.withClaimLock(t.claimId,async()=>{const t=this.options.privateStore.pendingClaimByReference(e);return t||bh("CONTROL_PLANE_PROXY_CLAIM_NOT_FOUND",`Proxy claim ${e} was not found.`),this.completeClaim(t)})}async cancelClaim(e,t=!1){const n=this.options.privateStore.pendingClaimByReference(e);return n?this.withClaimLock(n.claimId,async()=>{const n=this.options.privateStore.pendingClaimByReference(e);if(!n)return{deleted:!1,compensationRequired:!1,remoteRevoke:"not-required"};if(t)return{deleted:this.options.privateStore.forceDeletePendingClaim(e),compensationRequired:!1,remoteRevoke:"not-required",forced:!0,orphanRisk:!0};if("pending"===n.status)return{...this.options.privateStore.cancelPendingClaim(n.claimId,!1),remoteRevoke:"not-required"};let i;try{i=await this.requestClaim(n)}catch(e){throw this.compensationError(n,"Trusted control-plane proxy is unavailable; claim cancellation requires retry.",e,503,"CONTROL_PLANE_PROXY_COMPENSATION_REQUIRED",!0,{forceDeleteAllowed:!0,forceDeleteReason:"proxy-unavailable"})}const s=await this.responsePayload(i);if(!i.ok){const e=s?.error?.code;if(e===Qa.InviteInvalid||e===Qa.BindingRevoked||e===Qa.BindingUnknown)return{deleted:this.options.privateStore.completePendingClaimCompensation(n.claimId),compensationRequired:!1,remoteRevoke:e===Qa.InviteInvalid?"not-created":"already-revoked"};throw this.compensationError(n,s?.error?.message||`Proxy claim recovery failed with HTTP ${i.status}.`,void 0,i.status,e,s?.error?.retryable)}const a=ul(fo,s?.data);this.requireClaimResultIdentity(n,a);const o=this.compensationCredential(n,a);let r;try{r=await this.revokeBinding(o)}catch(e){throw this.compensationError(n,"Trusted control-plane proxy is unavailable; binding revocation requires retry.",e,503,"CONTROL_PLANE_PROXY_COMPENSATION_REQUIRED",!0,{forceDeleteAllowed:!0,forceDeleteReason:"proxy-unavailable"})}const c=await this.responsePayload(r);if(!r.ok&&c?.error?.code!==Qa.BindingRevoked&&c?.error?.code!==Qa.BindingUnknown)throw this.compensationError(n,c?.error?.message||`Proxy binding revoke failed with HTTP ${r.status}.`,void 0,r.status,c?.error?.code,c?.error?.retryable);if(r.ok)try{this.requireRevocationReceipt(c,o)}catch(e){throw this.compensationError(n,"Proxy binding revocation returned an invalid receipt; compensation requires retry.",e,502,Qa.TransportFailed,!0)}return{deleted:this.options.privateStore.completePendingClaimCompensation(n.claimId),compensationRequired:!1,remoteRevoke:r.ok?"revoked":"already-revoked"}}):{deleted:!1,compensationRequired:!1,remoteRevoke:"not-required"}}applyTargetSnapshot(e,t){const n=this.requireProxyNodeIdentity(e,t.binding.id,t.binding.targetNodeId);return this.putTargetState(n,t.target,{reachability:"reachable",bindingStatus:t.binding.status,bindingRevision:t.binding.revision,streamId:t.streamId,revision:t.revision,observedAt:t.observedAt})}applyTargetEvent(e,t){const n=this.requireProxyNodeIdentity(e,void 0,t.targetNodeId),i=n.proxyState;if(!i?.streamId||i.streamId!==t.streamId||void 0===i.revision||t.revision!==i.revision+1){const e=new Error("Proxy target event does not continue the authoritative snapshot cursor.");throw Object.assign(e,{code:Qa.SnapshotRequired,statusCode:409,retryable:!0}),e}return this.putTargetState(n,t.target,{...i,reachability:"reachable",bindingStatus:"revoked"===i.bindingStatus?"revoked":"active",revision:t.revision,observedAt:t.event.createdAt})}markUnavailable(e,t){const n=this.requireProxyNodeIdentity(e),i=Hd();return this.options.nodes.put(jc.parse({...n,status:"degraded",health:"degraded",proxyState:{...n.proxyState,reachability:"unreachable",bindingStatus:n.proxyState?.bindingStatus??"unknown",lastError:t,updatedAt:i},updatedAt:i}))}markBindingRevoked(e,t){const n=this.requireProxyNodeIdentity(e),i=Hd();return this.options.nodes.put(jc.parse({...n,status:"degraded",health:"degraded",proxyState:{...n.proxyState,reachability:"reachable",bindingStatus:"revoked",lastError:t,updatedAt:i},updatedAt:i}))}assertIdentityPatch(e,t){const n=t.connectionMode??e.connectionMode,i=t.connectionPath??e.connectionPath,s=t.auth??e.auth,a="control-plane-proxy"===e.connectionMode||"control-plane-proxy"===e.connectionPath.kind||"proxy-binding"===e.auth.mode,o="control-plane-proxy"===n||"control-plane-proxy"===i.kind||"proxy-binding"===s.mode,r=n!==e.connectionMode||JSON.stringify(i)!==JSON.stringify(e.connectionPath)||JSON.stringify(s)!==JSON.stringify(e.auth);if((a||o)&&r){const e=new Error("Proxy node connection identity can only be changed through the control-plane proxy lifecycle API.");throw Object.assign(e,{statusCode:409,code:"CONTROL_PLANE_PROXY_IDENTITY_IMMUTABLE",retryable:!1}),e}}async deleteNode(e,t=!1){if("control-plane-proxy"!==e.connectionMode)return{deleted:this.options.deleteNode(e.id),revoke:{mode:"not-proxied",orphanRisk:!1}};const n=this.options.privateStore.nodeCredential(e.id);if(!n){if(!t){const e=new Error("Proxy node credential is missing; remote binding cannot be revoked.");throw Object.assign(e,{statusCode:409,code:"CONTROL_PLANE_PROXY_CREDENTIAL_REQUIRED",retryable:!1,details:{forceDeleteAllowed:!0,forceDeleteReason:"credential-missing"}}),e}return this.forceDeleteNode(e.id)}let i;try{i=await this.revokeBinding(n)}catch(n){if(t)return this.forceDeleteNode(e.id);const i=new Error("Trusted control-plane proxy is unavailable; the binding was not revoked.",{cause:n});throw Object.assign(i,{statusCode:503,code:"CONTROL_PLANE_PROXY_REVOKE_UNAVAILABLE",retryable:!0,details:{forceDeleteAllowed:!0,forceDeleteReason:"proxy-unavailable"}}),i}const s=await this.responsePayload(i);if(!i.ok){if(s?.error?.code===Qa.BindingRevoked||s?.error?.code===Qa.BindingUnknown){const t=s.error.details?.bindingId;if(t===n.proxyBindingId)return this.finishRevokedNodeDelete(e.id)}const t=new Error(s?.error?.message||`Proxy binding revoke failed with HTTP ${i.status}.`);throw Object.assign(t,{statusCode:i.status,code:s?.error?.code||"CONTROL_PLANE_PROXY_REVOKE_FAILED",retryable:s?.error?.retryable??i.status>=500,details:{...(a=s?.error?.details,a&&"object"==typeof a&&!Array.isArray(a)?a:{}),forceDeleteAllowed:!1}}),t}var a;try{this.requireRevocationReceipt(s,n)}catch(e){if(e&&"object"==typeof e){const t=e;t.details={...t.details||{},forceDeleteAllowed:!1}}throw e}return this.finishRevokedNodeDelete(e.id)}async completeClaim(e,t){let n;this.options.privateStore.markCompensationRequired(e.claimId);try{n=await this.requestClaim(e,t)}catch(t){const n=new Error(`Trusted control-plane proxy ${e.proxyOrigin} is unavailable.`,{cause:t});throw Object.assign(n,{statusCode:503,code:"CONTROL_PLANE_PROXY_UNAVAILABLE",retryable:!0,claimId:e.claimId}),n}const i=await this.responsePayload(n);if(!n.ok){const t=i?.error?.retryable??n.status>=500;t||this.options.privateStore.completePendingClaimCompensation(e.claimId);const s=new Error(i?.error?.message||`Proxy claim failed with HTTP ${n.status}.`);throw Object.assign(s,{statusCode:n.status,code:i?.error?.code||"CONTROL_PLANE_PROXY_CLAIM_FAILED",retryable:t,details:i?.error?.details,claimId:e.claimId}),s}const s=ul(fo,i?.data);this.requireClaimResultIdentity(e,s);const a=this.options.nodes.get(s.target.id),o="control-plane-proxy"===a?.connectionMode&&"control-plane-proxy"===a.connectionPath.kind&&a.connectionPath.proxyBindingId===s.binding.id&&a.connectionPath.targetNodeId===s.target.id;if(a&&!o){this.options.privateStore.markCompensationRequired(e.claimId);const t=new Error(`Node ${s.target.id} already exists with another connection identity.`);throw Object.assign(t,{statusCode:409,code:"CONTROL_PLANE_PROXY_NODE_IDENTITY_CONFLICT",claimId:e.claimId}),t}const r={id:`proxy_credential_${s.target.id}`,nodeId:s.target.id,proxyOrigin:e.proxyOrigin,proxyBindingId:s.binding.id,targetNodeId:s.target.id,sourceControlPlaneId:e.sourceControlPlaneId,bindingKeyId:e.bindingKeyId,credential:e.credential,createdAt:e.createdAt,updatedAt:Hd()},c=a||jc.parse({id:s.target.id,name:e.requestedName||s.target.name,connectionMode:"control-plane-proxy",connectionPath:{kind:"control-plane-proxy",proxyId:new URL(e.proxyOrigin).host,proxyBindingId:s.binding.id,targetNodeId:s.target.id},connectionEnabled:!0,auth:{mode:"proxy-binding"},status:s.target.status,health:s.target.health,capabilities:s.target.capabilities,proxyState:{reachability:"reachable",bindingStatus:s.binding.status,bindingRevision:s.binding.revision,observedAt:Hd(),target:s.target,updatedAt:Hd()},labels:{},lastSeenAt:s.target.lastSeenAt,createdAt:Hd(),updatedAt:Hd()});a||this.options.nodes.put(c);try{this.options.privateStore.promotePendingClaim(e.claimId,r)}catch(e){throw a||this.options.nodes.delete(c.id),e}return{node:ph(c),binding:s.binding}}requireProxyNodeIdentity(e,t,n){const i=this.options.requireNode(e);if("control-plane-proxy"!==i.connectionMode||"control-plane-proxy"!==i.connectionPath.kind||void 0!==t&&i.connectionPath.proxyBindingId!==t||void 0!==n&&i.connectionPath.targetNodeId!==n){const e=new Error("Proxy state identity does not match the node connection path.");throw Object.assign(e,{code:Qa.BindingIdentityConflict,statusCode:409,retryable:!1}),e}return i}putTargetState(e,t,n){const i=Hd();return this.options.nodes.put(jc.parse({...e,name:t.name,status:t.status,health:t.health,capabilities:t.capabilities,lastSeenAt:t.lastSeenAt,proxyState:{...n,target:t,updatedAt:i},updatedAt:i}))}requestClaim(e,t){return this.options.fetchImpl(new URL("/api/node-proxy/claims",e.proxyOrigin),{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({protocolVersion:Ma,...t?{inviteToken:t}:{},claimId:e.claimId,sourceControlPlaneId:e.sourceControlPlaneId,...e.targetNodeId?{targetNodeId:e.targetNodeId}:{},bindingKeyId:e.bindingKeyId,credential:e.credential})})}revokeBinding(e){return this.options.fetchImpl(new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}`,e.proxyOrigin),{method:"DELETE",headers:$m(e)})}async responsePayload(e){return e.json().catch(()=>{})}requireRevocationReceipt(e,t){const n=pl(Ih,e),i=n.success?n.data.data.binding:void 0;if(!i||i.id!==t.proxyBindingId||i.sourceControlPlaneId!==t.sourceControlPlaneId||i.targetNodeId!==t.targetNodeId||i.bindingKeyId!==t.bindingKeyId||"revoked"!==i.status){const e=new Error("Proxy binding revocation receipt does not match the local binding identity.");throw Object.assign(e,{statusCode:502,code:Qa.TransportFailed,retryable:!0,details:{bindingId:t.proxyBindingId}}),e}return i}requireClaimResultIdentity(e,t){if(t.binding.claimId!==e.claimId||t.binding.sourceControlPlaneId!==e.sourceControlPlaneId||t.binding.bindingKeyId!==e.bindingKeyId||t.binding.targetNodeId!==t.target.id||void 0!==e.targetNodeId&&t.binding.targetNodeId!==e.targetNodeId){const t=new Error("Proxy claim response does not match the persisted pending identity.");throw Object.assign(t,{statusCode:409,code:Qa.BindingIdentityConflict,retryable:!1,claimId:e.claimId,compensationRequired:!0}),t}}compensationCredential(e,t){return{id:`proxy_compensation_${t.binding.id}`,nodeId:t.target.id,proxyOrigin:e.proxyOrigin,proxyBindingId:t.binding.id,targetNodeId:t.target.id,sourceControlPlaneId:e.sourceControlPlaneId,bindingKeyId:e.bindingKeyId,credential:e.credential,createdAt:e.createdAt,updatedAt:Hd()}}compensationError(e,t,n,i=503,s="CONTROL_PLANE_PROXY_COMPENSATION_REQUIRED",a=!0,o){const r=new Error(t,void 0===n?void 0:{cause:n});return Object.assign(r,{statusCode:i,code:s,retryable:a,claimId:e.claimId,compensationRequired:!0,...o?{details:o}:{}}),r}async withClaimLock(e,t){const n=(this.claimOperations.get(e)??Promise.resolve()).catch(()=>{}).then(t);this.claimOperations.set(e,n);try{return await n}finally{this.claimOperations.get(e)===n&&this.claimOperations.delete(e)}}finishRevokedNodeDelete(e){const t=this.options.deleteNode(e);return this.options.privateStore.deleteNodeCredential(e),{deleted:t,revoke:{mode:"revoked",orphanRisk:!1}}}forceDeleteNode(e){const t=this.options.deleteNode(e);return this.options.privateStore.deleteNodeCredential(e),{deleted:t,revoke:{mode:"forced",orphanRisk:!0}}}}const wh=f.z.object({id:Xr.shape.id.optional(),name:Xr.shape.name,source:Wr,defaultImageSelection:Xr.shape.defaultImageSelection,defaultNodeId:Xr.shape.defaultNodeId,workspacePolicy:Kr.optional(),labels:Xr.shape.labels.optional()}),Sh={defaultRuntimeId:Dc.shape.id.optional()},Ah=wh.extend(Sh).strict().transform(({defaultRuntimeId:e,...t})=>({...t,source:Wr.parse(t.source)})),Eh=wh.omit({id:!0}).partial().extend(Sh).strict().transform(({defaultRuntimeId:e,...t})=>({...t,...t.source?{source:Wr.parse(t.source)}:{}}));function _h(e){return 1===Array.from(e).length&&!/[\p{L}\p{N}\s]/u.test(e)&&"/"!==e&&"\\"!==e}const Th=f.z.string().refine(_h,"Mention trigger must be one printable non-alphanumeric character other than / or \\.");function zh(e){return 1===Array.from(e).length&&!/[\p{L}\p{N}\s]/u.test(e)&&"\\"!==e}const kh=f.z.string().refine(zh,"Command trigger must be one printable non-alphanumeric character other than \\."),Nh=f.z.object({publicBaseUrl:f.z.string().trim().max(2048).optional(),updateChannel:Nr.default("stable"),mentionTrigger:Th.default("@"),commandTrigger:kh.default("/"),diagnosticLogs:f.z.boolean().default(!1)}).strict().refine(e=>e.mentionTrigger!==e.commandTrigger,{path:["commandTrigger"],message:"Command and mention triggers must be different."}),Ch=f.z.object({publicBaseUrl:f.z.string().trim().max(2048).optional(),updateChannel:Nr.optional(),mentionTrigger:Th.optional(),commandTrigger:kh.optional(),diagnosticLogs:f.z.boolean().optional()}).strict(),Rh=f.z.object({id:bc.shape.id.optional(),name:bc.shape.name,description:bc.shape.description,cover:bc.shape.cover,reference:bc.shape.reference,pullPolicy:bc.shape.pullPolicy.optional(),capabilities:f.z.array(f.z.string().trim().min(1).max(80)).optional(),optionalApps:f.z.array(f.z.string().trim().min(1).max(120)).optional(),defaultEnv:bc.shape.defaultEnv.optional(),labels:bc.shape.labels.optional()}).strict(),Oh=Rh.omit({id:!0}).partial().strict(),jh=f.z.object({name:Id.shape.name.optional(),channel:Id.shape.channel.optional(),enabled:f.z.boolean().optional(),token:Id.shape.token,defaultChatId:Id.shape.defaultChatId,allowedUserIds:f.z.array(f.z.string().trim().min(1).max(240)).optional(),pollIntervalMs:Id.shape.pollIntervalMs.optional(),settings:Id.shape.settings.optional()}).strict(),Ph=jh.extend({channel:Id.shape.channel,name:Id.shape.name.optional()}),Dh=Ea.extend({id:Ea.shape.configHash}),Lh=f.z.object({name:Ea.shape.name,description:Ea.shape.description,source:wa,action:Sa,policy:Aa.partial().optional()}).strict(),Mh=Lh,qh=f.z.object({instanceIds:f.z.array(dd.shape.id).min(1),target:_a,enabled:f.z.boolean().optional()}).strict(),Uh=f.z.object({configHash:Ea.shape.configHash,enabled:f.z.boolean().optional()}).strict(),$h=f.z.object({mode:f.z.enum(["local-static-key","paired-hmac","proxy-binding"]).default("local-static-key"),keyId:jc.shape.id.optional(),secret:f.z.string().trim().max(4096).optional(),pairedAt:jc.shape.createdAt.optional(),pairing:f.z.object({status:f.z.enum(["pending","paired","expired"]).default("pending"),joinToken:f.z.string().trim().max(4096).optional(),expiresAt:jc.shape.createdAt.optional()}).strict().optional()}).strict(),Bh=f.z.object({autoImportAgentConfigs:f.z.boolean().optional(),defaultCodexPermissionMode:di.optional(),aiSessionHistoryLimit:f.z.number().int().min(1).max(es).optional(),aiSessionAttachmentRetentionDays:f.z.number().int().min(0).max(365).optional(),aiSessionMaxFileAttachmentBytes:f.z.number().int().positive().max(yn).optional()}).strict(),Fh=f.z.object({id:dd.shape.id.optional(),name:dd.shape.name.optional(),projectId:dd.shape.projectId,source:Wr.optional(),sourceSnapshot:f.z.record(f.z.string(),f.z.unknown()).optional(),nodeId:dd.shape.nodeId.optional(),runtimeId:dd.shape.runtimeId.optional(),environmentSource:Yo.optional(),imageSelection:dd.shape.imageSelection,config:Bh.optional(),modelSelection:dd.shape.modelSelection.optional(),gitCredentialRetention:em.optional(),start:f.z.boolean().default(!1)}).strict().superRefine((e,t)=>{e.environmentSource&&e.imageSelection&&t.addIssue({code:"custom",path:["environmentSource"],message:"environmentSource and imageSelection are mutually exclusive."}),e.gitCredentialRetention&&"local-folder"===e.source?.type&&t.addIssue({code:"custom",path:["gitCredentialRetention"],message:"Git credential retention requires a Git source."})}),Hh=f.z.object({name:dd.shape.name.optional(),config:Bh.optional(),modelSelection:dd.shape.modelSelection.optional()}).strict(),Gh=f.z.object({name:Jr.shape.name,endpoint:Jr.shape.endpoint,key:Jr.shape.key,model:Jr.shape.model,app:Jr.shape.app,enabled:Jr.shape.enabled.optional(),order:Jr.shape.order.optional(),labels:Jr.shape.labels.optional()}).strict(),Wh=Gh.partial().strict(),Vh=f.z.object({endpoint:Jr.shape.endpoint,key:Jr.shape.key.optional(),existingModelId:Jr.shape.id.optional()}).strict(),Kh=Vh.extend({model:Jr.shape.model,app:Jr.shape.app}).strict(),Yh=f.z.object({id:jc.shape.id.optional(),name:jc.shape.name,connectionMode:jc.shape.connectionMode.optional(),connectionPath:jc.shape.connectionPath.optional(),connectionEnabled:jc.shape.connectionEnabled.optional(),auth:$h.optional(),joinToken:f.z.string().trim().min(1).max(4096).optional(),endpoint:jc.shape.endpoint,controlEndpoint:jc.shape.controlEndpoint,containerEndpoint:jc.shape.containerEndpoint,publicWebBase:jc.shape.publicWebBase,status:f.z.enum(["unknown","online","offline","degraded"]).optional(),health:f.z.enum(["unknown","ok","degraded","failed"]).optional(),capabilities:jc.shape.capabilities.optional(),labels:jc.shape.labels.optional(),lastSeenAt:jc.shape.lastSeenAt}).strict(),Xh=f.z.object({name:jc.shape.name.optional(),connectionMode:jc.shape.connectionMode.unwrap().optional(),connectionPath:jc.shape.connectionPath.unwrap().optional(),connectionEnabled:jc.shape.connectionEnabled.unwrap().optional(),auth:$h.optional(),endpoint:jc.shape.endpoint,controlEndpoint:jc.shape.controlEndpoint,containerEndpoint:jc.shape.containerEndpoint,publicWebBase:jc.shape.publicWebBase,status:jc.shape.status.unwrap().optional(),health:jc.shape.health.unwrap().optional(),capabilities:jc.shape.capabilities.unwrap().optional(),labels:jc.shape.labels.unwrap().optional(),lastSeenAt:jc.shape.lastSeenAt}).strict(),Jh=f.z.object({controlPlaneUrl:f.z.string().trim().url().max(2048),joinToken:f.z.string().trim().min(1).max(4096),controlPlaneName:f.z.string().trim().min(1).max(160).optional(),activate:f.z.boolean().optional()}).strict(),Qh=f.z.object({nodeName:f.z.string().trim().min(1).max(160).optional(),expiresInMs:f.z.number().int().positive().max(36e5).optional()}).strict(),Zh=f.z.object({id:f.z.string().min(1),endpoint:f.z.string().min(1),nodeId:f.z.string().min(1),keyId:f.z.string().min(1),secret:f.z.string().min(1),pairedAt:f.z.string().min(1),createdAt:f.z.string().min(1),updatedAt:f.z.string().min(1)}).strict();class eg{options;activePendingPairingRevokes=new Set;constructor(e){this.options=e}async syncLocal(){const e={[this.options.localNodeLabel]:"true",[this.options.builtinNodeLabel]:"true"},t=process.env.TASK_HANDOFF_NODE_AGENT_TOKEN?.trim()||void 0,n=process.env.TASK_HANDOFF_NODE_AGENT_CONTROL_ENDPOINT||process.env.TASK_HANDOFF_NODE_AGENT_ENDPOINT||"http://127.0.0.1:8091",i=function(e){return km(e)?"local-ipc":"local-loopback"}(n),s=jc.parse({id:"node_local_probe",name:"Local Node Probe",connectionMode:i,auth:{mode:"local-static-key",secret:t},labels:e,createdAt:Hd(),updatedAt:Hd()}),a=await this.inspect(n,s),o=Hd(),r=this.options.nodes.get(a.nodeId);for(const e of this.options.nodes.list())"true"===e.labels[this.options.localNodeLabel]&&e.id!==a.nodeId&&this.options.nodes.delete(e.id);return this.options.nodes.put(jc.parse({...r||{},id:a.nodeId,name:r?.name||"Local Node",connectionMode:i,auth:{mode:"local-static-key",secret:t},endpoint:n,controlEndpoint:n,containerEndpoint:process.env.TASK_HANDOFF_NODE_AGENT_CONTAINER_URL,publicWebBase:process.env.TASK_HANDOFF_INSTANCE_PUBLIC_WEB_BASE,status:"online",health:"ok",capabilities:{...r?.capabilities||{},agent:lh(a.data)},labels:{...r?.labels||{},...e},createdAt:r?.createdAt||o,updatedAt:o}))}async create(e){const t=Yh.parse(e),n=Hd(),i=t.connectionMode||"direct-http";let s="auth"in(e&&"object"==typeof e&&!Array.isArray(e)?e:{})?t.auth:{mode:"local-ipc"===i||"local-loopback"===i?"local-static-key":"paired-hmac"};const a="direct-http"===i||"reverse-wss"===i;if(a&&"paired-hmac"!==s.mode)throw tg("Remote node connections require paired-HMAC authentication.","NODE_AGENT_REMOTE_REQUIRES_PAIRED_HMAC");const o=t.controlEndpoint||t.endpoint;if(!o&&"reverse-wss"!==i)throw tg("Node agent direct HTTP mode requires an endpoint.","NODE_AGENT_ENDPOINT_REQUIRED");const r=t.joinToken&&o?await this.completePairing(o,t.joinToken):void 0;let c,d=!1;try{if(c=r&&o?this.pendingPairingRevoke(o,r):void 0,c&&(this.activePendingPairingRevokes.add(c.id),this.options.pendingPairingRevokes?.put(c)),r){if(r.invalidResponse||r.unsafePublicIdentifiers)throw Object.assign(new Error("Node agent pairing response reflected secret material in a public identifier."),{statusCode:502,code:"NODE_AGENT_PAIRING_RESPONSE_INVALID"});s={mode:"paired-hmac",keyId:r.keyId,secret:r.secret,pairedAt:r.pairedAt,pairing:{status:"paired"}}}if(a&&!s.secret)throw tg("Remote node connections require a paired node secret or join token.","NODE_AGENT_REMOTE_SECRET_REQUIRED");if(a&&!s.keyId)throw tg("Remote node connections require a paired key id.","NODE_AGENT_REMOTE_KEY_ID_REQUIRED");const e=t.id||r?.nodeId||Xd("node"),u=jc.parse({id:e,name:t.name,connectionMode:i,auth:s,labels:t.labels||{},createdAt:n,updatedAt:n}),m="reverse-wss"===i&&(t.id||r?.nodeId)?void 0:await this.inspect(o||"",u),h=t.id||r?.nodeId||m?.nodeId||e;if(!h)throw tg("Node id is required.","NODE_ID_REQUIRED");if(r&&t.id&&t.id!==r.nodeId)throw tg(`Paired node id ${r.nodeId} does not match requested node id ${t.id}.`,"NODE_AGENT_ID_MISMATCH");if(t.id&&m?.nodeId&&m.nodeId!==t.id)throw tg(`Node agent id ${m.nodeId} does not match requested node id ${t.id}.`,"NODE_AGENT_ID_MISMATCH");if(r&&m?.nodeId&&m.nodeId!==r.nodeId)throw Object.assign(new Error("Node agent health identity did not match the completed pairing."),{statusCode:502,code:"NODE_AGENT_PAIRING_IDENTITY_MISMATCH"});const{joinToken:g,...f}=t,y=jc.parse({...f,id:h,connectionMode:i,auth:s,endpoint:o,controlEndpoint:o,status:t.status||(m?"online":"unknown"),health:t.health||(m?"ok":"unknown"),capabilities:{...t.capabilities||{},...m?{agent:lh(m.data)}:{}},labels:t.labels||{},createdAt:n,updatedAt:n});if(r&&(l=y,p=r.secret,og(ph(l),p)))throw Object.assign(new Error("Node agent health response reflected pairing secret material."),{statusCode:502,code:"NODE_AGENT_PAIRING_SECRET_REFLECTED"});d=!0;const b=this.options.nodes.put(y);return this.clearPendingPairingRevoke(c,r),b}catch(e){if(r&&o){const t=this.pairingPersistence(r);if("present"===t.state)return this.clearPendingPairingRevoke(c,r),t.node;if("unknown"===t.state&&d)throw rg(Object.assign(new Error("Node creation persistence outcome is uncertain; pairing compensation is pending."),{statusCode:503,code:"NODE_AGENT_PAIRING_PERSISTENCE_UNCERTAIN",retryable:!0}),r.secret);throw await this.compensatePairing(o,r,e),this.clearPendingPairingRevoke(c,r),rg(e,r.secret)}throw e}finally{c&&this.activePendingPairingRevokes.delete(c.id)}var l,p}async recoverPendingPairingRevokes(){const e=(this.options.pendingPairingRevokes?.list()||[]).filter(e=>!this.activePendingPairingRevokes.has(e.id));await Promise.all(e.map(async e=>{try{const t={nodeId:e.nodeId,keyId:e.keyId,secret:e.secret,pairedAt:e.pairedAt,invalidResponse:!1,unsafePublicIdentifiers:!1},n=this.pairingPersistence(t);if("present"===n.state)return void this.clearPendingPairingRevoke(e,t);if("unknown"===n.state)return;await this.compensatePairing(e.endpoint,t,Object.assign(new Error("Recovering a pending pairing revocation."),{code:"NODE_AGENT_PAIRING_REVOCATION_PENDING"})),this.clearPendingPairingRevoke(e,t)}catch{}}))}pendingPairingRevoke(e,t){if(!this.options.pendingPairingRevokes)return;const n=Hd();return Zh.parse({id:Xd("pairing_revoke"),endpoint:e,nodeId:t.nodeId,keyId:t.keyId,secret:t.secret,pairedAt:t.pairedAt,createdAt:n,updatedAt:n})}pairingPersistence(e){let t;try{t=this.options.nodes.get(e.nodeId)}catch{return{state:"unknown"}}return"paired-hmac"===t?.auth.mode&&t.auth.keyId===e.keyId&&t.auth.secret===e.secret?{state:"present",node:t}:{state:"absent"}}clearPendingPairingRevoke(e,t){if(e)try{this.options.pendingPairingRevokes?.delete(e.id)}catch(e){try{this.options.warn({nodeId:t?sg(t.nodeId,t.secret):void 0,keyId:t?sg(t.keyId,t.secret):void 0,errorCode:"NODE_AGENT_PAIRING_OUTBOX_CLEANUP_FAILED"},"node agent pairing outbox cleanup failed; recovery will retry")}catch{}}}async inspect(e,t){const n="/health",i=t?_m(t,{method:"GET",pathWithQuery:`/api/node-agent${n}`}):{},s=await Om(this.options.fetchImpl,e,n,{headers:i}),a=await s.json().catch(()=>({}));if(!s.ok)throw this.options.warn(ag({nodeEndpoint:e,statusCode:s.status,errorCode:"NODE_AGENT_HEALTH_FAILED"},t?.auth.secret),"node agent health check failed"),Object.assign(new Error(a.error?.message||`Node agent health check failed with HTTP ${s.status}`),{statusCode:s.status,code:"NODE_AGENT_HEALTH_FAILED"});const o="string"==typeof a.data?.nodeId&&a.data.nodeId.trim()?a.data.nodeId.trim():void 0;if(!o)throw this.options.warn(ag({nodeEndpoint:e,errorCode:"NODE_AGENT_ID_MISSING"},t?.auth.secret),"node agent health response missing node id"),Object.assign(new Error("Node agent health response did not include nodeId."),{statusCode:502,code:"NODE_AGENT_ID_MISSING"});const r=pl(zr,a.data?.build);return a.data?.protocolVersion!==wo&&this.options.warn(ag({nodeId:o,nodeEndpoint:e,expectedProtocolVersion:wo,actualProtocolVersion:a.data?.protocolVersion,build:r.success?r.data:void 0,errorCode:"PROTOCOL_VERSION_MISMATCH"},t?.auth.secret),"node agent protocol version mismatch"),this.options.info(ag({nodeId:o,nodeEndpoint:e,protocolVersion:a.data.protocolVersion,build:r.success?r.data:void 0},t?.auth.secret),"node agent health check ok"),{nodeId:o,data:a.data||{}}}async completePairing(e,t){const n=await this.options.fetchImpl(`${e.replace(/\/$/,"")}/api/node-agent/pairing/complete`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({joinToken:t,controlPlaneName:"Control Plane"})}),i=await n.json().catch(()=>({}));if(!n.ok)throw Object.assign(new Error(i.error?.message||`Node agent pairing failed with status ${n.status}.`),{statusCode:n.status,code:"NODE_AGENT_PAIRING_FAILED"});const s=i.data;if("string"!=typeof s?.nodeId||!s.nodeId.trim()||"string"!=typeof s?.keyId||!s.keyId.trim()||"string"!=typeof s?.secret||!s.secret.trim())throw Object.assign(new Error("Node agent pairing response did not include nodeId, keyId, and secret."),{statusCode:502,code:"NODE_AGENT_PAIRING_RESPONSE_INVALID"});const a=pl(Kc,s),o=s.nodeId.trim(),r=s.keyId.trim(),c=s.secret.trim();return{nodeId:o,keyId:r,secret:c,pairedAt:a.success?a.data.pairedAt:Hd(),invalidResponse:!a.success,unsafePublicIdentifiers:o.includes(c)||r.includes(c)}}async compensatePairing(e,t,n){const i="/pairing/current",s=`/api/node-agent${i}`,a={id:t.nodeId,connectionMode:"direct-http",auth:{mode:"paired-hmac",keyId:t.keyId,secret:t.secret}};try{const o=await Om(this.options.fetchImpl,e,i,{method:"DELETE",headers:_m(a,{method:"DELETE",pathWithQuery:s}),signal:AbortSignal.timeout(1e4)}),r=await o.json().catch(()=>({}));if(!o.ok)throw Object.assign(new Error(`Node agent pairing revoke failed with HTTP ${o.status}.`),{statusCode:o.status,code:ig(r.error?.code,t.secret,"NODE_AGENT_PAIRING_REVOKE_FAILED"),retryable:408===o.status||429===o.status||o.status>=500});const c=pl(Xc,r.data);if(!c.success)throw Object.assign(new Error("Node agent pairing revoke receipt was invalid."),{statusCode:502,code:"NODE_AGENT_PAIRING_REVOKE_RECEIPT_INVALID",retryable:!1});if(c.data.keyId!==t.keyId)throw Object.assign(new Error("Node agent pairing revoke receipt did not match the paired key."),{statusCode:502,code:"NODE_AGENT_PAIRING_REVOKE_RECEIPT_MISMATCH",retryable:!1});try{this.options.info({nodeId:sg(t.nodeId,t.secret),keyId:sg(t.keyId,t.secret),originalErrorCode:ng(n,t.secret)},"node agent pairing revoked after node creation failed")}catch{}}catch(e){const i={nodeId:sg(t.nodeId,t.secret),keyId:sg(t.keyId,t.secret),originalErrorCode:ng(n,t.secret),compensationErrorCode:ng(e,t.secret)};try{this.options.warn(i,"node agent pairing compensation failed")}catch{}throw Object.assign(new Error("Node creation failed after pairing, and the remote pairing could not be revoked."),{statusCode:502,code:"NODE_AGENT_PAIRING_COMPENSATION_FAILED",retryable:(o=e,!o||"object"!=typeof o||!("retryable"in o)||"boolean"!=typeof o.retryable||o.retryable),details:i})}var o}}function tg(e,t){return Object.assign(new Error(e),{statusCode:400,code:t})}function ng(e,t){return ig(e&&"object"==typeof e&&"code"in e?e.code:void 0,t,"UNKNOWN_ERROR")}function ig(e,t,n){return"string"!=typeof e||!/^[A-Z][A-Z0-9_]{0,127}$/.test(e)||e.includes(t)?n:e}function sg(e,t){return e.includes(t)?"[redacted]":e}function ag(e,t){if(!t)return e;const n=e=>"string"==typeof e?e.includes(t)?"[redacted]":e:Array.isArray(e)?e.map(n):e&&"object"==typeof e?Object.fromEntries(Object.entries(e).map(([e,i])=>[e.includes(t)?"[redacted-key]":e,n(i)])):e;return n(e)}function og(e,t){return"string"==typeof e?e.includes(t):Array.isArray(e)?e.some(e=>og(e,t)):!(!e||"object"!=typeof e)&&Object.entries(e).some(([e,n])=>e.includes(t)||og(n,t))}function rg(e,t){const n=e instanceof Error&&!e.message.includes(t)?e.message:"Node creation failed after pairing.",i=e&&"object"==typeof e&&"statusCode"in e&&"number"==typeof e.statusCode?e.statusCode:502,s=Object.assign(new Error(n),{statusCode:i,code:ng(e,t)});return e&&"object"==typeof e&&"retryable"in e&&"boolean"==typeof e.retryable&&Object.assign(s,{retryable:e.retryable}),s}class cg{values=new Map;put(e,t,n=Date.now()){this.prune(n),this.values.set(e,t)}take(e,t=Date.now()){this.prune(t);const n=this.values.get(e);return n&&this.values.delete(e),n}peek(e,t=Date.now()){return this.prune(t),this.values.get(e)}delete(e,t=Date.now()){this.prune(t);const n=this.values.get(e);return n&&this.values.delete(e),n}list(e=Date.now()){return this.prune(e),[...this.values.values()]}prune(e=Date.now()){for(const[t,n]of this.values)Date.parse(n.expiresAt)<=e&&this.values.delete(t)}}const dg=f.z.object({joinToken:f.z.string().trim().min(1).max(4096),nodeId:jc.shape.id,nodeName:jc.shape.name.optional(),keyId:f.z.string().trim().min(1).max(160),secret:f.z.string().trim().min(1).max(4096),pairedAt:f.z.string().datetime().optional()}).strict();class lg{options;invites=new cg;completedInvites=new cg;constructor(e){this.options=e}createInvite(e={}){const t=Qh.parse(e&&"object"==typeof e?e:{}),n=Jd(),i={id:Xd("node_join"),tokenHash:pg(n),expiresAt:new Date(Date.now()+(t.expiresInMs||6e5)).toISOString(),...t.nodeName?{nodeName:t.nodeName}:{}};return this.invites.put(i.tokenHash,i),{id:i.id,joinToken:n,expiresAt:i.expiresAt}}status(e){const t=this.completedInvites.peek(e);if(t)return{id:e,status:"completed",nodeId:t.nodeId};if(this.invites.list().some(t=>t.id===e))return{id:e,status:"pending"};throw Object.assign(new Error(`Node join invite ${e} was not found or has expired.`),{statusCode:404,code:"NODE_JOIN_INVITE_NOT_FOUND"})}complete(e){const t=dg.parse(e),n=pg(t.joinToken),i=this.invites.take(n);if(!i)throw Object.assign(new Error("Node join token is invalid or expired."),{statusCode:401,code:"NODE_JOIN_TOKEN_INVALID"});const s=Hd();if(this.options.nodes.get(t.nodeId))throw Object.assign(new Error(`Node ${t.nodeId} already exists in this control-plane.`),{statusCode:409,code:"NODE_JOIN_NODE_ALREADY_EXISTS"});const a=this.options.nodes.put(jc.parse({id:t.nodeId,name:t.nodeName||i.nodeName||t.nodeId,connectionMode:"reverse-wss",auth:{mode:"paired-hmac",keyId:t.keyId,secret:t.secret,pairedAt:t.pairedAt||s,pairing:{status:"paired"}},status:"unknown",health:"unknown",capabilities:{},labels:{},createdAt:s,updatedAt:s}));return this.completedInvites.put(i.id,{nodeId:a.id,expiresAt:new Date(Date.now()+6e5).toISOString()}),{node:a,inviteId:i.id}}}function pg(e){return i.createHash("sha256").update(e).digest("hex")}function ug(e,t){const n=mg(e);return n.pathname=`${n.pathname.replace(/\/+$/,"")}/${t.replace(/^\/+/,"")}`,n.search="",n.hash="",n.toString()}function mg(e){let t;try{t=new URL(e.trim())}catch{throw yg("MODEL_ENDPOINT_INVALID","The model endpoint must be a valid HTTP or HTTPS URL.",400)}if("http:"!==t.protocol&&"https:"!==t.protocol||t.username||t.password)throw yg("MODEL_ENDPOINT_INVALID","The model endpoint must be an HTTP or HTTPS URL without embedded credentials.",400);return t}async function hg(e,t,n){try{return await e(t,{...n,redirect:"error",signal:AbortSignal.timeout(15e3)})}catch(e){const t=e&&"object"==typeof e&&"name"in e&&"TimeoutError"===e.name;throw yg(t?"MODEL_ENDPOINT_TIMEOUT":"MODEL_ENDPOINT_UNREACHABLE",t?"The model endpoint timed out.":"The model endpoint could not be reached.",t?504:502)}}async function gg(e,t){const n=await e.text();if(n.length>1e6)throw yg(t,"The model endpoint response was too large.",502);try{const e=JSON.parse(n);if(!e||"object"!=typeof e||Array.isArray(e))throw new Error("not an object");return e}catch{throw yg(t,"The model endpoint returned invalid JSON.",502)}}function fg(e,t){return yg(e,401===t||403===t?"The model endpoint rejected the API key.":"The model endpoint rejected the request.",502,t)}function yg(e,t,n,i){return Object.assign(new Error(t),{code:e,statusCode:n,...i?{details:{upstreamStatus:i}}:{}})}function bg(e,t){e.includes(t)||e.push(t)}function vg(e){const t=new Set;return e.filter(e=>!t.has(e.id)&&(t.add(e.id),!0))}class Ig{options;constructor(e){this.options=e}list(){return this.listAll().map(hh)}async listFederated(e,t=!1){const n=this.options.listNodes(),i=t?this.options.gateway.readFleetModels(n):await this.options.gateway.listFleetModels(n,{signal:e});t&&this.options.gateway.refreshFleetModels(n);const s=new Map;for(const e of this.listAll())s.set(e.id,{id:e.id,model:hh(e),locations:[{type:"control-plane",name:e.name,enabled:e.enabled,order:e.order}],referenceCount:0});for(const{nodeId:e,model:t}of i.items){const{referenceCount:n,...i}=t,a=s.get(t.id);a?(a.locations.push({type:"node",nodeId:e,name:t.name,enabled:t.enabled,order:t.order,referenceCount:t.referenceCount}),a.referenceCount+=t.referenceCount):s.set(t.id,{id:t.id,model:i,locations:[{type:"node",nodeId:e,name:t.name,enabled:t.enabled,order:t.order,referenceCount:t.referenceCount}],referenceCount:t.referenceCount})}return sc.parse({models:[...s.values()].sort((e,t)=>e.model.order-t.model.order||e.model.name.localeCompare(t.model.name)),nodeDiagnostics:i.nodeErrors.map(e=>({nodeId:e.nodeId,code:e.code,message:e.message})),updatedAt:Hd()})}create(e){const t=Gh.parse(e),n=Hd(),i=ac(t),s=this.options.models.get(i),a=Jr.parse({...t,id:i,enabled:t.enabled??!0,order:t.order??this.nextOrder(),labels:t.labels||{},createdAt:s?.createdAt||n,updatedAt:n});return hh(this.options.models.put(a))}update(e,t){const n=Wh.parse(t),i=this.requireSecret(e),s=Jr.parse({...i,...n,key:n.key?.trim()?n.key:i.key,createdAt:i.createdAt,updatedAt:Hd()}),a=ac(s);return hh(this.options.models.put(Jr.parse({...s,id:a})))}delete(e){return this.requireSecret(e),this.options.models.delete(e)}reorder(e){const t=[...new Set(e)],n=new Map(this.options.models.list().map(e=>[e.id,e]));for(const e of t)n.has(e)||bh("MODEL_NOT_FOUND",`Model ${e} was not found.`);return t.forEach((e,t)=>{const i=n.get(e);this.options.models.put(Jr.parse({...i,order:100*(t+1),updatedAt:Hd()}))}),this.list()}createOnNode(e,t){return this.options.gateway.createModel(this.options.requireNode(e),t)}updateOnNode(e,t,n){return this.options.gateway.updateModel(this.options.requireNode(e),t,n)}deleteOnNode(e,t){return this.options.gateway.deleteModel(this.options.requireNode(e),t)}discover(e){const t=Vh.parse(e);return async function(e,t){const n=function(e){const t=mg(e),n=[],i=t.pathname.split("/").filter(Boolean).at(-1)||"";return bg(n,ug(t.toString(),/^v\d+$/.test(i)?"models":"v1/models")),bg(n,new URL("/v1/models",t.origin).toString()),bg(n,new URL("/models",t.origin).toString()),n}(t.endpoint),i=Date.now();let s;for(const a of n){const n=await hg(e,a,{method:"GET",headers:{accept:"application/json",authorization:`Bearer ${t.key}`}});if(404===n.status||405===n.status){s=n.status;continue}if(!n.ok)throw fg("MODEL_DISCOVERY_FAILED",n.status);const o=await gg(n,"MODEL_DISCOVERY_RESPONSE_INVALID"),r=Array.isArray(o.data)?o.data:void 0;if(!r)throw yg("MODEL_DISCOVERY_RESPONSE_INVALID","The model endpoint returned an invalid model list.",502);const c=r.flatMap(e=>{if(!e||"object"!=typeof e||Array.isArray(e))return[];const t=e,n="string"==typeof t.id?t.id.trim():"";if(!n)return[];const i="string"==typeof t.owned_by?t.owned_by.trim():"";return[{id:n,...i?{ownedBy:i}:{}}]}).sort((e,t)=>e.id.localeCompare(t.id));return{models:vg(c),latencyMs:Date.now()-i}}throw yg("MODEL_DISCOVERY_UNSUPPORTED","No compatible model-list endpoint was found for this endpoint.",502,s)}(this.options.fetchImpl,this.resolvePrivateInput(t))}test(e){const t=Kh.parse(e);return async function(e,t){const n=Date.now(),i="codex"===t.app||"opencode"===t.app?await hg(e,ug(t.endpoint,"responses"),{method:"POST",headers:{accept:"application/json",authorization:`Bearer ${t.key}`,"content-type":"application/json"},body:JSON.stringify({model:t.model,input:"Reply with OK.",max_output_tokens:32,stream:!1})}):await hg(e,function(e){const t=mg(e),n=t.pathname.split("/").filter(Boolean).at(-1)||"";return ug(t.toString(),/^v\d+$/.test(n)?"messages":"v1/messages")}(t.endpoint),{method:"POST",headers:{accept:"application/json","anthropic-version":"2023-06-01","content-type":"application/json","x-api-key":t.key},body:JSON.stringify({model:t.model,max_tokens:8,messages:[{role:"user",content:"Reply with OK."}]})});if(!i.ok)throw fg("MODEL_TEST_FAILED",i.status);if((await gg(i,"MODEL_TEST_RESPONSE_INVALID")).error)throw yg("MODEL_TEST_RESPONSE_INVALID","The model endpoint returned an error payload.",502);return{success:!0,latencyMs:Date.now()-n}}(this.options.fetchImpl,this.resolvePrivateInput(t))}discoverOnNode(e,t){const n=this.options.requireNode(e);return xg(n),this.options.gateway.discoverModels(n,t)}testOnNode(e,t){const n=this.options.requireNode(e);return xg(n),this.options.gateway.testModel(n,t)}require(e,t=!1){const n=this.requireSecret(e);return t?n:hh(n)}async prepareAssignment(e,t){const n=await this.options.gateway.listModels(e),i={...null===t.codexModelHash?{codexModelHash:null}:t.codexModelHash?.trim()?{codexModelHash:t.codexModelHash.trim()}:{},...null===t.claudeModelHash?{claudeModelHash:null}:t.claudeModelHash?.trim()?{claudeModelHash:t.claudeModelHash.trim()}:{},...null===t.opencodeModelHash?{opencodeModelHash:null}:t.opencodeModelHash?.trim()?{opencodeModelHash:t.opencodeModelHash.trim()}:{}},s=async(t,i)=>{if(null===i)return;const s=i?this.listAll().find(e=>e.id===i):this.listAll().find(e=>e.enabled&&e.app===t);if(s)return wg(s,t),await this.options.gateway.deployModel(e,s.id,s),s.id;if(!i)return;const a=n.find(e=>e.id===i);return a||bh("MODEL_NOT_FOUND",`Model ${i} was not found on control-plane or node ${e.id}.`),wg(a,t),a.id};return{modelSelection:i,codexModelHash:await s("codex",i.codexModelHash),claudeModelHash:await s("claude",i.claudeModelHash),opencodeModelHash:await s("opencode",i.opencodeModelHash)}}async ensureInstanceAssignment(e){const t=this.options.requireNode(e.nodeId),n=await this.prepareAssignment(t,e.modelSelection);return this.options.gateway.assignInstanceModels(t,e.id,n)}listAll(){return this.options.models.list().map(e=>this.normalize(e)).sort((e,t)=>e.order-t.order||e.createdAt.localeCompare(t.createdAt)||e.id.localeCompare(t.id))}requireSecret(e){const t=this.options.models.get(e);return t||bh("MODEL_NOT_FOUND",`Model ${e} was not found.`),this.normalize(t)}normalize(e){const t=function(e){if(e&&"object"==typeof e&&!Array.isArray(e)){const t={...e};if(!("app"in t)){const e=Array.isArray(t.apps)?t.apps:[];t.app=e.includes("claude")&&!e.includes("codex")?"claude":"codex"}return delete t.apps,Jr.parse(t)}return Jr.parse(e)}(e);return t!==e&&this.options.models.put(t),t}nextOrder(){return this.options.models.list().reduce((e,t)=>Math.max(e,t.order),0)+100}resolvePrivateInput(e){const t=e.key?.trim()||(e.existingModelId?this.requireSecret(e.existingModelId).key:"");if(!t)throw Object.assign(new Error("An API key is required to contact the model endpoint."),{statusCode:400,code:"MODEL_API_KEY_REQUIRED"});return{...e,key:t}}}function xg(e){const t=e.capabilities.agent,n=t&&"object"==typeof t&&!Array.isArray(t)?t.capabilities:void 0;if(!n||"object"!=typeof n||Array.isArray(n)||!0!==n.modelEndpointProbe)throw Object.assign(new Error("This node agent does not support model endpoint discovery or testing."),{statusCode:409,code:"NODE_MODEL_ENDPOINT_PROBE_UNSUPPORTED"})}function wg(e,t){if(e.app!==t)throw Object.assign(new Error(`Model ${e.id} is not a ${t} model.`),{statusCode:400,code:"MODEL_APP_MISMATCH"});if(!e.enabled)throw Object.assign(new Error(`Model ${e.id} is disabled.`),{statusCode:400,code:"MODEL_DISABLED"})}class Sg{requireNode;nodeAgentTransport;constructor(e){this.requireNode=e.requireNode,this.nodeAgentTransport=e.nodeAgentTransport}async request(e,t,n={},i){if(!e.target.web||"online"!==e.connectionStatus&&"online"!==e.agentStatus){const t=new Error(`Instance ${e.name} is not reachable.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_UNREACHABLE"}),t}Ag(e);const s=this.requireNode(e.nodeId),a=gh(n.headers),o=performance.now(),r=await this.nodeAgentTransport(s).request(s,`/instances/${encodeURIComponent(e.id)}/proxy`,{method:"POST",headers:{"content-type":"application/json",...a[eu]?{[eu]:a[eu]}:{}},body:JSON.stringify({path:`/api/${t.replace(/^\/+/,"")}`,method:n.method||"GET",headers:a,body:(c=n.body,"string"==typeof c?c:null==c?void 0:String(c))})});var c;const d=performance.now()-o,l=nu(r.headers.get("server-timing"),tu("node_transport",d));i?.({traceId:r.headers.get(eu)||void 0,serverTiming:l,nodeTransportMs:d});const p=await r.json().catch(()=>({}));if(!r.ok){const n=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return;const t=e,n="string"==typeof t.code&&t.code.trim()?t.code:void 0,i="string"==typeof t.message&&t.message?t.message:void 0,s=t.details&&"object"==typeof t.details&&!Array.isArray(t.details)?t.details:void 0,a="boolean"==typeof t.retryable?t.retryable:void 0;return n||i?{code:n,message:i,details:s,retryable:a}:void 0}(p.error),i=n?.message||function(e){if(!e||"object"!=typeof e||Array.isArray(e))return"";const t=e.message;return"string"==typeof t?t:""}(p.error)||`Instance request failed with HTTP ${r.status}`,s=500===r.status&&"NODE_AGENT_ERROR"===n?.code,a=new Error(i);throw Object.assign(a,{statusCode:s?502:r.status,code:s?"INSTANCE_PROXY_UPSTREAM_FAILED":n?.code||"INSTANCE_REQUEST_FAILED",...s?{retryable:!0}:"boolean"==typeof n?.retryable?{retryable:n.retryable}:{},...n?.details?{details:n.details}:{},instanceId:e.id,nodeId:e.nodeId,route:t}),a}return p.data??p}async proxyHttp(e,t,n={}){if("online"!==e.connectionStatus&&"online"!==e.agentStatus){const t=new Error(`Instance ${e.name} is not reachable.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_UNREACHABLE"}),t}if(!e.target.web){const t=new Error(`Instance ${e.name} web endpoint is not reachable.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_WEB_UNREACHABLE"}),t}Ag(e);const i=this.requireNode(e.nodeId),s=await this.nodeAgentTransport(i).requestStream(i,`/instances/${encodeURIComponent(e.id)}/proxy/stream`,{method:"POST",headers:{"content-type":"application/json"},signal:n.signal,body:JSON.stringify({path:t,method:n.method||"GET",headers:gh(n.headers),...(a=n.body,null==a?{}:"string"==typeof a?{body:a}:Buffer.isBuffer(a)?{bodyBase64:a.toString("base64")}:a instanceof Uint8Array?{bodyBase64:Buffer.from(a).toString("base64")}:{body:String(a)})})});var a;return{status:s.status||502,headers:Object.fromEntries(s.headers.entries()),body:s.body}}proxyWebSocket(e,t,n,i,s={}){if(!e.target.web||"online"!==e.connectionStatus&&"online"!==e.agentStatus){const t=new Error(`Instance ${e.name} web endpoint is not reachable.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_WEB_UNREACHABLE"}),t}Ag(e);const a=this.requireNode(e.nodeId),o=n.startsWith("/")?n.slice(1):n;this.nodeAgentTransport(a).proxyWebSocket(a,t,`/instances/${encodeURIComponent(e.id)}/proxy/ws/${o}`,i,s)}async reportHeartbeat(e,t){if(!e.registrationToken)return;const n=this.requireNode(e.nodeId),i=`/instances/${encodeURIComponent(e.id)}/heartbeat`,s={method:"POST",headers:{"content-type":"application/json",authorization:`Bearer ${e.registrationToken}`},body:JSON.stringify(t)},a=await this.nodeAgentTransport(n).request(n,i,s),o=await a.json().catch(()=>({}));if(!a.ok){const e=new Error(o.error?.message||`Instance heartbeat sync failed with HTTP ${a.status}`);throw Object.assign(e,{statusCode:a.status,code:"INSTANCE_HEARTBEAT_SYNC_FAILED"}),e}}}function Ag(e){if(Ad(e))return;const t=new Error(`Instance ${e.name} is not ready.`);throw Object.assign(t,{statusCode:409,code:"INSTANCE_NOT_READY",runtimePhase:e.runtimeVersion?.phase}),t}class Eg{read(e){const t=new Map(e.projects.map(e=>[e.id,e])),n=new Map(e.images.map(e=>[e.id,e])),i=new Map(e.nodes.map(e=>[e.id,e])),s=new Map(e.runtimes.map(e=>[`${e.nodeId}:${e.id}`,e])),a=Date.now();return{items:e.instances.map(e=>function(e){const t=e.instance.lastHeartbeatAt?e.currentTime-Date.parse(e.instance.lastHeartbeatAt):void 0,n=void 0!==t&&t>3e4?"offline":e.instance.connectionStatus,i=mh(e.instance);return{...i,aiSessions:ls(i.aiSessions),connectionStatus:n,heartbeatAgeMs:t,project:e.project,image:e.image,node:e.node?ph(e.node):void 0,runtime:e.runtime,protocolCompatible:!e.instance.protocolVersion||e.instance.protocolVersion===wo}}({instance:e,currentTime:a,project:e.projectId?t.get(e.projectId):void 0,image:e.imageSnapshot||(e.imageSelection?n.get(e.imageSelection.imageId):void 0),node:i.get(e.nodeId),runtime:s.get(`${e.nodeId}:${e.runtimeId}`)})),nodeErrors:e.nodeErrors||[],nodeStates:e.nodeStates||[]}}}class _g{options;constructor(e){this.options=e}targetNodeId(e){const t=Fh.parse(e),n=t.projectId?this.options.requireProject(t.projectId):void 0,i=t.nodeId||n?.defaultNodeId||this.options.defaultNodeId();if(!i)throw zg("At least one node connection is required before creating an instance.",400,"NODE_REQUIRED");return i}async create(e){const t=Fh.parse(e),n=t.projectId?this.options.requireProject(t.projectId):void 0,i=t.runtimeId||"runtime_local_docker",s=this.targetNodeId(t),a=this.options.requireNode(s),o=a.capabilities.agent,r=o&&"object"==typeof o&&!Array.isArray(o)?o.capabilities:void 0;if(void 0!==t.config?.aiSessionMaxFileAttachmentBytes&&!Fc(r))throw zg("This node does not support managed AI session file attachment limits.",409,"AI_SESSION_FILE_ATTACHMENT_LIMIT_UNSUPPORTED");const c=await this.options.requireRuntime(a.id,i),d=c.capabilities.requiresImage??"local"!==c.type,l=t.environmentSource||(t.imageSelection?{type:"image",imageSelection:t.imageSelection}:void 0)||(d&&n?.defaultImageSelection?{type:"image",imageSelection:n.defaultImageSelection}:void 0);if("template"===l?.type&&"docker"!==c.type)throw zg(`Runtime ${c.name} does not support environment templates.`,409,"ENVIRONMENT_TEMPLATE_RUNTIME_UNSUPPORTED");const p="image"===l?.type?l.imageSelection:void 0,u=p?this.options.resolveImageSelection(p):void 0,m="template"===l?.type?await this.options.gateway.getEnvironmentTemplate(a,l.environmentTemplateId):void 0;if(m&&"ready"!==m.status)throw zg(`Environment template ${m.id} is ${m.status}.`,409,"ENVIRONMENT_TEMPLATE_NOT_READY");if(m&&m.nodeId!==a.id)throw zg(`Environment template ${m.id} belongs to node ${m.nodeId}.`,409,"ENVIRONMENT_TEMPLATE_NODE_MISMATCH");if(d&&!u&&!m)throw zg(`Runtime ${c.name} requires an image.`,400,"RUNTIME_IMAGE_REQUIRED");const h=await this.resolveSource({node:a,runtime:c,project:n,source:t.source,sourceSnapshot:t.sourceSnapshot,imageOption:u}),g=t.id||Xd("inst"),f=this.prepareGitProvisioning({instanceId:g,runtime:c,source:h.configured,retention:t.gitCredentialRetention,agentCapabilities:r}),y=await this.options.prepareModels(a,t.modelSelection||{}),b=u?function(e){const t=Hd();return{id:e.id,origin:e.origin,name:e.name,description:e.description,localizedDescriptions:e.localizedDescriptions,cover:e.cover,repository:e.repository,tag:e.tag,requestedReference:e.reference,resolvedDigest:e.digest,resolvedReference:e.digest?`${e.repository}@${e.digest}`:void 0,downloadSizeBytes:e.downloadSizeBytes,pullPolicy:"if-not-present",capabilities:e.capabilities,optionalApps:e.optionalApps,defaultEnv:e.defaultEnv,labels:e.labels,market:e.market,createdAt:t,updatedAt:t}}(u):void 0,v="instance-retained"===f?.retention?f.input.credentials[0].payload:void 0;let I,x,w=!1,S=!1;try{"operation-only"===f?.retention&&this.options.gitCredentials.rememberOperationProvisioning(f.input);const e={id:g,name:t.name,runtimeId:i,...l?{environmentSource:l}:{},...u&&b?{image:b}:{},projectId:n?.id,source:h.value,sourceSnapshot:h.snapshot,config:t.config,modelSelection:{},..."operation-only"===f?.retention?{gitWorkspaceProvisioning:f.input}:{}};try{I=await this.options.gateway.createInstance(a,e)}catch(e){if(I=await this.options.gateway.listInstances(a).then(e=>e.find(e=>e.id===g)).catch(()=>{}),!I)throw e}x=I,"instance-retained"===f?.retention&&(w=!0,await this.options.gateway.deployGitCredential(a,v),this.options.gitCredentials.authorize(I.id,f.credentialId),S=!0,await this.options.gateway.replaceGitCredentialAuthorizations(a,this.options.gitCredentials.desiredAuthorizationSet(I.id)),this.options.gitCredentials.markAssignmentStatus(I.id,f.credentialId,"synced")),x=(await this.options.gateway.assignInstanceModels(a,I.id,y)).instance}catch(e){let t;if(S&&"instance-retained"===f?.retention){this.options.gitCredentials.revoke(g,f.credentialId);try{await this.options.gateway.replaceGitCredentialAuthorizations(a,this.options.gitCredentials.desiredAuthorizationSet(g))}catch(e){t=e}}let n,i,s=!1;try{const e=await this.options.gateway.deleteInstance(a,g,{deleteVolumes:!0});s=e.completed,e.completed||(n=new Error(`Instance ${g} deletion requires retry.`))}catch(e){!function(e){if(!e||"object"!=typeof e)return!1;const t=e;return 404===t.statusCode||"CONTROLLED_INSTANCE_NOT_FOUND"===t.code}(e)?n=e:s=!0}if(w&&v)try{await this.options.gateway.removeGitCredential(a,v.credential.id)}catch(e){i=e}if(s&&"operation-only"===f?.retention&&this.options.gitCredentials.forgetOperationProvisioning(g),n||t||i){const s=zg(`Instance ${g} creation failed and node cleanup could not be confirmed.`,502,"INSTANCE_CREATE_COMPENSATION_REQUIRED");throw Object.assign(s,{cause:e,compensationError:n,retainedAuthorizationCleanupError:t,retainedPayloadCleanupError:i}),s}throw e}if(!x)throw zg("Instance creation did not return an instance.",502,"INSTANCE_CREATE_FAILED");let A={status:"not-requested"};if(t.start)try{const e=await this.options.gateway.startInstance(a,x.id,"operation-only"===f?.retention?{gitWorkspaceProvisioning:f.input}:{});x=e.instance,"operation-only"===f?.retention&&e.gitWorkspaceProvisioningOperationId===f.input.operationId&&this.options.gitCredentials.forgetOperationProvisioning(x.id),A={status:"started"}}catch(e){A={status:"failed",error:Tg(e,"INSTANCE_START_FAILED")},x=await this.options.gateway.listInstances(a).then(e=>e.find(e=>e.id===x.id)||x).catch(()=>x)}return{...mh(x),registrationToken:x.registrationToken,startOutcome:A}}prepareGitProvisioning(e){if("local-folder"===e.source.type){if(e.retention)throw zg("Git credential retention requires a Git source.",400,"GIT_CREDENTIAL_SOURCE_REQUIRED");return}if("none"===e.source.auth.type){if(e.retention)throw zg("The Git Repository does not have a credential to retain.",409,"GIT_REPOSITORY_CREDENTIAL_NOT_CONFIGURED");return}const t=e.source.auth.secretId;if(!t)throw zg("The Git Repository credential reference is missing.",409,"GIT_REPOSITORY_CREDENTIAL_REQUIRED");const n=e.retention||"operation-only";if(!$c(e.agentCapabilities)||!Bc(e.agentCapabilities))throw zg("The selected node does not support managed Git credentials.",409,"GIT_CREDENTIAL_NODE_UNSUPPORTED");if(i=e.agentCapabilities,s=e.runtime.type,!Uc(i).managedGitCredentials.workspaceProvisioning[s])throw zg(`Runtime ${e.runtime.name} does not support managed Git workspace provisioning.`,409,"GIT_CREDENTIAL_PROVISIONING_UNSUPPORTED");var i,s;const a=this.options.gitCredentials.payload(t);if(a.credential.kind!==e.source.auth.type)throw zg("The Git Repository auth type does not match its credential.",409,"GIT_REPOSITORY_CREDENTIAL_KIND_MISMATCH");const o=xm(e.source.url,[{id:a.credential.id,kind:a.credential.kind,scope:a.credential.scope,status:a.credential.status,pinnedKnownHosts:"ssh-key"===a.secret.kind&&Boolean(a.secret.pinnedKnownHosts.trim())}]);if("unique"!==o.status||o.credential.id!==t)throw zg(`The Git Repository credential does not uniquely authorize its remote (${o.status}).`,409,`GIT_REPOSITORY_CREDENTIAL_${o.status.replace(/-/g,"_").toUpperCase()}`);return{credentialId:t,retention:n,input:{operationId:Xd("gitop"),instanceId:e.instanceId,remoteUrl:e.source.url,ref:e.source.ref,clone:e.source.clone,credentials:[{operationId:Xd("gitcredop"),retention:n,payload:a}]}}}async resolveSource(e){let t=e.source||e.project?.source,n=function(e){const t=Wr.safeParse(e.source);return t.success?{...e,source:Vr(t.data)}:e}(e.sourceSnapshot||(e.project?{...e.project,source:Vr(e.project.source)}:{}));if(!t)throw zg("Instance source is required.",400,"INSTANCE_SOURCE_REQUIRED");if("local"===e.runtime.type&&"local-folder"!==t.type)throw zg("Localhost runtime currently supports local folder sources only.",400,"LOCAL_RUNTIME_REQUIRES_LOCAL_FOLDER");if("local-folder"!==t.type)return{value:Vr(t),configured:t,snapshot:n};if(t.ownerNodeId&&t.ownerNodeId!==e.node.id)throw zg(`Local folder ${t.path} belongs to node ${t.ownerNodeId}, not ${e.node.id}.`,400,"LOCAL_FOLDER_REQUIRES_OWNER_NODE");const i=t.localFolderId?await this.options.requireLocalFolder(e.node,t.localFolderId):await this.options.gateway.createLocalFolder(e.node,{name:"string"==typeof n.name?n.name:"Local folder",path:t.path,defaultImageSelection:e.imageOption?{imageId:e.imageOption.id,tag:e.imageOption.tag}:void 0});return t={...t,localFolderId:i.id,ownerNodeId:i.nodeId,path:i.path},n=i,{value:t,configured:t,snapshot:n}}}function Tg(e,t){const n=e&&"object"==typeof e?e:{};return{code:"string"==typeof n.code&&n.code.trim()?n.code:t,message:"string"==typeof n.message&&n.message.trim()?n.message:String(e)}}function zg(e,t,n){return Object.assign(new Error(e),{statusCode:t,code:n})}class kg{triggers;listInstances;listMutationInstances;requireInstance;instanceRequest;constructor(e){this.triggers=e.triggers,this.listInstances=e.listInstances,this.listMutationInstances=e.listMutationInstances??(async()=>({items:await e.listInstances(),partialFailures:[]})),this.requireInstance=e.requireInstance,this.instanceRequest=e.instanceRequest}async listTriggers(){const e=await this.listInstances(),t=new Map;for(const e of this.triggers.list())t.set(e.configHash,{configHash:e.configHash,config:Cg(e),deploymentCount:0,enabledCount:0,runningCount:0,errorCount:0,ownedByControlPlane:!0,controlPlaneDeploymentCount:0,deployments:[],recentRuns:[]});for(const n of e){const e=n.triggers;for(const i of e?.configs||[]){const s=t.get(i.configHash)||{configHash:i.configHash,config:i.config,deploymentCount:0,enabledCount:0,runningCount:0,errorCount:0,ownedByControlPlane:!1,controlPlaneDeploymentCount:0,deployments:[],recentRuns:[]},a=(i.deployments||[]).map(e=>({instanceId:n.id,instanceName:n.name,deployment:e,runtime:(i.runtime||[]).find(t=>t.deploymentId?t.deploymentId===e.deploymentId:t.configHash===e.configHash)}));s.deploymentCount+=a.length,s.enabledCount+=a.filter(e=>Boolean(e.deployment.enabled)).length,s.controlPlaneDeploymentCount+=a.filter(e=>"control-plane"===e.deployment.origin).length,s.runningCount+=(i.runtime||[]).filter(e=>"running"===e.status).length,s.errorCount+=(i.runtime||[]).filter(e=>"error"===e.status).length,s.deployments.push(...a),s.recentRuns.push(...(e.recentRuns||[]).filter(e=>e.configHash===i.configHash).map(e=>({...e,instanceId:n.id,instanceName:n.name}))),t.set(i.configHash,s)}}return Oa.parse({updatedAt:(new Date).toISOString(),triggers:[...t.values()].sort((e,t)=>String(e.config.name||e.configHash).localeCompare(String(t.config.name||t.configHash)))})}createTrigger(e){const t=Lh.parse(e||{}),n=Hd(),i={maxConcurrentRuns:t.policy?.maxConcurrentRuns??1,whenBusy:t.policy?.whenBusy??"skip",cooldownMs:t.policy?.cooldownMs},s=ja({source:t.source,action:t.action,policy:i}),a=Dh.parse({id:s,configHash:s,name:t.name,description:t.description,source:t.source,action:t.action,policy:i,createdAt:n,updatedAt:n});return this.triggers.put(a)}async updateTrigger(e,t){const n=this.requireTrigger(e),i=Mh.parse(t||{}),s=Hd(),a={maxConcurrentRuns:i.policy?.maxConcurrentRuns??1,whenBusy:i.policy?.whenBusy??"skip",cooldownMs:i.policy?.cooldownMs},o=ja({source:i.source,action:i.action,policy:a});if(o!==e&&this.triggers.get(o)){const e=new Error(`Trigger ${o} already exists.`);throw Object.assign(e,{statusCode:409,code:"TRIGGER_ALREADY_EXISTS"}),e}const r=Dh.parse({id:o,configHash:o,name:i.name,description:i.description,source:i.source,action:i.action,policy:a,createdAt:n.createdAt,updatedAt:s}),c=await this.listMutationInstances(),d=await Ng(c.items,8,async t=>{const n=[],i=[],s=t.triggers?.configs?.find(t=>t.configHash===e),a=(s?.deployments||[]).filter(e=>"control-plane"===e.origin);if(o===e){if(a.length)try{const i=await this.instanceRequest(t,`/triggers/${encodeURIComponent(e)}`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({name:r.name,description:r.description??null})});n.push({instanceId:t.id,data:i})}catch(e){i.push(Rg(t,e))}return{results:n,partialFailures:i}}for(const s of a){const a="ai-session"===s.target.type?Og(s.target.aiSessionId,o):s.deploymentId;try{const i=await this.instanceRequest(t,"/triggers",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:r.name,description:r.description,source:r.source,action:r.action,policy:r.policy,deployment:{deploymentId:a,origin:"control-plane",enabled:s.enabled,target:s.target,localName:s.localName}})}),o=s.deploymentId||s.configHash;await this.instanceRequest(t,`/triggers/${encodeURIComponent(e)}/deployments/${encodeURIComponent(o)}`,{method:"DELETE"}),n.push({instanceId:t.id,deploymentId:a,data:i})}catch(e){i.push(Rg(t,e))}}return{results:n,partialFailures:i}}),l=d.flatMap(e=>e.results),p=[...c.partialFailures,...d.flatMap(e=>e.partialFailures)];return this.triggers.put(r),o!==e&&this.triggers.delete(e),{previousConfigHash:e,trigger:r,results:l,partialFailures:p}}async deleteTrigger(e){const t=await this.listMutationInstances(),n=this.triggers.delete(e),i=await Ng(t.items,8,async t=>{const n=[],i=[],s=t.triggers?.configs?.find(t=>t.configHash===e);if(!s)return{results:n,partialFailures:i};const a=(s.deployments||[]).filter(e=>"control-plane"===e.origin);if(!a.length)return{results:n,partialFailures:i};const o=s.deployments.every(e=>"control-plane"===e.origin);for(const s of a)try{const a=s.deploymentId?`/triggers/${encodeURIComponent(e)}/deployments/${encodeURIComponent(s.deploymentId)}`:o?`/triggers/${encodeURIComponent(e)}`:void 0;if(!a){n.push({instanceId:t.id,configHash:e,deploymentId:s.deploymentId,deleted:!1,skipped:"missing-deployment-id"}),i.push({scope:"instance",nodeId:t.nodeId,instanceId:t.id,code:"TRIGGER_DEPLOYMENT_ID_MISSING",message:`Trigger deployment on instance ${t.name} has no deletable deployment id.`});continue}const r=await this.instanceRequest(t,a,{method:"DELETE"});if(n.push({instanceId:t.id,configHash:e,deploymentId:s.deploymentId,deleted:!0,data:r}),!s.deploymentId)break}catch(a){i.push(Rg(t,a)),n.push({instanceId:t.id,configHash:e,deploymentId:s.deploymentId,deleted:!1,error:a instanceof Error?a.message:String(a)})}return{results:n,partialFailures:i}}),s=i.flatMap(e=>e.results),a=[...t.partialFailures,...i.flatMap(e=>e.partialFailures)];return n||s.length||bh("TRIGGER_NOT_FOUND",`Trigger ${e} was not found.`),{configHash:e,deletedTemplate:n,results:s,partialFailures:a}}async applyTrigger(e,t){const n=this.requireTrigger(e),i=qh.parse(t||{});return{configHash:e,results:await Ng(i.instanceIds,8,async e=>{const t=await this.requireInstance(e);return{instanceId:e,data:await this.instanceRequest(t,"/triggers",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:n.name,description:n.description,source:n.source,action:n.action,policy:n.policy,deployment:{origin:"control-plane",enabled:i.enabled??!0,target:i.target}})})}})}}async listInstanceTriggers(e){const t=await this.requireInstance(e);return this.instanceRequest(t,"/triggers")}async bindAiSessionTrigger(e,t,n){const i=Uh.parse(n||{}),s=this.requireTrigger(i.configHash),a=await this.requireInstance(e);return this.instanceRequest(a,"/triggers",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({name:s.name,description:s.description,source:s.source,action:s.action,policy:s.policy,deployment:{deploymentId:Og(t,i.configHash),origin:"control-plane",enabled:i.enabled??!0,target:{type:"ai-session",aiSessionId:t}}})})}async unbindAiSessionTrigger(e,t,n){const i=await this.requireInstance(e),s=Og(t,n);return this.instanceRequest(i,`/triggers/${encodeURIComponent(n)}/deployments/${encodeURIComponent(s)}`,{method:"DELETE"})}async runInstanceTrigger(e,t,n={}){const i=await this.requireInstance(e);return this.instanceRequest(i,`/triggers/${encodeURIComponent(t)}/run`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n||{})})}requireTrigger(e){const t=this.triggers.get(e);return t||bh("TRIGGER_NOT_FOUND",`Trigger ${e} was not found.`),t}}async function Ng(e,t,n){const i=new Array(e.length);let s,a=0,o=!1;if(await Promise.all(Array.from({length:Math.min(t,e.length)},async()=>{for(;!o&&a<e.length;){const t=a++;try{i[t]=await n(e[t],t)}catch(e){o=!0,s=e}}})),o)throw s;return i}function Cg(e){return{configHash:e.configHash,name:e.name,...void 0!==e.description?{description:e.description}:{},source:e.source,action:e.action,policy:e.policy,createdAt:e.createdAt,updatedAt:e.updatedAt}}function Rg(e,t){const n=t&&"object"==typeof t?t:void 0,i="string"==typeof n?.code&&n.code?n.code:"TRIGGER_INSTANCE_MUTATION_FAILED",s="string"==typeof n?.message&&n.message?n.message:String(t);return{scope:"instance",nodeId:e.nodeId,instanceId:e.id,code:i.slice(0,160),message:s.slice(0,4e3)}}function Og(e,t){return`ai_${Buffer.from(e).toString("base64url")}_${t}`}class jg{options;constructor(e){this.options=e}getSettings(){return Nh.parse(this.options.settings.get())}updateSettings(e){const t=Ch.parse(e),n=Nh.parse({...this.getSettings(),...t,..."publicBaseUrl"in t?{publicBaseUrl:t.publicBaseUrl?.trim()||void 0}:{}});return this.options.settings.put(n)}seedDefaults(){}listProjects(){return this.options.projects.list().map(e=>this.normalizeProjectRecord(e))}getProject(e){const t=this.options.projects.get(e);return t?this.normalizeProjectRecord(t):void 0}createProject(e){const t=Ah.parse(e),n=Hd(),i=this.validateProjectSource(t.source);return this.options.projects.put(Xr.parse({...t,id:t.id||Xd("proj"),source:i,defaultImageSelection:t.defaultImageSelection||{imageId:"market_taskhandoff_browser"},defaultNodeId:t.defaultNodeId||this.options.defaultNodeId(),workspacePolicy:Kr.parse(t.workspacePolicy||uh(i)),labels:t.labels||{},createdAt:n,updatedAt:n}))}updateProject(e,t){const n=Eh.parse(t),i=this.requireProject(e),s=n.source?this.validateProjectSource(n.source):i.source;return this.options.projects.put(Xr.parse({...i,...n,id:e,source:s,workspacePolicy:n.workspacePolicy?Kr.parse(n.workspacePolicy):i.workspacePolicy,createdAt:i.createdAt,updatedAt:Hd()}))}deleteProject(e){return this.options.projects.delete(e)}requireProject(e){const t=this.getProject(e);return t||bh("PROJECT_NOT_FOUND",`Project ${e} was not found.`),t}validateProjectSource(e){const t=Wr.parse(e);if("local-folder"===t.type)return t;if("none"===t.auth.type){if(t.auth.secretId)throw Pg("A public Git repository cannot reference a credential.","GIT_REPOSITORY_AUTH_INVALID");return t}if(!t.auth.secretId)throw Pg("Git repository authentication requires a credential.","GIT_REPOSITORY_CREDENTIAL_REQUIRED");const n=this.options.requireGitCredential(t.auth.secretId);if("enabled"!==n.status)throw Pg("The Git repository credential is disabled.","GIT_REPOSITORY_CREDENTIAL_DISABLED");if(n.kind!==t.auth.type)throw Pg("Git repository auth type does not match its credential.","GIT_REPOSITORY_CREDENTIAL_KIND_MISMATCH");const i=xm(t.url,[{...n,status:"enabled"}]);if("unique"!==i.status||i.credential.id!==n.id)throw Pg(`Git repository credential does not authorize its remote (${i.status}).`,`GIT_REPOSITORY_CREDENTIAL_${i.status.replace(/-/g,"_").toUpperCase()}`);return t}listImages(){return this.options.images.list()}getMarketCatalog(){return{catalog:this.options.market.getCatalog(),status:this.options.market.getStatus()}}listImageOptions(e){return[...this.options.market.getCatalog().items.map(t=>this.marketImageOption(t,void 0,e,!0)),...this.listImages().map(e=>this.customImageOption(e))]}resolveImageSelection(e,t){const n=this.options.market.getCatalog().items.find(t=>t.id===e.imageId);if(n)return this.marketImageOption(n,e.tag,t);const i=this.options.images.get(e.imageId);if(i||bh("IMAGE_NOT_FOUND",`Image ${e.imageId} was not found.`),e.tag&&e.tag!==i.tag)throw Object.assign(new Error(`Custom image ${i.id} cannot override its stored tag.`),{statusCode:400,code:"CUSTOM_IMAGE_TAG_OVERRIDE"});return this.customImageOption(i)}createImage(e){const t=Rh.parse(e),n=Hd(),i=Ho(t.reference);return this.options.images.put(bc.parse({...t,id:t.id||Xd("img"),origin:"custom",reference:i.reference,repository:i.repository,tag:i.tag,pullPolicy:t.pullPolicy||"if-not-present",capabilities:t.capabilities||[],optionalApps:t.optionalApps||[],defaultEnv:t.defaultEnv||{},labels:t.labels||{},createdAt:n,updatedAt:n}))}updateImage(e,t){const n=Oh.parse(t),i=this.requireImage(e),s=Ho(n.reference||i.reference);return this.options.images.put(bc.parse({...i,...n,id:e,origin:"custom",reference:s.reference,repository:s.repository,tag:s.tag,createdAt:i.createdAt,updatedAt:Hd()}))}deleteImage(e){return this.options.images.delete(e)}requireImage(e){if(this.options.market.getCatalog().items.some(t=>t.id===e))throw Object.assign(new Error(`Market image ${e} is read-only.`),{statusCode:403,code:"MARKET_IMAGE_READ_ONLY"});const t=this.options.images.get(e);return t||bh("IMAGE_NOT_FOUND",`Image ${e} was not found.`),t}normalizeProjectRecord(e){const t=function(e){return e&&"object"==typeof e&&!Array.isArray(e)?Xr.parse(rr(e)):Xr.parse(e)}(e);return t!==e&&this.options.projects.put(t),t}customImageOption(e){return Ic.parse({id:e.id,origin:"custom",name:e.name,description:e.description,localizedDescriptions:e.localizedDescriptions,cover:e.cover||dc,repository:e.repository,tag:e.tag,availableTags:e.tag?[{name:e.tag,reference:e.reference,status:"active"}]:[],reference:e.reference,capabilities:e.capabilities,optionalApps:e.optionalApps,defaultEnv:e.defaultEnv,labels:e.labels,readOnly:!1})}marketImageOption(e,t,n,i=!1){if("yanked"===e.status&&!i)throw Object.assign(new Error(`Market image ${e.id} is no longer selectable.`),{statusCode:409,code:"MARKET_IMAGE_YANKED"});const s=t||e.defaultTag,a=e.tags.find(e=>e.name===s);if(!a)throw Object.assign(new Error(`Market image ${e.id} does not provide tag ${s}.`),{statusCode:400,code:"MARKET_IMAGE_TAG_NOT_FOUND"});if("yanked"===a.status&&!i)throw Object.assign(new Error(`Market image tag ${e.id}:${s} is no longer selectable.`),{statusCode:409,code:"MARKET_IMAGE_TAG_YANKED"});const o=a.platforms.find(e=>!(n?.os&&e.os!==n.os||n?.architecture&&e.architecture!==n.architecture)),r=this.options.market.getCatalog();return Ic.parse({id:e.id,origin:"market",name:e.name,description:e.description,localizedDescriptions:e.localizedDescriptions,cover:e.cover||dc,repository:e.repository,tag:a.name,availableTags:e.tags.map(e=>({name:e.name,version:e.version,reference:e.reference,manifestDigest:e.manifestDigest,status:e.status})),reference:a.reference,digest:o?.digest||a.manifestDigest,downloadSizeBytes:o?.downloadSizeBytes,unpackedSizeBytes:o?.unpackedSizeBytes,capabilities:e.capabilities,optionalApps:e.optionalApps,defaultEnv:e.defaultEnv,labels:e.labels,readOnly:!0,lifecycleStatus:"yanked"===a.status||"yanked"===e.status?"yanked":"deprecated"===a.status||"deprecated"===e.status?"deprecated":"active",market:{catalogId:r.catalogId,catalogRevision:r.revision,publisher:e.publisher,version:a.version}})}}function Pg(e,t){return Object.assign(new Error(e),{code:t,statusCode:409})}function Dg(e){const t=Ho(e.reference),n=t.tag||"latest";return{id:e.id,publisher:"task-handoff",slug:e.slug,name:e.name,description:e.description,localizedDescriptions:e.localizedDescriptions,cover:dc,repository:t.repository,defaultTag:n,tags:[{name:n,reference:t.reference,platforms:[],status:"active"}],capabilities:e.capabilities,optionalApps:e.optionalApps,defaultEnv:{},labels:{"task-handoff.image.kind":"controlled-instance","task-handoff.image.profile":e.slug},status:"active"}}function Lg(){const e=(t=process.env.TASK_HANDOFF_BUILT_AT)&&!Number.isNaN(Date.parse(t))?new Date(t).toISOString():(new Date).toISOString();var t;return fc.parse({protocolVersion:"2026-07-29",catalogId:"task_handoff_embedded",revision:process.env.TASK_HANDOFF_VERSION||"0.0.1",source:"embedded",generatedAt:e,items:[Dg({id:"market_taskhandoff_codex",slug:"codex",name:"TaskHandoff Codex",description:"Minimal Codex runtime with terminal and Codex.",localizedDescriptions:{"zh-CN":"最小 Codex 运行环境,包含终端和 Codex。"},reference:process.env.TASK_HANDOFF_CONTROLLED_CODEX_IMAGE||"huadream/task-handoff-controlled-codex:latest",capabilities:["terminal","codex"],optionalApps:["terminal-tty"]}),Dg({id:"market_taskhandoff_ai",slug:"ai",name:"TaskHandoff Codex + Claude",description:"AI development runtime with Codex, Claude, and terminal.",localizedDescriptions:{"zh-CN":"AI 开发运行环境,包含 Codex、Claude 和终端。"},reference:process.env.TASK_HANDOFF_CONTROLLED_AI_IMAGE||"huadream/task-handoff-controlled-ai:latest",capabilities:["terminal","codex","claude"],optionalApps:["terminal-tty"]}),Dg({id:"market_taskhandoff_webcap",slug:"webcap",name:"TaskHandoff WebCap",description:"Browser automation runtime with WebCap, Codex, Claude, Chromium, and VNC.",localizedDescriptions:{"zh-CN":"浏览器自动化运行环境,包含 WebCap、Codex、Claude、Chromium 和 VNC。"},reference:process.env.TASK_HANDOFF_CONTROLLED_WEB_CAP_IMAGE||"huadream/task-handoff-controlled-webcap:latest",capabilities:["browser","terminal","gui-terminal","web-cap","codex","claude"],optionalApps:["chromium","terminal-tty","gui-terminal"]}),Dg({id:"market_taskhandoff_browser",slug:"browser",name:"TaskHandoff Browser",description:"Full runtime with Codex, Claude, Chromium, VNC, and code-server.",localizedDescriptions:{"zh-CN":"完整运行环境,包含 Codex、Claude、Chromium、VNC 和 code-server。"},reference:process.env.TASK_HANDOFF_CONTROLLED_BROWSER_IMAGE||"huadream/task-handoff-controlled-browser:latest",capabilities:["browser","terminal","gui-terminal","vscode-web","codex","claude"],optionalApps:["chromium","terminal-tty","gui-terminal","vscode-web"]})]})}class Mg{async loadCatalog(){return Lg()}}class qg{snapshot;status;constructor(e=Lg()){this.snapshot=fc.parse(e),this.status=yc.parse({source:this.snapshot.source,state:"ready",revision:this.snapshot.revision,updatedAt:this.snapshot.generatedAt})}getCatalog(){return this.snapshot}getStatus(){return this.status}acceptCandidate(e){const t=fc.safeParse(e);return t.success?(this.snapshot=t.data,this.status=yc.parse({source:t.data.source,state:"ready",revision:t.data.revision,updatedAt:(new Date).toISOString()}),{accepted:!0,snapshot:t.data}):(this.status=yc.parse({...this.status,state:"failed",updatedAt:(new Date).toISOString(),error:t.error.message}),{accepted:!1,error:t.error})}recordRefreshFailure(e){return this.status=yc.parse({...this.status,state:this.snapshot?"stale":"failed",updatedAt:(new Date).toISOString(),error:e instanceof Error?e.message:String(e)}),this.snapshot}async refresh(e){try{const t=await e.loadCatalog();return this.acceptCandidate(t)}catch(e){return this.recordRefreshFailure(e),{accepted:!1,error:e}}}}const Ug=f.z.object({id:lm.shape.id,name:lm.shape.name,kind:lm.shape.kind,scope:lm.shape.scope,status:lm.shape.status,revision:lm.shape.revision,secretCiphertext:f.z.string().min(1).max(262144),createdAt:lm.shape.createdAt,updatedAt:lm.shape.updatedAt}).strict(),$g=fm.extend({id:f.z.string().trim().min(1).max(300),createdAt:lm.shape.createdAt}).strict(),Bg=f.z.object({id:f.z.string().trim().min(1).max(120),action:f.z.enum(["create","update","delete","authorize","assignment-status","revoke"]),credentialId:lm.shape.id,instanceId:lm.shape.id.optional(),credentialRevision:lm.shape.revision.optional(),assignmentRevision:lm.shape.revision.optional(),createdAt:lm.shape.createdAt,updatedAt:lm.shape.updatedAt}).strict(),Fg=f.z.object({id:lm.shape.id,instanceId:lm.shape.id,credentialId:lm.shape.id,operationId:Im.shape.operationId,remoteUrl:Im.shape.remoteUrl,ref:Im.shape.ref,clone:Im.shape.clone,createdAt:lm.shape.createdAt,updatedAt:lm.shape.updatedAt}).strict();function Hg(e,t){return`${e}:${t}`}function Gg(e,t,n){return Object.assign(new Error(e),{code:t,statusCode:n})}function Wg(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e,n=t.scope&&"object"==typeof t.scope&&!Array.isArray(t.scope)?t.scope:void 0;return{id:t.id,name:t.name,kind:t.kind,scope:n?{scheme:n.scheme,host:n.host,...void 0===n.port?{}:{port:n.port},pathPrefix:n.pathPrefix}:t.scope,status:t.status,revision:t.revision,secretCiphertext:t.secretCiphertext,createdAt:t.createdAt,updatedAt:t.updatedAt}}function Vg(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e;return Object.fromEntries(["id","instanceId","credentialId","credentialRevision","assignmentRevision","status","authorizedAt","createdAt","updatedAt"].flatMap(e=>Object.prototype.hasOwnProperty.call(t,e)?[[e,t[e]]]:[]))}function Kg(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e;return{id:t.id,instanceId:t.instanceId,credentialId:t.credentialId,operationId:t.operationId||t.instanceId,remoteUrl:t.remoteUrl,ref:t.ref,clone:t.clone,createdAt:t.createdAt,updatedAt:t.updatedAt}}class Yg{credentials;assignments;audit;provisioningIntents;secrets;repositoryReferences;constructor(e,t={}){this.credentials=new Qd(e.gitCredentialsDir,{schema:Ug,sanitize:Wg,directoryMode:448,fileMode:384}),this.assignments=new Qd(e.gitCredentialAssignmentsDir,{schema:$g,sanitize:Vg,directoryMode:448,fileMode:384}),this.audit=new Qd(e.gitCredentialAuditDir,{schema:Bg,directoryMode:448,fileMode:384}),this.provisioningIntents=new Qd(e.gitCredentialProvisioningIntentsDir,{schema:Fg,sanitize:Kg,directoryMode:448,fileMode:384}),this.secrets=new Kl(e.gitCredentialEncryptionKeyPath),this.repositoryReferences=t.repositoryReferences||(()=>[])}init(){this.secrets.init(),this.credentials.init(),this.assignments.init(),this.audit.init(),this.provisioningIntents.init()}list(){return this.credentials.list().map(e=>this.publicCredential(e))}get(e){const t=this.credentials.get(e);return t?this.publicCredential(t):void 0}requirePublic(e){return this.publicCredential(this.require(e))}require(e){const t=this.credentials.get(e);if(!t)throw Gg(`Git credential ${e} was not found.`,"GIT_CREDENTIAL_NOT_FOUND",404);return t}create(e){const t=hm.parse(e),n=Hd(),i=this.credentials.put({id:Xd("gitcred"),name:t.name,kind:t.secret.kind,scope:cm(t.scope),status:"enabled",revision:1,secretCiphertext:this.secrets.seal(JSON.stringify(t.secret)),createdAt:n,updatedAt:n});return this.auditEvent("create",i.id,{credentialRevision:i.revision}),this.publicCredential(i)}update(e,t){const n=gm.parse(t),i=this.require(e),s=n.scope?cm(n.scope):i.scope;if("https"===s.scheme!=("https-token"===i.kind))throw Gg("Credential kind must match the remote scheme.","GIT_CREDENTIAL_SCOPE_KIND_MISMATCH",400);if(n.secret&&n.secret.kind!==i.kind)throw Gg("Credential kind cannot be changed during secret rotation.","GIT_CREDENTIAL_KIND_IMMUTABLE",409);const a=void 0!==n.secret,o={...i,...void 0===n.name?{}:{name:n.name},...void 0===n.scope?{}:{scope:s},...void 0===n.status?{}:{status:n.status},...a?{secretCiphertext:this.secrets.seal(JSON.stringify(n.secret))}:{},revision:i.revision+1,updatedAt:Hd()};this.assertRepositoryCompatibility(this.publicCredential(o));const r=this.credentials.put(o);return this.auditEvent("update",r.id,{credentialRevision:r.revision}),this.publicCredential(r)}disable(e){return this.update(e,{status:"disabled"})}remove(e){this.require(e);const t=this.assignments.list().filter(t=>t.credentialId===e&&"revoked"!==t.status),n=this.repositoryReferences(e),i=this.provisioningIntents.list().filter(t=>t.credentialId===e).map(e=>e.instanceId);if(t.length>0||n.length>0||i.length>0)throw Object.assign(Gg("Git credential is referenced by one or more repositories or instances.","GIT_CREDENTIAL_IN_USE",409),{details:{instances:[...new Set([...t.map(e=>e.instanceId),...i])].sort(),repositories:n.map(e=>({id:e.id,name:e.name}))}});const s=this.credentials.delete(e);return s&&this.auditEvent("delete",e),s}payload(e,t={}){const n=this.require(e);if("enabled"!==n.status&&!t.allowDisabled)throw Gg(`Git credential ${e} is disabled.`,"GIT_CREDENTIAL_DISABLED",409);let i;try{i=mm.parse(JSON.parse(this.secrets.open(n.secretCiphertext)))}catch{throw Gg(`Git credential ${e} secret could not be opened.`,"GIT_CREDENTIAL_SECRET_INVALID",500)}return ym.parse({credential:this.publicCredential(n),secret:i})}rememberOperationProvisioning(e){const t=Im.parse(e),n=1===t.credentials.length&&"operation-only"===t.credentials[0].retention?t.credentials[0]:void 0;if(!n)throw Gg("Operation-only provisioning requires exactly one credential.","GIT_CREDENTIAL_PROVISIONING_INVALID",400);const i=Hd();return this.provisioningIntents.put({id:t.instanceId,instanceId:t.instanceId,credentialId:n.payload.credential.id,operationId:t.operationId,remoteUrl:t.remoteUrl,ref:t.ref,clone:t.clone,createdAt:this.provisioningIntents.get(t.instanceId)?.createdAt||i,updatedAt:i})}operationProvisioning(e){const t=this.provisioningIntents.get(e);if(t)return Im.parse({operationId:t.operationId,instanceId:e,remoteUrl:t.remoteUrl,ref:t.ref,clone:t.clone,credentials:[{operationId:t.operationId,retention:"operation-only",payload:this.payload(t.credentialId)}]})}forgetOperationProvisioning(e){return this.provisioningIntents.delete(e)}listAssignments(e){return this.assignments.list().filter(t=>"revoked"!==t.status&&(!e||t.instanceId===e)).map(({id:e,createdAt:t,...n})=>fm.parse(n))}authorize(e,t,n={}){const i=this.require(t);if("enabled"!==i.status&&!n.allowDisabled)throw Gg(`Git credential ${t} is disabled.`,"GIT_CREDENTIAL_DISABLED",409);const s=Hg(e,t),a=this.assignments.get(s),o=Hd(),r=this.assignments.put({id:s,instanceId:e,credentialId:t,credentialRevision:i.revision,assignmentRevision:(a?.assignmentRevision||0)+1,status:"pending",authorizedAt:a?.authorizedAt||o,createdAt:a?.createdAt||o,updatedAt:o});this.auditEvent("authorize",t,{instanceId:e,credentialRevision:r.credentialRevision,assignmentRevision:r.assignmentRevision});const{id:c,createdAt:d,...l}=r;return fm.parse(l)}markAssignmentStatus(e,t,n){const i=Hg(e,t),s=this.assignments.get(i);if(!s)throw Gg("Git credential assignment was not found.","GIT_CREDENTIAL_ASSIGNMENT_NOT_FOUND",404);const a=this.assignments.put({...s,status:n,assignmentRevision:s.assignmentRevision+1,updatedAt:Hd()});this.auditEvent("assignment-status",t,{instanceId:e,credentialRevision:a.credentialRevision,assignmentRevision:a.assignmentRevision});const{id:o,createdAt:r,...c}=a;return fm.parse(c)}revoke(e,t){const n=this.assignments.get(Hg(e,t));if(!n||"revoked"===n.status)return!1;const i=this.assignments.put({...n,status:"revoked",assignmentRevision:n.assignmentRevision+1,updatedAt:Hd()});return this.auditEvent("revoke",t,{instanceId:e,credentialRevision:i.credentialRevision,assignmentRevision:i.assignmentRevision}),!0}desiredAuthorizationSet(e){const t=this.assignments.list().filter(t=>t.instanceId===e);return bm.parse({instanceId:e,generation:t.reduce((e,t)=>e+t.assignmentRevision,0),credentialIds:t.filter(e=>"revoking"!==e.status&&"revoked"!==e.status).map(e=>e.credentialId),updatedAt:Hd()})}revokeInstance(e){let t=0;for(const n of this.assignments.list().filter(t=>t.instanceId===e))this.assignments.delete(n.id)&&(t+=1);return this.provisioningIntents.delete(e),t}publicCredential(e){return lm.parse({id:e.id,name:e.name,kind:e.kind,scope:e.scope,secretSet:!0,status:e.status,revision:e.revision,createdAt:e.createdAt,updatedAt:e.updatedAt})}assertRepositoryCompatibility(e){const t=this.provisioningIntents.list().filter(t=>t.credentialId===e.id).map(t=>({id:t.instanceId,name:t.instanceId,url:t.remoteUrl,authType:e.kind}));for(const n of[...this.repositoryReferences(e.id),...t]){if(n.authType!==e.kind)throw Gg(`Credential kind no longer matches repository ${n.id}.`,"GIT_CREDENTIAL_REPOSITORY_KIND_MISMATCH",409);if("unique"!==xm(n.url,[{...e,status:"enabled"}]).status)throw Gg(`Credential scope no longer covers repository ${n.id}.`,"GIT_CREDENTIAL_REPOSITORY_SCOPE_MISMATCH",409)}}auditEvent(e,t,n={}){const i=Hd();this.audit.put({id:Xd("gitaudit"),action:e,credentialId:t,...n,createdAt:i,updatedAt:i})}}class Xg{records=new Map;options;constructor(e){this.options=e}create(e){const t=i.randomBytes(this.options.tokenBytes).toString("base64url"),n={...e,token:t,expiresAt:new Date(Date.now()+(e.ttlMs||this.options.ttlMs)).toISOString()};return this.records.set(t,n),n}resolve(e,t){const n=this.records.get(e);if(!n)throw this.invalidError();if(n.expiresAt<=(new Date).toISOString())throw this.records.delete(e),this.invalidError();if(t&&!t(n))throw this.invalidError();return n}revoke(e,t){const n=this.resolve(e,t);return this.records.delete(e),n}invalidError(){const e=new Error(this.options.invalidMessage);return Object.assign(e,{statusCode:this.options.invalidStatusCode||400,code:this.options.invalidCode}),e}}class Jg{requireInstance;listAppSessions;tokens=new Xg({invalidMessage:"App access link is invalid or expired.",invalidCode:"APP_ACCESS_TOKEN_INVALID",invalidStatusCode:401,tokenBytes:24,ttlMs:9e5});constructor(e){this.requireInstance=e.requireInstance,this.listAppSessions=e.listAppSessions}createToken(e){return this.tokens.create({instanceId:e.instanceId,sessionId:e.sessionId,mode:e.mode,ttlMs:e.ttlMs,authorization:e.authorization})}async createSessionToken(e){await this.requireInstance(e.instanceId);const t=await this.requireSession(e.instanceId,e.sessionId),n=Gs(t);if("vnc"!==n){const e=new Error("This app session does not expose a VNC view.");throw Object.assign(e,{statusCode:409,code:"APP_SESSION_ACCESS_UNAVAILABLE"}),e}if("running"!==t.status){const e=new Error("The app session is not running.");throw Object.assign(e,{statusCode:409,code:"APP_SESSION_NOT_RUNNING"}),e}return this.createToken({instanceId:e.instanceId,sessionId:e.sessionId,ttlMs:e.ttlMs,mode:n,...e.authorization?{authorization:e.authorization}:{}})}resolveToken(e,t){return this.tokens.resolve(e,e=>!t||e.mode===t)}revokeToken(e,t){this.tokens.revoke(e,e=>e.instanceId===t.instanceId&&e.sessionId===t.sessionId)}async proxyTarget(e,t,n=""){const i=this.resolveToken(e,t),s=await this.requireInstance(i.instanceId),a=await this.requireSession(i.instanceId,i.sessionId);return{access:i,instance:s,session:a,path:Qg(t,i.sessionId,a,n)}}async requireSession(e,t){const n=await this.listAppSessions(),i=n.instances.find(t=>t.instanceId===e)?.appSessions.sessions.find(e=>ef(e.id)===t);if(i)return i;const s=new Error("App session was not found.");throw Object.assign(s,{statusCode:404,code:"APP_SESSION_NOT_FOUND"}),s}}function Qg(e,t,n,i=""){return"tty"===e?`/api/apps/sessions/${encodeURIComponent(t)}/tty`:"vnc"===e?i?function(e,t){const n=`/${t.replace(/^\/+/,"")}`,i=n.split("?",1)[0]||"/",s=encodeURIComponent(e);if(!["/api/novnc/",`/api/apps/sessions/${s}/web/`,`/api/apps/sessions/${s}/vnc`,`/api/apps/sessions/${s}/novnc/`].some(e=>i===e.replace(/\/$/,"")||i.startsWith(e))){const e=new Error("App access token cannot be used for this path.");throw Object.assign(e,{statusCode:403,code:"APP_ACCESS_PATH_FORBIDDEN"}),e}return n}(t,i):ef(Zg(n.vnc).noVncPath)||`/api/apps/sessions/${encodeURIComponent(t)}/web/`:ef(Zg(n.web).webPath)||`/api/apps/sessions/${encodeURIComponent(t)}/web/`}function Zg(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function ef(e){return"string"==typeof e&&e.trim()?e.trim():void 0}const tf={allow:"a",deny:"d",skip:"s"};function nf(e){return i.createHash("sha256").update(e).digest("base64url").slice(0,Math.ceil(16))}class sf{tokens=new Xg({invalidMessage:"Chat action expired.",invalidCode:"CHAT_ACTION_TOKEN_INVALID",tokenBytes:9,ttlMs:6e5});create(e){return this.tokens.create({type:e.type,instanceId:"instanceId"in e?e.instanceId:void 0,appId:"appId"in e?e.appId:void 0,routeId:"routeId"in e?e.routeId:void 0,decision:"decision"in e?e.decision:void 0,ttlMs:e.ttlMs})}resolve(e,t){return this.tokens.resolve(e,e=>!t||e.type===t)}pendingDecisionCallbackData(e,t){return`task_handoff:cp_p:v1:${tf[t]}:${nf(e)}`}}function af(e){const{token:t,...n}=e;return{...n,settings:rf(e.settings),tokenSet:Boolean(e.token)}}function of(e,t){if(!t)return e;const n={...e};for(const[e,i]of Object.entries(t))void 0!==i&&""!==i&&(n[e]=i);return n}function rf(e){const t={...e};return"string"==typeof t.clientSecret&&t.clientSecret&&(delete t.clientSecret,t.clientSecretSet=!0),"string"==typeof t.appSecret&&t.appSecret&&(delete t.appSecret,t.appSecretSet=!0),t}class cf{chatBridges;chatSessions;constructor(e){this.chatBridges=e.chatBridges,this.chatSessions=e.chatSessions}list(){return this.chatBridges.list().map(af)}require(e){const t=this.chatBridges.get(e);return t||bh("CHAT_BRIDGE_NOT_FOUND",`Chat bridge ${e} was not found.`),t}create(e){const t=Ph.parse(e),n=Hd(),i=Id.parse({...t,id:Xd(`chat_${t.channel}`),name:t.name||(s=t.channel,a=this.chatBridges.list().filter(e=>e.channel===t.channel).length+1,`${"telegram"===s?"Telegram":"wechat"===s?"WeChat":"dingding"===s?"DingDing":"lark"===s?"Lark":"Web"} ${a}`),enabled:t.enabled??!1,allowedUserIds:t.allowedUserIds||[],pollIntervalMs:t.pollIntervalMs||3e3,settings:of({},t.settings),createdAt:n,updatedAt:n});var s,a;return this.chatBridges.put(i),af(i)}update(e,t){const n=jh.parse(t),i=this.require(e),s=of(i.settings,n.settings),a=Id.parse({...i,...n,id:e,channel:i.channel,name:n.name||i.name,settings:s,updatedAt:Hd()});return this.chatBridges.put(a),af(a)}delete(e){const t=this.chatBridges.delete(e);if(t)for(const t of this.chatSessions.list())t.bridgeId===e&&this.chatSessions.delete(t.id);return t}}class df{chatSessions;constructor(e){this.chatSessions=e.chatSessions}list(){return this.chatSessions.list()}require(e){const t=this.chatSessions.get(e);return t||bh("CHAT_SESSION_NOT_FOUND",`Chat session ${e} was not found.`),t}upsert(e){const t=Hd(),n=(i=e.channel,s=e.chatSessionId,`${e.bridgeId||i}:${s.replace(/[^a-zA-Z0-9_.:-]/g,"_")}`);var i,s;const a=this.chatSessions.get(n),o=xd.parse({...a||{},...e,id:n,channel:e.channel,bridgeId:e.bridgeId,chatSessionId:e.chatSessionId,lastUsedAt:t,createdAt:a?.createdAt||t,updatedAt:t});return this.chatSessions.put(o),o}}function lf(e){return{inline_keyboard:e.map(e=>e.map(e=>({text:e.text,...e.url?{url:e.url}:{callback_data:e.callbackData||""}})))}}function pf(e,t=40){return lf(e.slice(0,t).map(e=>[e]))}function uf(e){return Buffer.from(e,"utf8").toString("base64url")}function mf(e){const t=gf(e).inline_keyboard,n=Array.isArray(t)?t:[],i=[];for(const e of n)if(Array.isArray(e))for(const t of e){const e=gf(t),n=String(e.callback_data||""),s=String(e.text||"").trim();s&&n&&i.push({text:s,id:`th_cb_${uf(n)}`})}return i.slice(0,40)}function hf(e,t){const n=String(e||"").replace(/\s+/g," ").trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-3))}...`}function gf(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function ff(e){return(e.aiSessions?.sessions||[]).filter(t=>function(e,t){const n=(e.apps?.sessions||[]).filter(wf);if(t.appSessionId&&n.some(e=>e.id===t.appSessionId))return!0;const i=new Set(t.appBindingKeys||[]);return Boolean(i.size&&n.some(e=>function(e){return[...Bs(e).bindings.map(Ws),...Ks(e)].filter(Boolean)}(e).some(e=>i.has(e))))}(e,t))}function yf(e){return"waiting"===e.status?4:"failed"===e.status?3:"running"===e.status?2:"idle"===e.status?1:0}function bf(e){return[e.cwd||"",e.agent||"",e.providerSessionId||e.id].join("\0")}function vf(e){const t=e.session.title||e.session.userPrompt||e.session.summary||e.session.lastMessage||"",n=t?` - ${hf(t,18)}`:"";return`${e.instance.name} - ${e.session.agent} ${e.session.status}${n}`}function If(e,t=(e,t)=>`task_handoff:approval:${e.id}:${t}`){return pf(e.flatMap(e=>"approval"!==e.kind?[]:[{text:hf(`Allow ${e.instance?.name||e.instanceId} / ${e.aiSessionId}`,56),callbackData:t(e,"allow")},{text:hf(`Skip ${e.instance?.name||e.instanceId} / ${e.aiSessionId}`,56),callbackData:t(e,"skip")},{text:hf(`Deny ${e.instance?.name||e.instanceId} / ${e.aiSessionId}`,56),callbackData:t(e,"deny")}]))}function xf(e){const t=`${e.project?.name||e.projectId} / ${e.instance?.name||e.instanceId}`,n="approval"===e.kind?`/approve ${e.id} | /deny ${e.id} | /skip ${e.id}`:`/reply ${e.id} <message>`;return`[${t}] ${e.kind} ${e.id}: ${e.result}\n${n}`}function wf(e){const t=e&&"object"==typeof e&&!Array.isArray(e)?e:{};return Hs("string"==typeof t.status?t.status:void 0)}class Sf{deps;targets;constructor(e,t){this.deps=e,this.targets=t}async handleAiSessionsCommand(e){const t=await this.targets.aiSessionChoices(e),n=t.find(e=>e.active),i=t.map(e=>function(e){const t=e.session.userPrompt||e.session.summary||e.session.lastMessage||"",n=e.active?"* ":"",i=e.session.phase&&"unknown"!==e.session.phase?`/${e.session.phase}`:"";return`${n}${e.index+1}. ${e.projectName} / ${e.instance.name} - ${e.session.agent} - ${e.session.status}${i} - ${e.session.id}${t?` - ${t}`:""}`}(e));return{accepted:!0,routed:!1,binding:e,instances:t.map(e=>e.instance),reply:t.length?["Select AI session",`Current ${n?`${n.projectName} / ${n.instance.name} / ${n.session.id}`:await this.targets.renderChatTarget(e)}, total ${t.length}`,"",...i].join("\n"):"No AI sessions found.",replyMarkup:t.length?pf(t.map(e=>({text:`${e.active?"✓ ":""}${vf(e)}`,callbackData:`task_handoff:cp_session:${e.index}`}))):void 0}}async handleAiSessionCommand(e,t){const n=String(t[0]||"").trim();if(!n)return this.handleAiSessionsCommand(e);const i=await this.targets.findAiSession(n);if(!i)return{accepted:!1,routed:!1,binding:e,reply:`AI session ${n} was not found. Try /sessions.`};const s=i.instance.projectId?this.deps.getProject(i.instance.projectId):void 0;return{accepted:!0,routed:!1,binding:this.deps.upsertChatSession({...e,activeProjectId:s?.id||e.activeProjectId,activeInstanceId:i.instance.id,activeAiSessionId:i.session.id}),instance:i.instance,aiSession:i.session,reply:`Active AI session: ${i.instance.name} / ${i.session.agent} ${i.session.id}`}}async handleAiSessionIndexAction(e,t){const n=(await this.targets.aiSessionChoices(e)).find(e=>e.index===t);if(!n)return{accepted:!1,routed:!1,binding:e,reply:"AI session was not found. Use /session to refresh the list.",replyMarkup:void 0};const i=this.deps.upsertChatSession({...e,activeProjectId:n.projectId||e.activeProjectId,activeInstanceId:n.instance.id,activeAiSessionId:n.session.id}),s=await this.handleAiSessionsCommand(i);return{...s,accepted:!0,binding:i,instance:n.instance,aiSession:n.session,message:`selected ${n.session.id}`,reply:[`Current chat is bound to AI session ${n.session.id}`,"",s.reply].join("\n")}}async handleAiSessionInterruptCommand(e){if(!e.activeInstanceId||!e.activeAiSessionId)return{accepted:!1,routed:!1,binding:e,reply:"No active AI session is selected. Use /sessions and /session <id> first."};const t=await this.deps.requireControlledInstance(e.activeInstanceId,!0),n=await this.deps.interruptAiSession(t.id,e.activeAiSessionId);return{accepted:!0,routed:!0,binding:e,instance:mh(t),aiSession:n,reply:`Interrupt sent to ${t.name} / ${e.activeAiSessionId}.`}}}function Af(e){return e.providerTurnId||e.turnId||""}function Ef(e){return Hs(kf(e.status))}function _f(e,t){const n=kf(t.appId)||"App",i=kf(t.title).trim();if(i&&i!==n)return i;const s=function(e,t){for(const n of e.appInventory?.items||[])if(n.id===t)return n.name;return""}(e,n);return s||n}function Tf(e){const t=function(e){return"online"!==e.connectionStatus?[]:(e.appInventory?.items||[]).filter(e=>"available"===e.availability)}(e),n=new Map;for(const e of t){const t=Nf(e);t&&!n.has(t.id)&&n.set(t.id,t)}return[...n.values()]}function zf(e,t,n,i){const s=kf(t.id)&&function(e,t){const n=Gs(e);if(!n)return;return`/apps/access/${n}?token=${encodeURIComponent(t(n))}`}(t,i)||`/instances/${encodeURIComponent(e.id)}/`,a=function(e,t){const n=kf(t);if(n&&new RegExp("^https?://","i").test(n))return new URL(e,n.endsWith("/")?n:n+"/").toString()}(s,n);return{text:a||s,url:a}}function kf(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function Nf(e){if("string"==typeof e&&e.trim())return{id:e,label:Cf(e)};const t=function(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}(e),n=kf(t.id).trim();return n?{id:n,label:kf(t.name).trim()||Cf(n)}:void 0}function Cf(e){return{"terminal-tty":"Terminal","gui-terminal":"GUI Terminal",chromium:"Chromium",browser:"Browser","vscode-web":"VS Code"}[e]||e.replace(/[-_]+/g," ").replace(/\b\w/g,e=>e.toUpperCase())}class Rf{deps;targets;constructor(e,t){this.deps=e,this.targets=t}async handleInstancesCommand(e){const t=await this.targets.instancesForBinding(e);return{accepted:!0,routed:!1,binding:e,instances:t,reply:(n=t.length,0===n?"No controlled instances are registered yet.":`Instances: ${n}. Tap an instance to create an app.`),replyMarkup:t.length?pf(t.map(e=>{return{text:hf(e.name||e.id,56),callbackData:(t=this.deps.createChatActionToken({type:"instance-app-menu",instanceId:e.id}).token,`task_handoff:cp_i:${t}`)};var t})):void 0};var n}async handleInstanceAppMenuAction(e,t){const n=(await this.targets.instancesForBinding(e)).find(e=>e.id===t);if(!n)return{accepted:!1,routed:!1,binding:e,reply:"Instance not found."};const i=Tf(n);return{accepted:!0,routed:!1,binding:e,instance:n,message:`Select an app for ${n.name}.`,reply:i.length?`New app for ${n.name}`:`No launchable apps for ${n.name}.`,replyMarkup:i.length?pf(i.map(e=>{return{text:hf(e.label,56),callbackData:(t=this.deps.createChatActionToken({type:"launch-app",instanceId:n.id,appId:e.id}).token,`task_handoff:cp_a:${t}`)};var t})):void 0}}async handleLaunchAppAction(e,t,n){const i=(await this.targets.instancesForBinding(e)).find(e=>e.id===t);if(!i)return{accepted:!1,routed:!1,binding:e,reply:"Instance not found."};const s=Tf(i).find(e=>e.id===n);return s?{accepted:!0,routed:!1,binding:e,instance:i,session:await this.deps.launchAppSession(i.id,s.id),message:`${s.label} launched`,reply:`Launched ${s.label} on ${i.name}.`}:{accepted:!1,routed:!1,binding:e,reply:`App ${n} is not launchable for ${i.name}.`}}async handleAppsCommand(e){const t=await this.deps.boardAsync(),n=new Map(t.map(e=>[e.id,e])),i=(await this.deps.listAppSessions()).instances.flatMap(e=>{const t=n.get(e.instanceId);return t?e.appSessions.sessions.filter(Ef).filter(e=>Boolean(kf(e.id))).map(e=>({instance:t,session:e,link:zf(t,e,this.deps.controlPlanePublicBaseUrl(),n=>this.deps.createAppAccessToken({instanceId:t.id,sessionId:kf(e.id)||"",mode:n}).token)})):[]}),s=i.filter(e=>e.link.url).map(e=>({text:hf(`${e.instance.name} · ${_f(e.instance,e.session)}`,56),url:e.link.url}));return{accepted:!0,routed:!1,binding:e,instances:t,reply:(a=i.length,o=s.length,0===a?"No app sessions found.":0===o?`App sessions: ${a}. Set the control plane public URL in Settings > Appearance to open them from chat.`:`App sessions: ${a}. Tap a button to open.`),replyMarkup:s.length?pf(s):void 0};var a,o}}class Of{deps;targets;constructor(e,t){this.deps=e,this.targets=t}async forwardChatMessage(e,t){const n=t.target?.instanceId||e.activeInstanceId||"",i=t.target?.aiSessionId||e.activeAiSessionId,s=await this.deps.requireControlledInstance(n,!0),a=s.projectId?this.deps.requireProject(s.projectId):void 0;if("online"!==s.connectionStatus){const e=new Error(`Instance ${s.name} is not reachable.`);throw Object.assign(e,{statusCode:409,code:"CHAT_TARGET_UNREACHABLE"}),e}if(i){const n=await this.trySendAiSessionMessage(e,s.id,i,t.message.text,t.message.attachments,!t.target);return n.ok?this.sentResult(e,a,s,i,n.aiSession):this.failedSendResult(n.binding,a,s,n.reply)}const o=await this.targets.defaultAiSessionIdForInstance(s.id);if(o){const n=this.deps.upsertChatSession({...e,activeAiSessionId:o}),i=await this.trySendAiSessionMessage(n,s.id,o,t.message.text,t.message.attachments);return i.ok?this.sentResult(n,a,s,o,i.aiSession):this.failedSendResult(i.binding,a,s,i.reply)}return{accepted:!1,routed:!1,binding:e,project:a||void 0,instance:mh(s),reply:`No active AI session is selected for ${s.name}. Use /sessions and /session <id> first.`}}async trySendAiSessionMessage(e,t,n,i,s=[],a=!0){try{return{ok:!0,binding:e,aiSession:await this.deps.sendAiSessionMessage(t,n,i||"请查看附件。",void 0,s)}}catch(t){return function(e){return"AI_SESSION_NOT_FOUND"===(e&&"object"==typeof e?e:{}).code}(t)?{ok:!1,binding:a?this.deps.upsertChatSession({...e,activeAiSessionId:void 0}):e,reply:`The selected AI session ${n} no longer exists. Use /session to choose an active AI session.`}:{ok:!1,binding:e,reply:`Failed to send to AI session ${n}: ${yh(t)}`}}}failedSendResult(e,t,n,i){return{accepted:!1,routed:!1,binding:e,project:t||void 0,instance:mh(n),reply:i}}sentResult(e,t,n,i,s){return{accepted:!0,routed:!0,binding:e,project:t||void 0,instance:mh(n),aiSession:s,instanceId:n.id,aiSessionId:i,turnId:(a=s,a.turnId||a.providerTurnId||""),providerTurnId:Af(s),reply:`Sent to ${t?.name||n.sourceSnapshot.name||"Source"} / ${n.name} / ${i}.`};var a}}class jf{deps;constructor(e){this.deps=e}async handlePendingCommand(e){const t=await this.deps.listPendingRoutes(),n=e.activeInstanceId?t.filter(t=>t.instanceId===e.activeInstanceId):t;return{accepted:!0,routed:!1,binding:e,pending:n,reply:n.length?n.map(xf).join("\n"):"No pending routes.",replyMarkup:n.length?If(n,(e,t)=>this.deps.pendingDecisionCallbackData(e.id,t)):void 0}}async handlePendingDecisionCommand(e,t,n){const i=fh(t[0]);return i?i.aiSessionId?{accepted:!0,routed:!0,binding:e,pending:i,aiSession:await this.deps.resolveAiSessionApproval(i.instanceId,i.aiSessionId,n),reply:`${n} sent for ${i.instanceId}:${i.aiSessionId}.`}:{accepted:!1,routed:!1,binding:e,pending:i,reply:"Only AI session pending routes are supported here."}:{accepted:!1,routed:!1,binding:e,reply:`Usage: /${"allow"===n?"approve":n} <instance-id:pending-id>`}}async handlePendingReplyCommand(e,t){const n=fh(t[0]),i=t.slice(1).join(" ").trim();return n&&i?n.aiSessionId?{accepted:!0,routed:!0,binding:e,pending:n,aiSession:await this.deps.sendAiSessionMessage(n.instanceId,n.aiSessionId,i),reply:`Reply sent for ${n.instanceId}:${n.aiSessionId}.`}:{accepted:!1,routed:!1,binding:e,pending:n,reply:"Only AI session pending routes are supported here."}:{accepted:!1,routed:!1,binding:e,reply:"Usage: /reply <instance-id:pending-id> <message>"}}}class Pf{deps;targets;constructor(e,t){this.deps=e,this.targets=t}async handleUseCommand(e,t){if(0===t.length)return{accepted:!0,routed:!1,binding:e,instances:await this.targets.instancesForBinding(e),reply:await this.targets.renderUseHelp(e)};if(t.length>=2){const n=this.targets.resolveProject(t[0]),i=await this.targets.resolveInstance(t[1],n.id),s=this.deps.upsertChatSession({...e,activeProjectId:n.id,activeInstanceId:i.id,activeAiSessionId:await this.targets.defaultAiSessionIdForInstance(i.id)});return{accepted:!0,routed:!1,binding:s,reply:await this.targets.renderTargetSelected(s)}}const n=t[0],i=await this.targets.findInstance(n);if(i){const t=i.projectId?this.deps.requireProject(i.projectId):void 0,n=this.deps.upsertChatSession({...e,activeProjectId:t?.id,activeInstanceId:i.id,activeAiSessionId:await this.targets.defaultAiSessionIdForInstance(i.id)});return{accepted:!0,routed:!1,binding:n,reply:await this.targets.renderTargetSelected(n)}}const s=this.targets.resolveProject(n),a=(await this.deps.boardAsync()).filter(e=>e.projectId===s.id),o=a.filter(e=>"running"===e.status&&"online"===e.connectionStatus);if(1===o.length){const t=this.deps.upsertChatSession({...e,activeProjectId:s.id,activeInstanceId:o[0].id,activeAiSessionId:await this.targets.defaultAiSessionIdForInstance(o[0].id)});return{accepted:!0,routed:!1,binding:t,reply:await this.targets.renderTargetSelected(t)}}return{accepted:!0,routed:!1,binding:this.deps.upsertChatSession({...e,activeProjectId:s.id,activeInstanceId:void 0,activeAiSessionId:void 0}),instances:a,reply:`${s.name} selected. Choose an instance with /use ${s.id} <instance-id-or-name>.\n${this.targets.renderInstanceLines(a)}`}}async handleProjectCommand(e,t){if(0===t.length)return{accepted:!1,routed:!1,binding:e,reply:"Usage: /project <project-id-or-name>"};const n=this.targets.resolveProject(t[0]),i=e.activeInstanceId?await this.deps.requireControlledInstance(e.activeInstanceId).catch(()=>{}):void 0,s=this.deps.upsertChatSession({...e,activeProjectId:n.id,activeInstanceId:i?.projectId===n.id?i.id:void 0,activeAiSessionId:i?.projectId===n.id?e.activeAiSessionId:void 0});return{accepted:!0,routed:!1,binding:s,reply:`Active project: ${n.name}${s.activeInstanceId?"":". Choose an instance with /use."}`}}}class Df{deps;constructor(e){this.deps=e}async instancesForBinding(e){const t=await this.deps.boardAsync();return e.activeProjectId?t.filter(t=>t.projectId===e.activeProjectId):t}async fullInstancesForBinding(e){const t=await this.deps.listNodeInstances();return e.activeProjectId?t.filter(t=>t.projectId===e.activeProjectId):t}async renderUseHelp(e){return`Active target: ${await this.renderChatTarget(e)}\nUse /instances to list targets, then /use <instance-id-or-name>. Use /sessions to choose an AI session when there is more than one.`}async renderChatStatus(e){const t=e.activeInstanceId?(await this.deps.boardAsync()).find(t=>t.id===e.activeInstanceId):void 0;return t?`Active target: ${await this.renderChatTarget(e)}\nStatus: ${t.status}, connection: ${t.connectionStatus}`:`Active target: ${await this.renderChatTarget(e)}`}async renderChatHelp(e){return["TaskHandoff chat commands:","/help - show this help","/status or /target - show the active project, instance, and AI session","/instances - list controlled instances","/apps - list app sessions","/use <instance-id-or-name> - choose an active instance","/use <project-id-or-name> <instance-id-or-name> - choose a project and instance","/project <project-id-or-name> - narrow instance selection to a project","/sessions - list all AI sessions","/session <ai-session-id> - choose an active AI session","/pending - list waiting approvals","/approve <instance-id:pending-id>, /deny <...>, /skip <...> - answer approvals","/reply <instance-id:pending-id> <message> - reply to a waiting session","/cancel - interrupt the active AI session","","Send normal text after selecting a target; if there is only one AI session, it is selected automatically.",`Current target: ${await this.renderChatTarget(e)}`].join("\n")}renderInstanceLines(e){return e.map(e=>`${e.name} (${e.id}) - ${e.status}/${e.connectionStatus}`).join("\n")}async renderChatTarget(e){const t=e.activeProjectId?this.deps.getProject(e.activeProjectId):void 0,n=e.activeInstanceId?await this.deps.requireControlledInstance(e.activeInstanceId).catch(()=>{}):void 0,i=e.activeAiSessionId||"none";return`${t?.name||e.activeProjectId||"none"} / ${n?.name||e.activeInstanceId||"none"} / ${i}`}async renderTargetSelected(e){const t=await this.renderChatTarget(e);return e.activeAiSessionId?`Active target: ${t}`:`Active target: ${t}\nNo AI session selected yet. Use /sessions and /session <id>, or send a message once exactly one session is available.`}async defaultAiSessionIdForInstance(e){const t=await this.aiSessionSnapshotForInstance(e),n=(await this.deps.boardAsync()).find(t=>t.id===e),i=(await this.deps.listAppSessions()).instances.find(t=>t.instanceId===e),s=n?{...n,apps:{...n.apps,sessions:i?.appSessions.sessions||[]}}:void 0,a=t&&n?ff({...s,aiSessions:t}):t?.sessions||[];return 1===a.length?a[0].id:void 0}async aiSessionChoices(e){return(await this.boardInstancesForBinding({},{refresh:!0})).flatMap(t=>ff(t).map(n=>({index:0,projectId:t.projectId,projectName:t.project?.name||("string"==typeof t.sourceSnapshot.name?t.sourceSnapshot.name:"Source"),instance:t,session:n,active:e.activeInstanceId===t.id&&e.activeAiSessionId===n.id}))).sort((e,t)=>{const n=yf(t.session)-yf(e.session);return n||(String(e.instance.name||"").localeCompare(String(t.instance.name||""))||e.instance.id.localeCompare(t.instance.id)||bf(e.session).localeCompare(bf(t.session)))}).map((e,t)=>({...e,index:t}))}async boardInstancesForBinding(e,t={}){const n=await this.deps.boardAsync(),i=await this.deps.listAiSessions(t),s=await this.deps.listAppSessions(t),a=new Map(i.instances.map(e=>[e.instanceId,e.aiSessions])),o=new Map(s.instances.map(e=>[e.instanceId,e.appSessions])),r=n.map(e=>{return{...e,apps:{...e.apps,sessions:o.get(e.id)?.sessions||[]},aiSessions:a.get(e.id)||(t=e.aiSessions.updatedAt,{runningCount:0,waitingCount:0,staleCount:0,sessions:[],updatedAt:t})};var t});return e.activeProjectId?r.filter(t=>t.projectId===e.activeProjectId):r}async findAiSession(e){const t=await this.boardInstancesForBinding({},{refresh:!0});for(const n of t){const t=(n.aiSessions?.sessions||[]).find(t=>t.id===e||t.providerSessionId===e);if(t)return{instance:n,session:t}}}async aiSessionSnapshotForInstance(e){const t=await this.deps.listAiSessions();return t.instances.find(t=>t.instanceId===e)?.aiSessions}resolveProject(e){const t=this.deps.getProject(e)||this.deps.listProjects().find(t=>t.name===e);return t||bh("PROJECT_NOT_FOUND",`Project ${e} was not found.`),t}async resolveInstance(e,t){const n=await this.findInstance(e,t);return n||bh("CONTROLLED_INSTANCE_NOT_FOUND",`Controlled instance ${e} was not found.`),n}async findInstance(e,t){return(await this.deps.listNodeInstances()).find(n=>!(n.id!==e&&n.name!==e||t&&n.projectId!==t))}}class Lf{deps;targets;sender;appCommands;pendingCommands;aiSessionCommands;targetCommands;constructor(e){this.deps=e,this.targets=new Df(e),this.sender=new Of(e,this.targets),this.appCommands=new Rf(e,this.targets),this.pendingCommands=new jf(e),this.aiSessionCommands=new Sf(e,this.targets),this.targetCommands=new Pf(e,this.targets)}async handleChatGatewayMessage(e){const t=wd.parse(e),n=this.deps.upsertChatSession({channel:t.source.channel,bridgeId:t.source.bridgeId,chatSessionId:t.source.chatSessionId,userId:t.source.userId}),i=t.message.text.trim();return i.startsWith("/")?this.handleChatCommand(n,i):i||t.message.attachments.length?n.activeInstanceId?this.sender.forwardChatMessage(n,t):{accepted:!1,routed:!1,binding:n,reply:await this.targets.renderUseHelp(n)}:{accepted:!1,routed:!1,binding:n,reply:""}}async handleChatGatewayAction(e){const t=this.deps.upsertChatSession({channel:e.source.channel,bridgeId:e.source.bridgeId,chatSessionId:e.source.chatSessionId,userId:e.source.userId});return"ai-session"===e.action.type?this.aiSessionCommands.handleAiSessionIndexAction(t,e.action.index):"instance-app-menu"===e.action.type?this.appCommands.handleInstanceAppMenuAction(t,e.action.instanceId):"launch-app"===e.action.type?this.appCommands.handleLaunchAppAction(t,e.action.instanceId,e.action.appId):"pending-decision"===e.action.type?this.pendingCommands.handlePendingDecisionCommand(t,[e.action.routeId],e.action.decision):{accepted:!1,routed:!1,binding:t,reply:"Unknown action."}}async handleChatCommand(e,t){const[n="",...i]=t.split(/\s+/),s=n.replace(/@[\w_]+$/,"");switch(s.toLowerCase()){case"/help":case"/start":return{accepted:!0,routed:!1,binding:e,reply:await this.targets.renderChatHelp(e)};case"/sessions":return this.aiSessionCommands.handleAiSessionsCommand(e);case"/session":return this.aiSessionCommands.handleAiSessionCommand(e,i);case"/cancel":case"/interrupt":return this.aiSessionCommands.handleAiSessionInterruptCommand(e);case"/pending":return this.pendingCommands.handlePendingCommand(e);case"/approve":return this.pendingCommands.handlePendingDecisionCommand(e,i,"allow");case"/deny":return this.pendingCommands.handlePendingDecisionCommand(e,i,"deny");case"/skip":return this.pendingCommands.handlePendingDecisionCommand(e,i,"skip");case"/reply":return this.pendingCommands.handlePendingReplyCommand(e,i);case"/instances":return this.appCommands.handleInstancesCommand(e);case"/apps":return this.appCommands.handleAppsCommand(e);case"/use":return this.targetCommands.handleUseCommand(e,i);case"/project":return this.targetCommands.handleProjectCommand(e,i);case"/status":case"/target":return{accepted:!0,routed:!1,binding:e,instance:e.activeInstanceId?(await this.deps.boardAsync()).find(t=>t.id===e.activeInstanceId):void 0,reply:await this.targets.renderChatStatus(e)};default:return{accepted:!1,routed:!1,binding:e,reply:`Unknown command: ${s||n}. Try /help.`}}}}const Mf=f.z.object({id:f.z.string().trim().min(1),preferences:Yp,createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}).strict();function qf(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e,n=t.preferences&&"object"==typeof t.preferences&&!Array.isArray(t.preferences)?t.preferences:{};return{id:t.id,preferences:{import:"string"==typeof n.import&&n.import.trim()?n.import:".",export:"string"==typeof n.export&&n.export.trim()?n.export:"."},createdAt:t.createdAt,updatedAt:t.updatedAt}}function Uf(){return Yp.parse({})}function $f(e){return/^[a-z]:[\\/]/i.test(e)||/^[\\/]{2}[^\\/]+[\\/]+[^\\/]+/.test(e)}function Bf(e){return $f(e)?t.win32:t.posix}class Ff{retiredRoot;legacyControlledInstancesDir;legacyNodeRuntimesDir;legacyNodeJoinInvitesDir;paths;options;constructor(e,n={}){this.paths=e,this.options=n,this.retiredRoot=t.join(e.dataDir,"retired-persistence"),this.legacyControlledInstancesDir=t.join(e.dataDir,"controlled-instances"),this.legacyNodeRuntimesDir=t.join(e.dataDir,"node-runtimes"),this.legacyNodeJoinInvitesDir=t.join(e.dataDir,"node-join-invites")}run(){return this.removePersistedInvites(),this.retireLegacyProjection("controlled-instances",this.legacyControlledInstancesDir,!0),this.retireLegacyProjection("node-runtimes",this.legacyNodeRuntimesDir,!1),function(e){if(!n.existsSync(e.trashRoot))return[];const t=e.nowMs??Date.now(),i=e.retentionMs??Ed,s=[];for(const a of n.readdirSync(e.trashRoot,{withFileTypes:!0})){const o=_d(e.trashRoot,a.name);try{const e=Number(a.name.split("-",1)[0]);if(!Number.isFinite(e)||e+i>t)continue;const r=n.lstatSync(o);r.isSymbolicLink()?n.unlinkSync(o):r.isDirectory()?n.rmSync(o,{recursive:!0,force:!0}):n.unlinkSync(o),s.push(o)}catch(t){e.logger?.("retired persistence entry cleanup failed",{path:o,error:t instanceof Error?t.message:String(t)})}}return s}({trashRoot:this.retiredRoot,retentionMs:this.options.retentionMs??Ed,nowMs:this.now(),logger:this.options.logger})}removePersistedInvites(){n.existsSync(this.legacyNodeJoinInvitesDir)&&n.rmSync(this.legacyNodeJoinInvitesDir,{recursive:!0,force:!0})}retireLegacyProjection(e,i,s){if(!n.existsSync(i))return;const a=n.lstatSync(i);if(!a.isDirectory()||a.isSymbolicLink())return n.rmSync(i,{force:!0}),void this.options.logger?.("invalid legacy persistence path was removed",{store:e});n.readdirSync(i).length?(s&&this.redactLegacyInstanceCredentials(i),function(e){const t=_d(e.sourceRoot,e.entryName);if(!n.existsSync(t))return;const i=n.lstatSync(t);if(!i.isDirectory()||i.isSymbolicLink())throw new Error(`Retention source must be a real directory: ${t}`);Td(e.trashRoot);const s=e.nowMs??Date.now();let a=0,o=`${s}-${e.entryName}`;for(;n.existsSync(_d(e.trashRoot,o));)a+=1,o=`${s}-${a}-${e.entryName}`;const r=_d(e.trashRoot,o);n.renameSync(t,r)}({sourceRoot:this.paths.dataDir,entryName:t.basename(i),trashRoot:this.retiredRoot,nowMs:this.now()}),this.options.logger?.("legacy control-plane persistence was retired",{store:e})):n.rmdirSync(i)}redactLegacyInstanceCredentials(e){for(const i of n.readdirSync(e,{withFileTypes:!0})){if(!i.isFile()||i.isSymbolicLink())continue;const s=t.join(e,i.name);try{const e=JSON.parse(n.readFileSync(s,"utf8"));delete e.registrationToken,y.sync(s,`${JSON.stringify(e,null,2)}\n`,{encoding:"utf8",mode:384}),n.chmodSync(s,384)}catch(e){n.rmSync(s,{force:!0}),this.options.logger?.("unreadable legacy instance record was removed",{filePath:s,error:e instanceof Error?e.message:String(e)})}}Td(e)}now(){return this.options.now?.()??Date.now()}}const Hf="task-handoff.control-plane.local",Gf="task-handoff.control-plane.builtin";function Wf(e){return"true"===e.labels[Hf]}function Vf(e){return"true"===e.labels[Gf]}class Kf{projects;models;modelService;images;nodes;pendingPairingRevokes;chatSessions;chatBridges;triggers;nodeJoinService;configSyncPreferences;settings;paths;fetchImpl;dockerCommandRunner;logger;diagnosticLogsState;nodeConnectionRuntime;appAccessService;persistenceMaintenance;chatActionTokenService=new sf;nodeAgentTransportResolver;proxyPrivateStore;proxyLifecycle;nodeConnectionManager;nodeAgentGateway;controlledInstanceGateway;aiSessionActionService;controlledInstanceCreator;instanceBoardReader=new Eg;controlPlaneTriggerService;catalogService;marketCatalogService;gitCredentials;chatBridgeService;chatSessionService;chatSessionRuntime;aiSessionSnapshotProvider;appSessionSnapshotProvider;constructor(e,n={}){this.paths=e,this.fetchImpl=n.fetchImpl||fetch,this.dockerCommandRunner=n.dockerCommandRunner,this.nodeConnectionRuntime=n.nodeConnectionRuntime,this.persistenceMaintenance=new Ff(e,{logger:(e,t)=>this.logWarn(t,e)});const i=e=>({schema:e,logger:(e,t)=>this.logWarn(t,e)});this.proxyPrivateStore=new Ym(function(e){const n=t.resolve(e,"control-plane-proxy");return{pendingClaimsDir:t.join(n,"pending-claims"),nodeCredentialsDir:t.join(n,"node-credentials"),identityPath:t.join(n,"identity.json")}}(e.dataDir),(e,t)=>this.logWarn(t,e)),this.nodeAgentTransportResolver=new Mm({direct:Lm(this.fetchImpl),tunnel:n.nodeAgentTransport,proxy:new Hm({credentialForNode:e=>this.proxyPrivateStore.nodeCredential(e.id),fetchImpl:this.fetchImpl})});const s=(a=process.env.TASK_HANDOFF_DIAGNOSTIC_LOGS,["1","true","yes","on"].includes(String(a||"").trim().toLowerCase()));var a;this.diagnosticLogsState=s,this.settings=new Zd(e.settingsPath,()=>Nh.parse({diagnosticLogs:s}),{...i(Nh),sanitize:e=>function(e,t={}){if(!e||"object"!=typeof e||Array.isArray(e))return{};const n={...e};return"string"==typeof n.mentionTrigger&&_h(n.mentionTrigger)||(n.mentionTrigger="@"),"string"==typeof n.commandTrigger&&zh(n.commandTrigger)&&n.commandTrigger!==n.mentionTrigger||(n.commandTrigger="/"),"boolean"!=typeof n.diagnosticLogs&&(n.diagnosticLogs=t.diagnosticLogs??!1),n}(e,{diagnosticLogs:s})}),this.logger=n.logger?{info:(e,t)=>{this.diagnosticLogsEnabled()&&n.logger?.info?.(e,t)},warn:(e,t)=>{this.diagnosticLogsEnabled()&&n.logger?.warn?.(e,t)},error:(e,t)=>{this.diagnosticLogsEnabled()&&n.logger?.error?.(e,t)}}:void 0;const o=new Yu({request:(e,t,n)=>this.nodeAgentFetch(e,t,n),logger:this.logger});this.nodeAgentGateway=new wm(o,{onFleetStateChanged:n.onFleetStateChanged}),this.controlledInstanceGateway=new Sg({requireNode:e=>this.requireNode(e),nodeAgentTransport:e=>this.nodeAgentTransportResolver.resolve(e)}),this.aiSessionActionService=new Bu({requireInstance:e=>this.requireControlledInstance(e,!0),request:(e,t,n,i)=>this.instanceRequest(e,t,n,i),requireRuntime:(e,t)=>this.requireNodeRuntimeOnNode(e,t)}),this.projects=new Qd(e.projectsDir,{...i(Xr),sanitize:rr}),this.models=new Qd(e.modelsDir,i(Jr)),this.modelService=new Ig({models:this.models,gateway:this.nodeAgentGateway,listNodes:()=>this.listNodes(),requireNode:e=>this.requireNode(e),fetchImpl:this.fetchImpl}),this.images=new Qd(e.imagesDir,{...i(bc),sanitize:e=>kc(e,e=>this.logWarn(e,"legacy image profile field was migrated"))}),this.nodes=new Qd(e.nodesDir,{...i(jc),sanitize:e=>function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e,i=new Set(["id","name","connectionMode","connectionPath","connectionEnabled","auth","endpoint","controlEndpoint","containerEndpoint","publicWebBase","status","health","capabilities","proxyState","appInventory","labels","lastSeenAt","createdAt","updatedAt"]);for(const e of Object.keys(n))i.has(e)||t?.({field:e});const s=n.auth&&"object"==typeof n.auth&&!Array.isArray(n.auth)?bd(n.auth,["mode","keyId","secret","pairedAt","pairing"]):n.auth;s&&"object"==typeof s&&"pairing"in s&&(s.pairing=bd(s.pairing,["status","joinToken","expiresAt"]));const a=n.connectionPath&&"object"==typeof n.connectionPath&&!Array.isArray(n.connectionPath)?"control-plane-proxy"===n.connectionPath.kind?bd(n.connectionPath,["kind","proxyId","proxyBindingId","targetNodeId"]):bd(n.connectionPath,["kind"]):{kind:"direct"},o=n.proxyState&&"object"==typeof n.proxyState&&!Array.isArray(n.proxyState)?bd(n.proxyState,["reachability","bindingStatus","bindingRevision","streamId","revision","observedAt","target","lastError","updatedAt"]):n.proxyState;if(o&&"object"==typeof o){const e=o;e.target=bd(e.target,["id","name","status","health","lastSeenAt","capabilities"]),e.lastError=bd(e.lastError,["code","message","retryable","details"])}return{...Object.fromEntries(Object.entries(n).filter(([e])=>i.has(e))),auth:s,connectionPath:a,proxyState:o}}(e,e=>this.logWarn(e,"unknown stored node field was ignored"))}),this.pendingPairingRevokes=new Qd(e.pendingPairingRevokesDir,i(Zh)),this.proxyLifecycle=new xh({nodes:this.nodes,privateStore:this.proxyPrivateStore,fetchImpl:this.fetchImpl,requireNode:e=>this.requireNode(e),deleteNode:e=>this.deleteNode(e)}),this.nodeConnectionManager=new eg({nodes:this.nodes,pendingPairingRevokes:this.pendingPairingRevokes,fetchImpl:this.fetchImpl,localNodeLabel:Hf,builtinNodeLabel:Gf,info:(e,t)=>this.logInfo(e,t),warn:(e,t)=>this.logWarn(e,t)}),this.chatSessions=new Qd(e.chatSessionsDir,i(xd)),this.chatBridges=new Qd(e.chatBridgesDir,i(Id)),this.triggers=new Qd(e.triggersDir,i(Dh)),this.nodeJoinService=new lg({nodes:this.nodes}),this.configSyncPreferences=new Qd(t.join(e.dataDir,"config-sync-preferences"),{...i(Mf),sanitize:qf}),this.marketCatalogService=new qg,this.gitCredentials=new Yg(e,{repositoryReferences:e=>this.projects.list().flatMap(t=>{const n=t.source;return"local-folder"!==n.type&&n.auth.secretId===e?[{id:t.id,name:t.name,url:n.url,authType:n.auth.type}]:[]})}),this.catalogService=new jg({projects:this.projects,images:this.images,market:this.marketCatalogService,settings:this.settings,defaultNodeId:()=>this.defaultNodeId(),requireGitCredential:e=>this.gitCredentials.requirePublic(e)}),this.controlledInstanceCreator=new _g({gateway:this.nodeAgentGateway,defaultNodeId:()=>this.defaultNodeId(),requireProject:e=>this.requireProject(e),requireNode:e=>this.requireNode(e),requireRuntime:(e,t)=>this.requireNodeRuntimeOnNode(e,t),requireLocalFolder:(e,t)=>this.requireNodeLocalFolder(e,t),resolveImageSelection:e=>this.catalogService.resolveImageSelection(e),prepareModels:(e,t)=>this.modelService.prepareAssignment(e,t),gitCredentials:this.gitCredentials}),this.controlPlaneTriggerService=new kg({triggers:this.triggers,listInstances:()=>this.listCachedNodeInstances(),listMutationInstances:()=>this.listTriggerMutationInstances(),requireInstance:async e=>this.requireControlledInstance(e,!0),instanceRequest:(e,t,n)=>this.instanceRequest(e,t,n)}),this.appAccessService=new Jg({requireInstance:async e=>this.requireControlledInstance(e,!0),listAppSessions:()=>this.listAppSessions()}),this.chatBridgeService=new cf({chatBridges:this.chatBridges,chatSessions:this.chatSessions}),this.chatSessionService=new df({chatSessions:this.chatSessions}),this.chatSessionRuntime=new Lf({upsertChatSession:e=>this.upsertChatSession(e),boardAsync:()=>this.boardAsync(),listAiSessions:e=>this.listAiSessions(e),listAppSessions:e=>this.listAppSessions(e),listNodeInstances:()=>this.listBootstrapNodeInstances(),listPendingRoutes:()=>this.listPendingRoutes(),pendingDecisionCallbackData:(e,t)=>this.pendingDecisionCallbackData(e,t),createChatActionToken:e=>this.createChatActionToken(e),createAppAccessToken:e=>this.createAppAccessToken(e),controlPlanePublicBaseUrl:()=>this.getSettings().publicBaseUrl||process.env.TASK_HANDOFF_CONTROL_PLANE_URL||process.env.TASK_HANDOFF_PUBLIC_BASE||process.env.TASK_HANDOFF_CONTROL_PLANE_PUBLIC_URL,requireControlledInstance:(e,t)=>this.requireControlledInstance(e,t),requireProject:e=>this.requireProject(e),getProject:e=>this.catalogService.getProject(e),listProjects:()=>this.catalogService.listProjects(),resolveAiSessionApproval:(e,t,n)=>this.resolveAiSessionApproval(e,t,n),sendAiSessionMessage:(e,t,n,i,s)=>this.sendAiSessionMessage(e,t,n,i,s),interruptAiSession:(e,t)=>this.interruptAiSession(e,t),launchAppSession:(e,t,n)=>this.launchAppSession(e,t,n)})}logInfo(e,t){this.logger?.info?.(e,t)}logWarn(e,t){this.logger?.warn?.(e,t)}logError(e,t){this.logger?.error?.(e,t)}setNodeAgentTransport(e){this.nodeAgentTransportResolver.setTunnel(e)}resolveNodeAgentTransport(e){return this.nodeAgentTransportResolver.resolve(e)}setAiSessionSnapshotProvider(e){this.aiSessionSnapshotProvider=e}async listAiSessions(e={}){return this.aiSessionSnapshotProvider?this.aiSessionSnapshotProvider(e):this.bootstrapAiSessionsFromInstances()}setAppSessionSnapshotProvider(e){this.appSessionSnapshotProvider=e}async listAppSessions(e={}){return this.appSessionSnapshotProvider?this.appSessionSnapshotProvider(e):this.bootstrapAppSessionsFromInstances()}listInstanceGitCredentialAssignments(e){return this.gitCredentials.listAssignments(e)}async updateGitCredential(e,t){const n=this.gitCredentials.update(e,t),i=this.gitCredentials.payload(e,{allowDisabled:!0}),s=new Set;for(const t of this.gitCredentials.listAssignments().filter(t=>t.credentialId===e)){let a=this.gitCredentials.authorize(t.instanceId,e,{allowDisabled:!0});try{const n=await this.requireControlledInstance(t.instanceId,!0),o=this.requireNode(n.nodeId),r=o.capabilities.agent,c=r&&"object"==typeof r&&!Array.isArray(r)?r.capabilities:void 0;if(!$c(c)||!Bc(c)||!Ro(n.capabilities))throw new Error("Managed Git credential synchronization is unsupported by the target.");s.has(o.id)||(await this.nodeAgentGateway.deployGitCredential(o,i),s.add(o.id)),await this.nodeAgentGateway.replaceGitCredentialAuthorizations(o,this.gitCredentials.desiredAuthorizationSet(t.instanceId)),a=this.gitCredentials.markAssignmentStatus(t.instanceId,e,"synced")}catch(i){a=this.gitCredentials.markAssignmentStatus(t.instanceId,e,"deferred"),this.logWarn({instanceId:t.instanceId,credentialId:e,credentialRevision:n.revision,assignmentRevision:a.assignmentRevision,error:i instanceof Error?i.message:String(i)},"Git credential revision sync deferred")}}return n}async authorizeInstanceGitCredential(e,t){const n=await this.requireControlledInstance(e,!0),i=this.requireNode(n.nodeId);if(!Ro(n.capabilities))throw Object.assign(new Error(`Instance ${n.id} does not support managed Git CLI credentials.`),{code:"GIT_CREDENTIAL_INSTANCE_UNSUPPORTED",statusCode:409});const s=i.capabilities.agent,a=s&&"object"==typeof s&&!Array.isArray(s)?s.capabilities:void 0;if(!$c(a)||!Bc(a))throw Object.assign(new Error(`Node ${i.id} does not support managed Git credentials.`),{code:"GIT_CREDENTIAL_NODE_UNSUPPORTED",statusCode:409});const o=this.gitCredentials.payload(t);await this.nodeAgentGateway.deployGitCredential(i,o);let r=this.gitCredentials.authorize(e,t);try{await this.nodeAgentGateway.replaceGitCredentialAuthorizations(i,this.gitCredentials.desiredAuthorizationSet(e)),r=this.gitCredentials.markAssignmentStatus(e,t,"synced")}catch(n){r=this.gitCredentials.markAssignmentStatus(e,t,"deferred"),this.logWarn({instanceId:e,credentialId:t,error:n instanceof Error?n.message:String(n)},"Git credential assignment sync deferred")}return r}async revokeInstanceGitCredential(e,t){const n=await this.requireControlledInstance(e,!0),i=this.requireNode(n.nodeId);if(!this.gitCredentials.listAssignments(e).find(e=>e.credentialId===t))return!1;this.gitCredentials.markAssignmentStatus(e,t,"revoking");try{await this.nodeAgentGateway.replaceGitCredentialAuthorizations(i,this.gitCredentials.desiredAuthorizationSet(e)),this.gitCredentials.revoke(e,t);const n=await this.listCachedNodeInstances();return this.gitCredentials.listAssignments().some(e=>{if(e.credentialId!==t)return!1;const s=n.find(t=>t.id===e.instanceId);return s?.nodeId===i.id})||await this.nodeAgentGateway.removeGitCredential(i,t).catch(()=>{}),!0}catch(n){return this.logWarn({instanceId:e,credentialId:t,error:n instanceof Error?n.message:String(n)},"Git credential revocation deferred"),!1}}init(){this.runPersistenceMaintenance(),this.projects.init(),this.models.init(),this.images.init(),this.nodes.init(),this.pendingPairingRevokes.init(),this.chatSessions.init(),this.chatBridges.init(),this.triggers.init(),this.gitCredentials.init(),this.proxyPrivateStore.init(),this.proxyPrivateStore.gcNodeCredentials(e=>{const t=this.nodes.get(e.nodeId);return"control-plane-proxy"===t?.connectionMode&&"control-plane-proxy"===t.connectionPath.kind&&t.connectionPath.proxyBindingId===e.proxyBindingId&&t.connectionPath.targetNodeId===e.targetNodeId}),this.settings.init();const e=this.settings.put(this.settings.get());this.diagnosticLogsState=e.diagnosticLogs,this.migrateLegacyImageCatalog(),this.seedDefaults(),this.refreshCachedNodeInstances();const t=this.listNodes().map(e=>this.projectNodeConnection(e));this.nodeAgentGateway.refreshFleetRuntimes(t).catch(e=>{this.logWarn({error:yh(e)},"control plane runtime directory warmup failed")}),this.nodeAgentGateway.refreshFleetModels(t).catch(e=>{this.logWarn({error:yh(e)},"control plane model directory warmup failed")})}runPersistenceMaintenance(){try{return this.persistenceMaintenance.run()}catch(e){return this.logWarn({error:e instanceof Error?e.message:String(e)},"control-plane persistence maintenance failed"),[]}}migrateLegacyImageCatalog(){const e=Object.keys(ar),i=[];for(const t of e){const e=this.images.filePath(t);if(n.existsSync(e))try{i.push({id:t,filePath:e,record:JSON.parse(n.readFileSync(e,"utf8"))})}catch(e){return this.writeMarketMigrationState("failed",{code:"LEGACY_IMAGE_BACKUP_READ_FAILED",legacyId:t,error:yh(e)}),void this.logWarn({legacyId:t,error:yh(e)},"legacy embedded image migration was not applied")}}if(!i.length)return;const s=n.readdirSync(this.paths.projectsDir).filter(e=>e.endsWith(".json")).sort().map(e=>t.join(this.paths.projectsDir,e)),a=[];for(const e of s)try{const t=JSON.parse(n.readFileSync(e,"utf8")),i=Xr.parse(rr(t));a.push({filePath:e,raw:t,migrated:i})}catch(t){return this.writeMarketMigrationState("failed",{code:"PROJECT_REFERENCE_VALIDATION_FAILED",filePath:e,error:yh(t)}),void this.logWarn({filePath:e,error:yh(t)},"legacy embedded image migration was not applied")}const o=a.find(({migrated:t})=>{const n=t.defaultImageSelection?.imageId;return!!n&&e.includes(n)});if(o)this.writeMarketMigrationState("failed",{code:"PROJECT_REFERENCE_MIGRATION_INCOMPLETE",filePath:o.filePath});else{n.mkdirSync(this.paths.marketDir,{recursive:!0}),y.sync(this.paths.marketMigrationBackupPath,`${JSON.stringify({version:wo,createdAt:Hd(),images:i.map(({id:e,record:t})=>({id:e,record:t})),projects:a.map(({filePath:e,raw:n})=>({file:t.basename(e),record:n}))},null,2)}\n`,{encoding:"utf8"});for(const{migrated:e}of a)this.projects.put(e);for(const{id:e}of i)this.images.delete(e),this.logWarn({legacyId:e,marketId:ar[e]},"embedded image profile migrated to Market");this.writeMarketMigrationState("complete",{code:"LEGACY_IMAGE_MIGRATION_COMPLETE",migratedImageIds:i.map(({id:e})=>e),backupPath:this.paths.marketMigrationBackupPath})}}writeMarketMigrationState(e,t){n.mkdirSync(this.paths.marketDir,{recursive:!0}),y.sync(this.paths.marketStatePath,`${JSON.stringify({status:e,updatedAt:Hd(),...t},null,2)}\n`,{encoding:"utf8"})}getSettings(){return this.catalogService.getSettings()}diagnosticLogsEnabled(){return this.diagnosticLogsState}updateSettings(e){const t=this.catalogService.updateSettings(e);return this.diagnosticLogsState=t.diagnosticLogs,t}seedDefaults(){return this.catalogService.seedDefaults()}listProjects(){return this.catalogService.listProjects()}defaultNodeId(){return this.nodes.list().find(Wf)?.id||this.nodes.list()[0]?.id}async syncLocalNodeConnection(){const e=await this.nodeConnectionManager.syncLocal();return this.nodeConnectionRuntime?.observedReachable(e),this.projectNodeConnection(e)}async recoverPendingPairingRevokes(){await this.nodeConnectionManager.recoverPendingPairingRevokes(),await this.reconcileGitCredentialAssignments()}async reconcileGitCredentialAssignments(){const e=this.gitCredentials.listAssignments().filter(e=>"synced"!==e.status);for(const t of e)try{const e=await this.requireControlledInstance(t.instanceId,!0),n=this.requireNode(e.nodeId);if("revoking"===t.status){await this.nodeAgentGateway.replaceGitCredentialAuthorizations(n,this.gitCredentials.desiredAuthorizationSet(t.instanceId)),this.gitCredentials.revoke(t.instanceId,t.credentialId);continue}const i=this.gitCredentials.payload(t.credentialId,{allowDisabled:!0});await this.nodeAgentGateway.deployGitCredential(n,i),await this.nodeAgentGateway.replaceGitCredentialAuthorizations(n,this.gitCredentials.desiredAuthorizationSet(t.instanceId)),this.gitCredentials.markAssignmentStatus(t.instanceId,t.credentialId,"synced")}catch(e){this.logWarn({instanceId:t.instanceId,credentialId:t.credentialId,assignmentRevision:t.assignmentRevision,error:e instanceof Error?e.message:String(e)},"Git credential assignment convergence deferred")}}listModels(){return this.modelService.list()}listFederatedModels(e,t=!1){return this.modelService.listFederated(e,t)}createModel(e){return this.modelService.create(e)}updateModel(e,t){return this.modelService.update(e,t)}deleteModel(e){return this.modelService.delete(e)}reorderModels(e){return this.modelService.reorder(e)}createNodeModel(e,t){return this.modelService.createOnNode(e,t)}updateNodeModel(e,t,n){return this.modelService.updateOnNode(e,t,n)}deleteNodeModel(e,t){return this.modelService.deleteOnNode(e,t)}discoverModels(e){return this.modelService.discover(e)}testModel(e){return this.modelService.test(e)}discoverNodeModels(e,t){return this.modelService.discoverOnNode(e,t)}testNodeModel(e,t){return this.modelService.testOnNode(e,t)}createProject(e){return this.catalogService.createProject(e)}updateProject(e,t){return this.catalogService.updateProject(e,t)}deleteProject(e){return this.catalogService.deleteProject(e)}listImages(){return this.catalogService.listImages()}getMarketCatalog(){return this.catalogService.getMarketCatalog()}async refreshMarketCatalog(){return await this.marketCatalogService.refresh(new Mg),this.getMarketCatalog()}listImageOptions(){return this.catalogService.listImageOptions()}createImage(e){return this.catalogService.createImage(e)}async listNodeDockerImages(e){const t=this.requireNode(e);return this.nodeAgentGateway.listDockerImages(t)}async listNodeImageAvailability(e){const t=this.requireNode(e),n=t.capabilities.agent&&"object"==typeof t.capabilities.agent?t.capabilities.agent:{},i={os:"string"==typeof n.platform?n.platform:void 0,architecture:"string"==typeof n.arch?"x64"===n.arch?"amd64":n.arch:void 0},s=this.catalogService.listImageOptions(i);try{const e=await this.nodeAgentGateway.listDockerImages(t);return s.map(t=>{const n=e.find(e=>e.reference===t.reference||!!t.digest&&e.repoDigests.some(e=>e.endsWith(`@${t.digest}`))||e.repoDigests.includes(t.reference));return td.parse({image:t,status:n?"available":"pull-required",localImage:n,localSizeBytes:n?.sizeBytes,downloadSizeBytes:n?void 0:t.downloadSizeBytes,unpackedSizeBytes:n?void 0:t.unpackedSizeBytes})})}catch(e){const t=e instanceof Error?e.message:String(e);return s.map(e=>td.parse({image:e,status:"unknown",error:t}))}}async listNodeLocalFolders(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.listLocalFolders(n,{signal:t})}async listNodeFolderTree(e,t={}){const n=this.requireNode(e);return this.nodeAgentGateway.listFolderTree(n,t)}async listNodeFolderPlaces(e){const t=this.requireNode(e);if(n=t.capabilities?.agent&&"object"==typeof t.capabilities.agent?t.capabilities.agent.capabilities:void 0,!0!==qc.safeParse(n).data?.folderPlaces)return(await this.nodeAgentGateway.listFolderTree(t,{depth:0})).map(e=>id.parse({kind:"root",name:e.name,path:e.path}));var n;try{return await this.nodeAgentGateway.listFolderPlaces(t)}catch(e){if(404!==(e&&"object"==typeof e?e.statusCode:void 0))throw e;return(await this.nodeAgentGateway.listFolderTree(t,{depth:0})).map(e=>id.parse({kind:"root",name:e.name,path:e.path}))}}async createNodeLocalFolder(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.createLocalFolder(n,t)}async updateNodeLocalFolder(e,t,n){const i=this.requireNode(e);if(s=i.capabilities?.agent&&"object"==typeof i.capabilities.agent?i.capabilities.agent.capabilities:void 0,!0!==qc.safeParse(s).data?.localFolderNameUpdate){const e=new Error(`Node ${i.id} does not support local folder name updates.`);throw Object.assign(e,{statusCode:409,code:"NODE_LOCAL_FOLDER_NAME_UPDATE_UNSUPPORTED"})}var s;return this.nodeAgentGateway.updateLocalFolder(i,t,n)}async deleteNodeLocalFolder(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.deleteLocalFolder(n,t)}async checkNode(e){const t=this.requireNode(e);try{const e=await this.nodeAgentGateway.health(t),n=e&&"object"==typeof e?e:{},i="string"==typeof n.nodeId&&n.nodeId.trim()?n.nodeId.trim():t.id,s=jc.parse({...t,id:i,status:"online",health:"ok",capabilities:"object"==typeof e&&e?{...t.capabilities,agent:lh(e)}:t.capabilities,lastSeenAt:Hd(),updatedAt:Hd()});return i!==t.id&&this.nodes.delete(t.id),this.nodes.put(s),this.nodeConnectionRuntime?.observedReachable(s),{id:s.id,status:"online",checkedAt:Hd(),agent:e}}catch(e){const n=jc.parse({...t,status:"offline",health:"failed",updatedAt:Hd()});return this.nodes.put(n),this.nodeConnectionRuntime?.observedFailure(n,yh(e)),{id:t.id,status:"offline",checkedAt:Hd(),error:e instanceof Error?e.message:String(e)}}}async checkNodeUpdate(e,t){return this.nodeAgentGateway.checkUpdate(this.requireNode(e),t)}async applyNodeUpdate(e,t){return this.nodeAgentGateway.applyUpdate(this.requireNode(e),t)}async listNodeUpdateJobs(e){return this.nodeAgentGateway.listUpdateJobs(this.requireNode(e))}async getLocalNodeExternalListener(e){return this.nodeAgentGateway.getExternalListener(this.requireLocalListenerNode(e))}async updateLocalNodeExternalListener(e,t){return this.nodeAgentGateway.updateExternalListener(this.requireLocalListenerNode(e),t)}async createNodePairingInvite(e,t={}){const n=this.requireNode(e);return this.nodeAgentGateway.createPairingInvite(n,t)}requireLocalListenerNode(e){const t=this.requireNode(e);if(!Vf(t)||!Wf(t)){const e=new Error("Node agent TCP listener settings are available only for the built-in local node.");throw Object.assign(e,{statusCode:403,code:"LOCAL_NODE_LISTENER_ONLY"}),e}return t}createNodeJoinInvite(e={}){return this.nodeJoinService.createInvite(e)}getNodeJoinInviteStatus(e){return this.nodeJoinService.status(e)}completeNodeJoin(e){return this.nodeJoinService.complete(e)}async connectNodeToControlPlane(e,t){const n=this.requireNode(e),i=Jh.parse(t);return this.nodeAgentGateway.createControlPlaneConnection(n,i)}async listNodeControlPlanePairings(e){const t=this.requireNode(e);return this.nodeAgentGateway.listControlPlanePairings(t)}async deleteNodeControlPlanePairing(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.deleteControlPlanePairing(n,t)}async listNodeControlPlaneConnections(e){const t=this.requireNode(e);return this.nodeAgentGateway.listControlPlaneConnections(t)}async deleteNodeControlPlaneConnection(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.deleteControlPlaneConnection(n,t)}updateImage(e,t){return this.catalogService.updateImage(e,t)}async deleteImage(e){this.catalogService.requireImage(e);const t=this.listProjects().find(t=>t.defaultImageSelection?.imageId===e);if(t)throw Object.assign(new Error(`Image ${e} is the default for project ${t.name}.`),{statusCode:409,code:"IMAGE_IN_USE"});const n=this.readCachedNodeInstances(),i=n.nodeStates.filter(e=>"uninitialized"===e.phase||"loading"===e.phase||"stale"===e.phase);if(i.length){this.refreshCachedNodeInstances();const e=new Error("The instance directory is still loading; retry after every node has reported its instance snapshot.");throw Object.assign(e,{statusCode:503,code:"INSTANCE_DIRECTORY_LOADING",nodeIds:i.map(e=>e.nodeId)})}const s=n.items.find(t=>t.imageSelection?.imageId===e);if(s)throw Object.assign(new Error(`Image ${e} is used by instance ${s.name}.`),{statusCode:409,code:"IMAGE_IN_USE"});return this.catalogService.deleteImage(e)}listNodes(){return this.nodes.list()}listPublicNodes(){return this.listNodes().map(e=>ph(this.projectNodeConnection(e)))}projectNodeConnection(e){return this.nodeConnectionRuntime?.project(e)||e}createNode(e){return this.nodeConnectionManager.create(e)}listPendingProxyClaims(){return this.proxyLifecycle.listPendingClaims()}claimProxyNode(e){return this.proxyLifecycle.claimNode(e)}resumeProxyClaim(e){return this.proxyLifecycle.resumeClaim(e)}cancelProxyClaim(e,t=!1){return this.proxyLifecycle.cancelClaim(e,t)}applyProxyTargetSnapshot(e,t){return this.proxyLifecycle.applyTargetSnapshot(e,t)}applyProxyTargetEvent(e,t){return this.proxyLifecycle.applyTargetEvent(e,t)}markProxyUnavailable(e,t){return this.proxyLifecycle.markUnavailable(e,t)}markProxyBindingRevoked(e,t){return this.proxyLifecycle.markBindingRevoked(e,t)}updateNode(e,t){const n=Xh.parse(t),i=this.requireNode(e);this.proxyLifecycle.assertIdentityPatch(i,n);const s=jc.parse({...i,...n,id:e,createdAt:i.createdAt,updatedAt:Hd()});return this.nodes.put(s)}deleteNode(e){if(Vf(this.requireNode(e))){const e=new Error("The built-in local node connection cannot be deleted.");throw Object.assign(e,{statusCode:400,code:"LOCAL_NODE_CANNOT_BE_DELETED"}),e}return this.nodeAgentGateway.forgetNode(e),this.nodes.delete(e)}dispose(){this.nodeAgentGateway.dispose()}async deleteNodeWithProxyLifecycle(e,t=!1){return this.proxyLifecycle.deleteNode(this.requireNode(e),t)}async listNodeRuntimes(e,t){const n=e?[this.requireNode(e)]:this.listNodes();return e?this.nodeAgentGateway.listRuntimes(n[0],{signal:t}):(await this.nodeAgentGateway.listFleetRuntimes(n,{signal:t})).items}async listNodeRuntimesWithDiagnostics(e,t=!1){const n=this.listNodes().map(e=>this.projectNodeConnection(e));return t?(this.nodeAgentGateway.refreshFleetRuntimes(n).catch(e=>{this.logWarn({error:yh(e)},"control plane runtime directory refresh failed")}),this.nodeAgentGateway.readFleetRuntimes(n)):this.nodeAgentGateway.listFleetRuntimes(n,{signal:e})}async createNodeRuntime(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.createRuntime(n,t)}async updateNodeRuntime(e,t,n){const i=this.requireNode(e);return this.nodeAgentGateway.updateRuntime(i,t,n)}async deleteNodeRuntime(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.deleteRuntime(n,t)}async checkNodeRuntime(e,t){const n=this.requireNode(e);return this.nodeAgentGateway.checkRuntime(n,t)}async listControlledInstances(){return(await this.listNodeInstancesWithDiagnostics()).items.map(mh)}async listControlledInstancesWithDiagnostics(){const e=await this.listNodeInstancesWithDiagnostics();return{items:e.items.map(mh),nodeErrors:e.nodeErrors,nodeStates:e.nodeStates}}async instanceResourceMetrics(e){const t=await this.requireNodeInstance(e);return this.nodeAgentGateway.instanceResourceMetrics(this.requireNode(t.nodeId),t.id)}async nodeOwnsInstance(e,t){const n=this.requireNode(e),i=this.nodeAgentGateway.readFleetInstances([n]);return!!i.items.some(n=>n.id===t&&n.nodeId===e)||"ready"!==i.nodeStates[0]?.phase&&(await this.nodeAgentGateway.listInstances(n)).some(n=>n.id===t&&n.nodeId===e)}createControlledInstance(e){return this.controlledInstanceCreator.create(e)}resolveControlledInstanceTargetNodeId(e){return this.controlledInstanceCreator.targetNodeId(e)}async updateControlledInstance(e,t){const n=Hh.parse(t),i=await this.requireNodeInstance(e),s=this.requireNode(i.nodeId);void 0!==n.config?.aiSessionHistoryLimit&&function(e,t){const n=e.capabilities.agent,i=n&&"object"==typeof n&&!Array.isArray(n)?n.capabilities:void 0;if(!Boolean(i&&"object"==typeof i&&!Array.isArray(i)&&!0===i.aiSessionHistoryLimit)||!Co(t.capabilities).features.aiSessionPersistenceSettings)throw Object.assign(new Error("This instance does not support managed AI session history retention settings."),{statusCode:409,code:"AI_SESSION_HISTORY_LIMIT_UNSUPPORTED"})}(s,i),void 0!==n.config?.aiSessionAttachmentRetentionDays&&function(e,t){const n=e.capabilities.agent,i=n&&"object"==typeof n&&!Array.isArray(n)?n.capabilities:void 0;if(!Boolean(i&&"object"==typeof i&&!Array.isArray(i)&&!0===i.aiSessionAttachmentRetention)||!0!==t.capabilities.features.aiSessionConversationAttachments?.retentionSettings)throw Object.assign(new Error("This instance does not support managed AI session attachment retention settings."),{statusCode:409,code:"AI_SESSION_ATTACHMENT_RETENTION_UNSUPPORTED"})}(s,i),void 0!==n.config?.aiSessionMaxFileAttachmentBytes&&function(e,t){const n=e.capabilities.agent;if(!Fc(n&&"object"==typeof n&&!Array.isArray(n)?n.capabilities:void 0)||!0!==function(e){return Co(e).features.aiSessionConversationAttachments}(t.capabilities).fileSizeLimitSettings)throw Object.assign(new Error("This instance does not support managed AI session file attachment limits."),{statusCode:409,code:"AI_SESSION_FILE_ATTACHMENT_LIMIT_UNSUPPORTED"})}(s,i);const{modelSelection:a,...o}=n;let r=Object.keys(o).length?await this.nodeAgentGateway.updateInstance(s,e,o):i;if(a){const t=await this.modelService.prepareAssignment(s,a);r=(await this.nodeAgentGateway.assignInstanceModels(s,e,t)).instance}return mh(r)}async deleteControlledInstance(e,t){const n=nr.parse(t),i=await this.requireNodeInstance(e),s=this.requireNode(i.nodeId),a=await this.nodeAgentGateway.deleteInstance(s,e,n);return a.completed&&(this.configSyncPreferences.delete(e),this.gitCredentials.revokeInstance(e)),a}listEnvironmentTemplates(e){return this.nodeAgentGateway.listEnvironmentTemplates(this.requireNode(e))}getEnvironmentTemplate(e,t){return this.nodeAgentGateway.getEnvironmentTemplate(this.requireNode(e),t)}async createEnvironmentTemplate(e,t){const n=await this.requireNodeInstance(e);return this.nodeAgentGateway.createEnvironmentTemplate(this.requireNode(n.nodeId),e,t)}deleteEnvironmentTemplate(e,t){return this.nodeAgentGateway.deleteEnvironmentTemplate(this.requireNode(e),t)}async startControlledInstance(e){const t=await this.requireNodeInstance(e),n=this.requireNode(t.nodeId);await this.modelService.ensureInstanceAssignment(t);const i=this.gitCredentials.operationProvisioning(e),s=await this.nodeAgentGateway.startInstance(n,e,i?{gitWorkspaceProvisioning:i}:{});return i&&s.gitWorkspaceProvisioningOperationId===i.operationId&&this.gitCredentials.forgetOperationProvisioning(e),mh(s.instance)}async stopControlledInstance(e){const t=await this.requireNodeInstance(e),n=this.requireNode(t.nodeId);return mh(await this.nodeAgentGateway.stopInstance(n,e))}async restartControlledInstance(e){const t=await this.requireNodeInstance(e),n=this.requireNode(t.nodeId);await this.modelService.ensureInstanceAssignment(t);const i=this.gitCredentials.operationProvisioning(e),s=await this.nodeAgentGateway.restartInstance(n,e,i?{gitWorkspaceProvisioning:i}:{});return i&&s.gitWorkspaceProvisioningOperationId===i.operationId&&this.gitCredentials.forgetOperationProvisioning(e),mh(s.instance)}async retryControlledInstanceImageProvisioning(e){const t=await this.requireNodeInstance(e);return mh(await this.nodeAgentGateway.retryInstanceImageProvisioning(this.requireNode(t.nodeId),e))}async boardAsync(){return await this.listBootstrapNodeInstances(),(await this.boardWithDiagnostics(void 0,!0)).items}async boardWithDiagnostics(e,t=!1){const[n,i]=await Promise.all([this.listNodeRuntimesWithDiagnostics(e,t),this.listNodeInstancesWithDiagnostics(e,t)]);return this.instanceBoardReader.read({projects:this.listProjects(),images:this.listImageOptions(),nodes:this.nodes.list().map(e=>this.projectNodeConnection(e)),runtimes:n.items,instances:i.items,nodeErrors:[...n.nodeErrors,...i.nodeErrors],nodeStates:[...n.nodeStates,...i.nodeStates]})}async bootstrapAiSessionsFromInstances(){const e=await this.listBootstrapNodeInstances(),t=await Promise.all(e.map(async e=>{if(!Ad(e)||!e.target.web||"online"!==e.connectionStatus&&"online"!==e.agentStatus)return{streamId:`bootstrap:${e.id}:ai.sessions`,revision:0,lastEventAt:e.aiSessions.updatedAt,snapshot:e.aiSessions};try{return ul(cs,await this.instanceRequest(e,"/ai-sessions/state"))}catch(t){return this.logWarn({instanceId:e.id,error:yh(t),errorCode:"AI_SESSION_LIVE_REFRESH_FAILED"},"control plane failed to refresh live AI sessions"),{streamId:`bootstrap:${e.id}:ai.sessions`,revision:0,lastEventAt:e.aiSessions.updatedAt,snapshot:e.aiSessions}}}));return{updatedAt:(new Date).toISOString(),instances:e.map((e,n)=>({instanceId:e.id,streamId:t[n].streamId,aiSessions:t[n].snapshot,revision:t[n].revision,lastEventAt:t[n].lastEventAt}))}}async bootstrapAppSessionsFromInstances(){const e=await this.listBootstrapNodeInstances(),t=await Promise.all(e.map(async e=>{if(!Ad(e)||!e.target.web||"online"!==e.connectionStatus&&"online"!==e.agentStatus){const t=Qs();return{streamId:`bootstrap:${e.id}:app.sessions`,revision:0,lastEventAt:t.updatedAt,snapshot:t}}try{return ul(Os,await this.instanceRequest(e,"/apps/sessions/state"))}catch(t){this.logWarn({instanceId:e.id,error:yh(t),errorCode:"APP_SESSION_LIVE_REFRESH_FAILED"},"control plane failed to refresh live app sessions");const n=Qs();return{streamId:`bootstrap:${e.id}:app.sessions`,revision:0,lastEventAt:n.updatedAt,snapshot:n}}}));return{updatedAt:(new Date).toISOString(),instances:e.map((e,n)=>({instanceId:e.id,streamId:t[n].streamId,appSessions:t[n].snapshot,revision:t[n].revision,lastEventAt:t[n].lastEventAt}))}}async recoverAiSessionDelta(e,t,n){const i=await this.requireControlledInstance(e,!0),s=new URLSearchParams({streamId:t,sinceRevision:String(n)});return ul(vs,await this.instanceRequest(i,`/ai-sessions?${s}`))}async recoverAiSessionSnapshot(e){const t=await this.requireControlledInstance(e,!0);return ul(cs,await this.instanceRequest(t,"/ai-sessions/state"))}async recoverAppSessionDelta(e,t,n){const i=await this.requireControlledInstance(e,!0),s=new URLSearchParams({streamId:t,sinceRevision:String(n)});return ul(qs,await this.instanceRequest(i,`/apps/sessions?${s}`))}async recoverAppSessionSnapshot(e){const t=await this.requireControlledInstance(e,!0);return ul(Os,await this.instanceRequest(t,"/apps/sessions/state"))}async listTriggers(){return this.controlPlaneTriggerService.listTriggers()}createTrigger(e){return this.controlPlaneTriggerService.createTrigger(e)}async updateTrigger(e,t){return this.controlPlaneTriggerService.updateTrigger(e,t)}async deleteTrigger(e){return this.controlPlaneTriggerService.deleteTrigger(e)}async applyTrigger(e,t){return this.controlPlaneTriggerService.applyTrigger(e,t)}async listInstanceTriggers(e){return this.controlPlaneTriggerService.listInstanceTriggers(e)}async bindAiSessionTrigger(e,t,n){return this.controlPlaneTriggerService.bindAiSessionTrigger(e,t,n)}async unbindAiSessionTrigger(e,t,n){return this.controlPlaneTriggerService.unbindAiSessionTrigger(e,t,n)}async runInstanceTrigger(e,t,n={}){return this.controlPlaneTriggerService.runInstanceTrigger(e,t,n)}listChatSessions(){return this.chatSessionService.list()}createAppAccessToken(e){return this.appAccessService.createToken(e)}createAppSessionAccessToken(e){return this.appAccessService.createSessionToken(e)}revokeAppSessionAccessToken(e,t){this.appAccessService.revokeToken(e,t)}resolveAppAccessToken(e,t){return this.appAccessService.resolveToken(e,t)}createChatActionToken(e){return this.chatActionTokenService.create(e)}resolveChatActionToken(e,t){return this.chatActionTokenService.resolve(e,t)}pendingDecisionCallbackData(e,t){return this.chatActionTokenService.pendingDecisionCallbackData(e,t)}async appAccessProxyTarget(e,t,n=""){return this.appAccessService.proxyTarget(e,t,n)}listChatBridges(){return this.chatBridgeService.list()}requireChatBridge(e){return this.chatBridgeService.require(e)}createChatBridge(e){return this.chatBridgeService.create(e)}updateChatBridge(e,t){return this.chatBridgeService.update(e,t)}deleteChatBridge(e){return this.chatBridgeService.delete(e)}requireChatSession(e){return this.chatSessionService.require(e)}upsertChatSession(e){return this.chatSessionService.upsert(e)}async handleChatGatewayMessage(e){return this.chatSessionRuntime.handleChatGatewayMessage(e)}async handleChatGatewayAction(e){return this.chatSessionRuntime.handleChatGatewayAction(e)}async handleChatCommand(e,t){return this.chatSessionRuntime.handleChatCommand(e,t)}async listPendingRoutes(){const e=Hd(),t=[],n=await this.listAiSessions(),i=new Map(n.instances.map(e=>[e.instanceId,e.aiSessions])),s=this.readCachedNodeInstances();this.refreshCachedNodeInstances();for(const n of s.items){if("online"!==n.connectionStatus&&"online"!==n.agentStatus||!n.target.web)continue;const s=n.projectId?this.catalogService.getProject(n.projectId):void 0;for(const a of i.get(n.id)?.sessions||[]){if("waiting"!==a.status)continue;const i=Sd.parse({id:`${n.id}:ai:${a.id}`,instanceId:n.id,projectId:n.projectId,aiSessionId:a.id,providerSessionId:a.providerSessionId,result:a.summary||a.currentTool?.inputPreview||a.lastMessage||`${a.agent} is waiting for approval`,source:a.agent,kind:"approval",status:"pending",lastSeenAt:e});t.push({...i,project:s,instance:mh(n)})}}return t}async listAiSessionInstanceNames(){return(await this.listBootstrapNodeInstances()).map(e=>({id:e.id,name:e.name}))}resolveAiSessionApproval(e,t,n){return this.aiSessionActionService.resolveApproval(e,t,n)}listAiSessionHistory(e,t){return this.aiSessionActionService.listHistory(e,t)}getAiSessionHistoryDetail(e,t){return this.aiSessionActionService.historyDetail(e,t)}getAiSessionTimeline(e,t){return this.aiSessionActionService.timeline(e,t)}getAiSessionTurnTimeline(e,t,n){return this.aiSessionActionService.turnTimeline(e,t,n)}resumeAiSession(e,t){return this.aiSessionActionService.resume(e,t)}async createAiSession(e,t){const n=await this.requireControlledInstance(e,!0),{cwdFolderId:i,...s}=t,a={type:"runtime-path",path:await this.aiSessionRuntimeCwd(n,t.cwdFolderId)};return this.aiSessionActionService.create(e,{...s,cwd:a,...t.cwdFolderId?{cwdFolderId:t.cwdFolderId}:{}})}async inspectAiSessionWorkspace(e,t){const n=await this.requireControlledInstance(e,!0),i={type:"runtime-path",path:await this.aiSessionRuntimeCwd(n,t)};return this.aiSessionActionService.inspectWorkspace(e,i)}forkAiSession(e,t,n){return this.aiSessionActionService.fork(e,t,n)}openAiSessionApp(e,t,n){return this.aiSessionActionService.openApp(e,t,n)}closeAiSession(e,t,n){return this.aiSessionActionService.close(e,t,n)}aiSessionActionDiagnostics(){return this.aiSessionActionService.diagnostics()}async launchAppSession(e,t="terminal-tty",n={}){const i=await this.requireControlledInstance(e,!0);if("online"!==i.connectionStatus&&"online"!==i.agentStatus){const e=new Error(`Instance ${i.name} is still starting. Wait for it to connect before launching apps.`);throw Object.assign(e,{statusCode:409,code:"INSTANCE_NOT_CONNECTED"}),e}const s=await this.resolveAppLaunchOptions(i,n);return await this.instanceRequest(i,"/apps/sessions",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({appId:t,...s})})}async stopAppSession(e,t){const n=await this.requireControlledInstance(e,!0);return await this.instanceRequest(n,`/apps/sessions/${encodeURIComponent(t)}/stop`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({})})}async instanceAppManagement(e){const t=await this.requireControlledInstance(e,!0);try{return function(e){try{return ul(Er,e)}catch(e){if(e instanceof f.z.ZodError){const e=new Error("This controlled instance does not support managed app operations.");throw Object.assign(e,{statusCode:409,code:"INSTANCE_APP_MANAGEMENT_UNSUPPORTED"}),e}throw e}}(await this.instanceRequest(t,"/apps/management"))}catch(e){const t=e&&"object"==typeof e?e:{};if(e instanceof f.z.ZodError||404===t.statusCode){const e=new Error("This controlled instance does not support managed app operations.");throw Object.assign(e,{statusCode:409,code:"INSTANCE_APP_MANAGEMENT_UNSUPPORTED"}),e}throw e}}async requestInstanceAppOperation(e,t,n,i={}){const s=await this.requireControlledInstance(e,!0);return ul(Tr,await this.instanceRequest(s,`/apps/${encodeURIComponent(t)}/${n}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(i)}))}async instanceAppManagementJob(e,t){const n=await this.requireControlledInstance(e,!0);return ul(Tr,await this.instanceRequest(n,`/apps/jobs/${encodeURIComponent(t)}`))}async renameAppSession(e,t,n){const i=await this.requireControlledInstance(e,!0);return await this.instanceRequest(i,`/apps/sessions/${encodeURIComponent(t)}`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({title:n})})}sendAiSessionMessage(e,t,n,i,s=[],a=[],o,r){return this.aiSessionActionService.sendMessage(e,t,n,i,s,a,o,r)}aiSessionMentionCatalog(e,t){return this.aiSessionActionService.mentionCatalog(e,t)}searchAiSessionMentionFiles(e,t,n){return this.aiSessionActionService.searchMentionFiles(e,t,n)}executeAiSessionCommand(e,t,n){return this.aiSessionActionService.executeCommand(e,t,n)}aiSessionQueue(e,t){return this.aiSessionActionService.queue(e,t)}getAiSessionDetail(e,t){return this.aiSessionActionService.detail(e,t)}getAiSessionTurnIndex(e,t){return this.aiSessionActionService.turnIndex(e,t)}getAiSessionTurnBody(e,t,n){return this.aiSessionActionService.turnBody(e,t,n)}steerAiSessionQueuedMessage(e,t,n){return this.aiSessionActionService.steerQueuedMessage(e,t,n)}retryAiSessionQueuedMessage(e,t,n){return this.aiSessionActionService.retryQueuedMessage(e,t,n)}removeAiSessionQueuedMessage(e,t,n){return this.aiSessionActionService.removeQueuedMessage(e,t,n)}editAiSessionQueuedMessage(e,t,n,i){return this.aiSessionActionService.editQueuedMessage(e,t,n,i)}reorderAiSessionQueuedMessages(e,t,n){return this.aiSessionActionService.reorderQueuedMessages(e,t,n)}interruptAiSession(e,t){return this.aiSessionActionService.interrupt(e,t)}async proxyInstanceHttp(e,t,n={}){const i=await this.requireControlledInstance(e,!0);return this.controlledInstanceGateway.proxyHttp(i,t,n)}async proxyInstanceWebSocket(e,t,n,i,s={}){const a=await this.requireControlledInstance(e,!0);this.controlledInstanceGateway.proxyWebSocket(a,t,n,i,s)}async instanceConfigSyncState(e){const t=await this.requireControlledInstance(e,!0),n=f.z.array(Vp).parse(await this.instanceRequest(t,"/config-sync/programs"));return Xp.parse({programs:n,preferences:this.configSyncPreferences.get(e)?.preferences||Uf()})}async listInstanceConfigSyncFolders(e,t={}){const n=await this.requireControlledInstance(e,!0),i=new URLSearchParams;return t.path&&i.set("path",t.path),void 0!==t.depth&&i.set("depth",String(t.depth)),f.z.array(nd).parse(await this.instanceRequest(n,"/config-sync/folders"+(i.size?`?${i}`:"")))}async syncInstanceConfigs(e,t){const n=Kp.parse(t),i=await this.requireControlledInstance(e,!0);if("export"===n.direction&&"local-folder"!==i.source.type){const e=new Error("Exporting instance config is only available for local folder projects.");throw Object.assign(e,{statusCode:400,code:"CONFIG_SYNC_EXPORT_REQUIRES_LOCAL_PROJECT"}),e}const s=function(e){const t=function(e){const t=[];for(const n of e.split("/"))if(n&&"."!==n)if(".."===n){if(!t.length)return"..";t.pop()}else t.push(n);return t.join("/")||"."}(e.trim().replace(/\\/g,"/")||".");if(t.startsWith("/")||".."===t||t.startsWith("../")){const e=new Error("Config sync folder must stay inside the instance workspace.");throw Object.assign(e,{statusCode:400,code:"CONFIG_SYNC_FOLDER_INVALID"}),e}return t||"."}(n.workspaceFolder),a={...n,workspaceFolder:s},o=ul(Zp,await this.instanceRequest(i,"/config-sync",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(a)})),r=Hd(),c=this.configSyncPreferences.get(e);return this.configSyncPreferences.put({id:e,preferences:{...c?.preferences||Uf(),[n.direction]:s},createdAt:c?.createdAt||r,updatedAt:r}),o}async instanceRequest(e,t,n={},i){return this.controlledInstanceGateway.request(e,t,n,i)}async reportInstanceHeartbeat(e,t){await this.controlledInstanceGateway.reportHeartbeat(e,t)}async nodeAgentFetch(e,t,n={}){const i="reverse-wss"!==e.connectionMode&&"control-plane-proxy"!==e.connectionMode;try{const s=await this.nodeAgentTransportResolver.resolve(e).request(e,t,n);return i&&this.nodeConnectionRuntime?.observedReachable(e),s}catch(t){throw!i||n.signal?.aborted||function(e){return e instanceof Error&&("AbortError"===e.name||"ABORT_ERR"===e.code)}(t)||this.nodeConnectionRuntime?.observedFailure(e,yh(t)),t}}readCachedNodeInstances(){return this.nodeAgentGateway.readFleetInstances(this.listNodes().map(e=>this.projectNodeConnection(e)))}refreshCachedNodeInstances(){const e=this.listNodes().map(e=>this.projectNodeConnection(e));this.nodeAgentGateway.refreshFleetInstances(e).catch(e=>{this.logWarn({error:yh(e)},"control plane instance directory refresh failed")})}async listCachedNodeInstances(){const e=this.readCachedNodeInstances();return this.refreshCachedNodeInstances(),e.items}async listBootstrapNodeInstances(){const e=this.listNodes().map(e=>this.projectNodeConnection(e));return await this.nodeAgentGateway.refreshFleetInstances(e),this.nodeAgentGateway.readFleetInstances(e).items}async listTriggerMutationInstances(){const e=this.listNodes().map(e=>this.projectNodeConnection(e));await this.nodeAgentGateway.refreshFleetInstances(e);const t=this.nodeAgentGateway.readFleetInstances(e),n=new Set(t.nodeStates.filter(e=>"ready"===e.phase).map(e=>e.nodeId)),i=t.nodeStates.filter(e=>"ready"!==e.phase).map(e=>({scope:"node",nodeId:e.nodeId,code:e.error?.code||"TRIGGER_NODE_DIRECTORY_UNAVAILABLE",message:e.error?.message||`Node ${e.nodeId} instance directory is ${e.phase}; trigger deployment changes were skipped.`}));return{items:t.items.filter(e=>n.has(e.nodeId)),partialFailures:i}}async listNodeInstancesWithDiagnostics(e,t=!1){const n=this.listNodes().map(e=>this.projectNodeConnection(e));return t?(this.nodeAgentGateway.refreshFleetInstances(n).catch(e=>{this.logWarn({error:yh(e)},"control plane instance directory refresh failed")}),this.nodeAgentGateway.readFleetInstances(n)):this.nodeAgentGateway.listFleetInstances(n,{signal:e})}async requireNodeInstance(e,t=!1){return this.requireNodeInstanceFromNodes(e,this.listNodes(),t)}async requireNodeInstanceFromNodes(e,t,n=!1){const i=this.nodeAgentGateway.instanceFromSnapshot(t,e);if(i&&n){const n=t.find(e=>e.id===i.nodeId);if(n){await this.nodeAgentGateway.refreshFleetInstances([n],{},!0);const t=this.nodeAgentGateway.instanceFromSnapshot([n],e);if(t)return t;const i=this.nodeAgentGateway.readFleetInstances([n]).nodeStates.find(e=>e.nodeId===n.id);"ready"===i?.phase&&bh("CONTROLLED_INSTANCE_NOT_FOUND",`Controlled instance ${e} was not found.`)}}if(i)return i;const s=(await this.nodeAgentGateway.listFleetInstances(t)).items.find(t=>t.id===e);if(s)return s;bh("CONTROLLED_INSTANCE_NOT_FOUND",`Controlled instance ${e} was not found.`)}async requireNodeRuntimeOnNode(e,t){const n=(await this.listNodeRuntimes(e)).find(e=>e.id===t);return n||bh("NODE_RUNTIME_NOT_FOUND",`Runtime ${t} was not found on node ${e}.`),n}async requireNodeLocalFolder(e,t){return this.nodeAgentGateway.requireLocalFolder(e,t)}async resolveAppLaunchOptions(e,t){const n="string"==typeof t.cwdFolderId?t.cwdFolderId.trim():"",i={...t};return delete i.cwdFolderId,n?{...i,cwd:await this.runtimeCwdForFolderId(e,n)}:i}async runtimeCwdForFolderId(e,t){const n=this.requireNode(e.nodeId),i=await this.requireNodeLocalFolder(n,t);if(i.nodeId!==e.nodeId){const t=new Error(`Local folder ${i.id} belongs to node ${i.nodeId}, not ${e.nodeId}.`);throw Object.assign(t,{statusCode:400,code:"LOCAL_FOLDER_REQUIRES_INSTANCE_NODE"}),t}const s=await this.requireNodeRuntimeOnNode(e.nodeId,e.runtimeId);return this.appLaunchCwdForFolder(e,i,s)}async aiSessionRuntimeCwd(e,t){return t?this.runtimeCwdForFolderId(e,t):e.runtime.workspacePath||e.workspace.path||uh(e.source).path||"/workspace"}appLaunchCwdForFolder(e,n,i){const s=function(e,n,i){if("local"===i.type)return Bf(s=n).resolve(s);var s;if("local-folder"!==e.source.type)return;const a=function(e,t){if($f(e)!==$f(t))return;const n=Bf(e),i=n.resolve(e),s=n.resolve(t),a=n.relative(i,s);return a?".."===a||a.startsWith(`..${n.sep}`)||n.isAbsolute(a)?void 0:a.split(n.sep).filter(Boolean):[]}(e.source.path,n);if(!a)return;const o=e.runtime.workspacePath||e.workspace.path||uh(e.source).path||"/workspace";return a.length?t.posix.join(o,...a):o}(e,n.path,i);if(s)return s;if("local-folder"!==e.source.type){const e=new Error("App cwd folder selection is only supported for local-folder instances.");throw Object.assign(e,{statusCode:400,code:"APP_CWD_REQUIRES_LOCAL_FOLDER_SOURCE"}),e}const a=new Error(`Local folder ${n.path} is outside the instance workspace ${e.source.path}.`);throw Object.assign(a,{statusCode:400,code:"APP_CWD_OUTSIDE_WORKSPACE"}),a}requireProject(e){return this.catalogService.requireProject(e)}requireModel(e,t=!1){return this.modelService.require(e,t)}requireImage(e){return this.catalogService.requireImage(e)}requireNode(e){const t=this.nodes.get(e);return t||bh("NODE_NOT_FOUND",`Node ${e} was not found.`),t}requirePublicNode(e){return ph(this.projectNodeConnection(this.requireNode(e)))}async requireControlledInstance(e,t=!1,n=!1){const i=await this.requireNodeInstance(e,n);return t?i:mh(i)}requireControlledInstanceForAuthorization(e,t){const n=t?this.listNodes().filter(e=>t.has(e.id)):this.listNodes(),i=this.nodeAgentGateway.instanceFromSnapshot(n,e);return i||bh("CONTROLLED_INSTANCE_NOT_FOUND",`Controlled instance ${e} was not found.`),mh(i)}}function Yf(e){return x(String(e),"escape").replace(/\n+$/,"")}function Xf(e){const[t,...n]=String(e).split("\n");return[`*${Yf(t)}*`,...n.map(Yf)].join("\n")}function Jf(e,t=4e3){const n=String(e),i=Xf(n);if(i.length<=t)return i;const[s,...a]=n.split("\n"),o=a.join("\n"),r="...\n";let c=s;for(;Xf(`${c}\n${r}`).length>t&&c.length>0;)c=c.slice(0,Math.floor(.8*c.length));let d=0,l=o.length,p=0,u=Xf(`${c}\n${r}`);for(;d<=l;){const e=Math.floor((d+l)/2),n=Xf(`${c}\n${r}${o.slice(-e)}`);n.length<=t?(u=n,p=e,d=e+1):l=e-1}const m=o.slice(-p),h=m.indexOf("\n");return h>=0&&h<200&&(u=Xf(`${c}\n${r}${m.slice(h+1)}`)),u}function Qf(e){return String(e).replace(/\\([_*\[\]()~`>#+\-=|{}.!\\])/g,"$1")}async function Zf(e,t,n,i,s={}){if(!t.token)return;const a=n=>e(`https://api.telegram.org/bot${t.token}/sendMessage`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)}),o=function(e,t={}){const n=String(e),i=t.rawMarkdownV2?e=>e:Yf;if(i(n).length<=4e3)return[n];const s=[];let a=n;for(;a;){let e=1,t=a.length,n=1;for(;e<=t;){const s=Math.floor((e+t)/2);i(a.slice(0,s)).length<=4e3?(n=s,e=s+1):t=s-1}if(n<a.length){const e=a.slice(0,n),t=Math.max(e.lastIndexOf("\n"),e.lastIndexOf(" "));t>=Math.floor(.6*n)&&(n=t+1)}s.push(a.slice(0,n).trimEnd()),a=a.slice(n).trimStart()}return s.filter(Boolean)}(i,s);let r;for(const[e,t]of o.entries())r=await ty(a,"sendMessage",t,{chat_id:n,...0===e&&s.replyToMessageId?{reply_to_message_id:s.replyToMessageId,allow_sending_without_reply:!0}:{},...e===o.length-1&&s.replyMarkup?{reply_markup:s.replyMarkup}:{}},s);return r}async function ey(e,t,n){if(!t.token||!n)throw new Error("Telegram file id is required.");const i=await e(`https://api.telegram.org/bot${t.token}/getFile`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({file_id:n})}),s=await i.json().catch(()=>({}));if(!i.ok||!1===s.ok||!s.result?.file_path)throw new Error(s.description||`Telegram getFile failed with HTTP ${i.status}`);return`https://api.telegram.org/file/bot${t.token}/${s.result.file_path}`}async function ty(e,t,n,i,s){const a=s.parseMode||"MarkdownV2",o=s.rawMarkdownV2?String(n):Yf(n),r=await e({...i,text:o,disable_web_page_preview:!0,parse_mode:a}),c=await r.json().catch(()=>({}));if(r.ok&&!1!==c.ok)return c.result;if("editMessageText"===t&&ny(c.description))return;if(s.rawMarkdownV2&&"MarkdownV2"===a){const s=await e({...i,text:Qf(n),disable_web_page_preview:!0,parse_mode:"Markdown"}),a=await s.json().catch(()=>({}));if(s.ok&&!1!==a.ok)return a.result;if("editMessageText"===t&&ny(a.description))return}const d=await e({...i,text:s.rawMarkdownV2?Qf(n):String(n),disable_web_page_preview:!0}),l=await d.json().catch(()=>({}));if(d.ok&&!1!==l.ok)return l.result;if("editMessageText"!==t||!ny(l.description))throw new Error(l.description||c.description||`Telegram ${t} failed with HTTP ${d.status}`)}function ny(e){return"string"==typeof e&&e.toLowerCase().includes("message is not modified")}function iy(e,t){if("string"==typeof e&&e.trim())return e.trim();ay(`Chat action token is missing ${t}.`)}function sy(e){if("allow"===e||"deny"===e||"skip"===e)return e;ay("Chat action token has an invalid decision.")}function ay(e){const t=new Error(e);throw Object.assign(t,{statusCode:400,code:"CHAT_ACTION_TOKEN_INVALID"}),t}function oy(e){return Buffer.from(e,"base64url").toString("utf8")}function ry(e){return String(e||"").split(/\r?\n/,1)[0].replace(/^#+\s*/,"").trim().slice(0,20)||"消息通知"}function cy(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,"string"==typeof t?t:JSON.stringify(t)]))}function dy(e){return`dtv1.card//IM_GROUP.${e}`}function ly(e){return`dtv1.card//IM_ROBOT.${e}`}function py(e,t){return _y(t.biz_conversation_id).trim()||_y(e.spaceId).replace(/^dtv1\.card\/\/(?:IM_GROUP|IM_SINGLE|IM_ROBOT)\./,"")}function uy(e,t={}){const n=_y(e).trim().toUpperCase();return"2"===n||"IM_GROUP"===n?"IM_GROUP":"1"===n||"IM_SINGLE"===n?t.robotMessage?"IM_ROBOT":"IM_SINGLE":"IM_ROBOT"===n?"IM_ROBOT":void 0}function my(e){if(e.startsWith("task_handoff:"))return e;if(!e.startsWith("th_cb_"))return"";try{return Buffer.from(e.slice(6),"base64url").toString("utf8")}catch{return""}}function hy(e,t,n,i,s){const a=py(i,s);return{cardUpdateOptions:{updateCardDataByKey:!0,updatePrivateDataByKey:!1},cardData:{cardParamMap:cy({type:"actions",title:"TaskHandoff",description:e,list:mf(t),biz_out_track_id:i.outTrackId||s.biz_out_track_id||"",biz_conversation_id:a,biz_sender_id:s.biz_sender_id||i.userId||"",biz_session_webhook:s.biz_session_webhook||"",biz_conversation_type:s.biz_conversation_type||"",biz_step:n,error_msg:""})}}}function gy(e,t,n){const i=[];return fy(i,n),fy(i,t),fy(i,e),i.find(e=>my(e))||""}function fy(e,t){for(const n of["actionIdList","actionIds"]){const i=t[n];Array.isArray(i)&&e.push(...i.map(e=>_y(e)).filter(Boolean))}for(const n of["actionId","action_id","id","actionValue"]){const i=_y(t[n]);i&&e.push(i)}}async function yy(e,t,n,i){i?.("info",{target:"sessionWebhook",hasSessionWebhook:Boolean(t),textPreview:Sy(n)},"dingding webhook send requested");const s=await e(t,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({msgtype:"markdown",markdown:{title:ry(n),text:n}})}),a=await s.json().catch(()=>{});if(i?.(s.ok?"info":"warn",{target:"sessionWebhook",status:s.status,response:wy(a)},"dingding webhook send completed"),!s.ok)throw new Error(`DingDing webhook failed with HTTP ${s.status}`)}async function by(e){const t=mf(e.replyMarkup);if(!t.length&&!e.forceCard)return e.sessionWebhook&&await yy(e.fetchImpl,e.sessionWebhook,e.text,e.runtime.onLog),e.sessionWebhook?{delivered:!0}:void 0;const n=e.bridge.settings||{},i=_y(n.robotCode),s=_y(n.cardTemplateId)||"13fc6717-12e4-43ed-8533-111a310d4995.schema",a=_y(n.cardCallbackRouteKey)||"task_handoff_message",o=e.senderId||e.runtime.senderIds.get(e.chatId)||_y(n.senderId),r=(c=e.runtime,d=e.chatId,c.conversationTypes?.get(d)||"IM_GROUP");var c,d;if(!i||!s||!o){if(e.sessionWebhook&&!e.forceCard)return await yy(e.fetchImpl,e.sessionWebhook,e.text,e.runtime.onLog),{delivered:!0};throw new Error("DingDing card target is incomplete.")}const l=`task_handoff_cp_${Date.now()}_${Math.random().toString(16).slice(2)}`,p=cy({type:"actions",title:e.title||ry(e.text),description:e.text,list:t,biz_out_track_id:l,biz_step:e.step||"task_handoff_actions",biz_conversation_id:e.chatId,biz_sender_id:o,biz_session_webhook:e.sessionWebhook||e.runtime.chatWebhooks.get(e.chatId)||"",biz_conversation_type:r,error_msg:""}),u=function(e,t,n,i){return"IM_SINGLE"===e?{openSpaceId:(s=t,`dtv1.card//IM_SINGLE.${s}`),imSingleOpenSpaceModel:{},imSingleOpenDeliverModel:{extension:{}}}:"IM_ROBOT"===e?{openSpaceId:ly(n),imRobotOpenSpaceModel:{supportForward:!1},imRobotOpenDeliverModel:{extension:{},robotCode:i,spaceType:"IM_ROBOT"}}:{openSpaceId:dy(t),imGroupOpenSpaceModel:{supportForward:!1},imGroupOpenDeliverModel:{extension:{},robotCode:i}};var s}(r,e.chatId,o,i);return e.runtime.onLog?.("info",{target:"card",chatId:e.chatId,senderId:o,conversationType:r,openSpaceId:u.openSpaceId,hasSessionWebhook:Boolean(e.sessionWebhook||e.runtime.chatWebhooks.get(e.chatId)),hasReplyMarkup:Boolean(e.replyMarkup),actionCount:t.length,textPreview:Sy(e.text)},"dingding card send requested"),await vy(e.fetchImpl,e.bridge,e.runtime,"POST","/v1.0/card/instances/createAndDeliver",{userId:o,cardTemplateId:s,outTrackId:l,callbackType:"STREAM",callbackRouteKey:a,cardData:{cardParamMap:p},userIdType:Number(n.cardUserIdType||1),...u}),{delivered:!0,outTrackId:l}}async function vy(e,t,n,i,s,a){const o=await async function(e,t,n){if(n.accessToken&&n.accessToken.expiresAt>Date.now()+6e4)return n.accessToken.value;const i=_y(t.settings.clientSecret);if(!t.token||!i)throw new Error("DingDing client id/secret is not configured.");const s=await e("https://api.dingtalk.com/v1.0/oauth2/accessToken",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({appKey:t.token,appSecret:i})}),a=await s.json().catch(()=>({}));if(!s.ok||!a.accessToken)throw new Error(`DingDing access token failed with HTTP ${s.status}`);const o=Number(a.expireIn||7200);return n.accessToken={value:a.accessToken,expiresAt:Date.now()+1e3*Math.max(60,o-120)},n.accessToken.value}(e,t,n);n.onLog?.("info",{method:i,path:s,body:Iy(a)},"dingding api request");const r=await e(`https://api.dingtalk.com${s}`,{method:i,headers:{"content-type":"application/json","x-acs-dingtalk-access-token":o},body:JSON.stringify(a)}),c=await r.json().catch(()=>{});if(n.onLog?.(r.ok?"info":"warn",{method:i,path:s,status:r.status,response:wy(c)},"dingding api response"),!r.ok)throw new Error(`DingDing API failed with HTTP ${r.status}`);const d=Ay(c),l=d.code??d.errcode,p=d.success;if(void 0!==l&&"0"!==String(l)||!1===p)throw new Error(_y(d.message||d.errmsg)||`DingDing API returned ${String(l||"failure")}`);const u=function(e){const t=Ay(Ay(e).result).deliverResults;if(!Array.isArray(t))return"";const n=t.find(e=>!1===Ay(e).success);if(!n)return"";const i=Ay(n),s=_y(i.spaceId),a=_y(i.errorMsg||i.message||i.errmsg)||"delivery failed";return s?`DingDing card delivery failed for ${s}: ${a}`:`DingDing card delivery failed: ${a}`}(c);if(u)throw new Error(u);return r}function Iy(e){const t=Ay(e),n=Ay(t.cardData),i=Ay(n.cardParamMap);return{openSpaceId:_y(t.openSpaceId),outTrackId:_y(t.outTrackId),userId:_y(t.userId),userIdType:t.userIdType,callbackType:_y(t.callbackType),callbackRouteKey:_y(t.callbackRouteKey),hasImGroupTarget:Boolean(t.imGroupOpenSpaceModel||t.imGroupOpenDeliverModel),hasImSingleTarget:Boolean(t.imSingleOpenSpaceModel||t.imSingleOpenDeliverModel),hasImRobotTarget:Boolean(t.imRobotOpenSpaceModel||t.imRobotOpenDeliverModel),imGroupOpenDeliverModel:xy(t.imGroupOpenDeliverModel),imSingleOpenDeliverModel:xy(t.imSingleOpenDeliverModel),imRobotOpenDeliverModel:xy(t.imRobotOpenDeliverModel),bizConversationId:_y(i.biz_conversation_id),bizConversationType:_y(i.biz_conversation_type),bizSenderId:_y(i.biz_sender_id),hasBizSessionWebhook:Boolean(_y(i.biz_session_webhook))}}function xy(e){const t=Ay(e);if(Object.keys(t).length)return{hasExtension:Boolean(t.extension),hasRobotCode:Boolean(_y(t.robotCode)),spaceType:_y(t.spaceType),recipients:Array.isArray(t.recipients)?t.recipients.length:void 0,atUserIds:t.atUserIds&&"object"==typeof t.atUserIds?Object.keys(t.atUserIds).length:void 0}}function wy(e){const t=Ay(e),n=Ay(t.result);return{code:t.code??t.errcode,message:Sy(t.message||t.errmsg,240),success:t.success,requestId:t.requestId,result:Object.keys(n).length?n:void 0}}function Sy(e,t=160){const n=String(e||"").replace(/\s+/g," ").trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-3))}...`}function Ay(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function Ey(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:"string"==typeof e&&e.trim()?Ty(e):{}}function _y(e){return"string"==typeof e?e:""}function Ty(e){try{return Ay(JSON.parse(String(e||"{}")))}catch{return{}}}function zy(e){return JSON.stringify(mf(e))}const ky="task_handoff_action_id";function Ny(e,t){const n=mf(t);return{schema:"2.0",config:{summary:{content:Oy(e)}},body:{elements:[{tag:"markdown",content:e},...n.map(e=>({tag:"button",text:{tag:"plain_text",content:e.text},type:jy(e.text),width:"fill",size:"medium",behaviors:[{type:"callback",value:{[ky]:e.id}}]}))]}}}function Cy(e){const t=function(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}(e);return function(e){const t=String(e||"");return t.startsWith("th_cb_")?function(e){try{return Buffer.from(e,"base64url").toString("utf8")}catch{return""}}(t.slice(6)):""}(t[ky]||t.action_id||t.actionId||t.id||e)}function Ry(e){return JSON.stringify(mf(e))}function Oy(e){const t=e.replace(/\s+/g," ").trim();return t.length<=50?t:`${t.slice(0,47)}...`}function jy(e){const t=e.trim().toLowerCase();return["deny","cancel","delete","remove"].some(e=>t.includes(e))?"danger":["allow","approve","launch","open"].some(e=>t.includes(e))?"primary":"default"}function Py(e){return e instanceof Error?e.message:String(e)}function Dy(e){const t=Number(function(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}(e).message_id);return Number.isInteger(t)&&t>0?t:void 0}function Ly(e){return Array.isArray(e?.actionRows)?e.actionRows:(Array.isArray(e?.actions)?e.actions:[]).map(e=>[e])}function My(e,t){const n=Ly(e),i=Ly(t);return n.length===i.length&&n.every((e,t)=>{const n=i[t];return e.length===n.length&&e.every((e,t)=>{const i=n[t];return e.text===i?.text&&e.callbackData===i.callbackData})})}class qy{entries;updateIntervalMs;send;edit;deleteMessage;messageIdFromResult;retryAfterMs;isMessageTooLong;onLog;constructor(e){this.entries=e.entries||new Map,this.updateIntervalMs=e.updateIntervalMs||1e3,this.send=e.send,this.edit=e.edit,this.deleteMessage=e.delete,this.messageIdFromResult=e.messageIdFromResult||Dy,this.retryAfterMs=e.retryAfterMs,this.isMessageTooLong=e.isMessageTooLong,this.onLog=e.onLog}remember(e,t,n,i,s,a){const o=this.entries.get(e);return o&&(clearTimeout(o.timer),o.timer=void 0,o.pendingText=void 0),this.entries.set(e,{lastText:n,lastUpdateAt:Date.now(),messageId:t,route:i,options:s,lastOptions:s,renderOptions:a}),o}rekey(e,t){if(e===t)return this.entries.has(e);const n=this.entries.get(e);if(!n||this.entries.has(t))return!1;if(clearTimeout(n.timer),n.timer=void 0,this.entries.delete(e),this.entries.set(t,n),n.pendingText){const e=n.rateLimitedUntil?Math.max(0,n.rateLimitedUntil-Date.now()):Math.max(0,this.updateIntervalMs-(Date.now()-n.lastUpdateAt));this.scheduleFlush(t,e)}return!0}scheduleFlush(e,t){const n=this.entries.get(e);n&&!n.timer&&(n.timer=setTimeout(()=>{n.timer=void 0;const t=n.pendingText;n.pendingText=void 0,t&&this.applyUpdate(e,t,n.route,n.options)},t))}markRateLimited(e,t,n,i){const s=this.entries.get(e);s&&(s.rateLimitedUntil=Date.now()+n,s.pendingText=t,s.route=i||s.route,this.scheduleFlush(e,n))}async applyUpdate(e,t,n,i){let s=this.entries.get(e);const a=s,o=n||s?.route,r=i||s?.options;try{if(s&&(s.route=o,s.options=r),s?.pending&&await s.pending,s=this.entries.get(e),a&&s!==a)return!1;if(s?.messageId){if(s.lastText===t&&My(s.lastOptions,r))return!0;const n=Date.now()-(s.lastUpdateAt||0);return n<this.updateIntervalMs?(s.pendingText=t,s.route=o||s.route,s.options=r||s.options,this.scheduleFlush(e,this.updateIntervalMs-n),!0):(await this.edit(s.messageId,t,o||s.route,r),s.lastText=t,s.lastOptions=r,s.lastUpdateAt=Date.now(),s.rateLimitedUntil=void 0,!0)}const n={lastText:t,lastUpdateAt:Date.now(),route:o,options:r,lastOptions:r};return n.pending=this.send(t,o,r).then(e=>{const t=this.messageIdFromResult(e);t&&(n.messageId=t)}).finally(()=>{n.pending=void 0}),this.entries.set(e,n),await n.pending,this.entries.get(e)===n&&(n.rateLimitedUntil=void 0,Boolean(n.messageId))}catch(n){const i=this.retryAfterMs?.(n);return i&&this.markRateLimited(e,t,i,o),this.onLog?.(`Telegram progress update skipped: ${Py(n)}`),!1}}update(e,t,n,i){const s=String(t||"").trim();if(!s)return;const a=this.entries.get(e);if(a&&(a.route=n||a.route,a.options=i||a.options),a?.lastText===s&&My(a.lastOptions,i||a.options)&&!a.pending&&!a.pendingText)return;const o=Date.now();if(a?.rateLimitedUntil){if(a.rateLimitedUntil>o)return a.pendingText=s,void this.scheduleFlush(e,a.rateLimitedUntil-o);a.rateLimitedUntil=void 0}if(a?.pending&&!a.messageId)return a.pendingText=s,void this.scheduleFlush(e,this.updateIntervalMs);if(!a||!a.messageId)return void this.applyUpdate(e,s,n,i);const r=Date.now()-(a.lastUpdateAt||0);if(r>=this.updateIntervalMs)return clearTimeout(a.timer),a.timer=void 0,a.pendingText=void 0,void this.applyUpdate(e,s,n||a.route,i||a.options);a.pendingText=s,this.scheduleFlush(e,this.updateIntervalMs-r)}async finish(e,t,n,i,s){const a=this.entries.get(e);if(!a)return!1;try{if(clearTimeout(a.timer),a.timer=void 0,a.pendingText=void 0,a.pending&&await a.pending,this.entries.delete(e),!a.messageId)return!1;const o=i||a.options;return a.lastText===t&&My(a.lastOptions,o)||await this.edit(a.messageId,t,n||a.route,o,s||a.renderOptions),!0}catch(t){return this.entries.delete(e),this.isMessageTooLong?.(t)?this.onLog?.("Telegram progress finish too long; sending result as multiple messages"):this.onLog?.(`Telegram progress finish skipped: ${Py(t)}`),!1}}async delete(e,t){const n=this.entries.get(e);if(!n)return!1;try{return clearTimeout(n.timer),n.timer=void 0,n.pendingText=void 0,n.pending&&await n.pending,this.entries.delete(e),!(!this.deleteMessage||!n.messageId)&&(await this.deleteMessage(n.messageId,t||n.route),!0)}catch(t){return this.entries.delete(e),this.onLog?.(`Telegram progress delete skipped: ${Py(t)}`),!1}}async flush(e){const t=this.entries.get(e);if(t?.pending&&await t.pending,t?.timer){clearTimeout(t.timer),t.timer=void 0;const n=t.pendingText;t.pendingText=void 0,n&&await this.applyUpdate(e,n,t.route,t.options)}}async wait(e){await function(e){return new Promise(t=>setTimeout(t,e))}(e)}}const Uy=20971520;function $y(e){const t=[],n=[...e.photo||[]].filter(e=>e.file_id).sort((e,t)=>Number(t.file_size||t.width||0)-Number(e.file_size||e.width||0))[0];return n?.file_id&&t.push({fileId:n.file_id,fileName:"telegram-photo.jpg",fileSize:n.file_size}),e.document?.file_id&&String(e.document.mime_type||"").startsWith("image/")&&t.push({fileId:e.document.file_id,fileName:e.document.file_name,fileSize:e.document.file_size}),t}async function By(e,n,i="telegram-image",s){if(s&&s>Uy)throw new Error(`image is too large: ${s} bytes`);const a=await e.getFileLink(n),o=String(a),r=await(e.fetchFile||fetch)(o);if(!r.ok)throw new Error(`download failed with HTTP ${r.status}`);const c=Number(r.headers.get("content-length")||0);if(c>Uy)throw new Error(`image is too large: ${c} bytes`);const d=t.extname(i)||".jpg";let l=d;try{l=t.extname(new URL(o).pathname)||d}catch{l=d}const p=t.join(m.tmpdir(),"task-handoff-images");await w.mkdir(p,{recursive:!0});const u=l.replace(/[^.\w-]/g,"")||".jpg",h=t.join(p,`telegram-${Date.now()}-${Math.random().toString(16).slice(2)}${u}`),g=Buffer.from(await r.arrayBuffer());if(g.length>Uy)throw new Error(`image is too large: ${g.length} bytes`);return await w.writeFile(h,g),h}class Fy{store;constructor(e){this.store=new qy({updateIntervalMs:e.updateIntervalMs,send:(t,n,i)=>e.send(e.requireBridge(n?.bridgeId||""),n?.chatId||"",Jf(t),{rawMarkdownV2:!0,replyMarkup:Yy(i)}),edit:(t,n,i,s)=>e.edit(e.requireBridge(i?.bridgeId||""),i?.chatId||"",t,Jf(n),{rawMarkdownV2:!0,replyMarkup:Yy(s)}),delete:(t,n)=>e.deleteMessage(e.requireBridge(n?.bridgeId||""),n?.chatId||"",t),onLog:e.onLog})}get entries(){return this.store.entries}remember(e,t,n,i){return this.store.remember(e,t,n,i)}rekey(e,t){return this.store.rekey(e,t)}delete(e){return this.store.delete(e)}async applyUpdate(e){return this.store.applyUpdate(e.key,e.text,{bridgeId:e.bridge.id,chatId:e.chatId},{actionRows:e.actionRows})}}async function Hy(e){return(await async function(e,t,n,i){const s=[];for(const a of $y(n))try{const n=await By({getFileLink:n=>ey(e,t,n),fetchFile:e},a.fileId,a.fileName,a.fileSize);s.push(n)}catch(e){i?.({fileId:a.fileId,fileName:a.fileName,error:e})}return s}(e.fetchImpl,e.bridge,e.message,e.onImageDownloadError)).map((e,s)=>{const a=n.readFileSync(e);return{id:`tg_${i.randomUUID().replace(/-/g,"").slice(0,24)}`,kind:"image",name:t.basename(e)||`telegram-image-${s+1}`,mime:Gy(e),size:a.length,source:{type:"inline",encoding:"base64",data:a.toString("base64")}}})}function Gy(e){const n=t.extname(e).toLowerCase();return".png"===n?"image/png":".webp"===n?"image/webp":".gif"===n?"image/gif":".bmp"===n?"image/bmp":"image/jpeg"}function Wy(e){const t=Number(e?.message_id);return Number.isInteger(t)?t:void 0}function Vy(e){return e&&"object"==typeof e?e:{}}function Ky(e){return"string"==typeof e?e:""}function Yy(e){const t=Array.isArray(e?.actionRows)?e.actionRows:void 0;return lf(t||(Array.isArray(e?.actions)?e.actions:[]).map(e=>[e]))}function Xy(e){const t=Array.isArray(e.item_list)?e.item_list:[];for(const e of t){const t=Jy(e);if(1!==t.type)continue;const n=Qy(Jy(t.text_item).text).trim();if(n)return n}return""}function Jy(e){return e&&"object"==typeof e?e:{}}function Qy(e){return"string"==typeof e?e:""}function Zy(e){const{fetchImpl:t,bridge:n,dingdingRuntime:s,larkRuntime:a}=e;return"telegram"===n.channel?function(e,t){return{bridge:t,send:async(n,i,s={})=>{const a=await Zf(e,t,n,i,{replyMarkup:s.replyMarkup,replyToMessageId:s.replyToMessageId,rawMarkdownV2:s.rawMarkdownV2,parseMode:s.parseMode});return{provider:"telegram",raw:a,messageId:Number(Vy(a).message_id)||void 0}}}}(t,n):"dingding"===n.channel?function(e,t,n){return{bridge:t,send:async(i,s,a={})=>{const o=a.sessionWebhook||n?.chatWebhooks.get(i)||_y(t.settings.sessionWebhook);if(a.replyMarkup&&n){const r=await by({fetchImpl:e,bridge:t,runtime:n,chatId:i,text:s,replyMarkup:a.replyMarkup,sessionWebhook:o,senderId:a.senderId||n.senderIds.get(i)||_y(t.settings.senderId)});if(r?.delivered)return{provider:"dingding",interactionId:r.outTrackId}}if(o)return await yy(e,o,s,n?.onLog),{provider:"dingding"}}}}(t,n,s):"lark"===n.channel?function(e,t){return{bridge:e,send:async(e,n,i={})=>{if(!t)return;const s=await t.channel.send(e,i.replyMarkup?{card:Ny(n,i.replyMarkup)}:{markdown:n});return{provider:"lark",interactionId:s.messageId,raw:s}}}}(n,a):"wechat"===n.channel?function(e,t){return{bridge:t,send:async(n,s,a={})=>{const o=a.contextToken||Qy(t.settings.contextToken);if(o)return await async function(e,t,n,s,a){const o=Qy(t.settings.baseUrl)||"https://ilinkai.weixin.qq.com",r=await e(`${o}/ilink/bot/sendmessage`,{method:"POST",headers:{"content-type":"application/json",AuthorizationType:"ilink_bot_token",Authorization:`Bearer ${t.token}`,"X-WECHAT-UIN":String(Math.floor(Math.random()*2**31))},body:JSON.stringify({msg:{from_user_id:"",to_user_id:n,client_id:i.randomUUID(),message_type:2,message_state:2,context_token:s,item_list:[{type:1,text_item:{text:a}}]},base_info:{channel_version:"1.0.2"}})}),c=await r.json().catch(()=>({}));if(!r.ok||c.errcode)throw new Error(Qy(c.errmsg)||`WeChat send failed with HTTP ${r.status}`)}(e,t,n,o,s),{provider:"wechat"}}}}(t,n):{bridge:n,send:async()=>{}}}class eb{entries=new Map;fetchImpl;generations=new Map;constructor(e){this.fetchImpl=e}clear(){for(const e of new Set([...this.generations.keys(),...[...this.entries.values()].map(e=>e.bridgeId)]))this.clearBridge(e)}clearBridge(e){this.generations.set(e,this.generation(e)+1),this.clearEntries(t=>t.bridgeId===e)}generation(e){return this.generations.get(e)||0}isCurrent(e,t){return this.generation(e)===t}clearEntries(e){for(const[t,n]of this.entries)e(n)&&(n.timer&&clearTimeout(n.timer),n.cancelPending?.(new Error("DingDing progress update was cancelled.")),this.entries.delete(t))}async applyUpdate(e,t){const n=this.generation(e.bridge.id),i=zy(e.replyMarkup);let s=this.entries.get(e.key);if(s?.pending&&await s.pending,!this.isCurrent(e.bridge.id,n))return!1;if(s=this.entries.get(e.key),s?.outTrackId){if(s.lastText===e.text&&s.lastActionsFingerprint===i)return!0;const a=Date.now()-(s.lastUpdateAt||0);return a<1e3?(s.pendingText=e.text,s.pendingReplyMarkup=e.replyMarkup,s.timer||(s.pending=new Promise((i,o)=>{s.cancelPending=o,s.timer=setTimeout(()=>{s.timer=void 0,s.cancelPending=void 0;const a=s.pendingText,r=s.pendingReplyMarkup;if(s.pendingText=void 0,s.pendingReplyMarkup=void 0,!a)return i(void 0);this.updateExistingEntry(e,t,s,a,r,zy(r),n).then(i,o)},1e3-a)}).finally(()=>{s.pending=void 0,s.timer=void 0,s.cancelPending=void 0})),await s.pending,this.isCurrent(e.bridge.id,n)&&this.entries.has(e.key)):(await this.updateExistingEntry(e,t,s,e.text,e.replyMarkup,i,n),this.isCurrent(e.bridge.id,n))}const a={bridgeId:e.bridge.id,lastText:e.text,lastActionsFingerprint:i,lastUpdateAt:Date.now()};return a.pending=by({fetchImpl:this.fetchImpl,bridge:e.bridge,runtime:t,chatId:e.chatId,text:e.text,replyMarkup:e.replyMarkup,sessionWebhook:t.chatWebhooks.get(e.chatId)||tb(e.bridge.settings.sessionWebhook),senderId:t.senderIds.get(e.chatId)||tb(e.bridge.settings.senderId),title:"TaskHandoff 执行中",step:"progress",forceCard:!0}).then(t=>{this.isCurrent(e.bridge.id,n)&&(t?.outTrackId&&(a.outTrackId=t.outTrackId),t?.delivered&&(a.delivered=!0,a.lastUpdateAt=Date.now()))}).catch(t=>{throw this.isCurrent(e.bridge.id,n)&&this.entries.delete(e.key),t}).finally(()=>{a.pending=void 0}),this.entries.set(e.key,a),await a.pending,this.isCurrent(e.bridge.id,n)&&Boolean(a.delivered)}async updateExistingEntry(e,t,n,i,s,a,o){n.outTrackId&&(await async function(e){await vy(e.fetchImpl,e.bridge,e.runtime,"PUT","/v1.0/card/instances",{outTrackId:e.outTrackId,cardData:{cardParamMap:cy({type:"actions",title:e.title,description:e.text,list:mf(e.replyMarkup),biz_step:e.step,error_msg:""})},cardUpdateOptions:{updateCardDataByKey:!0,updatePrivateDataByKey:!1},userIdType:Number(e.bridge.settings.cardUserIdType||1)})}({fetchImpl:this.fetchImpl,bridge:e.bridge,runtime:t,outTrackId:n.outTrackId,text:i,replyMarkup:s,title:"TaskHandoff 执行中",step:"progress"}),this.isCurrent(e.bridge.id,o)&&(n.lastText=i,n.lastActionsFingerprint=a,n.lastUpdateAt=Date.now()))}}function tb(e){return"string"==typeof e?e:""}function nb(e){const t=new S.DWClient({clientId:e.clientId,clientSecret:e.clientSecret,ua:"task-handoff-control-plane",keepAlive:!1,autoReconnect:!1});let n,i=!1;return{async connect(){i=!1,await t.getEndpoint(),await t._connect();const e=t.socket;e?.once("close",()=>{i||n?.(new Error("DingDing stream connection closed."))})},disconnect(){i=!0,t.disconnect()},onDisconnect(e){n=e},getConfig:()=>t.getConfig(),registerCallbackListener(e,n){t.registerCallbackListener(e,n)},socketCallBackResponse(e,n){t.socketCallBackResponse(e,n)}}}class ib{runtimes=new Map;connected=new Set;reconnectTimers=new Map;progress;options;createClient;constructor(e){this.options=e,this.createClient=e.createClient||nb,this.progress=new eb(e.fetchImpl)}has(e){return this.runtimes.has(e)}isRunning(e){return this.connected.has(e)}get(e){return this.runtimes.get(e)}ids(){return this.runtimes.keys()}start(e){const t=(n=e.settings?.clientSecret,"string"==typeof n?n:"");var n;if(!e.token||!t)return this.options.onError(e.id,"DingDing client id/secret is not configured."),!1;const i={client:this.createClient({clientId:e.token,clientSecret:t}),chatWebhooks:new Map,senderIds:new Map,conversationTypes:new Map,onLog:(t,n,i)=>{this.options.logger["warn"===t?"warn":"info"]({bridgeId:e.id,...n},i)}};return i.client.onDisconnect?.(t=>{this.runtimes.get(e.id)===i&&this.handleConnectionFailure(e,i,t)}),i.client.registerCallbackListener(S.TOPIC_ROBOT,t=>{this.options.onRobotMessage(e,i,t).catch(t=>{this.options.onError(e.id,t)})}),i.client.registerCallbackListener(S.TOPIC_CARD,t=>{const n=t;this.options.onCardCallback(e,i,n).then(e=>i.client.socketCallBackResponse(n.headers.messageId,e||{})).catch(t=>{this.options.onError(e.id,t),i.client.socketCallBackResponse(n.headers.messageId,{})})}),this.options.clearError(e.id),this.runtimes.set(e.id,i),this.connect(e,i),!0}connect(e,t){this.reconnectTimers.delete(e.id),this.connected.add(e.id),t.client.connect().then(()=>{this.runtimes.get(e.id)===t&&(this.connected.add(e.id),this.options.clearError(e.id))}).catch(n=>{this.runtimes.get(e.id)===t&&this.handleConnectionFailure(e,t,n)})}handleConnectionFailure(e,t,n){if(this.connected.delete(e.id),this.progress.clearBridge(e.id),this.options.onError(e.id,n||"DingDing stream connection failed."),this.reconnectTimers.has(e.id))return;const i=setTimeout(()=>{this.runtimes.get(e.id)===t&&this.connect(e,t)},this.options.reconnectDelayMs??1e3);i.unref?.(),this.reconnectTimers.set(e.id,i)}stop(e){const t=this.reconnectTimers.get(e);t&&clearTimeout(t),this.reconnectTimers.delete(e),this.connected.delete(e);const n=this.runtimes.get(e);if(n){try{n.client.disconnect()}catch{}this.runtimes.delete(e)}this.progress.clearBridge(e)}stopAll(){for(const e of[...this.runtimes.keys()])this.stop(e);this.progress.clear()}applyUpdate(e){const t=this.runtimes.get(e.bridge.id);return t?this.progress.applyUpdate(e,t):Promise.resolve(!1)}applyProgressUpdate(e){return this.applyUpdate(e)}}class sb{entries=new Map;generations=new Map;updateIntervalMs;constructor(e=1e3){this.updateIntervalMs=e}clear(){for(const e of new Set([...this.generations.keys(),...[...this.entries.values()].map(e=>e.bridgeId)]))this.clearBridge(e)}clearBridge(e){this.generations.set(e,this.generation(e)+1);for(const[t,n]of this.entries)n.bridgeId===e&&(n.timer&&clearTimeout(n.timer),n.cancelPending?.(new Error("Lark progress update was cancelled.")),this.entries.delete(t))}generation(e){return this.generations.get(e)||0}isCurrent(e,t){return this.generation(e)===t}async applyUpdate(e,t){const n=this.generation(e.bridge.id),i=Ry(e.replyMarkup);let s=this.entries.get(e.key);if(s?.pending&&await s.pending,!this.isCurrent(e.bridge.id,n))return!1;if(s=this.entries.get(e.key),s?.messageId){if(s.lastText===e.text&&s.lastActionsFingerprint===i)return!0;const a=Date.now()-s.lastUpdateAt;return a<this.updateIntervalMs?(s.pendingText=e.text,s.pendingReplyMarkup=e.replyMarkup,s.timer||(s.pending=new Promise((i,o)=>{s.cancelPending=o,s.timer=setTimeout(()=>{s.timer=void 0,s.cancelPending=void 0;const a=s.pendingText,r=s.pendingReplyMarkup;if(s.pendingText=void 0,s.pendingReplyMarkup=void 0,!a)return i(void 0);this.updateExistingEntry(e,t,s,a,r,Ry(r),n).then(i,o)},this.updateIntervalMs-a)}).finally(()=>{s.pending=void 0,s.timer=void 0,s.cancelPending=void 0})),await s.pending,this.isCurrent(e.bridge.id,n)&&this.entries.has(e.key)):(await this.updateExistingEntry(e,t,s,e.text,e.replyMarkup,i,n),this.isCurrent(e.bridge.id,n))}const a={bridgeId:e.bridge.id,lastText:e.text,lastActionsFingerprint:i,lastUpdateAt:Date.now()};return a.pending=t.channel.send(e.chatId,{card:Ny(e.text,e.replyMarkup)}).then(t=>{this.isCurrent(e.bridge.id,n)&&(a.messageId=t.messageId,a.delivered=!0,a.lastUpdateAt=Date.now())}).catch(t=>{throw this.isCurrent(e.bridge.id,n)&&this.entries.delete(e.key),t}).finally(()=>{a.pending=void 0}),this.entries.set(e.key,a),await a.pending,this.isCurrent(e.bridge.id,n)&&Boolean(a.delivered)}async updateExistingEntry(e,t,n,i,s,a,o){n.messageId&&(await t.channel.updateCard(n.messageId,Ny(i,s)),this.isCurrent(e.bridge.id,o)&&(n.lastText=i,n.lastActionsFingerprint=a,n.lastUpdateAt=Date.now()))}}function ab(e){const t={appId:e.appId,appSecret:e.appSecret,domain:e.domain,transport:"websocket",source:"task-handoff-control-plane",handshakeTimeoutMs:15e3,policy:{requireMention:!0,dmMode:"open",respondToMentionAll:!1}};return A.createLarkChannel(t)}class ob{runtimes=new Map;connected=new Set;unsubscribe=new Map;reconnectTimers=new Map;options;createChannel;progress;constructor(e){this.options=e,this.createChannel=e.createChannel||ab,this.progress=new sb(e.progressUpdateIntervalMs)}has(e){return this.runtimes.has(e)}isRunning(e){return this.connected.has(e)}get(e){return this.runtimes.get(e)}ids(){return this.runtimes.keys()}start(e){const t=(n=e.settings?.appSecret,"string"==typeof n?n.trim():"");var n;if(!e.token||!t)return this.options.onError(e.id,"Lark app id/secret is not configured."),!1;const i={channel:this.createChannel({appId:e.token,appSecret:t,domain:rb(e.settings?.domain)})},s=i.channel.on({message:t=>{this.options.onMessage(e,i,t).catch(t=>{this.options.onError(e.id,t)})},cardAction:t=>{this.options.onCardAction(e,i,t).catch(t=>{this.options.onError(e.id,t)})},error:t=>{this.options.onError(e.id,t),this.options.logger.warn({bridgeId:e.id,error:t.message},"lark channel error")},reconnecting:()=>{this.connected.delete(e.id),this.options.onError(e.id,"Lark WebSocket is reconnecting."),this.options.logger.info({bridgeId:e.id},"lark channel reconnecting")},reconnected:()=>{this.runtimes.get(e.id)===i&&(this.connected.add(e.id),this.options.clearError(e.id),this.options.logger.info({bridgeId:e.id},"lark channel reconnected"))}});return this.options.clearError(e.id),this.runtimes.set(e.id,i),this.unsubscribe.set(e.id,s),this.connect(e,i),!0}connect(e,t){this.reconnectTimers.delete(e.id),t.channel.connect().then(()=>{this.runtimes.get(e.id)===t&&(this.connected.add(e.id),this.options.clearError(e.id),this.options.logger.info({bridgeId:e.id},"lark channel connected"))}).catch(n=>{if(this.runtimes.get(e.id)!==t)return;if(this.connected.delete(e.id),this.options.onError(e.id,n),t.channel.rawWsClient||this.reconnectTimers.has(e.id))return;const i=setTimeout(()=>{this.runtimes.get(e.id)===t&&this.connect(e,t)},this.options.reconnectDelayMs??1e3);i.unref?.(),this.reconnectTimers.set(e.id,i)})}stop(e){const t=this.reconnectTimers.get(e);t&&clearTimeout(t),this.reconnectTimers.delete(e),this.unsubscribe.get(e)?.(),this.unsubscribe.delete(e),this.connected.delete(e);const n=this.runtimes.get(e);if(this.runtimes.delete(e),this.progress.clearBridge(e),n){try{n.channel.rawWsClient?.close({force:!0})}catch{}n.channel.disconnect().catch(()=>{})}}stopAll(){for(const e of[...this.runtimes.keys()])this.stop(e);this.progress.clear()}applyUpdate(e){const t=this.runtimes.get(e.bridge.id);return t?this.progress.applyUpdate(e,t):Promise.resolve(!1)}applyProgressUpdate(e){return this.applyUpdate(e)}}function rb(e){return"lark"===String(e||"").trim().toLowerCase()?A.Domain.Lark:A.Domain.Feishu}class cb{ttlMs;load;now;cached;pending;generation=0;constructor(e,t,n={}){this.ttlMs=e,this.load=t,this.now=n.now||Date.now}get(){if(this.cached&&this.cached.expiresAt>this.now())return Promise.resolve(this.cached.value);if(this.pending)return this.pending;const e=this.generation,t=this.load().then(t=>(this.generation===e&&(this.cached={expiresAt:this.now()+this.ttlMs,value:t}),t)).finally(()=>{this.pending===t&&(this.pending=void 0)});return this.pending=t,t}invalidate(){this.generation+=1,this.cached=void 0,this.pending=void 0}}class db{aggregates=new Map;endTokens=new Map;options;delayMs;constructor(e){this.options=e,this.delayMs=e.delayMs??1e3}async handleIncoming(e,t,n,i,s=[],a={},o={}){const r=i.trim(),c=r.split(/\s+/,1)[0]?.toLowerCase()||"",d=lb(e.id,t,n),l=this.aggregates.get(d);return o.autoBegin&&!l?(this.start(d,e,t,n,a),this.enqueue(d,e,t,n,i,s,a,!0),void await this.sendCollectionStarted(e,t,d,a.sourceMessageId,"Image received. Continue sending messages, then send /end when done.")):"/begin"===c?(this.start(d,e,t,n,a),void await this.sendCollectionStarted(e,t,d,a.sourceMessageId,"Started collecting messages. Send /end when done.")):void("/end"!==c?l?.explicit?this.enqueue(d,e,t,n,i,s,a,!0):r.startsWith("/")?await this.options.dispatch(e,t,n,i,s,a):this.enqueue(d,e,t,n,i,s,a,!1):await this.flush(d,"manual"))}async handleEndCallback(e,t,n,i,s){const a=this.endTokens.get(i)||"";if(a!==lb(e.id,t,s))return void await this.options.answerCallback(e,n,"This collection is not active here");const o=await this.flush(a,"callback");await this.options.answerCallback(e,n,o?"Collected message sent":"No messages collected")}stop(){for(const e of this.aggregates.values())e.timer&&clearTimeout(e.timer);this.aggregates.clear(),this.endTokens.clear()}stopBridge(e){for(const[t,n]of this.aggregates)n.bridgeId===e&&(n.timer&&clearTimeout(n.timer),this.aggregates.delete(t));for(const[t,n]of this.endTokens)n.startsWith(`${e}:`)&&this.endTokens.delete(t)}start(e,t,n,i,s){const a=this.aggregates.get(e);a?.timer&&clearTimeout(a.timer),this.aggregates.set(e,{bridgeId:t.id,chatId:n,userId:i,texts:[],attachments:[],context:s,explicit:!0})}enqueue(e,t,n,i,s,a,o,r){const c=this.aggregates.get(e);c?.timer&&clearTimeout(c.timer);const d=c||{bridgeId:t.id,chatId:n,userId:i,texts:[],attachments:[],context:o,explicit:r};var l,p;d.bridgeId=t.id,d.chatId=n,d.userId=i,d.context=(l=d.context,p=o,{sourceMessageId:l?.sourceMessageId??p.sourceMessageId,replyToMessageId:l?.replyToMessageId??p.replyToMessageId,quoteText:l?.quoteText||p.quoteText}),d.explicit=d.explicit||r,s.trim()&&d.texts.push(s),d.attachments.push(...a),d.timer=d.explicit?void 0:setTimeout(()=>{this.flush(e,"timer").catch(e=>this.options.onError?.(d.bridgeId,e))},this.delayMs),this.aggregates.set(e,d)}async flush(e,t){const n=this.aggregates.get(e);if(!n)return!1;n.timer&&clearTimeout(n.timer),this.aggregates.delete(e);const i=this.options.requireBridge(n.bridgeId),s=n.texts.join("\n\n").trim();return s||n.attachments.length?(await this.options.dispatch(i,n.chatId,n.userId,s,n.attachments,n.context||{}),!0):("timer"!==t&&await this.options.send(i,n.chatId,"No messages collected.",{replyToMessageId:n.context?.sourceMessageId}),!1)}sendCollectionStarted(e,t,n,i,s){return this.options.send(e,t,s,{replyToMessageId:i,replyMarkup:lf([[{text:"/end",callbackData:this.endCallbackData(n)}]])})}endCallbackData(e){const t=i.createHash("sha256").update(e).digest("base64url").slice(0,16);return this.endTokens.set(t,e),`task_handoff:cp_msg_end:${t}`}}function lb(e,t,n){return[e,t,n||""].join(":")}class pb{cancelTokens=new Map;queueActionTokens=new Map;options;constructor(e){this.options=e}cancelCallbackData(e,t){this.pruneExpired();const n=mb([e,t]);return this.cancelTokens.set(n,this.expiring({instanceId:e,sessionId:t})),`task_handoff:cp_ai_cancel:${n}`}queueSteerCallbackData(e,t,n){return`task_handoff:cp_ai_steer:${this.queueActionToken({type:"steer",instanceId:e,sessionId:t,queueId:n})}`}queueDeleteMenuCallbackData(e,t){return`task_handoff:cp_ai_qdel_menu:${this.queueActionToken({type:"delete-menu",instanceId:e,sessionId:t})}`}async tryHandle(e,t){this.pruneExpired();const n=ub(e,"task_handoff:cp_ai_cancel:");if(void 0!==n){const e=this.cancelTokens.get(n)?.value;return e?(await this.cancel(t,e.instanceId,e.sessionId),!0):this.expired(t)}const i=ub(e,"task_handoff:cp_ai_steer:");if(void 0!==i){const e=this.queueActionTokens.get(i)?.value;return e&&"steer"===e.type?(await this.steer(t,e),!0):this.expired(t)}const s=ub(e,"task_handoff:cp_ai_qdel_menu:");if(void 0!==s){const e=this.queueActionTokens.get(s)?.value;return e&&"delete-menu"===e.type?(await this.deleteMenu(t,e),!0):this.expired(t)}const a=ub(e,"task_handoff:cp_ai_qdel:");if(void 0!==a){const e=this.queueActionTokens.get(a)?.value;return e&&"delete-item"===e.type?(await this.deleteItem(t,e),!0):this.expired(t)}return!1}async cancel(e,t,n){await this.requireAllowed(e,t,n)&&await this.run(e,{instanceId:t,sessionId:n,successText:"Interrupt sent",failurePrefix:"Interrupt failed",logMessage:"chat ai session cancel sent",operation:()=>this.options.interrupt(t,n)})}async steer(e,t){await this.requireAllowed(e,t.instanceId,t.sessionId)&&await this.run(e,{...t,successText:"Steered queued message",failurePrefix:"Steer failed",logMessage:"chat ai session queued message steered",operation:()=>this.options.steer(t.instanceId,t.sessionId,t.queueId)})}async deleteMenu(e,t){if(await this.requireAllowed(e,t.instanceId,t.sessionId))try{const n=gb(await this.options.queue(t.instanceId,t.sessionId)),i=(Array.isArray(n.items)?n.items:[]).map(gb).filter(e=>"queued"===fb(e.status)&&fb(e.id));if(!i.length)return void await this.answer(e,"Queue is empty");const s=i.slice(0,5).map((e,n)=>[{text:hb(fb(e.message),n),callbackData:this.queueDeleteItemCallbackData(t.instanceId,t.sessionId,fb(e.id))}]);await this.send(e,"Delete queued message",{replyMarkup:lf(s)}),await this.answer(e,"Select a queued message"),this.options.info(this.logData(e,t,{itemCount:i.length}),"chat ai session queue delete menu sent")}catch(t){await this.fail(e,t,"Queue menu failed")}}async deleteItem(e,t){if(await this.requireAllowed(e,t.instanceId,t.sessionId))try{await this.options.remove(t.instanceId,t.sessionId,t.queueId),await this.answer(e,"Queued message deleted"),(e.deleteMessage||Number.isInteger(e.messageId))&&await this.deleteMessage(e).catch(n=>{this.options.warn(this.logData(e,t,{messageId:e.messageId,error:yb(n)}),"chat ai session queue delete menu message delete failed")}),this.options.info(this.logData(e,t),"chat ai session queued message deleted")}catch(t){await this.fail(e,t,"Delete failed")}}async run(e,t){try{await t.operation(),await this.answer(e,t.successText),this.options.info(this.logData(e,t),t.logMessage)}catch(n){await this.fail(e,n,t.failurePrefix)}}async requireAllowed(e,t,n){return!!(e.actionAllowed?e.actionAllowed(t,n):this.options.actionAllowed(e.bridge,e.chatId,t,n,Number.isInteger(e.messageId)?e.messageId:void 0))||(await this.answer(e,"This chat is not bound to that AI session"),!1)}async fail(e,t,n){const i=yb(t);this.options.setBridgeError(e.bridge.id,i),await this.answer(e,`${n}: ${function(e){const t=e.replace(/\s+/g," ").trim();return t.length<=120?t:`${t.slice(0,Math.max(0,119))}…`}(i)}`)}async expired(e){return await this.answer(e,"This AI session action expired"),!0}answer(e,t){return e.answer?e.answer(t):this.options.answer(e.bridge,e.callbackQueryId,t)}send(e,t,n){return e.send?e.send(t,n):this.options.send(e.bridge,e.chatId,t,n)}deleteMessage(e){return e.deleteMessage?e.deleteMessage():Number.isInteger(e.messageId)?this.options.deleteMessage(e.bridge,e.chatId,e.messageId):Promise.resolve(void 0)}queueDeleteItemCallbackData(e,t,n){return`task_handoff:cp_ai_qdel:${this.queueActionToken({type:"delete-item",instanceId:e,sessionId:t,queueId:n})}`}queueActionToken(e){this.pruneExpired();const t=mb([e.type,e.instanceId,e.sessionId,"queueId"in e?e.queueId:""]);return this.queueActionTokens.set(t,this.expiring(e)),t}clear(){this.cancelTokens.clear(),this.queueActionTokens.clear()}expiring(e){return{value:e,expiresAt:(this.options.now||Date.now)()+(this.options.tokenTtlMs??864e5)}}pruneExpired(){const e=(this.options.now||Date.now)();for(const[t,n]of this.cancelTokens)n.expiresAt<=e&&this.cancelTokens.delete(t);for(const[t,n]of this.queueActionTokens)n.expiresAt<=e&&this.queueActionTokens.delete(t)}logData(e,t,n={}){return{bridgeId:e.bridge.id,chatId:e.chatId,instanceId:t.instanceId,sessionId:t.sessionId,...t.queueId?{queueId:t.queueId}:{},userId:e.userId,...n}}}function ub(e,t){if(!e.startsWith(t))return;const n=e.slice(t.length);return n&&!n.includes(":")?n:void 0}function mb(e){return i.createHash("sha256").update(e.join("\0")).digest("base64url").slice(0,16)}function hb(e,t){const n=`${t+1}. `,i=fb(e).replace(/\s+/g," ").trim()||"Queued message",s=Math.max(8,48-n.length),a=Array.from(i);return`${n}${a.length>s?`${a.slice(0,Math.max(1,s-3)).join("")}...`:i}`}function gb(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function fb(e){return"string"==typeof e?e.trim():""}function yb(e){return e instanceof Error?e.message:String(e)}class bb{announced=new Set;options;constructor(e){this.options=e}async poll(){const e=await this.options.listRoutes().catch(()=>[]);for(const t of e){if(this.announced.has(t.id))continue;const e=vb(t,this.options.callbackData),n=t.aiSessionId?this.options.listBindings().filter(e=>e.activeInstanceId===t.instanceId&&e.activeAiSessionId===t.aiSessionId):[];(await this.sendToBindings(n,e)||await this.sendToDefaults(e))&&this.announced.add(t.id)}}async sendToBindings(e,t){let n=!1;for(const i of e){if(!i.bridgeId)continue;const e=this.options.requireBridge(i.bridgeId);if(!e.enabled)continue;const s=await this.send(e,i.chatSessionId,t);n||=s}return n}async sendToDefaults(e){let t=!1;for(const n of this.options.listBridges()){if(!n.enabled||!n.defaultChatId)continue;let i=!1;await this.options.send(n,n.defaultChatId,e).catch(e=>(this.options.setBridgeError(n.id,Ib(e)),i=!0,!1))?t=!0:i||this.options.setBridgeError(n.id,"Chat bridge message was not delivered.")}return t}async send(e,t,n){return this.options.send(e,t,n).then(Boolean).catch(t=>(this.options.setBridgeError(e.id,Ib(t)),!1))}}function vb(e,t){const n=`${e.project?.name||e.projectId} / ${e.instance?.name||e.instanceId}`,i="approval"===e.kind?`/approve ${e.id}\n/deny ${e.id}\n/skip ${e.id}`:`/reply ${e.id} <message>`,s=`[${n}]\n${e.result}\n\n${i}`;return"approval"!==e.kind?{text:s}:{text:s,replyMarkup:lf([[{text:"Allow",callbackData:t(e.id,"allow")},{text:"Skip",callbackData:t(e.id,"skip")},{text:"Deny",callbackData:t(e.id,"deny")}]])}}function Ib(e){return e instanceof Error?e.message:String(e)}function xb(){return e=process.env.TASK_HANDOFF_DIAGNOSTIC_LOGS,["1","true","yes","on"].includes(String(e||"").trim().toLowerCase());var e}class wb{service;fetchImpl;logger;diagnosticLogsEnabled;bridgeTimers=new Map;bridgePollingGenerations=new Map;bridgePolls=new Map;dingdingBridges;larkBridges;bridgeErrors=new Map;telegramOffsets=new Map;seenTelegramUpdates=new Set;wechatCursors=new Map;pendingRouteNotifier;deliveredAiSessionFingerprints=new Map;telegramAiSessionCallbacks;telegramMessageAggregator;telegramProgressMessageTargets=new Map;aiSessionInstanceNamesCache;aiSessionPendingRoutesCache;telegramProgress;stopAiSessionListener;constructor(e,t=fetch,n={}){this.service=e,this.fetchImpl=t,this.logger=n.logger,this.diagnosticLogsEnabled=n.diagnosticLogsEnabled||xb,this.aiSessionInstanceNamesCache=new cb(3e4,async()=>{const e=await(this.service.listAiSessionInstanceNames?.()||this.service.boardAsync()).catch(()=>[]);return new Map(e.map(e=>[e.id,e.name||e.id]))}),this.aiSessionPendingRoutesCache=new cb(1e3,()=>this.service.listPendingRoutes().catch(()=>[])),this.telegramMessageAggregator=new db({requireBridge:e=>this.service.requireChatBridge(e),send:(e,t,n,i={})=>this.sendTelegramMessage(e,t,n,i),answerCallback:(e,t,n)=>this.answerTelegramCallback(e,t,n),dispatch:(e,t,n,i,s,a)=>this.dispatchTelegramGatewayMessage(e,t,n,i,s,a),onError:(e,t)=>this.bridgeErrors.set(e,Cb(t))}),this.telegramAiSessionCallbacks=new pb({interrupt:(e,t)=>this.service.interruptAiSession(e,t),queue:(e,t)=>this.service.aiSessionQueue(e,t),steer:(e,t,n)=>this.service.steerAiSessionQueuedMessage(e,t,n),remove:(e,t,n)=>this.service.removeAiSessionQueuedMessage(e,t,n),actionAllowed:(e,t,n,i,s)=>this.telegramAiSessionActionAllowed(e,t,n,i,s),answer:(e,t,n)=>this.answerTelegramCallback(e,t,n),send:(e,t,n,i={})=>this.sendTelegramMessage(e,t,n,i),deleteMessage:(e,t,n)=>this.deleteTelegramMessage(e,t,n),setBridgeError:(e,t)=>this.bridgeErrors.set(e,t),info:(e,t)=>this.logInfo(e,t),warn:(e,t)=>this.logWarn(e,t)}),this.pendingRouteNotifier=new bb({listRoutes:()=>this.service.listPendingRoutes(),listBindings:()=>this.service.listChatSessions(),listBridges:()=>this.service.listChatBridges(),requireBridge:e=>this.service.requireChatBridge(e),callbackData:(e,t)=>this.service.pendingDecisionCallbackData(e,t),send:(e,t,n)=>this.sendViaBridge(e,t,n),setBridgeError:(e,t)=>this.bridgeErrors.set(e,t)}),this.telegramProgress=new Fy({updateIntervalMs:n.telegramProgressUpdateIntervalMs,requireBridge:e=>this.service.requireChatBridge(e),send:(e,t,n,i={})=>this.sendTelegramMessage(e,t,n,i),edit:(e,t,n,i,s={})=>this.editTelegramMessage(e,t,n,i,s),deleteMessage:(e,t,n)=>this.deleteTelegramMessage(e,t,n),onLog:e=>this.logWarn({message:e},"telegram progress store warning")}),this.dingdingBridges=new ib({fetchImpl:this.fetchImpl,createClient:n.createDingdingClient,logger:{info:(e,t)=>this.logInfo(e,t),warn:(e,t)=>this.logWarn(e,t)},onRobotMessage:(e,t,n)=>this.handleDingdingRobotMessage(e,t,n),onCardCallback:(e,t,n)=>this.handleDingdingCardCallback(e,t,n),onError:(e,t)=>this.bridgeErrors.set(e,Cb(t)),clearError:e=>this.bridgeErrors.delete(e)}),this.larkBridges=new ob({createChannel:n.createLarkChannel,progressUpdateIntervalMs:n.larkProgressUpdateIntervalMs,logger:{info:(e,t)=>this.logInfo(e,t),warn:(e,t)=>this.logWarn(e,t)},onMessage:(e,t,n)=>this.handleLarkMessage(e,t,n),onCardAction:(e,t,n)=>this.handleLarkCardAction(e,t,n),onError:(e,t)=>this.bridgeErrors.set(e,Cb(t)),clearError:e=>this.bridgeErrors.delete(e)}),this.stopAiSessionListener=n.aiSessions?.onSnapshot(e=>{this.deliverAiSessionSnapshot(e.instanceId,e.aiSessions).catch(t=>{this.logWarn({instanceId:e.instanceId,snapshotRevision:e.revision,error:Cb(t)},"chat ai session snapshot delivery failed")})})}logInfo(e,t){this.diagnosticLogsEnabled()&&this.logger?.info?.({component:"control-plane-chat-gateway",...e},t)}logWarn(e,t){this.diagnosticLogsEnabled()&&this.logger?.warn?.({component:"control-plane-chat-gateway",...e},t)}updateChatBridge(e,t){this.service.updateChatBridge?.(e,t)}startEnabled(){this.logAiSessionDelivery({stage:"runtime-start-enabled",bridgeCount:this.service.listChatBridges().length,enabledBridgeCount:this.service.listChatBridges().filter(e=>e.enabled).length});for(const e of this.service.listChatBridges())e.enabled&&this.startBridge(e.id)}startBridge(e){if(this.bridgeTimers.has(e)||this.dingdingBridges.has(e)||this.larkBridges.has(e))return this.logAiSessionDelivery({stage:"bridge-start-skipped-running",bridgeId:e}),this.status();const t=this.service.requireChatBridge(e);return this.logAiSessionDelivery({stage:"bridge-start",bridgeId:t.id,channel:t.channel,enabled:t.enabled,hasToken:Boolean(t.token)}),"wechat"===t.channel?this.startPollingBridge(t,(e,t)=>this.pollWechat(e,t)):"dingding"===t.channel?this.startDingdingBridge(t):"lark"===t.channel?this.startLarkBridge(t):"telegram"!==t.channel?(this.bridgeErrors.set(e,`${t.channel} bridge is not supported in the control plane.`),this.status()):t.token?this.startPollingBridge(t,(e,t)=>this.pollTelegram(e,t)):(this.bridgeErrors.set(e,"Telegram token is not configured."),this.status())}stopBridge(e){this.advanceBridgePollingGeneration(e);const t=`:${e}:`;for(const e of this.deliveredAiSessionFingerprints.keys())e.includes(t)&&this.deliveredAiSessionFingerprints.delete(e);const n=this.bridgeTimers.get(e);return n&&(clearInterval(n),this.bridgeTimers.delete(e)),this.dingdingBridges.stop(e),this.larkBridges.stop(e),this.telegramMessageAggregator.stopBridge(e),this.status()}stopAll(){const e=new Set([...this.service.listChatBridges().map(e=>e.id),...this.bridgePollingGenerations.keys(),...this.bridgeTimers.keys(),...this.bridgePolls.keys(),...this.dingdingBridges.ids(),...this.larkBridges.ids()]);for(const t of e)this.stopBridge(t);this.dingdingBridges.stopAll(),this.larkBridges.stopAll(),this.telegramMessageAggregator.stop(),this.telegramAiSessionCallbacks.clear(),this.stopAiSessionListener?.(),this.stopAiSessionListener=void 0}async pollBridgeNow(e){const t=this.service.requireChatBridge(e),n=this.bridgePollingGeneration(e);return"telegram"===t.channel?(await this.runBridgePoll(t,n,(e,t)=>this.pollTelegram(e,t)),this.status()):"wechat"===t.channel?(await this.runBridgePoll(t,n,(e,t)=>this.pollWechat(e,t)),this.status()):("dingding"===t.channel||"lark"===t.channel||this.bridgeErrors.set(e,`${t.channel} bridge is not supported in the control plane.`),this.status())}async pollAiSessionsNow(){return await this.pollAiSessionUpdates(),this.status()}status(){const e=this.service.listChatBridges().map(e=>({id:e.id,channel:e.channel,name:e.name,running:this.bridgeTimers.has(e.id)||this.dingdingBridges.isRunning(e.id)||this.larkBridges.isRunning(e.id),tokenSet:Boolean(e.tokenSet),defaultChatId:e.defaultChatId,lastUpdateId:this.telegramOffsets.get(e.id),error:this.bridgeErrors.get(e.id)}));return{running:e.some(e=>e.running),bridges:e}}startPollingBridge(e,t){if(!e.token)return this.bridgeErrors.set(e.id,`${e.channel} token is not configured.`),this.status();this.bridgeErrors.delete(e.id);const n=this.advanceBridgePollingGeneration(e.id),i=()=>this.bridgePollingGeneration(e.id)===n,s=s=>{i()&&this.runBridgePoll(s,n,t).catch(t=>{i()&&this.bridgeErrors.set(e.id,t instanceof Error?t.message:String(t))})},a=setInterval(()=>{if(!i())return;const t=this.service.requireChatBridge(e.id);t.enabled?s(t):this.stopBridge(e.id)},e.pollIntervalMs);if(this.bridgeTimers.set(e.id,a),this.logAiSessionDelivery({stage:"bridge-poll-started",bridgeId:e.id,channel:e.channel,intervalMs:e.pollIntervalMs}),e.enabled){const t=this.service.requireChatBridge(e.id);s(t)}return this.status()}runBridgePoll(e,t,n){const i=this.bridgePolls.get(e.id);if(i?.generation===t)return i.promise;const s=(async()=>{const i=()=>this.bridgePollingGeneration(e.id)===t;i()&&await n(e,i)})();this.bridgePolls.set(e.id,{generation:t,promise:s});const a=()=>{this.bridgePolls.get(e.id)?.promise===s&&this.bridgePolls.delete(e.id)};return s.then(a,a),s}bridgePollingGeneration(e){return this.bridgePollingGenerations.get(e)||0}advanceBridgePollingGeneration(e){const t=this.bridgePollingGeneration(e)+1;return this.bridgePollingGenerations.set(e,t),t}startDingdingBridge(e){return this.dingdingBridges.start(e),this.status()}startLarkBridge(e){return this.larkBridges.start(e),this.status()}async handleLarkMessage(e,t,n){const i=this.bindOrAllowChatUser(e,n.senderId),s=String(n.content||"").trim();if(!i||!s)return void this.logWarn({bridgeId:e.id,chatId:n.chatId,senderId:n.senderId,allowed:i,hasText:Boolean(s)},"lark message ignored");let a;e.defaultChatId||this.updateChatBridge(e.id,{defaultChatId:n.chatId}),this.logInfo({bridgeId:e.id,chatId:n.chatId,senderId:n.senderId,chatType:n.chatType,messageId:n.messageId,textPreview:Ob(s)},"lark chat gateway message received");try{a=await this.service.handleChatGatewayMessage({source:{type:"chat-gateway",channel:"lark",bridgeId:e.id,chatSessionId:n.chatId,userId:n.senderId},message:{text:s,attachments:[]}})}catch(e){return void await t.channel.send(n.chatId,{markdown:`Failed to handle message: ${Cb(e)}`})}const o=Sb(a);if(!o)return;const r=Eb(a);if(await this.sendLarkRoutedAiSessionProgress(a,e,n.chatId,o,r))return;const c=Zy({fetchImpl:this.fetchImpl,bridge:e,larkRuntime:t}),d=await c.send(n.chatId,o,{replyMarkup:r});d&&this.logInfo({bridgeId:e.id,chatId:n.chatId,senderId:n.senderId,provider:d.provider,interactionId:d.interactionId,routed:!0===Db(a).routed,replyPreview:Ob(o)},"lark chat gateway reply sent")}async sendLarkRoutedAiSessionProgress(e,t,n,i,s){if(!0!==e.routed)return!1;const a=qb(e),{instanceId:o,sessionId:r,turnId:c}=a;if(!o||!r||!c)return this.logWarn({bridgeId:t.id,chatId:n,instanceId:o,sessionId:r,turnId:c,turnIdSources:a.sources,routed:e.routed},"lark ai session progress message not started"),!1;const d=Gb(o,r,c,t.id,n);return!!await this.larkBridges.applyProgressUpdate({bridge:t,key:d,chatId:n,text:i,replyMarkup:s})&&(this.deliveredAiSessionFingerprints.delete(d),this.logInfo({bridgeId:t.id,chatId:n,instanceId:o,sessionId:r,turnId:c,key:d,textPreview:Ob(i)},"lark ai session progress message started"),!0)}async handleLarkCardAction(e,t,n){const i=n.operator.openId||n.operator.userId;if(!this.bindOrAllowChatUser(e,i))return void this.logWarn({bridgeId:e.id,chatId:n.chatId,messageId:n.messageId,userId:i},"lark card action ignored");const s=Cy(n.action.value),a=(e,i)=>t.channel.updateCard(n.messageId,Ny(e||"Updated",i));if(!s)return void await a("Unsupported action");if(await this.telegramAiSessionCallbacks.tryHandle(s,{bridge:e,chatId:n.chatId,callbackQueryId:n.messageId,userId:i,messageId:n.messageId,actionAllowed:(t,i)=>this.chatAiSessionBindingActive(e,n.chatId,t,i),answer:e=>a(e),send:(e,i)=>t.channel.send(n.chatId,{card:Ny(e,i?.replyMarkup)})}))return;let o;try{o=await this.parseChatGatewayCallbackAction(s)}catch(e){if(Rb(e,"CHAT_PENDING_ACTION_STALE"))return void await a(Cb(e));throw e}if(!o)return void await a("Unsupported action");const r=await this.service.handleChatGatewayAction({source:{channel:"lark",bridgeId:e.id,chatSessionId:n.chatId,userId:i},action:o});if("pending-decision"===o.type&&Ab(r))return void await a(`${o.decision} sent`);const c=Sb(r)||Nb(r.message)||"Updated";await a(c,Eb(r))}async handleDingdingRobotMessage(e,t,n){const i=function(e){const t=Ty(e),n=_y(t.conversationId),i=_y(Ay(t.text).content).trim();if(!n||!i)return;const s=_y(t.senderStaffId||t.senderId);return{chatId:n,userId:s||void 0,senderId:s||void 0,sessionWebhook:_y(t.sessionWebhook)||void 0,conversationType:uy(t.conversationType,{robotMessage:!0}),text:i,raw:t}}(n.data);if(t.client.socketCallBackResponse(n.headers.messageId,{}),!i||!this.bindOrAllowChatUser(e,i.senderId))return void this.logWarn({bridgeId:e.id,hasEvent:Boolean(i),senderId:i?.senderId,allowed:i?this.bindOrAllowChatUser(e,i.senderId):void 0},"dingding robot message ignored");const{chatId:s,text:a,senderId:o,sessionWebhook:r}=i;r&&t.chatWebhooks.set(s,r),i.conversationType&&t.conversationTypes.set(s,i.conversationType);const c=r||t.chatWebhooks.get(s)||Nb(e.settings.sessionWebhook);let d;o&&t.senderIds.set(s,o),e.defaultChatId||this.updateChatBridge(e.id,{defaultChatId:s}),this.logInfo({bridgeId:e.id,chatId:s,senderId:o,conversationType:i.conversationType,hasSessionWebhook:Boolean(r),hasCachedSessionWebhook:Boolean(t.chatWebhooks.get(s)),hasResolvedSessionWebhook:Boolean(c),textPreview:Ob(a)},"dingding chat gateway message received");try{d=await this.service.handleChatGatewayMessage({source:{type:"chat-gateway",channel:"dingding",bridgeId:e.id,chatSessionId:s,userId:o||void 0},message:{text:a,attachments:[]}})}catch(e){if(c)return void await yy(this.fetchImpl,c,`Failed to handle message: ${Cb(e)}`,t.onLog);throw e}const l=Sb(d);if(l){const n=Eb(d);if(await this.sendDingdingRoutedAiSessionProgress(d,e,t,s,l,{replyMarkup:n,sessionWebhook:c,senderId:o,sourcePrompt:a}))return;const i=Zy({fetchImpl:this.fetchImpl,bridge:e,dingdingRuntime:t}),r=await i.send(s,l,{replyMarkup:n,sessionWebhook:c,senderId:o});if(r)return void this.logInfo({bridgeId:e.id,chatId:s,senderId:o,provider:r.provider,interactionId:r.interactionId,routed:!0===Db(d).routed,hasReplyMarkup:Boolean(n),replyPreview:Ob(l)},"dingding chat gateway reply sent");this.logWarn({bridgeId:e.id,chatId:s,senderId:o,hasReplyMarkup:Boolean(n),hasSessionWebhook:Boolean(c),hasRobotCode:Boolean(Nb(e.settings.robotCode)),replyPreview:Ob(l)},"dingding chat gateway reply skipped")}}async sendDingdingRoutedAiSessionProgress(e,t,n,i,s,a={}){if(!0!==e.routed)return!1;const o=qb(e),{instanceId:r,sessionId:c,turnId:d}=o;if(!r||!c||!d)return this.logWarn({bridgeId:t.id,chatId:i,instanceId:r,sessionId:c,turnId:d,turnIdSources:o.sources,routed:e.routed},"dingding ai session progress card not started"),!1;const l=Gb(r,c,d,t.id,i);return!!await this.dingdingBridges.applyProgressUpdate({bridge:t,key:l,chatId:i,text:s,replyMarkup:a.replyMarkup})&&(this.deliveredAiSessionFingerprints.delete(l),this.logInfo({bridgeId:t.id,chatId:i,instanceId:r,sessionId:c,turnId:d,key:l,hasSessionWebhook:Boolean(a.sessionWebhook),hasSenderId:Boolean(a.senderId),sourcePrompt:Ob(a.sourcePrompt,80),textPreview:Ob(s)},"dingding ai session progress card started"),!0)}async handleDingdingCardCallback(e,t,n){const i=function(e){const t=Ty(e),n=Ey(t.cardActionData||t.content),i=Ey(n.cardPrivateData||t.cardPrivateData||t.content),s=Ey(i.params||n.params||t.params),a=_y(t.userId),o=_y(s.biz_sender_id);return{userId:a||void 0,chatId:py(t,s),senderId:a||void 0,deliverySenderId:o||void 0,sessionWebhook:_y(s.biz_session_webhook)||void 0,conversationType:uy(s.biz_conversation_type||t.conversationType||t.conversation_type),callbackData:my(gy(t,n,i)),body:t,params:s}}(n.data);if(!this.bindOrAllowChatUser(e,i.userId))return hy("not authorized",void 0,"unauthorized",i.body,i.params);const s=i.chatId||Nb(e.defaultChatId),a=i.deliverySenderId||i.senderId,o=i.sessionWebhook;let r;s&&o&&t.chatWebhooks.set(s,o),s&&i.conversationType&&t.conversationTypes.set(s,i.conversationType),s&&a&&t.senderIds.set(s,a);try{r=await this.parseChatGatewayCallbackAction(i.callbackData)}catch(e){if(Rb(e,"CHAT_PENDING_ACTION_STALE"))return hy(Cb(e),void 0,"approval_stale",i.body,i.params);throw e}if(!r)return this.logWarn({bridgeId:e.id,chatId:s,userId:i.userId,senderId:a,...jb(i)},"dingding card callback action unsupported"),hy("Unsupported action",void 0,"unsupported",i.body,i.params);this.logInfo({bridgeId:e.id,chatId:s,userId:i.userId,senderId:a,actionType:r.type,...jb(i)},"dingding card callback action parsed");const c=await this.service.handleChatGatewayAction({source:{channel:"dingding",bridgeId:e.id,chatSessionId:s,userId:i.userId||void 0},action:r});return"pending-decision"===r.type&&Ab(c)?hy(`${r.decision} sent`,void 0,"approval_done",i.body,i.params):hy(Sb(c)||Nb(c.message)||"updated",Eb(c),"updated",i.body,i.params)}async pollWechat(e,t=()=>!0){if(!e.token)return;const n=e.settings||{},i=this.wechatCursors.get(e.id)||Nb(n.updatesBuf),s=await async function(e){const t=Qy((e.bridge.settings||{}).baseUrl)||"https://ilinkai.weixin.qq.com",n=await e.fetchImpl(`${t}/ilink/bot/getupdates`,{method:"POST",headers:{"content-type":"application/json",AuthorizationType:"ilink_bot_token",Authorization:`Bearer ${e.bridge.token}`,"X-WECHAT-UIN":String(Math.floor(Math.random()*2**31))},body:JSON.stringify({get_updates_buf:e.cursor,base_info:{channel_version:"1.0.2"}})}),i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(`HTTP ${n.status}`);const s=Number(i.errcode??i.ret??0);if(0!==s)throw new Error(Qy(i.errmsg||i.msg)||`chat bridge API returned ${s}`);const a=[];for(const e of Array.isArray(i.msgs)?i.msgs:[]){const t=Jy(e);if(1!==t.message_type)continue;const n=Qy(t.from_user_id),i=Xy(t);n&&i&&a.push({chatId:n,text:i,contextToken:Qy(t.context_token)})}return{cursor:Qy(i.get_updates_buf),messages:a}}({fetchImpl:this.fetchImpl,bridge:e,cursor:i});if(t()){s.cursor&&(this.wechatCursors.set(e.id,s.cursor),this.updateChatBridge(e.id,{settings:{updatesBuf:s.cursor}}));for(const i of s.messages){if(!t())return;const{chatId:s,contextToken:a,text:o}=i;if(e.defaultChatId||this.updateChatBridge(e.id,{defaultChatId:s,settings:{contextToken:a}}),e.defaultChatId&&e.defaultChatId!==s)continue;const r=await this.service.handleChatGatewayMessage({source:{type:"chat-gateway",channel:"wechat",bridgeId:e.id,chatSessionId:s},message:{text:o,attachments:[]}});if(!t())return;const c=Sb(r);if(c){const t=Zy({fetchImpl:this.fetchImpl,bridge:e});await t.send(s,c,{contextToken:a||Nb(n.contextToken)})}}}}pollPendingRoutes(){return this.pendingRouteNotifier.poll()}async sendToChatBinding(e,t){if(!e.bridgeId)return!1;const n=this.service.requireChatBridge(e.bridgeId);if(!n.enabled)return!1;const i=await this.sendViaBridge(n,e.chatSessionId,t).catch(e=>{this.bridgeErrors.set(n.id,e instanceof Error?e.message:String(e))});return Boolean(i)}async sendViaBridge(e,t,n){const i="string"==typeof n?n:n.text,s="string"==typeof n?void 0:n.replyMarkup;return Zy({fetchImpl:this.fetchImpl,bridge:e,dingdingRuntime:this.dingdingBridges.get(e.id),larkRuntime:this.larkBridges.get(e.id)}).send(t,i,{replyMarkup:s})}async pollTelegram(e,t=()=>!0){if(!e.token)return;const n=Number(e.settings?.telegramLastUpdateId),i=this.telegramOffsets.get(e.id)||(Number.isInteger(n)?n:void 0),s=await async function(e){const t=new URLSearchParams({timeout:"0",...e.offset?{offset:String(e.offset+1)}:{}}),n=await e.fetchImpl(`https://api.telegram.org/bot${e.bridge.token}/getUpdates?${t.toString()}`),i=await n.json().catch(()=>({}));if(!n.ok||!1===i.ok){if(409===n.status||/terminated by other getUpdates request/i.test(String(i.description||"")))return{updates:[],conflict:i.description||"Telegram getUpdates conflict: another bot instance is polling this token."};throw new Error(i.description||`Telegram getUpdates failed with HTTP ${n.status}`)}const s=[];for(const t of i.result||[]){const n=Number(t.update_id),i=Number.isInteger(n)?n:void 0,a=Vy(t.callback_query);if(Object.keys(a).length>0){s.push({updateId:i,callbackQuery:a});continue}const o=Vy(t.message||t.edited_message);if(0===Object.keys(o).length)continue;const r=Vy(o.chat),c=Vy(o.from),d=void 0!==r.id?String(r.id):e.bridge.defaultChatId,l=void 0!==c.id?String(c.id):void 0;if(!d)continue;const p=Ky(o.text??o.caption),u=$y(o);(p||0!==u.length)&&s.push({updateId:i,chatId:d,userId:l,text:p,rawText:p,message:o,messageId:Wy(o),replyToMessageId:Wy(Vy(o.reply_to_message)),quoteText:Ky(Vy(o.quote).text),autoBegin:1===u.length&&!p.trim(),hasSingleImageWithoutText:1===u.length&&!p.trim()})}return{updates:s}}({fetchImpl:this.fetchImpl,bridge:e,offset:i});if(t())if(s.conflict)this.bridgeErrors.set(e.id,s.conflict);else for(const n of s.updates){if(!t())return;if(void 0!==n.updateId){const t=`${e.id}:${n.updateId}`;if(this.seenTelegramUpdates.has(t)||n.updateId<=(this.telegramOffsets.get(e.id)||0))continue;this.seenTelegramUpdates.add(t),this.telegramOffsets.set(e.id,n.updateId),this.updateChatBridge(e.id,{settings:{...e.settings,telegramLastUpdateId:n.updateId}})}if("callbackQuery"in n){const t=n.callbackQuery;await this.handleTelegramCallback(e,t).catch(async n=>{const i=Db(t.message),s=Db(i.chat),a=void 0!==s.id?String(s.id):e.defaultChatId;this.bridgeErrors.set(e.id,Cb(n)),a&&await this.sendTelegramMessage(e,a,`Action failed: ${Cb(n)}`).catch(t=>{this.bridgeErrors.set(e.id,Cb(t))})});continue}if(!this.bindOrAllowChatUser(e,n.userId))continue;const i=await Hy({fetchImpl:this.fetchImpl,bridge:e,message:n.message,onImageDownloadError:({fileId:t,fileName:n,error:i})=>{this.logWarn({bridgeId:e.id,fileId:t,fileName:n,error:Cb(i)},"telegram image download skipped")}});if(!t())return;const s=n.rawText.trim();(s||i.length)&&(this.logInfo({bridgeId:e.id,chatId:n.chatId,messageId:n.messageId,replyToMessageId:n.replyToMessageId,hasQuote:Boolean(n.quoteText),textPreview:Ob(s)},"telegram chat gateway message received"),await this.telegramMessageAggregator.handleIncoming(e,n.chatId,n.userId,s,i,{sourceMessageId:n.messageId,replyToMessageId:n.replyToMessageId,quoteText:n.quoteText},{autoBegin:n.autoBegin}))}}async dispatchTelegramGatewayMessage(e,t,n,i,s=[],a={}){try{const o=void 0!==a.replyToMessageId?this.telegramReplyAiSessionTarget(e.id,t,a.replyToMessageId):void 0,r=function(e,t){const n=String(t||"").trim(),i=e.trim();return n?[`引用:${n}`,i].filter(Boolean).join("\n"):i}(i,a.quoteText),c=await this.service.handleChatGatewayMessage({source:{type:"chat-gateway",channel:"telegram",bridgeId:e.id,chatSessionId:t,userId:n},message:{text:r,attachments:s},...o?{target:{instanceId:o.instanceId,aiSessionId:o.sessionId}}:{}}),d=Sb(c),l=Eb(c);if(d){const n=await this.sendTelegramMessage(e,t,d,{replyMarkup:l,replyToMessageId:a.sourceMessageId});this.logInfo({bridgeId:e.id,chatId:t,sourceMessageId:a.sourceMessageId,replyToMessageId:a.replyToMessageId,replyTargetInstanceId:o?.instanceId,replyTargetSessionId:o?.sessionId,sentMessageId:Number(Db(n).message_id)||void 0,routed:!0===Db(c).routed,replyPreview:Ob(d)},"telegram chat gateway reply sent"),await this.rememberTelegramProgressMessage(c,e,t,n,d)}}catch(n){this.bridgeErrors.set(e.id,Cb(n)),await this.sendTelegramMessage(e,t,`Failed to handle message: ${Cb(n)}`,{replyToMessageId:a.sourceMessageId}).catch(t=>{this.bridgeErrors.set(e.id,Cb(t))})}}async handleTelegramCallback(e,t){const n=Nb(t.data),i=Db(t.from),s=Db(t.message),a=Db(s.chat),o=void 0!==a.id?String(a.id):e.defaultChatId,r=void 0!==i.id?String(i.id):void 0;if(!o||!this.bindOrAllowChatUser(e,r))return;if(await this.telegramAiSessionCallbacks.tryHandle(n,{bridge:e,chatId:o,callbackQueryId:Nb(t.id),userId:r,messageId:Tb(s)}))return;const c=n.match(/^task_handoff:cp_msg_end:([^:]+)$/);if(c)return void await this.telegramMessageAggregator.handleEndCallback(e,o,Nb(t.id),c[1],r);let d;try{d=await this.parseChatGatewayCallbackAction(n)}catch(n){if(Rb(n,"CHAT_PENDING_ACTION_STALE")){await this.answerTelegramCallback(e,Nb(t.id),Cb(n));const i=Tb(s);return void(void 0!==i&&await this.deleteTelegramStandaloneApprovalMessage(e,o,i))}throw n}if(!d)return void await this.answerTelegramCallback(e,Nb(t.id),"Unsupported action");const l=await this.service.handleChatGatewayAction({source:{channel:"telegram",bridgeId:e.id,chatSessionId:o,userId:r},action:d});if("pending-decision"===d.type&&Ab(l)){await this.answerTelegramCallback(e,Nb(t.id),"");const n=Tb(s);return void(void 0!==n&&await this.deleteTelegramStandaloneApprovalMessage(e,o,n))}await this.answerTelegramCallback(e,Nb(t.id),Nb(l.message)||"updated");const p=Sb(l),u=Eb(l),m=s.message_id;p&&"number"==typeof m?await this.editTelegramMessage(e,o,m,p,{replyMarkup:u}):p&&await this.sendTelegramMessage(e,o,p,{replyMarkup:u})}async deleteTelegramStandaloneApprovalMessage(e,t,n){[...this.telegramProgress.entries.values()].find(i=>i.messageId===n&&i.route?.bridgeId===e.id&&i.route?.chatId===t)||await this.deleteTelegramMessage(e,t,n).catch(i=>{this.logWarn({bridgeId:e.id,chatId:t,messageId:n,error:Cb(i)},"telegram callback message delete failed")})}chatAiSessionBindingActive(e,t,n,i){return this.service.listChatSessions().some(s=>s.bridgeId===e.id&&s.chatSessionId===t&&s.activeInstanceId===n&&s.activeAiSessionId===i)}telegramAiSessionActionAllowed(e,t,n,i,s){if(this.chatAiSessionBindingActive(e,t,n,i))return!0;if(!Number.isInteger(s))return!1;const a=this.telegramReplyAiSessionTarget(e.id,t,s);return Boolean(a&&a.instanceId===n&&a.sessionId===i)}async parseChatGatewayCallbackAction(e){const t=function(e){const t=e.match(/^task_handoff:cp_p:v1:([ads]):([A-Za-z0-9_-]{16})$/);if(!t)return;const n=Object.entries(tf).find(([,e])=>e===t[1])?.[0];return"allow"===n||"deny"===n||"skip"===n?{routeFingerprint:t[2],decision:n}:void 0}(e);if(t){const e=(await this.service.listPendingRoutes()).filter(e=>"approval"===e.kind&&"pending"===e.status&&nf(e.id)===t.routeFingerprint);if(1!==e.length){const e=new Error("This approval is no longer pending.");throw Object.assign(e,{statusCode:409,code:"CHAT_PENDING_ACTION_STALE"}),e}return{type:"pending-decision",routeId:e[0].id,decision:t.decision}}return function(e,t){const n=e.match(/^task_handoff:cp_session:(\d+)$/);if(n)return{type:"ai-session",index:Number(n[1])};const i=e.match(/^task_handoff:cp_i:([^:]+)$/)||e.match(/^task_handoff:cp_instance_apps:([^:]+)$/);if(i)return i[0].startsWith("task_handoff:cp_i:")?{type:"instance-app-menu",instanceId:iy(t(i[1],"instance-app-menu").instanceId,"instanceId")}:{type:"instance-app-menu",instanceId:oy(i[1])};const s=e.match(/^task_handoff:cp_a:([^:]+)$/)||e.match(/^task_handoff:cp_launch_app:([^:]+):([^:]+)$/);if(s){if(s[0].startsWith("task_handoff:cp_a:")){const e=t(s[1],"launch-app");return{type:"launch-app",instanceId:iy(e.instanceId,"instanceId"),appId:iy(e.appId,"appId")}}return{type:"launch-app",instanceId:oy(s[1]),appId:oy(s[2])}}const a=e.match(/^task_handoff:cp_p:([^:]+)$/);if(a){const e=t(a[1],"pending-decision");return{type:"pending-decision",routeId:iy(e.routeId,"routeId"),decision:sy(e.decision)}}const o=e.match(/^task_handoff:approval:([^:]+:ai:[^:]+):(allow|deny|skip)$/);return o?{type:"pending-decision",routeId:o[1],decision:o[2]}:void 0}(e,(e,t)=>this.service.resolveChatActionToken(e,t))}bindOrAllowChatUser(e,t){const n=String(t||"").trim();return!!n&&(0===e.allowedUserIds.length?(e.allowedUserIds=[n],this.updateChatBridge(e.id,{allowedUserIds:e.allowedUserIds}),this.logInfo({bridgeId:e.id,channel:e.channel,userId:n},"chat user bound"),!0):e.allowedUserIds.includes(n))}async answerTelegramCallback(e,t,n){return async function(e,t,n,i){t.token&&n&&await e(`https://api.telegram.org/bot${t.token}/answerCallbackQuery`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({callback_query_id:n,text:i.slice(0,200)})})}(this.fetchImpl,e,t,n)}async editTelegramMessage(e,t,n,i,s={}){return async function(e,t,n,i,s,a={}){if(t.token)return ty(n=>e(`https://api.telegram.org/bot${t.token}/editMessageText`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(n)}),"editMessageText",s,{chat_id:n,message_id:i,...a.replyMarkup?{reply_markup:a.replyMarkup}:{}},a)}(this.fetchImpl,e,t,n,i,s)}async sendTelegramMessage(e,t,n,i={}){return Zf(this.fetchImpl,e,t,n,i)}async deleteTelegramMessage(e,t,n){return async function(e,t,n,i){if(!t.token||!Number.isInteger(i))return;const s=await e(`https://api.telegram.org/bot${t.token}/deleteMessage`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({chat_id:n,message_id:i})}),a=await s.json().catch(()=>({}));if(!s.ok||!1===a.ok)throw new Error(a.description||`Telegram deleteMessage failed with HTTP ${s.status}`)}(this.fetchImpl,e,t,n)}async rememberTelegramProgressMessage(e,t,n,i,s){if(!0!==e.routed)return;const a=qb(e),{instanceId:o,sessionId:r,turnId:c}=a,d=Number(Db(i).message_id);if(!(o&&r&&c&&Number.isInteger(d)))return void this.logWarn({bridgeId:t.id,chatId:n,instanceId:o,sessionId:r,turnId:c,turnIdSources:a.sources,messageId:Number.isInteger(d)?d:void 0,routed:e.routed},"telegram ai session progress message not remembered");const l=Gb(o,r,c,t.id,n),p=this.telegramProgress.remember(l,d,s,{bridgeId:t.id,chatId:n});this.telegramProgressMessageTargets.set(zb(t.id,n,d),{instanceId:o,sessionId:r,turnId:c,messageId:d}),this.deliveredAiSessionFingerprints.delete(l),this.logInfo({bridgeId:t.id,chatId:n,instanceId:o,sessionId:r,turnId:c,turnIdSources:a.sources,key:l,messageId:d,progressKeys:this.telegramProgressKeysFor(o,r,t.id,n),textPreview:Ob(s)},"telegram ai session progress message remembered"),"queue"===function(e){return e.aiSession&&"action"in e.aiSession?e.aiSession.action:void 0}(e)&&p?.messageId&&p.messageId!==d&&(this.telegramProgressMessageTargets.delete(zb(t.id,n,p.messageId)),await this.deleteTelegramMessage(t,n,p.messageId).catch(e=>{this.logWarn({bridgeId:t.id,chatId:n,instanceId:o,sessionId:r,turnId:c,replacedMessageId:p.messageId,replacementMessageId:d,error:Cb(e)},"telegram queued progress message replacement cleanup failed")}))}telegramReplyAiSessionTarget(e,t,n){const i=this.telegramProgressMessageTargets.get(zb(e,t,n));if(i)return i;for(const[i,s]of this.telegramProgress.entries)if(s.messageId===n&&s.route?.bridgeId===e&&s.route?.chatId===t){const s=kb(i,e,t);if(s){const i={...s,messageId:n};return this.telegramProgressMessageTargets.set(zb(e,t,n),i),i}}}async pollAiSessionUpdates(){this.logAiSessionDelivery({stage:"poll-tick"});const e=await this.service.listAiSessions({refresh:!0}).catch(()=>{});if(!e)return void this.logAiSessionDelivery({stage:"poll-no-snapshot"});const t=new Map(e.instances.map(e=>[e.instanceId,e.aiSessions]));this.logAiSessionDelivery({stage:"poll-snapshot",instanceCount:t.size,instances:[...t.entries()].map(([e,t])=>({instanceId:e,sessionCount:t.sessions?.length||0,runningCount:t.runningCount,waitingCount:t.waitingCount,updatedAt:t.updatedAt}))});const n=await this.aiSessionInstanceNames();for(const[e,i]of t)await this.deliverAiSessionSnapshot(e,i,n)}async deliverAiSessionSnapshot(e,t,n){const i=Array.isArray(t.sessions)?t.sessions:[];if(this.pruneAiSessionDeliveryState(e,new Set(i.map(e=>e.id))),0===i.length)return;const s=n||await this.aiSessionInstanceNames(),a=await this.aiSessionPendingApprovalRoutes(e);await this.deliverOwnedTelegramProgress(e,i,s,a),await this.deliverActiveBindingTelegramProgress(e,i,s,a)}pruneAiSessionDeliveryState(e,t){for(const[n,i]of this.telegramProgress.entries){const s=i.route?.bridgeId&&i.route.chatId?this.telegramProgressMessageTargets.get(zb(i.route.bridgeId,i.route.chatId,i.messageId||0))||kb(n,i.route.bridgeId,i.route.chatId):void 0;s&&s.instanceId===e&&!t.has(s.sessionId)&&(i.timer&&clearTimeout(i.timer),this.telegramProgress.entries.delete(n),this.deliveredAiSessionFingerprints.delete(n),i.route?.bridgeId&&i.route.chatId&&i.messageId&&this.telegramProgressMessageTargets.delete(zb(i.route.bridgeId,i.route.chatId,i.messageId)))}}async deliverActiveBindingTelegramProgress(e,t,n,i){for(const s of this.service.listChatSessions()){if(!s.bridgeId||s.activeInstanceId!==e||!s.activeAiSessionId)continue;const a=t.find(e=>e.id===s.activeAiSessionId);if(!a)continue;const o=Xb(n.get(e)||e,a),r=Yb(a,o);if(!r){this.logAiSessionDelivery({stage:"skip-empty-text",instanceId:e,sessionId:a.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,status:a.status,phase:a.phase,activeTurnId:a.activeTurnId,latestTurn:Pb(Qb(a))});continue}const c=Wb(a);if(!c){this.logAiSessionDelivery({stage:"skip-empty-turn-id",instanceId:e,sessionId:a.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,status:a.status,phase:a.phase,activeTurnId:a.activeTurnId,latestTurn:Pb(Qb(a))});continue}if(this.listTelegramOwnedProgressEntries(e).some(e=>e.route.bridgeId===s.bridgeId&&e.route.chatId===s.chatSessionId&&e.owner.sessionId===a.id&&e.owner.turnId===c))continue;const d=Gb(e,a.id,c,s.bridgeId||"",s.chatSessionId),l=Vb(a,o);if(!l||this.deliveredAiSessionFingerprints.get(d)===l){this.logAiSessionDelivery({stage:"skip-duplicate-fingerprint",instanceId:e,sessionId:a.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:c,key:d,hasFingerprint:Boolean(l),fingerprintMatched:this.deliveredAiSessionFingerprints.get(d)===l,latestTurn:Pb(Qb(a)),textPreview:Ob(r)});continue}const p=Bb({cancelCallbackData:this.telegramAiSessionCallbacks.cancelCallbackData(e,a.id),queueSteerCallbackData:t=>this.telegramAiSessionCallbacks.queueSteerCallbackData(e,a.id,t),queueDeleteMenuCallbackData:()=>this.telegramAiSessionCallbacks.queueDeleteMenuCallbackData(e,a.id),permissionCallbackData:(e,t)=>this.service.pendingDecisionCallbackData(e,t),pendingApproval:i.get(a.id)||Fb(e,a),session:a});if(this.logAiSessionDelivery({stage:"attempt",instanceId:e,sessionId:a.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:c,key:d,relatedProgressKeys:this.telegramProgressKeysFor(e,a.id,s.bridgeId||"",s.chatSessionId),hasProgressEntry:this.telegramProgress.entries.has(d),status:a.status,phase:a.phase,activeTurnId:a.activeTurnId,latestTurn:Pb(Qb(a)),textPreview:Ob(r)}),await this.updateChatAiSessionProgress(s,r,d,p).catch(t=>(this.bridgeErrors.set(s.bridgeId||"",t instanceof Error?t.message:String(t)),this.logWarn({bridgeId:s.bridgeId,chatId:s.chatSessionId,instanceId:e,sessionId:a.id,turnId:c,key:d,error:Cb(t)},"chat ai session progress update failed"),!1)))this.logAiSessionDelivery({stage:"delivered",instanceId:e,sessionId:a.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:c,key:d,textPreview:Ob(r)}),this.deliveredAiSessionFingerprints.set(d,l);else{if("telegram"===this.service.requireChatBridge(s.bridgeId).channel){const t=this.telegramProgress.entries.get(d),n=this.service.requireChatBridge(s.bridgeId);this.logAiSessionDelivery({stage:t?"telegram-update-not-delivered":"telegram-no-progress-entry",instanceId:e,sessionId:a.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:c,key:d,relatedProgressKeys:this.telegramProgressKeysFor(e,a.id,s.bridgeId||"",s.chatSessionId),bridgeEnabled:n.enabled,bridgeChannel:n.channel,progressMessageId:t?.messageId,progressLastText:Ob(t?.lastText),progressHasPending:Boolean(t?.pending),latestTurn:Pb(Qb(a)),textPreview:Ob(r)});continue}await this.sendToChatBinding(s,{text:r}).catch(e=>(this.bridgeErrors.set(s.bridgeId||"",e instanceof Error?e.message:String(e)),!1))&&(this.logAiSessionDelivery({stage:"fallback-sent",instanceId:e,sessionId:a.id,bridgeId:s.bridgeId,chatId:s.chatSessionId,turnId:c,key:d,textPreview:Ob(r)}),this.deliveredAiSessionFingerprints.set(d,l))}}}async deliverOwnedTelegramProgress(e,t,n,i){for(const s of this.listTelegramOwnedProgressEntries(e)){const a=this.service.requireChatBridge(s.route.bridgeId);if("telegram"!==a.channel||!a.enabled)continue;const o=this.matchTelegramOwnedProgressSession(s,t);if(!o)continue;const r={bridgeId:s.route.bridgeId,chatSessionId:s.route.chatId},c=Xb(n.get(e)||e,o),d=Yb(o,c),l=Wb(o);if(!d||!l){this.logAiSessionDelivery({stage:"remembered-skip-turn-or-text",key:s.key,parsedTurnId:s.owner.turnId,currentTurnId:l,hasText:Boolean(d),instanceId:e,sessionId:o.id,bridgeId:s.route.bridgeId,chatId:s.route.chatId});continue}if(s.owner.turnId&&l!==s.owner.turnId){this.logAiSessionDelivery({stage:"remembered-skip-different-active-turn",key:s.key,ownerTurnId:s.owner.turnId,currentTurnId:l,instanceId:e,sessionId:o.id,bridgeId:s.route.bridgeId,chatId:s.route.chatId});continue}const p=l===s.owner.turnId?s.key:Gb(e,o.id,l,s.route.bridgeId,s.route.chatId);if(p!==s.key&&this.telegramProgress.entries.has(p))continue;if(p!==s.key&&!this.rekeyTelegramOwnedProgress(s,p,{instanceId:e,sessionId:o.id,turnId:l}))continue;const u=Vb(o,c);if(!u||this.deliveredAiSessionFingerprints.get(p)===u){this.logAiSessionDelivery({stage:"remembered-skip-fingerprint",key:s.key,hasFingerprint:Boolean(u),fingerprintMatched:this.deliveredAiSessionFingerprints.get(p)===u,instanceId:e,sessionId:o.id,bridgeId:s.route.bridgeId,chatId:s.route.chatId});continue}const m=Bb({cancelCallbackData:this.telegramAiSessionCallbacks.cancelCallbackData(e,o.id),queueSteerCallbackData:t=>this.telegramAiSessionCallbacks.queueSteerCallbackData(e,o.id,t),queueDeleteMenuCallbackData:()=>this.telegramAiSessionCallbacks.queueDeleteMenuCallbackData(e,o.id),permissionCallbackData:(e,t)=>this.service.pendingDecisionCallbackData(e,t),pendingApproval:i.get(o.id)||Fb(e,o),session:o}),h=await this.updateChatAiSessionProgress(r,d,p,m).catch(e=>(this.bridgeErrors.set(r.bridgeId||"",e instanceof Error?e.message:String(e)),!1));this.logAiSessionDelivery({stage:h?"remembered-delivered":"remembered-not-delivered",key:p,instanceId:e,sessionId:o.id,bridgeId:s.route.bridgeId,chatId:s.route.chatId,textPreview:Ob(d)}),h&&(this.telegramProgressMessageTargets.set(zb(s.route.bridgeId,s.route.chatId,s.messageId),{instanceId:e,sessionId:o.id,turnId:l,messageId:s.messageId}),this.deliveredAiSessionFingerprints.set(p,u))}}rekeyTelegramOwnedProgress(e,t,n){return!!this.telegramProgress.rekey(e.key,t)&&(this.deliveredAiSessionFingerprints.delete(e.key),this.telegramProgressMessageTargets.set(zb(e.route.bridgeId,e.route.chatId,e.messageId),{...n,messageId:e.messageId}),!0)}logAiSessionDelivery(e){this.logInfo(e,"telegram ai session delivery flow")}telegramProgressKeysFor(e,t,n,i){const s=`${e}:${t}:`,a=`:${n}:${i}`;return[...this.telegramProgress.entries.keys()].filter(e=>e.startsWith(s)&&e.endsWith(a))}listTelegramOwnedProgressEntries(e){const t=[];for(const[n,i]of this.telegramProgress.entries){if(!i.route?.bridgeId||!i.route.chatId||!Number.isInteger(i.messageId))continue;const s=this.telegramProgressMessageTargets.get(zb(i.route.bridgeId,i.route.chatId,i.messageId))||kb(n,i.route.bridgeId,i.route.chatId);s&&s.instanceId===e&&t.push({key:n,route:{bridgeId:i.route.bridgeId,chatId:i.route.chatId},messageId:i.messageId,owner:{...s,messageId:i.messageId}})}return t}matchTelegramOwnedProgressSession(e,t){const n=t.find(t=>t.id===e.owner.sessionId);if(n)return n;if(e.owner.turnId){const n=t.find(t=>t.activeTurnId===e.owner.turnId||Qb(t)?.id===e.owner.turnId||Qb(t)?.providerTurnId===e.owner.turnId);if(n)return n}}async updateChatAiSessionProgress(e,t,n,i){if(!e.bridgeId)return this.logAiSessionDelivery({stage:"chat-update-skip-missing-bridge",chatId:e.chatSessionId,key:n}),!1;const s=this.service.requireChatBridge(e.bridgeId);if(!s.enabled)return this.logAiSessionDelivery({stage:"chat-update-skip-bridge-state",bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,bridgeEnabled:s.enabled,bridgeChannel:s.channel}),!1;if("dingding"===s.channel){if(!this.dingdingBridges.get(s.id))return!1;const a=await this.dingdingBridges.applyProgressUpdate({bridge:s,key:n,chatId:e.chatSessionId,text:t,replyMarkup:_b({actionRows:i})});return a&&this.logInfo({bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,textPreview:Ob(t)},"dingding ai session progress updated"),a}if("lark"===s.channel){const a=await this.larkBridges.applyProgressUpdate({bridge:s,key:n,chatId:e.chatSessionId,text:t,replyMarkup:_b({actionRows:i})});return a&&this.logInfo({bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,textPreview:Ob(t)},"lark ai session progress updated"),a}if("telegram"!==s.channel)return!1;const a=this.telegramProgress.entries.get(n);if(!await this.telegramProgress.applyUpdate({bridge:s,key:n,chatId:e.chatSessionId,text:t,actionRows:i})){const t=this.telegramProgress.entries.get(n);return this.logAiSessionDelivery({stage:"telegram-update-returned-false",bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,progressMessageId:a?.messageId||t?.messageId,progressLastText:Ob(a?.lastText||t?.lastText),progressHasPending:Boolean(a?.pending||t?.pending)}),!1}return this.logInfo({bridgeId:e.bridgeId,chatId:e.chatSessionId,key:n,messageId:a?.messageId||this.telegramProgress.entries.get(n)?.messageId,textPreview:Ob(t)},a?"telegram ai session progress edited":"telegram ai session progress sent"),!0}async aiSessionInstanceNames(){return this.aiSessionInstanceNamesCache.get()}async aiSessionPendingApprovalRoutes(e){const t=await this.aiSessionPendingRoutesCache.get();return new Map(t.filter(t=>t.instanceId===e&&t.aiSessionId&&"approval"===t.kind).map(e=>[e.aiSessionId||"",e]))}}function Sb(e){return"object"==typeof e&&e&&"reply"in e?String(e.reply||""):""}function Ab(e){return"object"==typeof e&&null!==e&&!0===e.accepted}function Eb(e){const t="object"==typeof e&&e&&"replyMarkup"in e?e.replyMarkup:void 0;if(t&&"object"==typeof t&&!Array.isArray(t))return t}function _b(e){const t=Array.isArray(e?.actionRows)?e.actionRows:void 0;return lf(t||(Array.isArray(e?.actions)?e.actions:[]).map(e=>[e]))}function Tb(e){const t=Number(e?.message_id);return Number.isInteger(t)?t:void 0}function zb(e,t,n){return[e,t,String(n)].join(":")}function kb(e,t,n){const i=`:${t}:${n}`;if(!e.endsWith(i))return;const s=e.slice(0,-i.length).split(":"),a=s[0]||"",o=s[1]||"",r=s.slice(2).join(":")||void 0;return a&&o?{instanceId:a,sessionId:o,turnId:r}:void 0}function Nb(e){return"string"==typeof e?e:""}function Cb(e){return e instanceof Error?e.message:String(e)}function Rb(e,t){return Boolean(e&&"object"==typeof e&&"code"in e&&e.code===t)}function Ob(e,t=160){const n=String(e||"").replace(/\s+/g," ").trim();return n.length<=t?n:`${n.slice(0,Math.max(0,t-3))}...`}function jb(e){const t=Lb(e.body.cardActionData||e.body.content),n=Lb(t.cardPrivateData||e.body.cardPrivateData||e.body.content);return{outTrackId:Nb(e.body.outTrackId),spaceId:Nb(e.body.spaceId),conversationType:e.conversationType,hasCallbackData:Boolean(e.callbackData),callbackDataPreview:Ob(e.callbackData,120),actionIds:[...Mb(n.actionIdList),...Mb(t.actionIdList),Nb(n.actionId),Nb(t.actionId),Nb(e.body.actionId)].filter(Boolean).slice(0,5),cardActionDataKeys:Object.keys(t).sort(),privateDataKeys:Object.keys(n).sort(),paramKeys:Object.keys(e.params).sort(),hasSessionWebhook:Boolean(e.sessionWebhook)}}function Pb(e){if(e)return{id:e.id,providerTurnId:e.providerTurnId,source:e.source,status:e.status,phase:e.phase,revision:e.revision,userPrompt:Ob(e.userPrompt,80),hasResponse:Boolean(e.lastMessage?.trim()||e.summary?.trim()),responsePreview:Ob(e.lastMessage||e.summary,80),updatedAt:e.updatedAt,observedAt:e.observedAt}}function Db(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function Lb(e){if(e&&"object"==typeof e&&!Array.isArray(e))return e;if("string"==typeof e&&e.trim())try{return Db(JSON.parse(e))}catch{return{}}return{}}function Mb(e){return Array.isArray(e)?e.map(e=>Nb(e)).filter(Boolean):[]}function qb(e){const t=e.aiSession&&"sessionId"in e.aiSession?e.aiSession:void 0,n=e.aiSession&&"id"in e.aiSession?e.aiSession:void 0;return{instanceId:e.instanceId||e.instance?.id||"",sessionId:e.aiSessionId||t?.sessionId||n?.id||e.binding?.activeAiSessionId||"",turnId:e.turnId||e.providerTurnId||t?.turnId||t?.providerTurnId||(n?Wb(n):""),sources:{resultTurnId:e.turnId,resultProviderTurnId:e.providerTurnId,actionTurnId:t?.turnId,actionProviderTurnId:t?.providerTurnId,sessionActiveTurnId:n?.activeTurnId,latestTurnId:n?Qb(n)?.id:void 0}}}const Ub=5,$b=48;function Bb(e){const{cancelCallbackData:t,queueSteerCallbackData:n,queueDeleteMenuCallbackData:i,permissionCallbackData:s,pendingApproval:a,session:o}=e,r="approval"===a?.kind?[[{text:"Allow",callbackData:s(a.id,"allow")},{text:"Skip",callbackData:s(a.id,"skip")},{text:"Deny",callbackData:s(a.id,"deny")}]]:[];if("running"!==o.status)return r;const c=(o.queue?.items||[]).filter(e=>"queued"===e.status).slice(0,Ub);return[...c.map((e,t)=>[{text:Hb(e.message,t),callbackData:n(e.id)}]),c.length?[{text:"Delete Queue",callbackData:i()},{text:"Cancel",callbackData:t}]:[{text:"Cancel",callbackData:t}]]}function Fb(e,t){if("approval"===t.phase)return{id:`${e}:ai:${t.id}`,kind:"approval"}}function Hb(e,t){const n=`${t+1}. `,i=e.replace(/\s+/g," ").trim()||"Queued message",s=Math.max(8,$b-n.length),a=Array.from(i);return`${n}${a.length>s?`${a.slice(0,Math.max(1,s-3)).join("")}...`:i}`}function Gb(e,t,...n){return[e,t,...n].join(":")}function Wb(e){const t=Qb(e);return t?.id?t.id:Nb(e.activeTurnId)}function Vb(e,t=""){const n=Qb(e);return[t,n?.id||"",n?.status||e.status||"",n?.phase||e.phase||"",n?.lastMessage||"",n?.summary||"",n?.userPrompt||"",e.error||"",e.currentTool?.id||"",e.currentTool?.name||"",e.currentTool?.inputPreview||"",String(e.toolCallsSinceLastMessage??0),Kb(e)].join("\0")}function Kb(e){return(e.queue?.items||[]).map(e=>[e.id,e.status,e.message].join(":")).join("|")}function Yb(e,t){const n=function(e,t){let n="";t?"waiting"===t.status&&"approval"===t.phase&&t.summary?.trim()?n=t.summary.trim():t.lastMessage?.trim()?n=t.lastMessage.trim():t.summary?.trim()&&(n=t.summary.trim()):"waiting"===e.status&&"approval"===e.phase&&e.summary?.trim()?n=e.summary.trim():e.lastMessage?.trim()?n=e.lastMessage.trim():e.summary?.trim()?n=e.summary.trim():e.error?.trim()&&(n="failed"===e.status?`${e.agent} session failed:\n${e.error.trim()}`:e.error.trim());const i=function(e){if(e.currentTool?.name)return`Thinking... · ${e.currentTool.name}${e.currentTool.inputPreview?` · ${e.currentTool.inputPreview}`:""}`;const t=e.toolCallsSinceLastMessage??0;return t>0?`Thinking... · ${t} ${1===t?"tool":"tools"} completed`:""}(e);return[n,i&&!Jb(n,e)?i:""].filter(Boolean).join("\n\n")}(e,Qb(e));return n?`${t}\n${n}`:""}function Xb(e,t){const n=["idle"===t.status?"completed":t.status,t.phase&&"unknown"!==t.phase?t.phase:void 0].filter(Boolean).join("/");return`${e} · ${t.agent||"ai"} ${n||"unknown"}`}function Jb(e,t){if("waiting"!==t.status||"approval"!==t.phase)return!1;const n=t.currentTool?.inputPreview?.trim();return Boolean(n&&e.includes(n))}function Qb(e){return(e.turns||[]).filter(e=>e.id||e.userPrompt?.trim()||e.lastMessage?.trim()||e.summary?.trim()).at(-1)}class Zb{clients=new Set;listeners=new Set;transientDemandListeners=new Set;externalTransientDemands=new Map;seq=0;droppedUnscopedNodeEvents=0;lastUnscopedNodeEvent;connect(e,t={}){e.topics=new Set(["*"]),e.instanceIds=t.instanceIds?.length?new Set(t.instanceIds):void 0,e.metricInstanceIds=t.expectsMetricSubscription?new Set:void 0,e.authorization=t.authorization,e.subscriptionReceived=!t.authorization&&!0!==t.expectsTransientSubscription,this.clients.add(e),this.publishTransientDemand();const n=e.ping?setInterval(()=>{if(e.readyState===e.OPEN)try{e.ping?.()}catch{}},2e4):void 0;n?.unref?.(),e.on("close",()=>{n&&clearInterval(n),this.clients.delete(e),this.publishTransientDemand()}),e.on("message",t=>{const n=function(e){try{const t=JSON.parse(String(e||"{}"));if(!t||"object"!=typeof t)return;const n=kd.safeParse(t);if(n.success)return n.data;const i=t;if(void 0!==i.metricInstanceIds&&!Array.isArray(i.metricInstanceIds))return;const s=void 0===i.aiSessionTransient?void 0:Cd.safeParse(i.aiSessionTransient);if(s&&!s.success)return;return{type:i.type,topics:Array.isArray(i.topics)?i.topics.map(String).filter(Boolean):void 0,instanceIds:Array.isArray(i.instanceIds)?i.instanceIds.map(String).map(e=>e.trim()).filter(Boolean):void 0,metricInstanceIds:Array.isArray(i.metricInstanceIds)?i.metricInstanceIds.map(String).map(e=>e.trim()).filter(Boolean):void 0,...s?.success?{aiSessionTransient:s.data}:{},...i.eventEnvelopeVersion===zd?{eventEnvelopeVersion:zd}:{}}}catch{return}}(t);"ping"!==n?.type?"subscribe"===n?.type&&(e.topics=new Set(void 0===n.topics?["*"]:n.topics),e.instanceIds=function(e,t){const n=e.authorization?.allowedInstanceIds;if(!n)return t?.length?new Set(t):void 0;const i=t?.length?t.filter(e=>n.has(e)):[...n];return new Set(i)}(e,n.instanceIds),e.metricInstanceIds=function(e,t){if(void 0===t)return;const n=e.authorization?.allowedInstanceIds;return new Set(n?t.filter(e=>n.has(e)):t)}(e,n.metricInstanceIds),e.aiSessionTransient=function(e,t){const n=e.authorization?.allowedInstanceIds;return n?t?{...t,messageDeltas:{allInstances:!1,instanceIds:t.messageDeltas.allInstances?[...n]:t.messageDeltas.instanceIds.filter(e=>n.has(e))},timelineAllSessions:!1,timelineSessions:t.timelineSessions.filter(e=>n.has(e.instanceId))}:{messageDeltas:{allInstances:!1,instanceIds:[...n]},timelineAllSessions:!1,timelineSessions:[]}:t}(e,n.aiSessionTransient),e.eventEnvelopeVersion=n.eventEnvelopeVersion??1,e.subscriptionReceived=!0,this.publishTransientDemand()):e.send(JSON.stringify({v:1,type:"pong",sentAt:n.sentAt,receivedAt:(new Date).toISOString()}))})}publish(e,t,n={}){const i=this.createEvent(e,t,n);!ov.has(i.topic)||i.scope?.nodeId||i.scope?.instanceId||(this.droppedUnscopedNodeEvents+=1,this.lastUnscopedNodeEvent={type:i.type,topic:i.topic,createdAt:i.createdAt});const s=i.topic,a=JSON.stringify(i),o=Buffer.byteLength(a,"utf8");let r;for(const e of this.listeners)try{e(i)}catch{this.listeners.delete(e)}for(const t of this.clients)if(t.readyState===t.OPEN&&rv(t,i)&&tv(t.topics,s,e)&&iv(t.instanceIds,i.scope)&&sv(t,i)&&av(t,i)){const e=t.eventEnvelopeVersion===zd?r??=dv(i):{encoded:a,bytes:o};if((t.bufferedAmount??0)+e.bytes>16777216){this.clients.delete(t);try{t.close?.(1013,"Event consumer is too slow.")}catch{}this.publishTransientDemand();continue}try{t.send(e.encoded)}catch{this.clients.delete(t),this.publishTransientDemand()}}return i}authorizationDiagnostics(){return{droppedUnscopedNodeEvents:this.droppedUnscopedNodeEvents,...this.lastUnscopedNodeEvent?{lastUnscopedNodeEvent:this.lastUnscopedNodeEvent}:{}}}invalidateUserAuthorization(e,t){for(const n of this.clients){const i=n.authorization;if(i&&i.userId===e&&i.authorizationRevision!==t){this.clients.delete(n);try{n.close?.(4001,"Authorization changed. Reconnect for a current snapshot.")}catch{}}}this.publishTransientDemand()}on(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}onAiSessionTransientDemand(e){return this.transientDemandListeners.add(e),e(this.aiSessionTransientDemand()),()=>this.transientDemandListeners.delete(e)}registerAiSessionTransientDemand(e){const t=Symbol("ai-session-transient-demand");return this.externalTransientDemands.set(t,e),this.publishTransientDemand(),()=>{this.externalTransientDemands.delete(t),this.publishTransientDemand()}}registerLegacyAiSessionTransientDemand(e){const t=new Set(e);if(t.has("*")||t.has(In))return this.registerAiSessionTransientDemand();const n=t.has(An),i=t.has(En);return n||i?this.registerAiSessionTransientDemand({messageDeltas:{allInstances:n,instanceIds:[]},timelineAllSessions:i,timelineSessions:[]}):()=>{}}aiSessionTransientDemand(){let e=!1,t=!1,n=!1;const i=new Set,s=new Map;let a;for(const o of this.clients)if(o.subscriptionReceived&&nv(o.topics))if(o.aiSessionTransient){t||=o.aiSessionTransient.messageDeltas.allInstances,n||=o.aiSessionTransient.timelineAllSessions,a=ev(a,o.aiSessionTransient.replaySince);for(const e of o.aiSessionTransient.messageDeltas.instanceIds)i.add(e);for(const e of o.aiSessionTransient.timelineSessions)s.set(JSON.stringify([e.instanceId,e.sessionId]),e)}else e=!0;for(const o of this.externalTransientDemands.values())if(o){t||=o.messageDeltas.allInstances,n||=o.timelineAllSessions,a=ev(a,o.replaySince);for(const e of o.messageDeltas.instanceIds)i.add(e);for(const e of o.timelineSessions)s.set(JSON.stringify([e.instanceId,e.sessionId]),e)}else e=!0;return{legacyAll:e,...a?{replaySince:a}:{},messageDeltas:{allInstances:e||t,instanceIds:[...i]},timelineAllSessions:e||n,timelineSessions:[...s.values()]}}send(e,t,n,i={}){const s=this.createEvent(t,n,i);return e.send(JSON.stringify(s)),s}createEvent(e,t,n={}){return{v:1,id:n.sourceEvent?.id||`evt_${Date.now().toString(36)}_${Math.random().toString(16).slice(2)}`,seq:++this.seq,type:e,topic:n.topic||Nd(e),createdAt:n.sourceEvent?.createdAt||(new Date).toISOString(),payload:t,...n.sourceEvent?.replay?{replay:!0}:{},scope:cv(n.scope,t)}}publishTransientDemand(){const e=this.aiSessionTransientDemand();for(const t of this.transientDemandListeners)try{t(e)}catch{}}}function ev(e,t){return t&&(!e||t<e)?t:e}function tv(e,t,n){return!e||e.has("*")||e.has(t)||e.has(n)}function nv(e){return tv(e,In,An)||tv(e,In,En)}function iv(e,t){return!e||!t?.instanceId||e.has(t.instanceId)}function sv(e,t){return"instance.metrics.snapshot"!==t.type||!e.metricInstanceIds||Boolean(t.scope?.instanceId&&e.metricInstanceIds.has(t.scope.instanceId))}function av(e,t){return"ai-session.message-delta"!==t.type&&"ai-session.timeline-item"!==t.type||!!e.subscriptionReceived&&Rd(e.aiSessionTransient,t)}const ov=new Set(["nodes","node.state","node.runtime","instances","app.sessions","ai.sessions","apps"]);function rv(e,t){const n=e.authorization;return!n||("triggers"!==t.topic||t.scope?.nodeId||t.scope?.instanceId?t.scope?.nodeId?!n.allowedNodeIds||n.allowedNodeIds.has(t.scope.nodeId):t.scope?.instanceId?!n.allowedInstanceIds||n.allowedInstanceIds.has(t.scope.instanceId):!n.allowedNodeIds&&!n.allowedInstanceIds||!ov.has(t.topic):n.permissionIds.includes("triggers:manage"))}function cv(e,t){if(e?.nodeId||e?.instanceId)return e;if(!t||"object"!=typeof t||Array.isArray(t))return e;const n=t,i=n.meta&&"object"==typeof n.meta&&!Array.isArray(n.meta)?n.meta:{},s=n.nodeId??i.nodeId,a=n.instanceId??i.instanceId,o="string"==typeof s&&s.trim()?s.trim():void 0,r="string"==typeof a&&a.trim()?a.trim():void 0;return o||r?{...o?{nodeId:o}:{},...r?{instanceId:r}:{}}:e}function dv(e){const t=e.type===An?fs.safeParse(e.payload):void 0,n=function(e,t,n={}){const i=e.scope?n.publicScope&&e.scope.instanceId?{instanceId:e.scope.instanceId}:e.scope:void 0;return{v:zd,id:e.id,type:e.type,createdAt:e.createdAt,payload:void 0===n.payload?e.payload:n.payload,...e.topic!==Nd(e.type)?{topic:e.topic}:{},...e.replay?{replay:!0}:{},...i&&Object.keys(i).length?{scope:i}:{}}}(e,0,{publicScope:!0,...t?.success?{payload:(i=t.data,ys.parse({sessionId:i.sessionId,turnId:i.turnId,itemId:i.itemId,delta:i.delta,generatedAt:i.generatedAt}))}:{}});var i;const s=JSON.stringify(n);return{encoded:s,bytes:Buffer.byteLength(s,"utf8")}}function lv(e,n="attachment",i={}){const s=i.maxLength??240,a=i.maxBytes??240,o=t.posix.basename(String(e).replace(/\\/g,"/")).replace(/[\u0000-\u001f\u007f<>:"/\\|?*]/g,"_").trim().replace(/[. ]+$/g,""),r=pv(/^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(o)?`_${o}`:o,s,a).replace(/[. ]+$/g,"");return r&&"."!==r&&".."!==r?r:pv(n,s,a)||"attachment"}function pv(e,t,n){if(!Number.isInteger(t)||t<=0||!Number.isInteger(n)||n<=0)return"";let i="",s=0,a=0;for(const o of e){const e=s+o.length,r=a+Buffer.byteLength(o);if(e>t||r>n)break;i+=o,s=e,a=r}return i}const uv={"image/bmp":".bmp","image/gif":".gif","image/jpeg":".jpg","image/png":".png","image/webp":".webp"},mv=f.z.object({instanceId:f.z.string().trim().min(1).max(120),sessionId:f.z.string().trim().min(1).max(120),kind:f.z.enum(["image","file"]),name:f.z.string().trim().min(1).max(240),mime:f.z.string().trim().min(1).max(120),data:f.z.string().min(1).max(31457280)}).strict();function hv(){return t.join(m.tmpdir(),"task-handoff-ai-session-attachments")}class gv{items=new Map;ttlMs;constructor(e=864e5){this.ttlMs=e,this.pruneOrphanFiles()}upload(e){this.pruneExpired();const s=mv.parse(e),a=function(e,t){const n=/^data:([^;,]+);base64,(.+)$/i.exec(e.trim()),i=n?.[1]||t,s=n?.[2]||e;return{mime:i,buffer:Buffer.from(s,"base64")}}(s.data,s.mime),o=a.mime.toLowerCase(),r=uv[o]||"";if("image"===s.kind&&!r)throw new Error(`Unsupported image type: ${o}`);const c="image"===s.kind?a.buffer.length>hn:a.buffer.length>=gn;if(!a.buffer.length||c)throw new Error("image"===s.kind?"Image must be between 1 byte and 20971520 bytes.":"File must be smaller than 512000 bytes.");const d=`att_${i.randomUUID().replace(/-/g,"").slice(0,24)}`,l=new Date,p=new Date(l.getTime()+this.ttlMs),u=hv();n.mkdirSync(u,{recursive:!0});const m=lv(s.name),h=`${d}-`,g=lv(m.endsWith(r)?m:`${m}${r}`,"attachment",{maxBytes:255-Buffer.byteLength(h)}),f=t.join(u,`${h}${g}`);n.writeFileSync(f,a.buffer);const y={id:d,instanceId:s.instanceId,sessionId:s.sessionId,kind:s.kind,name:m,mime:o,size:a.buffer.length,source:{type:"inline",encoding:"base64",data:a.buffer.toString("base64")},path:f,createdAt:l.toISOString(),expiresAt:p.toISOString()};return this.items.set(d,y),this.publicAttachment(y)}resolveRefs(e,t,n){this.pruneExpired();const i=f.z.array(ri).max(6).default([]).parse(e),s=i.map(e=>"runtime-path"===e.source.type?ai.parse(e):this.requireAttachment(e,t,n));if(s.reduce((e,t)=>e+("inline"===t.source.type?t.size:0),0)>bn)throw new Error("Inline attachments must be 41943040 bytes or less in total.");for(const e of i)"upload-ref"===e.source.type&&this.consumeAttachment(e.id);return s}dispose(){for(const e of[...this.items.keys()])this.consumeAttachment(e)}requireAttachment(e,t,n){const i=this.items.get(e.id);if(!i)throw new Error(`AI session attachment not found or expired: ${e.id}`);if(e.kind&&e.kind!==i.kind)throw new Error(`AI session attachment kind mismatch: ${e.id}`);if(i.instanceId!==t||i.sessionId!==n)throw new Error(`AI session attachment scope mismatch: ${e.id}`);return ai.parse({id:i.id,kind:i.kind,name:i.name,mime:i.mime,size:i.size,source:i.source})}consumeAttachment(e){const t=this.items.get(e);if(t){this.items.delete(e);try{n.unlinkSync(t.path)}catch{}}}publicAttachment(e){return{id:e.id,kind:e.kind,name:e.name,mime:e.mime,size:e.size,expiresAt:e.expiresAt}}pruneExpired(){const e=Date.now();for(const[t,i]of this.items)if(!(Date.parse(i.expiresAt)>e)){this.items.delete(t);try{n.unlinkSync(i.path)}catch{}}this.pruneOrphanFiles()}pruneOrphanFiles(){const e=hv();let i;try{i=n.readdirSync(e)}catch{return}const s=Date.now()-Math.max(this.ttlMs,864e5);for(const a of i){const i=t.join(e,a);try{n.statSync(i).isFile()&&n.statSync(i).mtimeMs<=s&&n.unlinkSync(i)}catch{}}}}const fv=864e5,yv=f.z.object({schemaVersion:f.z.literal(1),cacheId:f.z.string().regex(/^[a-f0-9]{64}$/),instanceId:f.z.string().trim().min(1).max(120),scopeType:f.z.enum(["session","create-request"]),scopeId:f.z.string().trim().min(1).max(160),attachmentId:f.z.string().trim().min(1).max(120),sessionId:f.z.string().trim().min(1).max(120).optional(),messageId:f.z.string().trim().min(1).max(240).optional(),kind:f.z.enum(["image","file"]),name:f.z.string().trim().min(1).max(240),mime:f.z.string().trim().min(1).max(120),disposition:f.z.string().trim().min(1).max(1024).optional(),size:f.z.number().int().positive(),etag:f.z.string().trim().min(1).max(160).optional(),instanceEpoch:f.z.string().trim().min(1).max(240).optional(),cachedAt:f.z.string().datetime(),lastAccessedAt:f.z.string().datetime(),expiresAt:f.z.string().datetime()}).strict();class bv{root;contentDir;manifestDir;maxBytes;now;onWarning;entries=new Map;pendingBindings=new Map;reservedBytes=0;constructor(e,i={}){this.root=t.join(e,"ai-session-attachment-cache"),this.contentDir=t.join(this.root,"content"),this.manifestDir=t.join(this.root,"manifests"),this.maxBytes=i.maxBytes??2147483648,this.now=i.now||Date.now,this.onWarning=i.onWarning,n.mkdirSync(this.contentDir,{recursive:!0,mode:448}),n.mkdirSync(this.manifestDir,{recursive:!0,mode:448}),this.restore(),this.gc()}putFile(e){this.gc();const t=n.statSync(e.sourcePath);if(!t.isFile()||t.size!==e.size||e.size<=0)throw new Error("Attachment cache source size mismatch.");if(this.evictFor(e.size),this.usedBytes()+this.reservedBytes+e.size>this.maxBytes)return;const s=vv(e.instanceId,e.attachmentId),a=this.contentPath(s),o=`${a}.${process.pid}.${i.randomUUID()}.tmp`;n.copyFileSync(e.sourcePath,o,n.constants.COPYFILE_EXCL),n.chmodSync(o,384),n.renameSync(o,a);const r=new Date(this.now()).toISOString(),c=new Date(Math.min(this.now()+fv,e.cacheUntil??Number.POSITIVE_INFINITY)).toISOString(),d=yv.parse({schemaVersion:1,cacheId:s,instanceId:e.instanceId,scopeType:e.scopeType,scopeId:e.scopeId,attachmentId:e.attachmentId,...e.sessionId?{sessionId:e.sessionId}:{},...e.messageId?{messageId:e.messageId}:{},kind:e.kind,name:lv(e.name),mime:e.mime.toLowerCase(),...e.disposition?{disposition:e.disposition}:{},size:e.size,...e.etag?{etag:e.etag}:{},...e.instanceEpoch?{instanceEpoch:e.instanceEpoch}:{},cachedAt:r,lastAccessedAt:r,expiresAt:c});return this.save(d),this.project(d)}beginBestEffortWrite(e){if(this.gc(),this.evictFor(e.size),e.size<=0||this.usedBytes()+this.reservedBytes+e.size>this.maxBytes)return;this.reservedBytes+=e.size;const t=vv(e.instanceId,e.attachmentId),s=this.contentPath(t),a=`${s}.${process.pid}.${i.randomUUID()}.tmp`,o=n.createWriteStream(a,{flags:"wx",mode:384,highWaterMark:1048576});let r=0,c=!1,d=!0;const l=()=>{d&&(d=!1,this.reservedBytes=Math.max(0,this.reservedBytes-e.size))},p=()=>{if(!c){c=!0,l(),o.destroy();try{n.unlinkSync(a)}catch{}}};return o.on("error",p),{offer:t=>!c&&(r+=t.byteLength,!(r>e.size||!o.write(t))||(p(),!1)),finish:async()=>{if(c||r!==e.size)p();else if(await new Promise((e,t)=>{o.once("finish",e),o.once("error",t),o.end()}).catch(()=>{}),!c){l();try{n.renameSync(a,s);const i=new Date(this.now()).toISOString(),o=new Date(Math.min(this.now()+fv,e.cacheUntil??Number.POSITIVE_INFINITY)).toISOString(),r=yv.parse({schemaVersion:1,cacheId:t,instanceId:e.instanceId,scopeType:e.scopeType,scopeId:e.scopeId,attachmentId:e.attachmentId,...e.sessionId?{sessionId:e.sessionId}:{},...e.messageId?{messageId:e.messageId}:{},kind:e.kind,name:lv(e.name),mime:e.mime.toLowerCase(),...e.disposition?{disposition:e.disposition}:{},size:e.size,...e.etag?{etag:e.etag}:{},...e.instanceEpoch?{instanceEpoch:e.instanceEpoch}:{},cachedAt:i,lastAccessedAt:i,expiresAt:o});return this.save(r),this.project(r)}catch{return void p()}}},abort:p}}bind(e){const t=vv(e.instanceId,e.attachmentId),n=this.entries.get(t);if(!n)return this.pendingBindings.set(t,e),!1;if(n.scopeId!==e.scopeId)return!1;const i=new Date(Math.min(Date.parse(n.expiresAt),e.cacheUntil??Number.POSITIVE_INFINITY)).toISOString();return this.save(yv.parse({...n,sessionId:e.sessionId,messageId:e.messageId,expiresAt:i,...e.etag?{etag:e.etag}:{}})),!0}get(e){this.gc();const t=vv(e.instanceId,e.attachmentId),n=this.entries.get(t);if(!n||n.sessionId!==e.sessionId||n.messageId!==e.messageId||n.instanceEpoch&&n.instanceEpoch!==e.instanceEpoch)return;const i=yv.parse({...n,lastAccessedAt:new Date(this.now()).toISOString()});return this.entries.set(t,i),this.project(i)}removeInstance(e){for(const t of[...this.entries.values()])t.instanceId===e&&this.remove(t.cacheId);for(const[t,n]of this.pendingBindings)n.instanceId===e&&this.pendingBindings.delete(t)}gc(){const e=this.now();for(const t of[...this.entries.values()])(Date.parse(t.expiresAt)<=e||!this.validContent(t))&&this.remove(t.cacheId);this.cleanupOrphans()}restore(){let e=[];try{e=n.readdirSync(this.manifestDir)}catch{return}for(const i of e)if(i.endsWith(".json"))try{const e=JSON.parse(n.readFileSync(t.join(this.manifestDir,i),"utf8")),s=Iv(e),a=yv.safeParse(s);if(!a.success)throw new Error("invalid manifest");Object.keys(e).some(e=>!(e in yv.shape))&&this.writeManifest(a.data),this.entries.set(a.data.cacheId,a.data)}catch{this.onWarning?.(`invalid AI session attachment cache manifest ignored: ${i}`)}}evictFor(e){const t=[...this.entries.values()].sort((e,t)=>Date.parse(e.lastAccessedAt)-Date.parse(t.lastAccessedAt));let n=this.usedBytes();for(const i of t){if(n+this.reservedBytes+e<=this.maxBytes)break;n-=i.size,this.remove(i.cacheId)}}save(e){const t=this.pendingBindings.get(e.cacheId),n=t&&t.scopeId===e.scopeId?yv.parse({...e,sessionId:t.sessionId,messageId:t.messageId,expiresAt:new Date(Math.min(Date.parse(e.expiresAt),t.cacheUntil??Number.POSITIVE_INFINITY)).toISOString(),...t.etag?{etag:t.etag}:{}}):e;this.pendingBindings.delete(e.cacheId),this.writeManifest(n),this.entries.set(n.cacheId,n)}writeManifest(e){y.sync(this.manifestPath(e.cacheId),`${JSON.stringify(e,null,2)}\n`,{mode:384})}remove(e){this.entries.delete(e);try{n.unlinkSync(this.manifestPath(e))}catch{}try{n.unlinkSync(this.contentPath(e))}catch{}}cleanupOrphans(){const e=new Set(this.entries.keys());let i=[];try{i=n.readdirSync(this.contentDir)}catch{return}for(const s of i)if(!e.has(s))try{n.unlinkSync(t.join(this.contentDir,s))}catch{}}validContent(e){try{const t=n.statSync(this.contentPath(e.cacheId));return t.isFile()&&t.size===e.size}catch{return!1}}usedBytes(){return[...this.entries.values()].reduce((e,t)=>this.validContent(t)?e+t.size:e,0)}project(e){return{...e,path:this.contentPath(e.cacheId)}}contentPath(e){return t.join(this.contentDir,e)}manifestPath(e){return t.join(this.manifestDir,`${e}.json`)}}function vv(e,t){return i.createHash("sha256").update(`${e}\0${t}`).digest("hex")}function Iv(e){if(!e||"object"!=typeof e||Array.isArray(e))return e;const t=e;return Object.fromEntries(Object.keys(yv.shape).filter(e=>Object.prototype.hasOwnProperty.call(t,e)).map(e=>[e,t[e]]))}const xv={controlPlaneAuthBoundary:"public"},wv={controlPlaneAuthBoundary:"public-ui"},Sv={controlPlaneAuthBoundary:"proxy-binding"},Av={controlPlaneAuthBoundary:"node-tunnel"};function Ev(e,t=Math.random){const n=Math.max(1,Math.floor(e));if(1===n)return 0;if(2===n)return 250;const i=Math.min(6e4,250*2**(n-2));return Math.min(6e4,Math.round(i*(.75+.5*t())))}class _v{retryNumber=0;random;constructor(e=Math.random){this.random=e}get attempts(){return this.retryNumber}next(){return this.retryNumber+=1,{attempt:this.retryNumber,delay:Ev(this.retryNumber,this.random)}}reset(){this.retryNumber=0}}class Tv{backoff;timer;constructor(e=Math.random){this.backoff=new _v(e)}get pending(){return Boolean(this.timer)}get attempts(){return this.backoff.attempts}schedule(e,t={}){if(this.timer)return;const n=this.backoff.next(),i=t.setTimeoutFn||setTimeout;return this.timer=i(()=>{this.timer=void 0,e()},n.delay),n}reset(e=clearTimeout){this.timer&&e(this.timer),this.timer=void 0,this.backoff.reset()}cancel(e=clearTimeout){this.timer&&e(this.timer),this.timer=void 0}}class zv extends Tv{}function kv(e,t){return Number.isFinite(e)&&Number(e)>0?Number(e):t}function Nv(e){if(!e.length)return;const t=[...e].sort((e,t)=>e-t);return t[Math.ceil(.95*t.length)-1]}function Cv(e){return e.unref?.(),e}class Rv{connectTimeoutMs;handshakeTimeoutMs;heartbeatIntervalMs;heartbeatTimeoutMs;heartbeatMissThreshold;stableThresholdMs;now;setTimeoutFn;clearTimeoutFn;ping;onTimeout;onStable;onPhase;connectTimer;handshakeTimer;heartbeatTimer;stableTimer;awaitingPongSince;consecutiveHeartbeatMisses=0;stable=!1;stopped=!1;currentPhase="connecting";lastActivityAt;lastPongAt;pingRttMs;recentPingRttMs=[];constructor(e){this.connectTimeoutMs=kv(e.connectTimeoutMs,1e4),this.handshakeTimeoutMs=kv(e.handshakeTimeoutMs,1e4),this.heartbeatIntervalMs=kv(e.heartbeatIntervalMs,25e3),this.heartbeatTimeoutMs=kv(e.heartbeatTimeoutMs,15e3),this.heartbeatMissThreshold=Math.max(1,Math.floor(kv(e.heartbeatMissThreshold,2))),this.stableThresholdMs=kv(e.stableThresholdMs,6e4),this.now=e.now||Date.now,this.setTimeoutFn=e.setTimeoutFn||setTimeout,this.clearTimeoutFn=e.clearTimeoutFn||clearTimeout,this.ping=e.ping,this.onTimeout=e.onTimeout,this.onStable=e.onStable,this.onPhase=e.onPhase}get phase(){return this.currentPhase}start(){this.stopped=!1,this.setPhase("connecting"),this.clearTimer("connectTimer"),this.connectTimer=Cv(this.setTimeoutFn(()=>this.timeout("connect"),this.connectTimeoutMs))}opened(){this.stopped||(this.clearTimer("connectTimer"),this.setPhase("handshaking"),this.handshakeTimer=Cv(this.setTimeoutFn(()=>this.timeout("handshake"),this.handshakeTimeoutMs)),this.scheduleHeartbeat(this.heartbeatIntervalMs))}healthy(){this.stopped||(this.clearTimer("handshakeTimer"),this.activity(),this.setPhase("healthy"),this.stable||this.stableTimer||(this.stableTimer=Cv(this.setTimeoutFn(()=>{this.stableTimer=void 0,this.stopped||"healthy"!==this.currentPhase||(this.stable=!0,this.onStable?.())},this.stableThresholdMs))))}activity(){this.stopped||(this.lastActivityAt=this.now(),this.awaitingPongSince=void 0,this.consecutiveHeartbeatMisses=0,"handshaking"!==this.currentPhase&&"healthy"!==this.currentPhase||this.scheduleHeartbeat(this.heartbeatIntervalMs))}pong(){if(this.stopped)return;const e=this.now();void 0!==this.awaitingPongSince&&(this.pingRttMs=Math.max(0,e-this.awaitingPongSince),this.recentPingRttMs.push(this.pingRttMs),this.recentPingRttMs.length>20&&this.recentPingRttMs.shift()),this.awaitingPongSince=void 0,this.consecutiveHeartbeatMisses=0,this.lastPongAt=e,this.lastActivityAt=e,this.scheduleHeartbeat(this.heartbeatIntervalMs)}close(){this.stopped||(this.stopped=!0,this.clearTimers(),this.awaitingPongSince=void 0,this.setPhase("closed"))}diagnostics(){return{phase:this.currentPhase,stable:this.stable,...void 0===this.pingRttMs?{}:{pingRttMs:this.pingRttMs},...this.recentPingRttMs.length?{pingRttP95Ms:Nv(this.recentPingRttMs)}:{},...void 0===this.lastActivityAt?{}:{lastActivityAt:new Date(this.lastActivityAt).toISOString()},...void 0===this.lastPongAt?{}:{lastPongAt:new Date(this.lastPongAt).toISOString()},...this.consecutiveHeartbeatMisses?{consecutiveHeartbeatMisses:this.consecutiveHeartbeatMisses}:{}}}scheduleHeartbeat(e){this.stopped||(this.clearTimer("heartbeatTimer"),this.heartbeatTimer=Cv(this.setTimeoutFn(()=>{if(this.heartbeatTimer=void 0,!this.stopped){if(void 0!==this.awaitingPongSince){const e=Math.max(0,this.now()-this.awaitingPongSince);return e>=this.heartbeatTimeoutMs?(this.consecutiveHeartbeatMisses+=1,this.awaitingPongSince=void 0,this.consecutiveHeartbeatMisses>=this.heartbeatMissThreshold?void this.timeout("heartbeat"):void this.sendHeartbeatProbe()):void this.scheduleHeartbeat(this.heartbeatTimeoutMs-e)}this.sendHeartbeatProbe()}},e)))}sendHeartbeatProbe(){this.awaitingPongSince=this.now();try{this.ping()}catch{if(this.consecutiveHeartbeatMisses+=1,this.awaitingPongSince=void 0,this.consecutiveHeartbeatMisses>=this.heartbeatMissThreshold)return void this.timeout("heartbeat")}this.scheduleHeartbeat(this.heartbeatTimeoutMs)}timeout(e){this.stopped||(this.clearTimers(),this.setPhase("failed"),this.onTimeout(e))}setPhase(e){this.currentPhase!==e&&(this.currentPhase=e,this.onPhase?.(e))}clearTimers(){this.clearTimer("connectTimer"),this.clearTimer("handshakeTimer"),this.clearTimer("heartbeatTimer"),this.clearTimer("stableTimer")}clearTimer(e){const t=this[e];t&&this.clearTimeoutFn(t),this[e]=void 0}}class Ov{transport;constructor(e){this.transport=e}attachMain(e,t){this.transport.attach(e,t),t.send(JSON.stringify({type:"control-plane.hello",protocolVersion:"2026-08-01",nodeId:e,serverTime:(new Date).toISOString(),capabilities:{reverseTunnel:"request-response",auxiliaryChannels:!0,httpResponseStreaming:!0,lifecycleCommands:!0,instanceApiProxy:!0}})),t.on("message",n=>this.handleMainMessage(e,t,n))}attachAuxiliary(e,t,n){return this.transport.attachAuxiliary(e,t,n)}handleMainMessage(e,t,n){if(!this.transport.isCurrentSocket(e,t))return;let i;try{i=JSON.parse(String(n))}catch{return void t.send(JSON.stringify({type:"control-plane.error",code:"INVALID_JSON"}))}const s=i&&"object"==typeof i?i:{},a=this.transport.handleSocketMessage(e,t,s);if(void 0!==a&&!a){if("node-agent.ping"!==s.type)return"node-agent.identify"===s.type?(t.send(JSON.stringify({type:"control-plane.identified",nodeId:e,serverTime:(new Date).toISOString()})),void this.transport.markHealthy(e,t)):void t.send(JSON.stringify({type:"control-plane.error",code:"UNSUPPORTED_MESSAGE"}));t.send(JSON.stringify({type:"control-plane.pong",nodeId:e,serverTime:(new Date).toISOString()}))}}}const jv={[xn]:ms,[wn]:hs,[Sn]:gs,[An]:fs,[En]:bs,[As]:Ds,[Es]:Ls,[_s]:Ms},Pv=new Set(Object.keys(jv));class Dv{options;validatedScopes=new Map;validatingScopes=new Map;eventQueues=new Map;scopeEpochs=new Map;constructor(e={}){this.options=e}setLogger(e){this.options.logger=e}handle(e,t){const n="string"==typeof t.type?t.type:"";if("node-agent.streams.hello"===n){const n="string"==typeof t.instanceId?t.instanceId:"",i=pl(Pd,t.payload);return n&&i.success&&this.enqueue(e,n,()=>this.options.onStreamsHello?.(n,i.data)),!0}if(!n.startsWith("node-agent.event."))return!1;const i=Lv(t.event),s="string"==typeof i?.type?i.type:"";if(!s)return!0;const a="payload"in i?i.payload:{},o=Lv(i.scope)||{},r="string"==typeof t.instanceId?t.instanceId:void 0,c=function(...e){return e.find(e=>"string"==typeof e)}(o.instanceId,i.instanceId,r);if("instance.metrics.snapshot"===s){const t=pl(Lc,a);return!t.success||t.data.instanceId!==c||(this.enqueue(e,t.data.instanceId,()=>{this.options.events?.publish(s,t.data,{topic:"instances",scope:{...o,nodeId:e,instanceId:t.data.instanceId}})}),!0)}if(s===ud){const t=pl(md,a);return!t.success||t.data.instanceId!==c||(this.enqueue(e,t.data.instanceId,()=>{this.options.events?.publish(s,t.data,{topic:"instances",scope:{...o,nodeId:e,instanceId:t.data.instanceId}})}),!0)}if(s===Sc||s===Ac){const t=pl(s===Sc?_c:Tc,a);return!t.success||t.data.instanceId!==c||(this.enqueue(e,t.data.instanceId,()=>{this.options.events?.publish(s,t.data,{topic:"instances",scope:{...o,nodeId:e,instanceId:t.data.instanceId}})}),!0)}if(Pv.has(s)){const t=function(e,t,n){const i=jv[e];if(!i)return;let s=t;if(e===An&&n)try{s=function(e,t){const n=ys.safeParse(e);return n.success?fs.parse({instanceId:t,...n.data}):fs.parse(e)}(t,n)}catch{return}const a=pl(i,s);if(!a.success)return;const o=a.data;return{instanceId:"meta"in o?o.meta.instanceId:o.instanceId,payload:o}}(s,a,c);if(!t)return this.options.logger?.warn?.({nodeId:e,eventType:s,reason:"invalid-payload"},"session-event.transport.rejected"),!0;const n=function(e,t,n,i){const s=Lv(i)||{},a=Lv(s.meta)||{};return{nodeId:e,instanceId:n,eventType:t,traceId:"string"==typeof a.traceId?a.traceId:void 0,streamId:"string"==typeof a.streamId?a.streamId:void 0,revision:"number"==typeof a.revision?a.revision:void 0}}(e,s,t.instanceId,t.payload),d=[o.instanceId,i.instanceId,r].filter(e=>"string"==typeof e&&Boolean(e));return d.some(e=>e!==t.instanceId)?(this.options.logger?.warn?.({...n,claimedInstanceIds:d,reason:"instance-claim-mismatch"},"session-event.transport.rejected"),!0):(this.enqueue(e,t.instanceId,()=>{const a={...o,nodeId:e,instanceId:t.instanceId},r={v:1,id:"string"==typeof i.id?i.id:`forwarded_${Date.now().toString(36)}`,seq:"number"==typeof i.seq?i.seq:0,type:s,topic:"string"==typeof i.topic?i.topic:s.startsWith("app-session.")?"app.sessions":"ai.sessions",createdAt:"string"==typeof i.createdAt?i.createdAt:(new Date).toISOString(),payload:t.payload,...!0===i.replay?{replay:!0}:{},scope:a};!this.options.onSessionEvent||this.options.onSessionEvent(r)?this.options.events?.publish(s,t.payload,{topic:r.topic,scope:a,sourceEvent:{id:r.id,createdAt:r.createdAt,replay:r.replay}}):this.options.logger?.warn?.({...n,reason:"aggregator-rejected"},"session-event.transport.rejected")},n),!0)}const d=()=>{this.options.events?.publish(s,a,{topic:"string"==typeof i.topic?i.topic:void 0,scope:{...o,nodeId:e,...c?{instanceId:c}:{}}})};return c?this.enqueue(e,c,d):d(),!0}invalidate(e={}){const t=new Set;for(const[n,i]of this.validatedScopes)e.nodeId&&i.nodeId!==e.nodeId||e.instanceId&&i.instanceId!==e.instanceId||t.add(n);for(const n of new Set([...this.validatingScopes.keys(),...this.eventQueues.keys()])){const[i,s]=qv(n);e.nodeId&&i!==e.nodeId||e.instanceId&&s!==e.instanceId||t.add(n)}for(const e of t)this.scopeEpochs.delete(e),this.validatedScopes.delete(e),this.validatingScopes.delete(e),this.eventQueues.delete(e)}diagnostics(){return{validatedScopes:this.validatedScopes.size,validatingScopes:this.validatingScopes.size,queuedScopes:this.eventQueues.size,scopeEpochs:this.scopeEpochs.size}}enqueue(e,t,n,i){const s=Mv(e,t),a=this.scopeEpoch(s),o=(this.eventQueues.get(s)||Promise.resolve()).catch(()=>{}).then(async()=>{this.scopeEpochs.get(s)===a&&(await this.isScopeValid(e,t,a)&&this.scopeEpochs.get(s)===a?await n():i&&this.options.logger?.warn?.({...i,reason:"instance-scope-invalid"},"session-event.transport.rejected"))});this.eventQueues.set(s,o);const r=()=>{this.eventQueues.get(s)===o&&this.eventQueues.delete(s),this.scopeEpochs.get(s)!==a||this.eventQueues.has(s)||this.validatingScopes.has(s)||this.scopeEpochs.delete(s)};o.then(r,r)}async isScopeValid(e,t,n){const i=Mv(e,t);if((this.validatedScopes.get(i)?.expiresAt||0)>Date.now())return!0;const s=this.validatingScopes.get(i);if(s)return s;const a=Promise.resolve(this.options.validateInstanceScope?.(e,t)).then(Boolean).catch(()=>!1).then(s=>(s&&this.scopeEpochs.get(i)===n&&this.validatedScopes.set(i,{nodeId:e,instanceId:t,expiresAt:Date.now()+(this.options.scopeTtlMs??3e4)}),s));return this.validatingScopes.set(i,a),a.finally(()=>{this.validatingScopes.get(i)===a&&this.validatingScopes.delete(i)})}scopeEpoch(e){const t=this.scopeEpochs.get(e);if(t)return t;const n={};return this.scopeEpochs.set(e,n),n}}function Lv(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:void 0}function Mv(e,t){return JSON.stringify([e,t])}function qv(e){const t=JSON.parse(e);return Array.isArray(t)&&2===t.length?[String(t[0]),String(t[1])]:["",""]}const Uv=f.z.object({nodeId:f.z.string().trim().min(1).max(120)}).strict();class $v{OPEN=1;readyState=this.OPEN;listeners=new Map;pingUpstream;sendToUpstream;on(e,t){const n=this.listeners.get(e)||new Set;n.add(t),this.listeners.set(e,n)}send(e){this.readyState===this.OPEN&&this.emit("message",e,!1)}sendUpstream(e){if(this.readyState===this.OPEN)try{this.sendToUpstream?.(e)}catch{this.close(1011,"Node event subscription delivery failed.")}}ping(){this.readyState===this.OPEN&&this.pingUpstream?.()}control(e,t,n){this.pingUpstream=e,this.sendToUpstream=n,t?.(()=>this.emit("pong"))}opened(){this.readyState===this.OPEN&&this.emit("open")}terminate(){this.close(1006)}close(e=1e3,t=""){this.readyState===this.OPEN&&(this.readyState=3,this.emit("close",e,Buffer.from(t)))}emit(e,...t){for(const n of this.listeners.get(e)||[])n(...t)}}function Bv(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:void 0}function Fv(...e){return e.find(e=>"string"==typeof e&&Boolean(e))}function Hv(){return`req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}const Gv=new Map;function Wv(e,t){if("paired-hmac"!==e.auth.mode||!e.auth.keyId||!e.auth.secret){const e=new Error("Reverse tunnel requires paired-HMAC node auth.");throw Object.assign(e,{statusCode:401,code:"NODE_AGENT_TUNNEL_REQUIRES_PAIRED_HMAC"}),e}const n=function(e){const t=new Map;for(const[n,i]of Object.entries(e)){const e=Array.isArray(i)?i.join(","):"string"==typeof i?i:void 0===i?"":String(i);t.set(n.toLowerCase(),e)}return{nodeId:t.get("x-taskhandoff-node-id")||"",keyId:t.get("x-taskhandoff-key-id")||"",timestamp:t.get("x-taskhandoff-timestamp")||"",nonce:t.get("x-taskhandoff-nonce")||"",bodySha256:t.get("x-taskhandoff-body-sha256")||"",signature:t.get("x-taskhandoff-signature")||""}}(t.headers);if(n.nodeId!==e.id)throw Object.assign(new Error("Invalid reverse tunnel node id."),{statusCode:401,code:"NODE_AGENT_TUNNEL_NODE_MISMATCH"});if(n.keyId!==e.auth.keyId)throw Object.assign(new Error("Invalid reverse tunnel key id."),{statusCode:401,code:"NODE_AGENT_TUNNEL_KEY_INVALID"});const s=Date.parse(n.timestamp);if(!Number.isFinite(s)||Math.abs(Date.now()-s)>Am)throw Object.assign(new Error("Reverse tunnel timestamp is outside the allowed window."),{statusCode:401,code:"NODE_AGENT_TUNNEL_TIMESTAMP_INVALID"});const a=Date.now()-Am;for(const[e,t]of Gv)t<=a&&Gv.delete(e);const o=`${e.id}:${n.keyId}:${n.nonce}`;if(!n.nonce||Gv.has(o))throw Object.assign(new Error("Reverse tunnel nonce is invalid."),{statusCode:401,code:"NODE_AGENT_TUNNEL_NONCE_INVALID"});const r=Tm("");if(n.bodySha256!==r)throw Object.assign(new Error("Reverse tunnel body hash is invalid."),{statusCode:401,code:"NODE_AGENT_TUNNEL_BODY_HASH_INVALID"});const c=t.url||`${Em}?nodeId=${encodeURIComponent(e.id)}`,d=zm(e.auth.secret,{keyId:n.keyId,method:"GET",pathWithQuery:c,timestamp:n.timestamp,nonce:n.nonce,bodySha256:r});if(!function(e,t){const n=Buffer.from(e,"hex"),s=Buffer.from(t,"hex");return n.length===s.length&&i.timingSafeEqual(n,s)}(n.signature,d))throw Object.assign(new Error("Reverse tunnel signature is invalid."),{statusCode:401,code:"NODE_AGENT_TUNNEL_SIGNATURE_INVALID"});Gv.set(o,Date.now()+Am)}function Vv(e){return e?e instanceof Headers?Object.fromEntries(e.entries()):Array.isArray(e)?Object.fromEntries(e.map(([e,t])=>[e,t])):Object.fromEntries(Object.entries(e).map(([e,t])=>[e,String(t)])):{}}class Kv{sockets=new Map;eventSubscriptions=new Map;eventRouter;httpStreamHeaderTimeoutMs;requestTimeoutMs;auxiliaryAttachTimeoutMs;connectionRuntime;connectionOptions;constructor(e,t={}){this.eventRouter=new Dv({events:e,onStreamsHello:t.onStreamsHello,onSessionEvent:t.onSessionEvent,validateInstanceScope:t.validateInstanceScope}),this.httpStreamHeaderTimeoutMs=t.httpStreamHeaderTimeoutMs??3e4,this.requestTimeoutMs=t.requestTimeoutMs??3e4,this.auxiliaryAttachTimeoutMs=t.auxiliaryAttachTimeoutMs??3e4,this.connectionRuntime=t.connectionRuntime,this.connectionOptions=t}attach(e,t){const n=this.sockets.get(e);if(n?.socket===t)return;n&&this.invalidateInstanceScope({nodeId:e});const i=new Map,s={socket:t,runtimeGeneration:this.connectionRuntime?.begin(e,"reverse-wss","handshaking"),pending:i,streams:new Map,httpStreams:new Map,pendingChannels:new Map},a=new Rv({...this.connectionOptions,ping:()=>t.ping?.(),onTimeout:n=>{this.sockets.get(e)===s&&(s.failureReason=`Reverse tunnel ${n} timeout.`,void 0!==s.runtimeGeneration&&this.connectionRuntime?.update(e,s.runtimeGeneration,{phase:"suspect",error:s.failureReason}),t.terminate?t.terminate():t.close?.(1011,`Reverse tunnel ${n} timeout.`))},onStable:()=>{void 0!==s.runtimeGeneration&&this.connectionRuntime?.stable(e,s.runtimeGeneration)}});s.supervisor=a,this.sockets.set(e,s),a.start(),a.opened(),t.on?.("pong",()=>{this.sockets.get(e)===s&&(a.pong(),void 0!==s.runtimeGeneration&&this.connectionRuntime?.pong(e,s.runtimeGeneration,a.diagnostics()))}),t.on?.("close",()=>this.detach(e,t)),t.on?.("error",n=>{s.failureReason||=n instanceof Error?n.message:String(n||"Reverse tunnel transport error."),this.detach(e,t)}),n&&n.socket!==t&&this.finalizeConnection(n,new Error(`Reverse tunnel for node ${e} was replaced.`),"Reverse tunnel was replaced.",!0)}setEventSubscription(e,t){this.eventSubscriptions.set(e,t),this.sendEventSubscription(e,t)}sendEventSubscription(e,t){const n=this.sockets.get(e);if(n)try{n.socket.send(JSON.stringify({type:"control-plane.event-subscribe",eventEnvelopeVersion:zd,aiSessionTransient:{...t.replaySince?{replaySince:t.replaySince}:{},messageDeltas:t.messageDeltas,timelineAllSessions:t.timelineAllSessions,timelineSessions:t.timelineSessions}}))}catch(t){n.failureReason=t instanceof Error?t.message:"Reverse tunnel event subscription delivery failed.",this.detach(e,n.socket);try{n.socket.close?.(1011,"Event subscription delivery failed.")}catch{}}}detach(e,t){const n=this.sockets.get(e);!n||t&&n.socket!==t||(this.sockets.delete(e),n.supervisor?.close(),void 0!==n.runtimeGeneration&&this.connectionRuntime?.disconnected(e,n.runtimeGeneration,{error:n.failureReason||"Reverse tunnel disconnected."}),this.invalidateInstanceScope({nodeId:e}),this.finalizeConnection(n,new Error(`Reverse tunnel for node ${e} disconnected.`),"Reverse tunnel disconnected.",!0))}disconnect(e,t="Node connection disabled locally."){const n=this.sockets.get(e);return!!n&&(this.detach(e,n.socket),n.socket.close?.(1e3,t),!0)}connected(e){return this.sockets.has(e)}markHealthy(e,t){const n=this.sockets.get(e);if(!n||n.socket!==t||void 0===n.runtimeGeneration)return!1;n.supervisor?.healthy();const i=this.connectionRuntime?.connected(e,n.runtimeGeneration)??!0,s=this.eventSubscriptions.get(e);return s&&this.sendEventSubscription(e,s),i}finalizeConnection(e,t,n,i){e.supervisor?.close();for(const n of[...e.pending.keys()])this.cancelPendingRequest(e,n,t,!1);for(const[t,i]of e.streams)e.streams.delete(t),i.downstream.close(1011,n);for(const i of[...e.httpStreams.keys()])this.cancelHttpStream(e,i,t,n,!1);for(const t of e.pendingChannels.values())clearTimeout(t.timer);if(e.pendingChannels.clear(),i&&e.socket.close&&3!==e.socket.readyState)try{e.socket.close(1e3,n)}catch{}}isCurrentSocket(e,t){return this.sockets.get(e)?.socket===t}handleSocketMessage(e,t,n){if(this.isCurrentSocket(e,t))return this.sockets.get(e)?.supervisor?.activity(),this.handleMessage(e,n)}handleMessage(e,t){if(this.eventRouter.handle(e,t))return!0;if(this.handleWebSocketMessage(e,t))return!0;if("node-agent.response"!==t.type)return!1;const n="string"==typeof t.requestId?t.requestId:"",i=this.sockets.get(e),s=i?.pending.get(n);if(!s||!i)return!0;i.pending.delete(n),clearTimeout(s.timer),s.signal&&s.onAbort&&s.signal.removeEventListener("abort",s.onAbort);const a=Number(t.status)||502,o=t.headers&&"object"==typeof t.headers?t.headers:{},r="string"==typeof t.body?t.body:"";if(t.error&&"object"==typeof t.error){const e=t.error,n=new Error("string"==typeof e.message?e.message:`Reverse tunnel request failed with HTTP ${a}`);return Object.assign(n,{statusCode:a,code:"string"==typeof e.code?e.code:"NODE_AGENT_REVERSE_REQUEST_FAILED"}),s.reject(n),!0}return s.resolve(new Response(r,{status:a,headers:o})),!0}invalidateInstanceScope(e={}){this.eventRouter.invalidate(e)}instanceScopeDiagnostics(){return this.eventRouter.diagnostics()}setEventDiagnosticLogger(e){this.eventRouter.setLogger(e)}async request(e,t,n={}){const i=this.sockets.get(e.id);if(!i){const t=new Error(`Reverse tunnel for node ${e.id} is not connected.`);throw Object.assign(t,{statusCode:503,code:"NODE_AGENT_REVERSE_TUNNEL_OFFLINE"}),t}const s=Hv(),a=Mo(n.body),o={type:"control-plane.request",requestId:s,route:t,init:{method:n.method||"GET",headers:Vv(n.headers),body:a}};return new Promise((a,r)=>{let c;if(c={resolve:a,reject:r,timer:setTimeout(()=>{const n=new Error(`Reverse tunnel request to ${e.id}${t} timed out.`);Object.assign(n,{statusCode:504,code:"NODE_AGENT_REVERSE_REQUEST_TIMEOUT"}),this.cancelPendingRequest(i,s,n)},this.requestTimeoutMs),signal:n.signal||void 0},n.signal&&(c.onAbort=()=>{this.cancelPendingRequest(i,s,Object.assign(new Error("Reverse tunnel request was aborted."),{name:"AbortError",code:"ABORT_ERR"}))},n.signal.addEventListener("abort",c.onAbort,{once:!0})),i.pending.set(s,c),n.signal?.aborted)c.onAbort?.();else try{i.socket.send(JSON.stringify(o))}catch(e){this.cancelPendingRequest(i,s,e instanceof Error?e:new Error(String(e)),!1)}})}cancelPendingRequest(e,t,n,i=!0){const s=e.pending.get(t);if(!s)return!1;if(e.pending.delete(t),clearTimeout(s.timer),s.signal&&s.onAbort&&s.signal.removeEventListener("abort",s.onAbort),s.reject(n),i)try{e.socket.send(JSON.stringify({type:"control-plane.request.cancel",requestId:t}))}catch{}return!0}async requestStream(e,t,n={}){const i=this.sockets.get(e.id);if(!i)throw Object.assign(new Error(`Reverse tunnel for node ${e.id} is not connected.`),{statusCode:503,code:"NODE_AGENT_REVERSE_TUNNEL_OFFLINE"});const s=Hv(),a=Mo(n.body);return new Promise((o,r)=>{const c={resolve:o,reject:r,timer:setTimeout(()=>{this.cancelHttpStream(i,s,Object.assign(new Error(`Reverse tunnel stream to ${e.id}${t} timed out.`),{statusCode:504,code:"NODE_AGENT_REVERSE_STREAM_TIMEOUT"}),"Reverse HTTP stream header timeout.")},this.httpStreamHeaderTimeoutMs),settled:!1,finalized:!1,signal:n.signal||void 0};if(i.httpStreams.set(s,c),this.registerPendingChannel(i,{id:s,attach:t=>this.attachHttpStreamChannel(e.id,s,t),cancel:(e,t)=>{this.cancelHttpStream(i,s,e,t)}},"Reverse HTTP channel attach timed out."),n.signal&&(c.onAbort=()=>this.cancelHttpStream(i,s,Object.assign(new Error("Reverse HTTP stream consumer disconnected."),{name:"AbortError",code:"ABORT_ERR"}),"HTTP consumer disconnected."),n.signal.addEventListener("abort",c.onAbort,{once:!0}),n.signal.aborted))c.onAbort();else try{i.socket.send(JSON.stringify({type:"control-plane.http.open",streamId:s,route:t,init:{method:n.method||"GET",headers:Vv(n.headers),body:a}}))}catch(e){this.cancelHttpStream(i,s,e instanceof Error?e:new Error(String(e)),"Reverse tunnel send failed.",!1)}})}cancelHttpStream(e,t,n,i,s=!0){const a=e.httpStreams.get(t);if(!a||a.finalized)return!1;if(a.finalized=!0,e.httpStreams.delete(t),this.removePendingChannel(e,t),clearTimeout(a.timer),a.signal&&a.onAbort&&a.signal.removeEventListener("abort",a.onAbort),a.settled?a.body?.destroy(n):(a.settled=!0,a.reject(n)),1===a.socket?.readyState&&a.socket.close(1e3,i),s)try{e.socket.send(JSON.stringify({type:"control-plane.http.cancel",streamId:t,reason:i}))}catch{}return!0}completeHttpStream(e,t){const n=e.httpStreams.get(t);return!(!n||n.finalized||(n.finalized=!0,e.httpStreams.delete(t),this.removePendingChannel(e,t),clearTimeout(n.timer),n.signal&&n.onAbort&&n.signal.removeEventListener("abort",n.onAbort),n.body?.end(),0))}attachAuxiliary(e,t,n){const i=this.sockets.get(e),s=i?.pendingChannels.get(t);return i&&s?(this.removePendingChannel(i,t),s.attach(n)):(n.close(1008,"Unknown reverse tunnel channel."),!1)}registerPendingChannel(e,t,n){this.removePendingChannel(e,t.id),t.timer=setTimeout(()=>{e.pendingChannels.get(t.id)===t&&(e.pendingChannels.delete(t.id),t.cancel(Object.assign(new Error(n),{code:"NODE_AGENT_REVERSE_CHANNEL_ATTACH_TIMEOUT"}),n))},this.auxiliaryAttachTimeoutMs),t.timer.unref?.(),e.pendingChannels.set(t.id,t)}removePendingChannel(e,t){const n=e.pendingChannels.get(t);return n?.timer&&clearTimeout(n.timer),e.pendingChannels.delete(t),n}attachHttpStream(e,t,n){return this.attachAuxiliary(e,t,n)}attachHttpStreamChannel(e,t,n){const i=this.sockets.get(e),s=i?.httpStreams.get(t);if(!i||!s)return n.close(1008,"Unknown reverse HTTP stream."),!1;s.socket=n;const a=e=>{this.cancelHttpStream(i,t,e,"Reverse HTTP stream failed.")};return n.on("message",(e,o)=>{if(s.finalized||i.httpStreams.get(t)!==s)return;if(o)return s.body?void(s.body.write(Buffer.isBuffer(e)?e:Buffer.from(e))||(n.pause?.(),s.body.once("drain",()=>n.resume?.()))):a(new Error("Reverse HTTP stream received data before response headers."));let c;try{c=JSON.parse(String(e))}catch{return void a(new Error("Reverse HTTP stream sent invalid JSON control data."))}if("node-agent.http.head"===c.type){if(s.settled)return;clearTimeout(s.timer);const e=Number(c.status)||502,n=c.headers&&"object"==typeof c.headers?c.headers:{},a=new r.PassThrough({highWaterMark:65536});return s.body=a,s.settled=!0,a.once("close",()=>{this.cancelHttpStream(i,t,new Error("Reverse HTTP stream consumer closed."),"HTTP consumer closed.")}),void s.resolve(new Response(r.Readable.toWeb(a),{status:e,headers:n}))}"node-agent.http.end"!==c.type?"node-agent.http.error"===c.type&&a(new Error("string"==typeof c.message?c.message:"Reverse HTTP stream failed.")):s.settled?this.completeHttpStream(i,t):a(new Error("Reverse HTTP stream ended before response headers."))}),n.on("close",()=>{a(new Error("Reverse HTTP stream disconnected."))}),n.on("error",()=>a(new Error("Reverse HTTP stream failed."))),!0}proxyWebSocket(e,t,n,i,s={}){const a=e.id,o=this.sockets.get(a);if(!o)return void t.close(1011,"Reverse tunnel is not connected.");const r=Hv(),c=e=>{try{o.socket.send(JSON.stringify(e))}catch{this.removePendingChannel(o,r),o.streams.delete(r),t.close(1011,"Reverse tunnel send failed.")}},d={downstream:t,pendingFrames:[]};return o.streams.set(r,d),this.registerPendingChannel(o,{id:r,attach:e=>this.attachWebSocketStreamChannel(a,r,e),cancel:(e,n)=>{this.removePendingChannel(o,r),o.streams.delete(r),t.close(1011,n)}},"Reverse websocket channel attach timed out."),c({type:"control-plane.websocket.open",streamId:r,route:n,protocols:Array.isArray(i)?i:i?[i]:[],headers:s}),t.on("message",(e,n)=>{const i=o.streams.get(r);if(i&&!i.upstream)return i.pendingFrames.length>=256?(this.removePendingChannel(o,r),o.streams.delete(r),t.close(1011,"Reverse websocket stream pending frame limit exceeded."),void c({type:"control-plane.websocket.close",streamId:r,code:1011,reason:"Reverse websocket stream pending frame limit exceeded."})):void i.pendingFrames.push({data:e,isBinary:Boolean(n)})}),t.on("close",(e,t)=>{const n=o.streams.get(r);if(n){this.removePendingChannel(o,r),o.streams.delete(r);const i=dn(e),s=cn(t);n.upstream&&ln(n.upstream,i,s),c({type:"control-plane.websocket.close",streamId:r,...void 0===i?{}:{code:i},...s?{reason:s}:{}})}}),t.on("error",()=>{const e=o.streams.get(r);e&&(this.removePendingChannel(o,r),o.streams.delete(r),e.upstream?.close(1011,"Downstream websocket failed."),c({type:"control-plane.websocket.close",streamId:r,code:1011,reason:"Downstream websocket failed."}))}),{send:e=>{const t=o.streams.get(r);t&&(t.upstream?t.upstream.send(e):t.pendingFrames.push({data:e,isBinary:!1}))}}}attachWebSocketStream(e,t,n){return this.attachAuxiliary(e,t,n)}attachWebSocketStreamChannel(e,t,n){const i=this.sockets.get(e),s=i?.streams.get(t);if(!i||!s)return n.close(1008,"Unknown reverse websocket stream."),!1;s.upstream=n;for(const e of s.pendingFrames.splice(0))n.send(e.data,{binary:e.isBinary});return un(s.downstream,n,{pendingFrameLimit:256,onClientClose:()=>{this.removePendingChannel(i,t),i.streams.delete(t)},onClientError:()=>{this.removePendingChannel(i,t),i.streams.delete(t)},onUpstreamClose:()=>{this.removePendingChannel(i,t),i.streams.delete(t)},onUpstreamError:()=>{this.removePendingChannel(i,t),i.streams.delete(t)}}),!0}handleWebSocketMessage(e,t){const n="string"==typeof t.type?t.type:"";if(!n.startsWith("node-agent.websocket."))return!1;const i=this.sockets.get(e),s="string"==typeof t.streamId?t.streamId:"",a=i?.streams.get(s);return!a||("node-agent.websocket.close"===n?(i&&this.removePendingChannel(i,s),i?.streams.delete(s),ln(a.downstream,t.code,t.reason),!0):"node-agent.websocket.error"!==n||(i&&this.removePendingChannel(i,s),i?.streams.delete(s),a.downstream.close(1011,"string"==typeof t.message?t.message:"Reverse websocket proxy failed."),!0))}}class Yv{sockets=new Map;connectionKeys=new Map;retries=new Map;supervisors=new Map;runtimeGenerations=new Map;service;tunnel;safetyIntervalMs;logger;connectionRuntime;connectionOptions;reconnectAttempts=0;safetyReconciliations=0;timer;running=!1;transientDemand={legacyAll:!1,messageDeltas:{allInstances:!1,instanceIds:[]},timelineAllSessions:!1,timelineSessions:[]};constructor(e,t,n={}){var i;this.service=e,this.tunnel=t,this.safetyIntervalMs=(i=n.safetyIntervalMs,Math.min(6e4,Math.max(3e4,i??45e3))),this.logger=n.logger,this.tunnel.setEventDiagnosticLogger?.(this.logger),this.connectionRuntime=n.connectionRuntime,this.connectionOptions=n}start(){this.running||(this.running=!0,this.sync(),this.timer=setInterval(()=>{this.safetyReconciliations+=1,this.sync()},this.safetyIntervalMs))}stop(){this.running=!1,this.timer&&(clearInterval(this.timer),this.timer=void 0);for(const e of this.sockets.values())e.close();for(const e of this.supervisors.values())e.close();this.sockets.clear(),this.connectionKeys.clear(),this.supervisors.clear(),this.runtimeGenerations.clear();for(const e of this.retries.values())e.timer.cancel();this.retries.clear()}syncNow(){this.sync()}setAiSessionTransientDemand(e){this.transientDemand=e;const t=JSON.stringify({v:1,type:"subscribe",eventEnvelopeVersion:zd,aiSessionTransient:{...e.replaySince?{replaySince:e.replaySince}:{},messageDeltas:e.messageDeltas,timelineAllSessions:e.timelineAllSessions,timelineSessions:e.timelineSessions}});for(const e of this.sockets.values())e.sendUpstream(t);for(const t of this.service.listNodes())"reverse-wss"===t.connectionMode&&this.tunnel.setEventSubscription(t.id,e)}diagnostics(){return{reconnectAttempts:this.reconnectAttempts,safetyReconciliations:this.safetyReconciliations,activeConnections:this.sockets.size,pendingRetries:[...this.retries.values()].filter(e=>e.timer.pending).length,safetyIntervalMs:this.safetyIntervalMs,connections:[...this.supervisors.entries()].map(([e,t])=>({nodeId:e,...t.diagnostics()})),aiSessionTransientDemand:this.transientDemand}}sync(){const e=new Set;for(const t of this.service.listNodes()){const n=this.nodeEventConnectionKey(t);if(!n)continue;e.add(t.id);const i=this.retries.get(t.id);if(i?.timer.pending&&i.connectionKey!==n&&(i.timer.cancel(),this.retries.delete(t.id)),this.connectionKeys.get(t.id)!==n&&this.sockets.has(t.id)){const e=this.sockets.get(t.id),n=this.runtimeGenerations.get(t.id);this.supervisors.get(t.id)?.close(),this.sockets.delete(t.id),this.connectionKeys.delete(t.id),this.supervisors.delete(t.id),this.runtimeGenerations.delete(t.id),void 0!==n&&this.connectionRuntime?.disconnected(t.id,n,{error:"Direct event endpoint changed."}),e?.close()}this.sockets.has(t.id)||this.retries.get(t.id)?.timer.pending||this.connect(t,n)}for(const[t,n]of this.sockets)if(!e.has(t)){const e=this.runtimeGenerations.get(t);this.supervisors.get(t)?.close(),this.sockets.delete(t),this.connectionKeys.delete(t),this.supervisors.delete(t),this.runtimeGenerations.delete(t),void 0!==e&&this.connectionRuntime?.disconnected(t,e,{error:"Direct event connection is no longer configured."}),n.close();const i=this.retries.get(t);i?.timer.cancel(),this.retries.delete(t)}for(const[t,n]of this.retries)e.has(t)||(n.timer.cancel(),this.retries.delete(t),this.connectionKeys.delete(t))}connect(e,t){const n=new $v,i="control-plane-proxy"!==e.connectionMode?this.connectionRuntime?.begin(e.id,"direct-http","connecting"):void 0;void 0!==i&&this.runtimeGenerations.set(e.id,i);const s=this.retries.get(e.id)?.timer||new zv;this.retries.set(e.id,{timer:s,connectionKey:t});const a=new Rv({...this.connectionOptions,ping:()=>n.ping(),onTimeout:t=>{this.sockets.get(e.id)===n&&(void 0!==i&&this.connectionRuntime?.update(e.id,i,{phase:"suspect",error:`Direct event WebSocket ${t} timeout.`}),n.terminate())},onStable:()=>{s.reset(),void 0!==i&&this.connectionRuntime?.stable(e.id,i)}});this.sockets.set(e.id,n),this.connectionKeys.set(e.id,t),this.supervisors.set(e.id,a),a.start(),n.on("open",()=>{this.sockets.get(e.id)===n&&(a.opened(),void 0!==i&&this.connectionRuntime?.update(e.id,i,{phase:"handshaking"}))}),n.on("message",t=>{if(this.sockets.get(e.id)!==n)return;let s;try{s=JSON.parse(String(t))}catch{return}if(s&&"object"==typeof s&&!Array.isArray(s)){a.activity(),"healthy"!==a.phase&&(a.healthy(),void 0!==i&&this.connectionRuntime?.connected(e.id,i));const t=s,n=Bv(t.event),o=Bv(n?.payload),r=Bv(o?.meta);"string"==typeof n?.type&&n.type.startsWith("app-session.")&&this.logger?.info?.({nodeId:e.id,instanceId:Fv(t.instanceId,Bv(n.scope)?.instanceId,r?.instanceId),eventType:n.type,traceId:"string"==typeof r?.traceId?r.traceId:void 0,streamId:"string"==typeof r?.streamId?r.streamId:void 0,revision:"number"==typeof r?.revision?r.revision:void 0},"app-session.event.transport.received");const c="string"==typeof t.type&&t.type.startsWith("node-agent.")?t:{type:"node-agent.event.forwarded",event:t};this.tunnel.handleMessage(e.id,c)}}),n.on("pong",()=>{this.sockets.get(e.id)===n&&(a.pong(),void 0!==i&&this.connectionRuntime?.pong(e.id,i,a.diagnostics()))}),n.on("close",(t,s)=>{this.sockets.get(e.id)===n&&(a.close(),this.sockets.delete(e.id),this.connectionKeys.delete(e.id),this.supervisors.delete(e.id),this.runtimeGenerations.delete(e.id),this.scheduleReconnect(e.id,{generation:i,closeCode:"number"==typeof t?t:void 0,error:Buffer.isBuffer(s)?s.toString("utf8"):String(s||"Direct event WebSocket disconnected.")}))}),n.on("error",()=>{this.sockets.get(e.id)===n&&n.terminate()});try{n.opened();const t=this.service.resolveNodeAgentTransport(e).proxyWebSocket(e,n,"/events?aiSessionTransient=1");n.control(t&&t.ping,t&&t.onPong,t&&t.send),n.sendUpstream(JSON.stringify({v:1,type:"subscribe",eventEnvelopeVersion:zd,aiSessionTransient:{...this.transientDemand.replaySince?{replaySince:this.transientDemand.replaySince}:{},messageDeltas:this.transientDemand.messageDeltas,timelineAllSessions:this.transientDemand.timelineAllSessions,timelineSessions:this.transientDemand.timelineSessions}}))}catch{n.close(1011,"Node event transport failed.")}}scheduleReconnect(e,t={}){const n=this.service.listNodes().find(t=>t.id===e),i=n&&this.nodeEventConnectionKey(n);if(!this.running||!n||!i)return void(void 0!==t.generation&&this.connectionRuntime?.disconnected(e,t.generation,t));const s=this.retries.get(e)??{timer:new zv};if(s.timer.pending)return;s.connectionKey=i;const a=s.timer.schedule(()=>{this.running&&!this.sockets.has(e)&&this.connect(n,i)});a&&(this.reconnectAttempts+=1,void 0!==t.generation&&this.connectionRuntime?.disconnected(e,t.generation,{...t,nextRetryAt:new Date(Date.now()+a.delay).toISOString()}),this.logger?.info?.({nodeId:e,attempt:a.attempt,delay:a.delay,reconnectAttempts:this.reconnectAttempts},"session-stream.node-connection.reconnect-scheduled")),this.retries.set(e,s)}nodeEventConnectionKey(e){if(!1===e.connectionEnabled)return;if("reverse-wss"===e.connectionMode)return;const t="control-plane-proxy"===e.connectionMode?e.connectionPath:{endpoint:e.controlEndpoint||e.endpoint,auth:e.auth};return`transport:${e.connectionMode}:${Tm(JSON.stringify(t))}`}}function Xv(e=function(){return process.env.TASK_HANDOFF_CONTROL_PLANE_DATA_DIR||t.join(m.homedir(),".config","task-handoff","control-plane")}()){const n=t.resolve(e);return{dataDir:n,settingsPath:t.join(n,"control-plane-settings.json"),projectsDir:t.join(n,"projects"),modelsDir:t.join(n,"models"),imagesDir:t.join(n,"images"),marketDir:t.join(n,"market"),marketCachePath:t.join(n,"market","catalog-cache.json"),marketStatePath:t.join(n,"market","catalog-state.json"),marketMigrationBackupPath:t.join(n,"market","legacy-image-migration-backup.json"),nodesDir:t.join(n,"nodes"),pendingPairingRevokesDir:t.join(n,"pending-pairing-revokes"),chatSessionsDir:t.join(n,"chat-sessions"),chatBridgesDir:t.join(n,"chat-bridges"),triggersDir:t.join(n,"triggers"),proxyAuthorityPath:t.join(n,"control-plane-proxy","authority.json"),identitySigningPath:t.join(n,"control-plane-identity-signing.json"),cloudConnectivityPath:t.join(n,"cloud-connectivity.json"),authUsersDir:t.join(n,"auth-users"),authSessionsDir:t.join(n,"auth-sessions"),authMembershipsDir:t.join(n,"auth-memberships"),databasePath:t.join(n,"control-plane.sqlite"),identityProviderEncryptionKeyPath:t.join(n,"user-access","identity-provider-encryption-key.json"),gitCredentialsDir:t.join(n,"git-credentials","credentials"),gitCredentialAssignmentsDir:t.join(n,"git-credentials","assignments"),gitCredentialAuditDir:t.join(n,"git-credentials","audit"),gitCredentialProvisioningIntentsDir:t.join(n,"git-credentials","provisioning-intents"),gitCredentialEncryptionKeyPath:t.join(n,"git-credentials","encryption-key.json"),aiSessionUnreadDir:t.join(n,"ai-session-unread"),logsDir:t.join(n,"logs")}}var Jv,Qv,Zv=function(){if(Qv)return Jv;Qv=1;const e=n,{spawnSync:t}=E;return Jv={processStartIdentity:function(n,i=process.platform){if(Number.isInteger(n)&&!(n<=0)){if("linux"===i)try{const t=e.readFileSync(`/proc/${n}/stat`,"utf8"),i=t.lastIndexOf(")");if(i<0)return;const s=t.slice(i+2).trim().split(/\s+/)[19];return s?`linux:${s}`:void 0}catch{return}if(["darwin","freebsd","openbsd","aix","sunos"].includes(i)){const e=t("ps",["-o","lstart=","-p",String(n)],{encoding:"utf8",timeout:1e3}),s=0===e.status?e.stdout.trim().replace(/\s+/g," "):"";return s?`${i}:${s}`:void 0}if("win32"===i){const e=t("powershell.exe",["-NoProfile","-NonInteractive","-Command",`(Get-Process -Id ${n} -ErrorAction Stop).StartTime.ToUniversalTime().Ticks`],{encoding:"utf8",timeout:2e3}),i=0===e.status?e.stdout.trim():"";return/^\d+$/.test(i)?`win32:${i}`:void 0}}}}}();class eI extends Error{code;lockPath;owner;constructor(e,t,n={}){const i=t?.pid?` pid ${t.pid}`:"";super(`${n.label||"Process"} is already running${i}. Lock: ${e}`),this.name="ProcessSingletonError",this.code=n.code||"PROCESS_ALREADY_RUNNING",this.lockPath=e,this.owner=t}}function tI(e){return t.join(e,"owner.json")}function nI(e){return t.join(e,"initializing.json")}function iI(e){return t.join(e,"recovering.json")}function sI(e){return Number.isInteger(e)&&Number(e)>0}const aI=function(e){try{const t=JSON.parse(n.readFileSync(tI(e),"utf8"));if(sI(t.pid)&&"string"==typeof t.startTime){const e=t;return{pid:e.pid,hostname:"string"==typeof e.hostname&&e.hostname?e.hostname:m.hostname(),component:e.component||"server-update",command:"string"==typeof e.command?e.command:"",acquiredAt:"string"==typeof e.createdAt&&Number.isFinite(Date.parse(e.createdAt))?e.createdAt:new Date(0).toISOString(),token:"string"==typeof e.token&&e.token?e.token:`legacy:${e.pid}:${e.startTime}`,startIdentity:e.startTime.startsWith("linux:")?e.startTime:`linux:${e.startTime}`}}if(!(sI(t.pid)&&"string"==typeof t.hostname&&t.hostname&&"string"==typeof t.command&&"string"==typeof t.acquiredAt&&Number.isFinite(Date.parse(t.acquiredAt))&&"string"==typeof t.token&&t.token))return;return t}catch{return}};function oI(e){if(!sI(e))return!1;try{return process.kill(Number(e),0),!0}catch(e){return"EPERM"===e.code}}function rI(e){if(!e||!oI(e.pid))return!1;if(!e.startIdentity)return!0;const t=Zv.processStartIdentity(e.pid);return void 0===t||t===e.startIdentity}function cI(e,i){const s=t.join(e,`.owner-${i.token}.tmp`);n.writeFileSync(s,`${JSON.stringify(i,null,2)}\n`,{encoding:"utf8",mode:384,flag:"wx"});const a=lI(e);if(a?.token!==i.token)throw uI(s),new Error(`Process lock initialization was superseded: ${e}`);n.renameSync(s,tI(e)),uI(nI(e))}function dI(e,s,a){const o=aI(e);if(o?.token!==s.token)return!1;const r={...s};for(const[e,t]of Object.entries(a))void 0===t?delete r[e]:Object.assign(r,{[e]:t});const c=t.join(e,`.owner-update-${s.token}-${i.randomUUID()}.tmp`);try{if(n.writeFileSync(c,`${JSON.stringify(r,null,2)}\n`,{encoding:"utf8",mode:384,flag:"wx"}),aI(e)?.token!==s.token)return!1;n.renameSync(c,tI(e));for(const e of Object.keys(s))delete s[e];return Object.assign(s,r),!0}catch(e){if("ENOENT"===e.code)return!1;throw e}finally{uI(c)}}function lI(e){try{return JSON.parse(n.readFileSync(nI(e),"utf8"))}catch{return}}function pI(e){const t=lI(e);return sI(t?.pid)&&rI({pid:t.pid,startIdentity:t.startIdentity})}function uI(e){try{n.unlinkSync(e)}catch(e){if("ENOENT"!==e.code)throw e}}function mI(){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,20)}function hI(e){try{const t=lI(e),i=Date.parse(t?.startedAt||"");return Number.isFinite(i)?Math.max(0,Date.now()-i):Math.max(0,Date.now()-n.statSync(e).mtimeMs)}catch{return 0}}function gI(e,s){try{return n.writeFileSync(iI(e),`${JSON.stringify({token:s,pid:process.pid,startedAt:(new Date).toISOString()})}\n`,{encoding:"utf8",mode:384,flag:"wx"}),!0}catch(a){if("EEXIST"===a.code)return!!function(e){const s=iI(e),a=fI(s),o=Date.parse(a?.startedAt||"");if(oI(a?.pid)||Number.isFinite(o)&&Date.now()-o<2e3)return!1;const r=t.join(e,`.recovering-${i.randomUUID()}.stale`);try{n.renameSync(s,r)}catch(e){if(["ENOENT","EEXIST"].includes(e.code||""))return!1;throw e}const c=fI(r);if(c?.token===a?.token)return uI(r),!0;try{n.linkSync(r,s)}catch(e){if("EEXIST"!==e.code)throw e}finally{uI(r)}return!1}(e)&&gI(e,s);if("ENOENT"===a.code)return!1;throw a}}function fI(e){try{return JSON.parse(n.readFileSync(e,"utf8"))}catch{return}}function yI(e,t){return fI(iI(e))?.token===t}function bI(){const e=process.env.TASK_HANDOFF_CONTROL_PLANE_LOCK_PATH?.trim();return e?t.resolve(e):t.join(m.tmpdir(),`task-handoff-control-plane-${process.getuid?.()??"user"}.lock`)}function vI(e,s={}){return function(e,s={}){n.mkdirSync(t.dirname(e),{recursive:!0});const a=Zv.processStartIdentity(process.pid),o={pid:process.pid,hostname:m.hostname(),command:process.argv.join(" "),acquiredAt:(new Date).toISOString(),token:i.randomUUID(),...void 0!==s.component?{component:s.component}:{},...a?{startIdentity:a}:{},...void 0!==s.dataDir?{dataDir:s.dataDir}:{},...void 0!==s.host?{host:s.host}:{},...void 0!==s.port?{port:s.port}:{},...void 0!==s.instanceId?{instanceId:s.instanceId}:{}};for(let t=0;t<5;t+=1)try{return n.mkdirSync(e),n.writeFileSync(nI(e),`${JSON.stringify({token:o.token,pid:o.pid,startIdentity:o.startIdentity,startedAt:(new Date).toISOString()})}\n`,{encoding:"utf8",mode:384,flag:"wx"}),cI(e,o),{lockPath:e,owner:o,updateDetails:t=>dI(e,o,t),release(){const t=aI(e);t?.token===o.token&&n.rmSync(e,{recursive:!0,force:!0})}}}catch(a){if("EEXIST"!==a.code)throw a;const o=aI(e);if(rI(o))throw new eI(e,o,s.error);if(!o&&(pI(e)||hI(e)<(s.incompleteLockStaleMs??2e3))){if(t+1<5){mI();continue}throw new eI(e,void 0,s.error)}const r=i.randomUUID();if(!gI(e,r)){if(t+1<5){mI();continue}throw new eI(e,aI(e),s.error)}const c=aI(e);if(rI(c))throw uI(iI(e)),new eI(e,c,s.error);if(o?.token&&c?.token!==o.token){uI(iI(e));continue}if(!yI(e,r))continue;n.rmSync(e,{recursive:!0,force:!0})}const r=aI(e);throw new eI(e,r,s.error)}(e,{...s,component:"control-plane",error:{label:"Control plane",code:"CONTROL_PLANE_ALREADY_RUNNING"}})}function II(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:{}}function xI(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function wI(e){return{kind:"node",nodeId:e}}async function SI(e,t,n){if(!n)return{kind:"instance-derived",nodeId:"",instanceId:t};const i=e.requireControlledInstanceForAuthorization(t);return{kind:"instance-derived",nodeId:i.nodeId,instanceId:i.id}}const AI=new WeakMap;function EI(e,t){AI.set(e,t)}function _I(e){return AI.get(e)}const TI=f.z.string().trim().min(1),zI=f.z.object({id:TI}).strict(),kI=f.z.object({id:TI,keyId:TI}).strict(),NI=f.z.object({id:TI,connectionId:TI}).strict(),CI=f.z.object({id:TI,runtimeId:TI}).strict(),RI=f.z.object({id:TI,folderId:TI}).strict(),OI=f.z.object({id:TI,sessionId:TI}).strict(),jI=f.z.object({id:TI,sessionId:TI,turnId:TI}).strict(),PI=f.z.object({id:TI,sessionId:TI,messageId:TI,attachmentId:TI}).strict(),DI=f.z.object({id:TI,sessionId:TI,queueId:TI}).strict(),LI=f.z.object({configHash:TI}).strict(),MI=f.z.object({id:TI,configHash:TI}).strict(),qI=f.z.object({id:TI,sessionId:TI,configHash:TI}).strict(),UI=f.z.object({path:f.z.string().optional(),depth:f.z.coerce.number().int().min(0).max(32).optional()}).strict();async function $I(e,t,n){const i=new AbortController,s=()=>i.abort(),a=()=>{t.raw.writableEnded||s()};e.raw.once("aborted",s),t.raw.once("close",a);try{return await n(i.signal)}finally{e.raw.off("aborted",s),t.raw.off("close",a)}}function BI(e,t){const n=_I(e);return"user"!==n?.type||"all"===n.nodeScope.kind||n.nodeScope.nodeIds.includes(t)}function FI(e,t,n){return t.filter(t=>BI(e,n(t)))}function HI(e,t){const n=_I(e);return"user"!==n?.type||qd(n.nodeScope,n.instanceScope,t.id,t.nodeId)}function GI(e,t,n){return t.filter(t=>HI(e,n(t)))}function WI(e,t){return{...t,models:t.models.flatMap(t=>{const n=t.locations.filter(t=>"control-plane"===t.type||BI(e,t.nodeId));return n.length?[{...t,locations:n,referenceCount:n.reduce((e,t)=>e+("node"===t.type?t.referenceCount:0),0)}]:[]}),nodeDiagnostics:FI(e,t.nodeDiagnostics,e=>e.nodeId)}}async function VI(e,t){const n=await e.listControlledInstances();return new Set(n.filter(e=>HI(t,e)).map(e=>e.id))}async function KI(e,t,n){const i=await e.requireControlledInstance(n);if(HI(t,i))return i;throw Object.assign(new Error("The requested resource is not visible."),{statusCode:404,code:"CONTROL_PLANE_RESOURCE_NOT_VISIBLE"})}const YI=f.z.object({ids:f.z.array(f.z.string().trim().min(1).max(120)).default([])}).strict(),XI=f.z.object({nodeId:f.z.string().trim().min(1).max(120),modelId:f.z.string().trim().min(1).max(120).optional()}).strict(),JI=f.z.object({progressive:f.z.enum(["true","false"]).optional()}).strict();function QI(e,t){const n=e.body&&"object"==typeof e.body&&!Array.isArray(e.body)?e.body:void 0,i=n?.source&&"object"==typeof n.source&&!Array.isArray(n.source)?n.source:void 0,s=i?.auth&&"object"==typeof i.auth&&!Array.isArray(i.auth)?i.auth:void 0;if(!i||void 0===s?.secretId&&!t?.auth?.secretId)return;const a=_I(e);if(!a)throw Object.assign(new Error("Authentication is required."),{code:"CONTROL_PLANE_AUTH_REQUIRED",statusCode:401});$d(a,"manage-secrets",{type:"secret"})}const ZI=f.z.object({source:f.z.object({channel:vd,bridgeId:f.z.string().trim().min(1).max(120).optional(),chatSessionId:f.z.string().trim().min(1).max(240),userId:f.z.string().trim().max(240).optional()}).strict(),action:f.z.discriminatedUnion("type",[f.z.object({type:f.z.literal("ai-session"),index:f.z.number().int().nonnegative()}).strict(),f.z.object({type:f.z.literal("instance-app-menu"),instanceId:f.z.string().trim().min(1).max(120)}).strict(),f.z.object({type:f.z.literal("launch-app"),instanceId:f.z.string().trim().min(1).max(120),appId:f.z.string().trim().min(1).max(120)}).strict(),f.z.object({type:f.z.literal("pending-decision"),routeId:f.z.string().trim().min(1).max(120),decision:f.z.enum(["allow","deny","skip"])}).strict()])}).strict();function ex(e){const t=ZI.parse(e);if(!t.action)throw new Error("Chat gateway action is required.");return{source:t.source,action:t.action}}const tx=f.z.object({path:f.z.string().trim().max(1e3).optional(),depth:f.z.coerce.number().int().min(0).max(2).optional()}).strict(),nx=f.z.object({id:f.z.string().trim().min(1),appId:f.z.string().trim().min(1)}).strict(),ix=f.z.object({id:f.z.string().trim().min(1),jobId:f.z.string().trim().min(1)}).strict(),sx=f.z.object({projection:f.z.literal("directory").optional(),instanceId:f.z.string().trim().min(1).max(120).optional(),progressive:f.z.enum(["true","false"]).optional()}).strict();const ax=f.z.object({id:f.z.string().trim().min(1).max(120)}).strict(),ox=f.z.object({nodeId:f.z.string().trim().min(1).max(120),templateId:f.z.string().trim().min(1).max(120)}).strict(),rx=f.z.object({force:f.z.enum(["true","false"]).optional()}).strict(),cx=f.z.object({projection:f.z.literal("directory").optional()}).strict(),dx=f.z.object({progressive:f.z.enum(["true","false"]).optional()}).strict();const lx=f.z.object({cwdFolderId:f.z.string().trim().min(1).max(120).optional()}).strict(),px=f.z.object({appId:f.z.string().trim().min(1).max(120).default("terminal-tty"),cwdFolderId:f.z.string().trim().min(1).max(120).optional(),options:f.z.record(f.z.string(),f.z.unknown()).default({})}).strict().default({appId:"terminal-tty",options:{}}),ux=f.z.object({title:f.z.string().trim().min(1).max(120)}).strict(),mx=f.z.object({token:f.z.string().trim().min(1).max(512)}).strict(),hx=f.z.object({}).strict();function gx(e,t){if(!e)return t;const n=/filename\*=UTF-8''([^;]+)/i.exec(e)?.[1];if(n)try{return decodeURIComponent(n)}catch{}const i=/filename="([^"]+)"/i.exec(e)?.[1];return i||t}async function fx(e){let t={};if(e.body)try{t=await new Response(e.body).json()}catch{}if(e.status<200||e.status>=300)throw Object.assign(new Error(t.error?.message||`Controlled instance attachment request failed with HTTP ${e.status}.`),{statusCode:e.status,code:t.error?.code||"AI_SESSION_ATTACHMENT_UPLOAD_FAILED"});return t.data}function yx(e,t,n){const i=e.safeParse(t);if(i.success)return i.data;throw Object.assign(new Error(`Controlled instance returned an invalid attachment ${n} response: ${i.error.issues.map(e=>`${e.path.join(".")||"response"}: ${e.message}`).join("; ")}`),{statusCode:502,code:"AI_SESSION_ATTACHMENT_PROTOCOL_INVALID"})}function bx(e){const{app:t,service:s,events:a,appSessionAggregator:o,aiSessionAggregator:c,aiSessionUnread:d,chatGateway:l,aiSessionAttachments:p,aiSessionAttachmentCache:u,nodeAgentTunnel:m,nodeEventSubscriber:h,errorPayload:g,onInstanceDeleted:y}=e;!function({app:e,service:t,events:n}){e.get("/api/projects",async e=>({data:t.listProjects().filter(n=>"local-folder"!==n.source.type||Boolean(n.source.ownerNodeId&&t.nodes.get(n.source.ownerNodeId)&&BI(e,n.source.ownerNodeId)))})),e.post("/api/projects",async(e,i)=>{QI(e);const s=t.createProject(e.body);return n.publish("project.created",{projectId:s.id}),i.code(201).send({data:s})}),e.get("/api/projects/:id",async e=>({data:t.requireProject(zI.parse(e.params).id)})),e.patch("/api/projects/:id",async e=>{const i=zI.parse(e.params).id;QI(e,t.requireProject(i).source);const s=t.updateProject(i,e.body);return n.publish("project.updated",{projectId:s.id}),{data:s}}),e.delete("/api/projects/:id",async e=>{const i=zI.parse(e.params).id,s=t.deleteProject(i);return n.publish("project.deleted",{projectId:i,deleted:s}),{data:{deleted:s}}}),e.get("/api/models",async(e,n)=>$I(e,n,async n=>{const i=JI.parse(e.query);return{data:WI(e,await t.listFederatedModels(n,"true"===i.progressive))}})),e.post("/api/models",async(e,i)=>{const s=await t.createModel(e.body);return n.publish("model.created",{modelId:s.id}),i.code(201).send({data:s})}),e.post("/api/models/discover",async e=>({data:await t.discoverModels(e.body)})),e.post("/api/models/test",async e=>({data:await t.testModel(e.body)})),e.post("/api/models/reorder",async e=>{const i=YI.parse(e.body),s=await t.reorderModels(i.ids);return n.publish("model.reordered",{ids:i.ids}),{data:s}}),e.get("/api/models/:id",async e=>({data:t.requireModel(zI.parse(e.params).id)})),e.patch("/api/models/:id",async e=>{const i=await t.updateModel(zI.parse(e.params).id,e.body);return n.publish("model.updated",{modelId:i.id}),{data:i}}),e.delete("/api/models/:id",async e=>{const i=zI.parse(e.params).id,s=await t.deleteModel(i);return n.publish("model.deleted",{modelId:i,deleted:s}),{data:{deleted:s}}}),e.post("/api/nodes/:nodeId/models",async(e,i)=>{const{nodeId:s}=XI.parse(e.params),a=await t.createNodeModel(s,e.body);return n.publish("model.created",{modelId:a.id,nodeId:s}),i.code(201).send({data:a})}),e.post("/api/nodes/:nodeId/models/discover",async e=>{const{nodeId:n}=XI.parse(e.params);return{data:await t.discoverNodeModels(n,e.body)}}),e.post("/api/nodes/:nodeId/models/test",async e=>{const{nodeId:n}=XI.parse(e.params);return{data:await t.testNodeModel(n,e.body)}}),e.patch("/api/nodes/:nodeId/models/:modelId",async e=>{const{nodeId:i,modelId:s}=XI.parse(e.params),a=await t.updateNodeModel(i,s,e.body);return n.publish("model.updated",{modelId:s,nodeId:i}),{data:a}}),e.delete("/api/nodes/:nodeId/models/:modelId",async e=>{const{nodeId:i,modelId:s}=XI.parse(e.params),a=await t.deleteNodeModel(i,s);return n.publish("model.deleted",{modelId:s,nodeId:i,deleted:a.deleted}),{data:a}}),e.get("/api/market/catalog",async()=>({data:t.getMarketCatalog()})),e.post("/api/market/refresh",async()=>{const e=await t.refreshMarketCatalog();return n.publish("market.catalog.updated",{revision:e.catalog.revision,source:e.catalog.source}),{data:e}}),e.get("/api/image-options",async()=>({data:t.listImageOptions()})),e.get("/api/images",async()=>({data:t.listImages()})),e.post("/api/images",async(e,i)=>{const s=t.createImage(e.body);return n.publish("image.created",{imageId:s.id}),i.code(201).send({data:s})}),e.get("/api/images/:id",async e=>({data:t.requireImage(zI.parse(e.params).id)})),e.patch("/api/images/:id",async e=>{const i=t.updateImage(zI.parse(e.params).id,e.body);return n.publish("image.updated",{imageId:i.id}),{data:i}}),e.delete("/api/images/:id",async e=>{const i=zI.parse(e.params).id,s=await t.deleteImage(i);return n.publish("image.deleted",{imageId:i,deleted:s}),{data:{deleted:s}}})}({app:t,service:s,events:a}),function({app:e,service:t,events:n,nodeAgentTunnel:i,nodeEventSubscriber:s,errorPayload:a}){const o=e=>{if(!e||"object"!=typeof e||Array.isArray(e)||!("target"in e))return;const t=e.target;if(!t||"object"!=typeof t||Array.isArray(t)||"controlled-instance"!==t.component)return;const n=new Error("Independent controlled-instance updates were retired; update the Node rollout instead.");throw Object.assign(n,{statusCode:404,code:"LEGACY_INSTANCE_UPDATE_RETIRED"}),n};e.get("/api/nodes",async e=>{const n=cx.parse(e.query),i=FI(e,t.listNodes(),e=>e.id);return{data:"directory"===n.projection?i.map(e=>function(e){const t=e.proxyState?.lastError;return rh.parse({id:e.id,name:e.name,status:e.status,health:e.health,connectionMode:e.connectionMode,connectionPhase:e.connectionPhase,lastSeenAt:e.lastSeenAt,observedAt:e.updatedAt,capabilities:Object.keys(e.capabilities).sort(),error:t?{code:t.code,message:"Node connection failed. Use the desktop Control Plane for diagnostics."}:void 0})}(t.projectNodeConnection(e))):i.map(e=>t.requirePublicNode(e.id))}}),e.post("/api/nodes/local/sync",async()=>{const e=await t.syncLocalNodeConnection();return s.syncNow(),n.publish("node.local-synced",{nodeId:e.id}),{data:t.requirePublicNode(e.id)}}),e.post("/api/nodes",async(e,i)=>{const a=await t.createNode(e.body);return s.syncNow(),n.publish("node.created",{nodeId:a.id}),i.code(201).send({data:t.requirePublicNode(a.id)})}),e.post("/api/nodes/:id/check",async e=>{const i=await t.checkNode(zI.parse(e.params).id);return n.publish("node.checked",{nodeId:i.id},{topic:"node.state",scope:{nodeId:i.id}}),{data:i}}),e.get("/api/nodes/:id/updates/jobs",async e=>({data:await t.listNodeUpdateJobs(zI.parse(e.params).id)})),e.get("/api/nodes/:id/settings/external-listener",async e=>({data:await t.getLocalNodeExternalListener(zI.parse(e.params).id)})),e.patch("/api/nodes/:id/settings/external-listener",async e=>{const i=zI.parse(e.params).id,s=await t.updateLocalNodeExternalListener(i,e.body);return n.publish("node.external-listener.updated",{nodeId:i,bindScope:s.bindScope,port:s.port}),{data:s}}),e.post("/api/nodes/:id/updates/check",async e=>{o(e.body);const i=zI.parse(e.params).id,s=await t.checkNodeUpdate(i,Dr.parse(e.body));return n.publish("node.update.checked",{nodeId:i,availableVersion:s.availableVersion,impact:s.impact}),{data:s}}),e.post("/api/nodes/:id/updates/apply",async(e,i)=>{o(e.body);const s=zI.parse(e.params).id,a=await t.applyNodeUpdate(s,qr.parse(e.body));return n.publish("node.update.queued",{nodeId:s,updateJobId:a.id,desiredVersion:a.toVersion,impact:a.impact}),i.code(202).send({data:a})}),e.post("/api/nodes/:id/pairing/invites",async(e,i)=>{const s=zI.parse(e.params),a=await t.createNodePairingInvite(s.id,e.body);return n.publish("node.pairing-invite.created",{nodeId:s.id}),i.code(201).send({data:a})}),e.post("/api/nodes/:id/control-plane-connections",async e=>{const i=zI.parse(e.params),s=await t.connectNodeToControlPlane(i.id,e.body);return n.publish("node.remote-connect.requested",{nodeId:i.id}),{data:s}}),e.get("/api/nodes/:id/control-plane-pairings",async e=>{const n=zI.parse(e.params);return{data:await t.listNodeControlPlanePairings(n.id)}}),e.delete("/api/nodes/:id/control-plane-pairings/:keyId",async e=>{const i=kI.parse(e.params),s=await t.deleteNodeControlPlanePairing(i.id,i.keyId);return n.publish("node.control-plane-pairing.deleted",{nodeId:i.id,keyId:i.keyId}),{data:s}}),e.get("/api/nodes/:id/control-plane-connections",async e=>{const n=zI.parse(e.params);return{data:await t.listNodeControlPlaneConnections(n.id)}}),e.delete("/api/nodes/:id/control-plane-connections/:connectionId",async e=>{const i=NI.parse(e.params),s=await t.deleteNodeControlPlaneConnection(i.id,i.connectionId);return n.publish("node.control-plane-connection.deleted",{nodeId:i.id,connectionId:i.connectionId}),{data:s}}),e.post("/api/node-join/invites",async(e,i)=>{const s=t.createNodeJoinInvite(e.body);return n.publish("node-join.invite.created",{inviteId:s.id}),i.code(201).send({data:s})}),e.get("/api/node-join/invites/:id",async e=>({data:Rc.parse(t.getNodeJoinInviteStatus(zI.parse(e.params).id))})),e.post("/api/node-join/complete",{config:xv},async(e,i)=>{const{node:a,inviteId:o}=t.completeNodeJoin(e.body);return s.syncNow(),n.publish("node.joined",{nodeId:a.id,inviteId:o}),i.code(201).send({data:t.requirePublicNode(a.id)})}),e.get("/api/nodes/:id/runtimes",async e=>({data:await t.listNodeRuntimes(zI.parse(e.params).id)})),e.post("/api/nodes/:id/runtimes",async(e,i)=>{const s=zI.parse(e.params),a=await t.createNodeRuntime(s.id,e.body);return n.publish("node.runtime.created",{nodeId:s.id,runtimeId:a.id}),i.code(201).send({data:a})}),e.patch("/api/nodes/:id/runtimes/:runtimeId",async e=>{const i=CI.parse(e.params),s=await t.updateNodeRuntime(i.id,i.runtimeId,e.body);return n.publish("node.runtime.updated",{nodeId:i.id,runtimeId:s.id}),{data:s}}),e.delete("/api/nodes/:id/runtimes/:runtimeId",async e=>{const i=CI.parse(e.params),s=await t.deleteNodeRuntime(i.id,i.runtimeId);return n.publish("node.runtime.deleted",{nodeId:i.id,runtimeId:i.runtimeId}),{data:s}}),e.post("/api/nodes/:id/runtimes/:runtimeId/check",async e=>{const i=CI.parse(e.params),s=await t.checkNodeRuntime(i.id,i.runtimeId);return n.publish("node.runtime.checked",{nodeId:i.id,runtimeId:s.id}),{data:s}}),e.get("/api/nodes/:id/docker/images",async e=>({data:await t.listNodeDockerImages(zI.parse(e.params).id)})),e.get("/api/nodes/:id/image-options",async e=>({data:await t.listNodeImageAvailability(zI.parse(e.params).id)})),e.get("/api/nodes/:id/local-folders",async(e,n)=>$I(e,n,async n=>({data:await t.listNodeLocalFolders(zI.parse(e.params).id,n)}))),e.get("/api/nodes/:id/folders/places",async e=>({data:await t.listNodeFolderPlaces(zI.parse(e.params).id)})),e.get("/api/nodes/:id/folders/tree",async e=>{const n=zI.parse(e.params),i=UI.parse(e.query);return{data:await t.listNodeFolderTree(n.id,{path:i.path,depth:i.depth})}}),e.post("/api/nodes/:id/local-folders",async(e,i)=>{const s=zI.parse(e.params),a=await t.createNodeLocalFolder(s.id,e.body);return n.publish("node.local-folder.created",{nodeId:s.id,folderId:a.id}),i.code(201).send({data:a})}),e.patch("/api/nodes/:id/local-folders/:folderId",async e=>{const i=RI.parse(e.params),s=await t.updateNodeLocalFolder(i.id,i.folderId,e.body);return n.publish("node.local-folder.updated",{nodeId:i.id,folderId:i.folderId}),{data:s}}),e.delete("/api/nodes/:id/local-folders/:folderId",async e=>{const i=RI.parse(e.params),s=await t.deleteNodeLocalFolder(i.id,i.folderId);return n.publish("node.local-folder.deleted",{nodeId:i.id,folderId:i.folderId}),{data:s}}),e.get("/api/nodes/:id",async e=>({data:t.requirePublicNode(zI.parse(e.params).id)})),e.patch("/api/nodes/:id",async e=>{const a=t.updateNode(zI.parse(e.params).id,e.body);return a.connectionEnabled||i.disconnect(a.id),s.syncNow(),n.publish("node.updated",{nodeId:a.id}),{data:t.requirePublicNode(a.id)}}),e.delete("/api/nodes/:id",async e=>{const i=zI.parse(e.params).id,a=rx.parse(e.query),o=await t.deleteNodeWithProxyLifecycle(i,"true"===a.force);return s.syncNow(),n.publish("node.deleted",{nodeId:i,deleted:o.deleted,revoke:o.revoke}),{data:o}}),e.get("/api/node-runtimes",async(e,n)=>$I(e,n,async n=>{const i=dx.parse(e.query),s=await t.listNodeRuntimesWithDiagnostics(n,"true"===i.progressive);return{data:FI(e,s.items,e=>e.nodeId),meta:{nodeErrors:FI(e,s.nodeErrors,e=>e.nodeId),nodeStates:FI(e,s.nodeStates,e=>e.nodeId)}}})),function(e){const{app:t,service:n,nodeAgentTunnel:i,errorPayload:s}=e,a=new Ov(i),o=e=>{if(!1===e.connectionEnabled){const e=new Error("Node agent connection is disabled locally.");throw Object.assign(e,{statusCode:409,code:"NODE_AGENT_CONNECTION_DISABLED"}),e}};t.get(Em,{websocket:!0,config:Av},(e,t)=>{try{const i=Uv.parse(t.query),s=n.requireNode(i.nodeId);Wv(s,t),o(s),a.attachMain(s.id,e)}catch(t){const n=s(t);e.send(JSON.stringify({type:"control-plane.error",code:n.code,message:n.message})),e.close(1008,n.message)}}),t.get(`${Em}/streams/:streamId`,{websocket:!0,config:Av},(e,t)=>{try{const i=Uv.parse(t.query),s=n.requireNode(i.nodeId);Wv(s,t),o(s);const r=t.params.streamId;a.attachAuxiliary(s.id,r,e)}catch(t){const n=s(t);e.close(1008,n.message)}}),t.get(`${Em}/channels/:channelId`,{websocket:!0,config:Av},(e,t)=>{try{const i=Uv.parse(t.query),s=n.requireNode(i.nodeId);Wv(s,t),o(s);const r=t.params.channelId;a.attachAuxiliary(s.id,r,e)}catch(t){const n=s(t);e.close(1008,n.message)}}),t.get(`${Em}/http-streams/:streamId`,{websocket:!0,config:Av},(e,t)=>{try{const i=Uv.parse(t.query),s=n.requireNode(i.nodeId);Wv(s,t),o(s);const r=t.params.streamId;a.attachAuxiliary(s.id,r,e)}catch(t){const n=s(t);e.close(1008,n.message)}})}({app:e,service:t,nodeAgentTunnel:i,errorPayload:a})}({app:t,service:s,events:a,nodeAgentTunnel:m,nodeEventSubscriber:h,errorPayload:g}),function({app:e,service:t,events:n,onInstanceDeleted:i}){e.get("/api/controlled-instances",async e=>({data:GI(e,await t.listControlledInstances(),e=>e)})),e.post("/api/controlled-instances",async(e,i)=>{if("instance-retained"===(e.body&&"object"==typeof e.body&&!Array.isArray(e.body)?e.body:{}).gitCredentialRetention){const t=_I(e);if(!t)throw Object.assign(new Error("Authentication is required."),{code:"CONTROL_PLANE_AUTH_REQUIRED",statusCode:401});$d(t,"manage-secrets",{type:"secret"})}const s=await t.createControlledInstance(e.body);return n.publish("instance.created",{instanceId:s.id}),i.code(201).send({data:s})}),e.get("/api/controlled-instances/:id",async e=>({data:await t.requireControlledInstance(zI.parse(e.params).id,!1,!0)})),e.get("/api/controlled-instances/:id/metrics",async e=>({data:await t.instanceResourceMetrics(zI.parse(e.params).id)})),e.get("/api/controlled-instances/:id/apps/management",async e=>({data:await t.instanceAppManagement(zI.parse(e.params).id)})),e.post("/api/controlled-instances/:id/apps/:appId/install",async e=>{const n=nx.parse(e.params),i=_r.parse(e.body||{});return{data:await t.requestInstanceAppOperation(n.id,n.appId,"install",i)}}),e.post("/api/controlled-instances/:id/apps/:appId/uninstall",async e=>{const n=nx.parse(e.params),i=_r.parse(e.body||{});return{data:await t.requestInstanceAppOperation(n.id,n.appId,"uninstall",i)}}),e.get("/api/controlled-instances/:id/apps/jobs/:jobId",async e=>{const n=ix.parse(e.params);return{data:await t.instanceAppManagementJob(n.id,n.jobId)}}),e.patch("/api/controlled-instances/:id",async e=>{const i=await t.updateControlledInstance(zI.parse(e.params).id,e.body);return n.publish("instance.updated",{instanceId:i.id}),{data:i}}),e.delete("/api/controlled-instances/:id",async e=>{const s=zI.parse(e.params).id,a=await t.deleteControlledInstance(s,nr.parse(e.body));return a.completed&&(await(i?.(s)),n.publish("instance.deleted",{instanceId:s,result:a})),{data:a}}),e.post("/api/controlled-instances/:id/start",async e=>{const i=await t.startControlledInstance(zI.parse(e.params).id);return n.publish("instance.started",{instanceId:i.id}),{data:i}}),e.post("/api/controlled-instances/:id/stop",async e=>{const i=await t.stopControlledInstance(zI.parse(e.params).id);return n.publish("instance.stopped",{instanceId:i.id}),{data:i}}),e.post("/api/controlled-instances/:id/restart",async e=>{const i=await t.restartControlledInstance(zI.parse(e.params).id);return n.publish("instance.restarted",{instanceId:i.id}),{data:i}}),e.post("/api/controlled-instances/:id/image-provisioning/retry",async e=>{const i=await t.retryControlledInstanceImageProvisioning(zI.parse(e.params).id);return n.publish("instance.image-provisioning-retried",{instanceId:i.id}),{data:i}}),e.get("/api/controlled-instances/:id/config-sync",async e=>({data:await t.instanceConfigSyncState(zI.parse(e.params).id)})),e.get("/api/controlled-instances/:id/config-sync/folders",async e=>({data:await t.listInstanceConfigSyncFolders(zI.parse(e.params).id,tx.parse(e.query))})),e.post("/api/controlled-instances/:id/config-sync",async e=>{const i=zI.parse(e.params).id,s=await t.syncInstanceConfigs(i,e.body);return n.publish("instance.config-synced",{instanceId:i}),{data:s}}),e.get("/api/instance-board",async(e,n)=>$I(e,n,async n=>{const i=sx.parse(e.query),s=await t.boardWithDiagnostics(n,"true"===i.progressive);return{data:GI(e,i.instanceId?s.items.filter(e=>e.id===i.instanceId):s.items,e=>e).map(e=>"directory"===i.projection?function(e){const t=e.runtimeVersion?.error,n=e.imageProvisioning?.error,i=e.workspace.error,s=t?{code:t.code,message:"Instance runtime convergence failed. Use the desktop Control Plane for diagnostics."}:n?{code:"IMAGE_PROVISIONING_FAILED",message:"Instance image provisioning failed. Use the desktop Control Plane for diagnostics."}:i?{code:"WORKSPACE_FAILED",message:"Instance workspace preparation failed. Use the desktop Control Plane for diagnostics."}:void 0,a=e.node?.capabilities.agent,o=a&&"object"==typeof a&&!Array.isArray(a)?a:void 0,r="string"==typeof o?.protocolVersion?o.protocolVersion:void 0,c=!r||r===wo,d=[e.protocolCompatible?void 0:`Instance protocol ${e.protocolVersion||"unknown"} differs from this Control Plane.`,c?void 0:`Node protocol ${r} differs from this Control Plane.`].filter(e=>Boolean(e)),l="running"===e.status||"online"===e.connectionStatus||"reachable"===e.access.status,p=!["failed","stopped","stopping","unhealthy"].includes(e.status)&&"online"!==e.connectionStatus&&["provisioning","starting","registering","registered"].includes(e.status),u=[l||["provisioning","starting","registering","registered","stopping"].includes(e.status)?void 0:"start",["failed","stopped","stopping","unhealthy"].includes(e.status)||!l&&!p?void 0:"stop",l?"restart":void 0,"failed"===e.status&&"failed"===e.imageProvisioning?.phase?"retry-image":void 0].filter(e=>Boolean(e));return dh.parse({id:e.id,name:e.name,nodeId:e.nodeId,status:e.status,health:e.health,connectionStatus:e.connectionStatus,ready:e.ready,capabilities:{aiSessionTimeline:e.capabilities.features.aiSessionTimeline,aiSessionConversationAttachments:e.capabilities.features.aiSessionConversationAttachments,aiSessionProviders:e.capabilities.features.aiSessionProviders},config:{defaultCodexPermissionMode:e.config.defaultCodexPermissionMode,aiSessionMaxFileAttachmentBytes:e.config.aiSessionMaxFileAttachmentBytes},lastHeartbeatAt:e.lastHeartbeatAt,heartbeatAgeMs:e.heartbeatAgeMs,observedAt:e.updatedAt,runtime:{id:e.runtimeId,name:e.runtime?.name,type:e.runtime?.type},workspace:{status:e.workspace.status,path:e.workspace.path},protocol:{version:e.protocolVersion,compatible:e.protocolCompatible&&c,warning:d.length?d.join(" "):void 0},aiSessions:e.aiSessions,availableActions:u,availableApps:(e.appInventory?.items||[]).filter(e=>"available"===e.availability).map(e=>({id:e.id,name:e.name,kind:e.kind,supportsCwdSelection:e.capabilities.supportsCwdSelection})),availableAgents:(e.appInventory?.items||[]).filter(t=>"available"===t.availability&&e.capabilities.features.aiSessionProviders.some(e=>e.agent===t.id&&e.actions.create)).map(e=>({id:e.id,name:e.name,kind:e.kind,supportsCwdSelection:e.capabilities.supportsCwdSelection})),error:s})}(e):e),meta:{nodeErrors:FI(e,s.nodeErrors,e=>e.nodeId),nodeStates:FI(e,s.nodeStates,e=>e.nodeId)}}}))}({app:t,service:s,events:a,onInstanceDeleted:y}),function(e,t,n){e.get("/api/nodes/:id/environment-templates",async e=>({data:await t.listEnvironmentTemplates(ax.parse(e.params).id)})),e.get("/api/nodes/:nodeId/environment-templates/:templateId",async e=>{const n=ox.parse(e.params);return{data:await t.getEnvironmentTemplate(n.nodeId,n.templateId)}}),e.post("/api/controlled-instances/:id/environment-templates",async(e,i)=>{const s=ax.parse(e.params).id,a=await t.createEnvironmentTemplate(s,e.body);return n.publish("environment-template.updated",{templateId:a.id,nodeId:a.nodeId,status:a.status}),i.code(201).send({data:a})}),e.delete("/api/nodes/:nodeId/environment-templates/:templateId",async e=>{const i=ox.parse(e.params),s=await t.deleteEnvironmentTemplate(i.nodeId,i.templateId);return n.publish("environment-template.deleted",s),{data:s}})}(t,s,a),function({app:e,service:t,events:s,appSessionAggregator:a,aiSessionAggregator:o,aiSessionUnread:c,aiSessionAttachments:d,aiSessionAttachmentCache:l}){e.get("/api/app-sessions",async e=>{const n=f.z.object({refresh:f.z.string().optional(),instanceId:f.z.string().trim().min(1).optional(),streamId:f.z.string().trim().min(1).optional(),sinceRevision:f.z.string().optional()}).parse(e.query||{});if(n.instanceId&&await KI(t,e,n.instanceId),void 0!==n.sinceRevision){const e=Number(n.sinceRevision);if(!Number.isInteger(e)||e<0){const e=new Error("sinceRevision must be a non-negative integer.");throw Object.assign(e,{statusCode:400,code:"APP_SESSION_DELTA_INVALID"}),e}if(!n.streamId){const e=new Error("streamId is required with sinceRevision.");throw Object.assign(e,{statusCode:400,code:"APP_SESSION_DELTA_INVALID"}),e}return{data:await a.delta({instanceId:n.instanceId,streamId:n.streamId,sinceRevision:e})}}const i=await a.list({refresh:"true"===n.refresh||"1"===n.refresh,instanceId:n.instanceId}),s=await VI(t,e);return{data:{...i,instances:i.instances.filter(e=>s.has(e.instanceId)&&(!n.instanceId||e.instanceId===n.instanceId))}}}),e.post("/api/controlled-instances/:id/apps/sessions",async e=>{const n=zI.parse(e.params),i=px.parse(e.body),a=await t.launchAppSession(n.id,i.appId,{...i.options,...i.cwdFolderId?{cwdFolderId:i.cwdFolderId}:{}});return s.publish("instance.app-session.launched",{instanceId:n.id,sessionId:"string"==typeof a.id?a.id:void 0,appId:i.appId}),{data:a}}),e.post("/api/controlled-instances/:id/apps/sessions/:sessionId/stop",async e=>{const n=OI.parse(e.params),i=await t.stopAppSession(n.id,n.sessionId);return s.publish("instance.app-session.stopped",{instanceId:n.id,sessionId:n.sessionId}),{data:i}}),e.patch("/api/controlled-instances/:id/apps/sessions/:sessionId",async e=>{const n=OI.parse(e.params),i=ux.parse(e.body),a=await t.renameAppSession(n.id,n.sessionId,i.title);return s.publish("instance.app-session.renamed",{instanceId:n.id,sessionId:n.sessionId,title:i.title}),{data:a}}),e.post("/api/controlled-instances/:id/apps/sessions/:sessionId/access",async e=>{const n=OI.parse(e.params);hx.parse(e.body||{});const i=_I(e),s=await t.createAppSessionAccessToken({instanceId:n.id,sessionId:n.sessionId,..."user"===i?.type?{authorization:{userId:i.userId,authorizationRevision:i.authorizationRevision}}:{}});return{data:{mode:s.mode,url:`/apps/access/${s.mode}?token=${encodeURIComponent(s.token)}`,token:s.token,expiresAt:s.expiresAt}}}),e.delete("/api/controlled-instances/:id/apps/sessions/:sessionId/access",async e=>{const n=OI.parse(e.params),i=mx.parse(e.body||{});return t.revokeAppSessionAccessToken(i.token,{instanceId:n.id,sessionId:n.sessionId}),{data:{revoked:!0}}}),e.get("/api/controlled-instances/:id/app-sessions",async e=>{const t=zI.parse(e.params),n=(await a.list()).instances.find(e=>e.instanceId===t.id);return{data:n?.appSessions||{runningCount:0,problemCount:0,sessions:[],updatedAt:(new Date).toISOString()}}}),e.get("/api/controlled-instances/:id/ai-sessions/history",async e=>{const n=zI.parse(e.params),i=e.query.agents?.split(",").map(e=>e.trim()).filter(Boolean);return{data:await t.listAiSessionHistory(n.id,i)}}),e.get("/api/controlled-instances/:id/ai-sessions/history/:sessionId",async e=>{const n=OI.parse(e.params);return{data:await t.getAiSessionHistoryDetail(n.id,n.sessionId)}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId",async e=>{const n=OI.parse(e.params);return{data:await t.getAiSessionDetail(n.id,n.sessionId)}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/turns",async e=>{const n=OI.parse(e.params);return{data:await t.getAiSessionTurnIndex(n.id,n.sessionId)}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/turns/:turnId",async e=>{const n=jI.parse(e.params);return{data:await t.getAiSessionTurnBody(n.id,n.sessionId,n.turnId)}}),e.post("/api/controlled-instances/:id/ai-session-attachments/drafts",{bodyLimit:22020096},async(e,n)=>{const s=zI.parse(e.params),a=Cn.parse(e.query),o=(await t.requireControlledInstance(s.id,!0)).config.aiSessionMaxFileAttachmentBytes??fn;if("file"===a.kind&&a.size>=o)throw Object.assign(new Error(`File attachment must be smaller than ${o} bytes.`),{statusCode:413,code:"AI_SESSION_ATTACHMENTS_TOO_LARGE"});const r=`cia_${i.randomUUID().replace(/-/g,"").slice(0,24)}`,c="/api/ai-session-attachments/draft-streams",p=new AbortController,u=()=>p.abort();e.raw.once("aborted",u),n.raw.once("close",u);const m=l.beginBestEffortWrite({instanceId:s.id,scopeType:a.scopeType,scopeId:a.scopeId,attachmentId:r,kind:a.kind,name:a.name,mime:a.mime,size:a.size,cacheUntil:Date.now()+864e5});let h=0;try{const i=yx(jn,await fx(await t.proxyInstanceHttp(s.id,c,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(On.parse({attachmentId:r,...a})),signal:p.signal})),"start");if(i.attachmentId!==r||0!==i.offset)throw Object.assign(new Error("Controlled instance returned an invalid attachment upload offset."),{statusCode:502,code:"AI_SESSION_ATTACHMENT_OFFSET_MISMATCH"});for await(const n of e.body){const e=Buffer.isBuffer(n)?n:Buffer.from(n);for(let n=0;n<e.length;n+=vn){const i=e.subarray(n,Math.min(n+vn,e.length));m?.offer(i);const a=yx(jn,await fx(await t.proxyInstanceHttp(s.id,`${c}/${encodeURIComponent(r)}?offset=${h}`,{method:"PUT",headers:{"content-type":"application/octet-stream","content-length":String(i.length)},body:i,signal:p.signal})),"chunk"),o=h+i.length;if(a.attachmentId!==r||a.offset!==o)throw Object.assign(new Error("Controlled instance returned an invalid attachment upload offset."),{statusCode:502,code:"AI_SESSION_ATTACHMENT_OFFSET_MISMATCH"});h=a.offset}}const o=yx(Pn,await fx(await t.proxyInstanceHttp(s.id,`${c}/${encodeURIComponent(r)}/complete`,{method:"POST",headers:{"content-type":"application/json"},body:"{}",signal:p.signal})),"completion");return m?.finish(),n.code(201).send({data:o})}catch(i){if(m?.abort(),t.proxyInstanceHttp(s.id,`${c}/${encodeURIComponent(r)}`,{method:"DELETE"}).catch(()=>{}),0===h&&i&&"object"==typeof i&&"statusCode"in i&&404===i.statusCode&&(!("code"in i)||"AI_SESSION_NOT_FOUND"!==i.code)){const t=[];let i=0;for await(const n of e.body){const e=Buffer.isBuffer(n)?n:Buffer.from(n);if(i+=e.length,i>a.size)throw Object.assign(new Error("Attachment content exceeded its declared size."),{statusCode:400,code:"AI_SESSION_ATTACHMENT_SIZE_MISMATCH"});t.push(e)}if(i!==a.size)throw Object.assign(new Error("Attachment content did not match its declared size."),{statusCode:400,code:"AI_SESSION_ATTACHMENT_SIZE_MISMATCH"});return n.code(201).send({data:d.upload({instanceId:s.id,sessionId:a.scopeId,kind:a.kind,name:a.name,mime:a.mime,data:Buffer.concat(t).toString("base64")})})}throw i}finally{e.raw.off("aborted",u),n.raw.off("close",u)}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/messages/:messageId/attachments/:attachmentId/content",async(e,i)=>{const s=PI.parse(e.params),a=l.get({instanceId:s.id,sessionId:s.sessionId,messageId:s.messageId,attachmentId:s.attachmentId});if(a)return i.header("Content-Type",a.mime),i.header("Content-Length",String(a.size)),a.etag&&i.header("ETag",a.etag),i.header("Cache-Control","private, max-age=0, must-revalidate"),i.header("X-Content-Type-Options","nosniff"),i.header("Accept-Ranges","none"),i.header("Content-Disposition",a.disposition||`${"image"===a.kind?"inline":"attachment"}; filename*=UTF-8''${encodeURIComponent(a.name)}`),a.etag&&e.headers["if-none-match"]===a.etag?i.code(304).send():i.send(n.createReadStream(a.path));const o=new AbortController;i.raw.once("close",()=>o.abort());const c=await t.proxyInstanceHttp(s.id,`/api/ai-sessions/${encodeURIComponent(s.sessionId)}/messages/${encodeURIComponent(s.messageId)}/attachments/${encodeURIComponent(s.attachmentId)}/content`,{method:"GET",signal:o.signal}),d=c.headers["x-task-handoff-attachment-cache-until"],p=c.headers["x-task-handoff-attachment-size"];for(const[e,t]of Object.entries(c.headers))["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","x-task-handoff-attachment-cache-until","x-task-handoff-attachment-size"].includes(e.toLowerCase())||i.header(e,t);if(!c.body)return i.code(c.status).send();const u=r.Readable.fromWeb(c.body),m=Number(p||c.headers["content-length"]);200===c.status&&Number.isInteger(m)&&m>0&&i.header("Content-Length",String(m));const h=Number(d),g=c.headers["content-type"]||"application/octet-stream",f=c.headers["content-disposition"],y=200===c.status&&Number.isInteger(m)&&m>0&&Number.isFinite(h)?l.beginBestEffortWrite({instanceId:s.id,scopeType:"session",scopeId:s.sessionId,attachmentId:s.attachmentId,sessionId:s.sessionId,messageId:s.messageId,kind:Dn(g)?"image":"file",name:gx(f,s.attachmentId),mime:g,size:m,...f?{disposition:f}:{},...c.headers.etag?{etag:c.headers.etag}:{},cacheUntil:h}):void 0,b=new r.Transform({transform(e,t,n){y?.offer(e),n(null,e)},flush(e){y?.finish(),e()}});return i.raw.once("close",()=>{u.destroy(),u.readableEnded||y?.abort()}),i.code(c.status).send(u.pipe(b))}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/timeline",async e=>{const n=OI.parse(e.params);return{data:await t.getAiSessionTimeline(n.id,n.sessionId)}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/turns/:turnId/timeline",async e=>{const n=jI.parse(e.params);return{data:await t.getAiSessionTurnTimeline(n.id,n.sessionId,n.turnId)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/resume",async e=>{const n=OI.parse(e.params);hx.parse(e.body||{});const i=await t.resumeAiSession(n.id,n.sessionId);return s.publish("instance.ai-session.resumed",{instanceId:n.id,sessionId:i.aiSessionId,providerSessionId:i.providerSessionId,appSessionId:i.appSessionId,disposition:i.disposition}),{data:i}}),e.get("/api/controlled-instances/:id/ai-sessions/workspace",async e=>{const n=zI.parse(e.params),i=lx.parse(e.query||{});return{data:await t.inspectAiSessionWorkspace(n.id,i.cwdFolderId)}}),e.post("/api/controlled-instances/:id/ai-sessions",async e=>{const n=zI.parse(e.params),i=zi.parse(e.body||{}),a=i.attachments.filter(e=>"upload-ref"!==e.source.type||!e.id.startsWith("cia_")),o=d.resolveRefs(a,n.id,i.clientRequestId),r=new Map(o.map(e=>[e.id,e])),c=i.attachments.map(e=>"upload-ref"===e.source.type&&e.id.startsWith("cia_")?e:r.get(e.id)).filter(Boolean),p=await t.createAiSession(n.id,{...i,attachments:c}),u=new Set(i.attachments.filter(e=>"upload-ref"===e.source.type&&e.id.startsWith("cia_")).map(e=>e.id));if(u.size){const e=(await t.requireControlledInstance(n.id,!0)).config.aiSessionAttachmentRetentionDays??30;t.getAiSessionTurnIndex(n.id,p.aiSessionId).then(async s=>{const a=s.turns.at(-1);if(!a)return;const o=await t.getAiSessionTurnBody(n.id,p.aiSessionId,a.id),r=o.turn.userMessages?.find(e=>e.attachments.some(e=>u.has(e.id)))?.id;if(r)for(const t of u)l.bind({instanceId:n.id,attachmentId:t,scopeId:i.clientRequestId,sessionId:p.aiSessionId,messageId:r,cacheUntil:Date.now()+24*e*60*60*1e3})}).catch(()=>{})}return s.publish("instance.ai-session.created",{instanceId:n.id,sessionId:p.aiSessionId,providerSessionId:p.providerSessionId,clientRequestId:i.clientRequestId}),{data:p}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/open-app",async e=>{const n=OI.parse(e.params),i=Oi.parse(e.body||{}),a=await t.openAiSessionApp(n.id,n.sessionId,i.clientRequestId);return s.publish("instance.ai-session.app-opened",{instanceId:n.id,sessionId:n.sessionId,appSessionId:a.appSessionId}),{data:a}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/fork",async e=>{const n=OI.parse(e.params),i=Ci.parse(e.body||{}),a=await t.forkAiSession(n.id,n.sessionId,i);return s.publish("instance.ai-session.forked",{instanceId:n.id,sourceSessionId:n.sessionId,sessionId:a.aiSessionId,providerSessionId:a.providerSessionId,clientRequestId:i.clientRequestId}),{data:a}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/close",async e=>{const n=OI.parse(e.params),i=Pi.parse(e.body||{}),a=await t.closeAiSession(n.id,n.sessionId,i.clientRequestId);return s.publish("instance.ai-session.closed",{instanceId:n.id,sessionId:n.sessionId,providerSessionId:a.providerSessionId}),{data:a}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/messages",async(e,n)=>{const i=performance.now(),a=function(e,t){const n=Array.isArray(e)?e[0]:e,i="string"==typeof n?n.trim():"";return/^[A-Za-z0-9._:-]{1,128}$/.test(i)?i:t}(e.headers[eu],String(e.id));let o;const r=t=>{const s=performance.now()-i,r=nu(o?.serverTiming,tu("control_plane",s));n.header(eu,a),n.header("server-timing",r),e.log.info({traceId:a,instanceId:e.params.id,sessionId:e.params.sessionId,outcome:t,controlPlaneMs:s,nodeTransportMs:o?.nodeTransportMs,serverTiming:r},"AI session message request timing")},c=OI.parse(e.params),p=Ai.parse(e.body||{}),u=p.attachments.filter(e=>"upload-ref"!==e.source.type||!e.id.startsWith("cia_")),m=d.resolveRefs(u,c.id,c.sessionId),h=new Map(m.map(e=>[e.id,e])),g=p.attachments.map(e=>"upload-ref"===e.source.type&&e.id.startsWith("cia_")?e:h.get(e.id)).filter(Boolean);let f;try{f=await t.sendAiSessionMessage(c.id,c.sessionId,p.message,p.mode,g,p.references,p.permissionMode,{traceId:a,onTiming:e=>{o=e}})}catch(e){throw r("failed"),e}const y=new Set(p.attachments.filter(e=>"upload-ref"===e.source.type&&e.id.startsWith("cia_")).map(e=>e.id)),b=f.messageId;if(y.size&&b){const e=(await t.requireControlledInstance(c.id,!0)).config.aiSessionAttachmentRetentionDays??30,n=Date.now()+24*e*60*60*1e3;for(const e of y)l.bind({instanceId:c.id,attachmentId:e,scopeId:c.sessionId,sessionId:c.sessionId,messageId:b,cacheUntil:n})}return s.publish("instance.ai-session.message-sent",{instanceId:c.id,sessionId:c.sessionId}),r("completed"),{data:f}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/mentions",async e=>{const n=OI.parse(e.params);return{data:await t.aiSessionMentionCatalog(n.id,n.sessionId)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/mentions/files",async e=>{const n=OI.parse(e.params),i=Ii.parse(e.body||{});return{data:await t.searchAiSessionMentionFiles(n.id,n.sessionId,i.query)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/commands",async e=>{const n=OI.parse(e.params),i=pi.parse(e.body||{}),a=await t.executeAiSessionCommand(n.id,n.sessionId,i);return s.publish("instance.ai-session.command-executed",{instanceId:n.id,sessionId:n.sessionId,command:i.command}),{data:a}}),e.get("/api/controlled-instances/:id/ai-sessions/:sessionId/queue",async e=>{const n=OI.parse(e.params);return{data:await t.aiSessionQueue(n.id,n.sessionId)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/:queueId/steer",async e=>{const n=DI.parse(e.params),i=await t.steerAiSessionQueuedMessage(n.id,n.sessionId,n.queueId);return s.publish("instance.ai-session.message-sent",{instanceId:n.id,sessionId:n.sessionId}),{data:i}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/:queueId/retry",async e=>{const n=DI.parse(e.params);return{data:await t.retryAiSessionQueuedMessage(n.id,n.sessionId,n.queueId)}}),e.delete("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/:queueId",async e=>{const n=DI.parse(e.params);return{data:await t.removeAiSessionQueuedMessage(n.id,n.sessionId,n.queueId)}}),e.patch("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/:queueId",async e=>{const n=DI.parse(e.params),i=qi.parse(e.body||{});return{data:await t.editAiSessionQueuedMessage(n.id,n.sessionId,n.queueId,i)}}),e.patch("/api/controlled-instances/:id/ai-sessions/:sessionId/queue/reorder",async e=>{const n=OI.parse(e.params),i=Mi.parse(e.body||{});return{data:await t.reorderAiSessionQueuedMessages(n.id,n.sessionId,i)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/interrupt",async e=>{const n=OI.parse(e.params),i=await t.interruptAiSession(n.id,n.sessionId);return s.publish("instance.ai-session.interrupted",{instanceId:n.id,sessionId:n.sessionId}),{data:i}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/approval",async e=>{const n=OI.parse(e.params),i=Li.parse(e.body||{}),a=await t.resolveAiSessionApproval(n.id,n.sessionId,i.decision);return s.publish("instance.ai-session.approval-resolved",{instanceId:n.id,sessionId:n.sessionId,decision:i.decision}),{data:a}}),e.get("/api/ai-sessions",async(e,n)=>{const i=e.query;if(i.instanceId&&await KI(t,e,i.instanceId),void 0!==i.sinceRevision){const e=Number(i.sinceRevision);if(!Number.isInteger(e)||e<0)return n.code(400).send({error:"invalid_since_revision"});try{return i.streamId?{data:await o.delta({instanceId:i.instanceId,streamId:i.streamId,sinceRevision:e})}:n.code(400).send({error:"stream_id_required"})}catch(e){if("AI_SESSION_DELTA_INSTANCE_ID_REQUIRED"===e.message)return n.code(400).send({error:"instance_id_required"});throw e}}const s=await o.list({refresh:"true"===i.refresh||"1"===i.refresh,instanceId:i.instanceId}),a=await VI(t,e),r={...s,instances:s.instances.filter(e=>a.has(e.instanceId)&&(!i.instanceId||e.instanceId===i.instanceId))};for(const e of r.instances)c.reconcile(e.instanceId,e.aiSessions);return{data:{...r,instances:r.instances.map(e=>({...e,aiSessions:c.decorate(e.instanceId,e.aiSessions)}))}}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/read",async(e,t)=>{const n=OI.parse(e.params),i=f.z.object({sessionUpdatedAt:f.z.string().datetime()}).strict().parse(e.body||{}),a=(await o.list()).instances.find(e=>e.instanceId===n.id),r=a?.aiSessions.sessions.find(e=>e.id===n.sessionId);if(!a||!r)return t.code(404).send({error:{code:"AI_SESSION_NOT_FOUND",message:"AI session was not found."}});c.reconcile(n.id,a.aiSessions);const d=c.markRead(n.id,n.sessionId,i.sessionUpdatedAt);return d?(s.publish(_n,d,{topic:"ai.sessions",scope:{instanceId:n.id,sessionId:n.sessionId}}),{data:d}):t.code(404).send({error:{code:"AI_SESSION_NOT_FOUND",message:"AI session was not found."}})})}({app:t,service:s,events:a,appSessionAggregator:o,aiSessionAggregator:c,aiSessionUnread:d,aiSessionAttachments:p,aiSessionAttachmentCache:u}),function({app:e,service:t,events:n}){e.get("/api/triggers",async()=>({data:await t.listTriggers()})),e.post("/api/triggers",async(e,i)=>{const s=t.createTrigger(e.body);return n.publish("trigger.created",{configHash:s.configHash}),i.code(201).send({data:s})}),e.put("/api/triggers/:configHash",async e=>{const i=LI.parse(e.params),s=await t.updateTrigger(i.configHash,e.body);return n.publish("trigger.updated",{previousConfigHash:i.configHash,configHash:s.trigger.configHash}),{data:s}}),e.delete("/api/triggers/:configHash",async e=>{const i=LI.parse(e.params),s=await t.deleteTrigger(i.configHash);return n.publish("trigger.deleted",{configHash:i.configHash}),{data:s}}),e.post("/api/triggers/:configHash/apply",async e=>{const i=LI.parse(e.params),s=await t.applyTrigger(i.configHash,e.body||{});return n.publish("trigger.applied",{configHash:i.configHash}),{data:s}}),e.get("/api/controlled-instances/:id/triggers",async e=>{const n=zI.parse(e.params);return{data:await t.listInstanceTriggers(n.id)}}),e.post("/api/controlled-instances/:id/ai-sessions/:sessionId/triggers",async e=>{const i=OI.parse(e.params),s=await t.bindAiSessionTrigger(i.id,i.sessionId,e.body||{});return n.publish("trigger.deployment.bound",{instanceId:i.id,sessionId:i.sessionId},{topic:"triggers",scope:{instanceId:i.id}}),{data:s}}),e.delete("/api/controlled-instances/:id/ai-sessions/:sessionId/triggers/:configHash",async e=>{const i=qI.parse(e.params),s=await t.unbindAiSessionTrigger(i.id,i.sessionId,i.configHash);return n.publish("trigger.deployment.unbound",{instanceId:i.id,sessionId:i.sessionId,configHash:i.configHash},{topic:"triggers",scope:{instanceId:i.id}}),{data:s}}),e.post("/api/controlled-instances/:id/triggers/:configHash/run",async e=>{const i=MI.parse(e.params),s=await t.runInstanceTrigger(i.id,i.configHash,e.body||{});return n.publish("trigger.run.requested",{instanceId:i.id,configHash:i.configHash},{topic:"triggers",scope:{instanceId:i.id}}),{data:s}})}({app:t,service:s,events:a}),function({app:e,service:t,chatGateway:n}){e.get("/api/chat/sessions",async()=>({data:t.listChatSessions()})),e.get("/api/chat/sessions/:id",async e=>({data:t.requireChatSession(zI.parse(e.params).id)})),e.get("/api/chat-gateway/status",async()=>({data:n.status()})),e.post("/api/chat-gateway/poll-ai-sessions",async()=>({data:await n.pollAiSessionsNow()})),e.get("/api/chat-gateway/bridges",async()=>({data:t.listChatBridges()})),e.post("/api/chat-gateway/bridges",async e=>({data:t.createChatBridge(e.body)})),e.patch("/api/chat-gateway/bridges/:id",async i=>{const s=zI.parse(i.params).id,a=t.requireChatBridge(s),o=jh.parse(i.body),r=t.updateChatBridge(s,i.body),c="boolean"==typeof o.enabled?o.enabled:void 0;return e.log.info({component:"control-plane-chat-gateway",action:"bridge-patch",bridgeId:s,hasEnabled:void 0!==c,requestedEnabled:c,previousEnabled:a.enabled,updatedEnabled:t.requireChatBridge(s).enabled},"chat gateway bridge state changed"),void 0!==c&&c!==a.enabled&&(c?n.startBridge(s):n.stopBridge(s)),{data:r}}),e.post("/api/chat-gateway/bridges/:id/start",async i=>{const s=zI.parse(i.params).id,a=t.requireChatBridge(s);return t.updateChatBridge(s,{enabled:!0}),e.log.info({component:"control-plane-chat-gateway",action:"bridge-start-request",bridgeId:s,previousEnabled:a.enabled,updatedEnabled:t.requireChatBridge(s).enabled},"chat gateway bridge state changed"),{data:n.startBridge(s)}}),e.post("/api/chat-gateway/bridges/:id/stop",async i=>{const s=zI.parse(i.params).id,a=t.requireChatBridge(s);return t.updateChatBridge(s,{enabled:!1}),e.log.info({component:"control-plane-chat-gateway",action:"bridge-stop-request",bridgeId:s,previousEnabled:a.enabled,updatedEnabled:t.requireChatBridge(s).enabled},"chat gateway bridge state changed"),{data:n.stopBridge(s)}}),e.delete("/api/chat-gateway/bridges/:id",async e=>{const i=zI.parse(e.params).id;return n.stopBridge(i),{data:{deleted:t.deleteChatBridge(i)}}}),e.post("/api/chat-gateway/messages",{bodyLimit:67108864},async e=>({data:await t.handleChatGatewayMessage(wd.parse(e.body))})),e.post("/api/chat-gateway/actions",async e=>({data:await t.handleChatGatewayAction(ex(e.body))})),e.get("/api/pending-routes",async()=>({data:await t.listPendingRoutes()}))}({app:t,service:s,chatGateway:l})}const vx=new Set(["connection","content-length","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade"]);function Ix(e){const t=Object.entries(e).find(([e])=>"sec-websocket-protocol"===e.toLowerCase()),n=t?.[1],i=(Array.isArray(n)?n.join(","):"string"==typeof n?n:"").split(",").map(e=>e.trim()).filter(Boolean);return i.length?i:void 0}const xx=new Set(["content-encoding"]),wx=new Set(["host",...mn]);function Sx(e){return Object.fromEntries(Object.entries(e).flatMap(([e,t])=>{const n=e.toLowerCase();if(vx.has(n)||"authorization"===n||void 0===t)return[];const i=Array.isArray(t)?t.join(", "):String(t);if("cookie"!==n)return[[e,i]];const s=function(e){return e.split(";").map(e=>e.trim()).filter(e=>e&&e.slice(0,e.indexOf("=")).trim()!==Fp).join("; ")}(i);return s?[[e,s]]:[]}))}function Ax(e){return function(e,t={}){return Object.fromEntries(Object.entries(e).flatMap(([e,n])=>{const i=e.toLowerCase();return void 0===n||t.blockedHeaders?.has(i)||i.startsWith("sec-websocket-")&&"sec-websocket-origin"!==i?[]:[[e,Array.isArray(n)?n.join(", "):String(n)]]}))}(Sx(e),{blockedHeaders:wx})}function Ex(e,t,n,i,s={}){const a=new AbortController;return t.raw.once("close",()=>a.abort()),e.proxyInstanceHttp(n,i,{...s,signal:a.signal})}function _x(e,t,n){for(const[n,i]of Object.entries(t.headers)){const t=n.toLowerCase();vx.has(t)||xx.has(t)||e.header(n,i)}if(!t.body)return e.code(t.status).send();const i=r.Readable.fromWeb(t.body);return e.raw.once("close",()=>i.destroy()),e.code(t.status).send(n?i.pipe(n):i)}function Tx(e){return`/instances/${encodeURIComponent(e)}`}function zx(e,t,n,i){const s=function(e,t){const n=e.split("?",1)[0]||"/";return t.toLowerCase().includes("text/html")&&!n.startsWith("/api/")}(i,Object.entries(t.headers).find(([e])=>"content-type"===e.toLowerCase())?.[1]||"")?function(e){const t=[];let n=0,i=!1;const s=(s,a=!1)=>{if(i)return;const o=Buffer.concat(t,n).toString("utf8");!/<head(\s[^>]*)?>/i.exec(o)&&!a&&n<65536||(i=!0,s.push(function(e,t){if(e.includes("__TASK_HANDOFF_PUBLIC_BASE__"))return e;const n=`<script>window.__TASK_HANDOFF_PUBLIC_BASE__=${JSON.stringify(t)};<\/script>`;return/<head(\s[^>]*)?>/i.test(e)?e.replace(/<head(\s[^>]*)?>/i,e=>`${e}\n${n}`):`${n}\n${e}`}(o,e)),t.length=0,n=0)};return new r.Transform({transform(e,a,o){i?this.push(e):(t.push(Buffer.from(e)),n+=e.length,s(this)),o()},flush(e){s(this,!0),e()}})}(Tx(n)):void 0;return _x(e,t,s)}async function kx(e){if(Buffer.isBuffer(e))return e;if(e instanceof Uint8Array)return Buffer.from(e);if(e instanceof URLSearchParams)return e.toString();if(e&&"object"==typeof e&&Symbol.asyncIterator in e){const t=[];let n=0;for await(const i of e){const e=Buffer.isBuffer(i)?i:Buffer.from(i);if(n+=e.length,n>67108864)throw Object.assign(new Error("Instance proxy request body exceeds the configured limit."),{statusCode:413,code:"INSTANCE_PROXY_REQUEST_TOO_LARGE"});t.push(e)}return Buffer.concat(t,n)}return"string"==typeof e?e:null==e?void 0:JSON.stringify(e)}function Nx(e,t){if("string"!=typeof t||!e.hasContentTypeParser(t))try{e.addContentTypeParser(t,{parseAs:"buffer"},(e,t,n)=>n(null,t))}catch(e){if(e instanceof Error&&/Content type parser .* already present/i.test(e.message))return;throw e}}function Cx(e){return new URL(e,"http://control-plane.local").searchParams.get("token")||""}function Rx(e,t,n){const i=encodeURIComponent(e),s=encodeURIComponent(t),a=`apps/access/vnc/${i}/proxy`,o=n.vnc&&"object"==typeof n.vnc?n.vnc:{};return"kasmvnc"===("string"==typeof o.backend?o.backend:"")?`/${a}/api/apps/sessions/${s}/web/`:`/${a}/api/novnc/vnc.html?path=${encodeURIComponent(`${a}/api/apps/sessions/${s}/vnc`)}&autoconnect=1&resize=scale`}class Ox{snapshots=new Map;history=new Map;advertisedStreams=new Map;recoveries=new Map;listeners=new Set;bootstrap;logger;recoverDelta;recoverSnapshot;onRecoveredEvent;recoveryCount=0;counters={streamResets:0,gaps:0,deltaRecoveries:0,snapshotRecoveries:0,recoveryFailures:0};constructor(e){this.bootstrap=e.bootstrap,this.logger=e.logger,this.recoverDelta=e.recoverDelta,this.recoverSnapshot=e.recoverSnapshot,this.onRecoveredEvent=e.onRecoveredEvent}handleEvent(e){if(e.type===An||e.type===En){const t=pl(e.type===An?fs:bs,e.payload);return!!t.success||(this.logger?.warn?.({eventType:e.type,issues:t.error.issues,errorCode:"AI_SESSION_TRANSIENT_EVENT_INVALID"},"ai-session.aggregator.transient-event.invalid"),!1)}const t=e.type===xn?ms:e.type===wn?hs:e.type===Sn?gs:void 0;if(!t)return!1;const n=pl(t,e.payload);return n.success?e.type===xn?this.applySnapshot(n.data):e.type===wn?this.applyPatch(n.data):this.applyRemoved(n.data):(this.logger?.warn?.({eventType:e.type,issues:n.error.issues,errorCode:"AI_SESSION_EVENT_INVALID"},"ai-session.aggregator.event.invalid"),!1)}onSnapshot(e){return this.listeners.add(e),()=>this.listeners.delete(e)}applySnapshot(e){const t=this.advertisedStreams.get(e.meta.instanceId)?.streamId;return t&&t!==e.meta.streamId?(this.logger?.warn?.({instanceId:e.meta.instanceId,advertisedStreamId:t,streamId:e.meta.streamId,revision:e.meta.revision},"ai-session.aggregator.snapshot.obsolete-stream"),!1):this.apply({type:xn,payload:e})}advertiseStream(e,t){return this.advertisedStreams.set(e,t),this.recoverStream(e,t.streamId,t.latestRevision).catch(n=>{this.counters.recoveryFailures+=1,this.logger?.warn?.({instanceId:e,streamId:t.streamId,error:n instanceof Error?n.message:String(n)},"ai-session.aggregator.recovery.failed")})}diagnostics(){return{...this.counters,recoveriesStarted:this.recoveryCount,activeRecoveries:this.recoveries.size}}removeInstance(e){this.snapshots.delete(e),this.history.delete(e),this.advertisedStreams.delete(e)}applyPatch(e){return this.apply({type:wn,payload:e})}applyRemoved(e){return this.apply({type:Sn,payload:e})}async list(e={}){return e.refresh&&e.instanceId&&this.recoverSnapshot?await this.refreshInstance(e.instanceId):(e.refresh||0===this.snapshots.size)&&await this.bootstrapFromInstances(),this.view(e.instanceId)}async streamDescriptors(){return 0===this.snapshots.size&&await this.bootstrapFromInstances(),[...this.snapshots.entries()].map(([e,t])=>({topic:"ai.sessions",instanceId:e,streamId:t.streamId,latestRevision:t.revision,earliestRetainedRevision:this.history.get(e)?.[0]?.payload.meta.revision??t.revision+1}))}async delta(e){0===this.snapshots.size&&await this.bootstrapFromInstances();const t=this.resolveDeltaInstanceId(e.instanceId);this.pruneHistory(t);const n=this.snapshots.get(t)?.revision??0,i=this.snapshots.get(t)?.streamId||"unavailable",s=this.history.get(t)?.[0]?.payload.meta.revision??n+1;if(e.streamId!==i||e.sinceRevision>n)return vs.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:!0,events:[]});if(e.sinceRevision===n)return vs.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:!1,events:[]});const a=(this.history.get(t)??[]).filter(t=>t.payload.meta.revision>e.sinceRevision),o=!a.length||a[0].payload.meta.revision!==e.sinceRevision+1;return vs.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:o,events:o?[]:a.map(({type:e,payload:t})=>({type:e,payload:t}))})}apply(e,t=!1){const{meta:n}=e.payload,i=this.advertisedStreams.get(n.instanceId)?.streamId;if(i&&i!==n.streamId)return this.logger?.warn?.({instanceId:n.instanceId,advertisedStreamId:i,streamId:n.streamId,revision:n.revision},"ai-session.aggregator.event.obsolete-stream"),!1;const s=this.recoveries.get(n.instanceId);if(s&&!t)return s.streamId===n.streamId&&(s.highWater=Math.max(s.highWater,n.revision)),!1;const a=this.snapshots.get(n.instanceId);e.type===xn&&a&&a.streamId!==n.streamId&&(this.counters.streamResets+=1,this.logger?.info?.({instanceId:n.instanceId,previousStreamId:a.streamId,streamId:n.streamId,previousRevision:a.revision,revision:n.revision,traceId:n.traceId,resetCount:this.counters.streamResets},"ai-session.aggregator.stream-reset"));const o=function(e,t){const{meta:n}=t.payload;if(t.type===xn)return e?.streamId===n.streamId&&n.revision===e.revision?{kind:"duplicate",projection:e}:e?.streamId===n.streamId&&n.revision<e.revision?{kind:"stale",projection:e}:{kind:"applied",projection:cs.parse({streamId:n.streamId,revision:n.revision,lastEventAt:n.generatedAt,snapshot:t.payload.snapshot})};if(!e||e.streamId!==n.streamId)return{kind:"snapshot-required",projection:e,streamId:n.streamId};if(n.revision===e.revision)return{kind:"duplicate",projection:e};if(n.revision<e.revision)return{kind:"stale",projection:e};if(n.revision!==e.revision+1||n.previousRevision!==e.revision)return{kind:"gap",projection:e,expectedRevision:e.revision+1,receivedRevision:n.revision};const i=new Map(e.snapshot.sessions.map(e=>[e.id,e]));if(t.type===wn){for(const e of t.payload.upserted)i.set(e.id,e);for(const e of t.payload.removed)i.delete(e)}else for(const e of t.payload.sessionIds)i.delete(e);const s=[...i.values()],a=rs.parse({runningCount:s.filter(e=>"running"===e.status).length,waitingCount:s.filter(e=>"waiting"===e.status).length,staleCount:e.snapshot.staleCount,sessions:s,updatedAt:n.generatedAt});return{kind:"applied",projection:cs.parse({streamId:n.streamId,revision:n.revision,lastEventAt:n.generatedAt,snapshot:a})}}(a,e);if("applied"!==o.kind)return this.logger?.warn?.({traceId:n.traceId,streamId:n.streamId,instanceId:n.instanceId,currentRevision:a?.revision,revision:n.revision,outcome:o.kind},`ai-session.aggregator.event.${o.kind}`),"gap"!==o.kind&&"snapshot-required"!==o.kind||("gap"===o.kind&&(this.counters.gaps+=1),this.recoverStream(n.instanceId,n.streamId,n.revision).catch(e=>{this.logger?.warn?.({instanceId:n.instanceId,streamId:n.streamId,revision:n.revision,error:e instanceof Error?e.message:String(e)},"ai-session.aggregator.recovery.failed")})),!1;const r=o.projection;this.snapshots.set(n.instanceId,r),this.rememberEvent(n.instanceId,e);const c={instanceId:n.instanceId,streamId:r.streamId,aiSessions:r.snapshot,revision:r.revision,lastEventAt:r.lastEventAt};for(const e of this.listeners)try{e(c)}catch{this.listeners.delete(e)}return this.logger?.info?.({traceId:n.traceId,streamId:n.streamId,instanceId:n.instanceId,revision:n.revision,reason:n.reason,sessionCount:r.snapshot.sessions.length},"ai-session.aggregator.event.accepted"),!0}async bootstrapFromInstances(){this.logger?.info?.({},"ai-session.aggregator.bootstrap");const e=new Map(this.snapshots),t=await this.bootstrap(),n=new Set(t.instances.map(e=>e.instanceId));for(const[t,i]of e)n.has(t)||this.snapshots.get(t)!==i||(this.snapshots.delete(t),this.history.delete(t),this.advertisedStreams.delete(t));for(const n of t.instances){const t=this.snapshots.get(n.instanceId);if(t!==e.get(n.instanceId))continue;const i=this.advertisedStreams.get(n.instanceId)?.streamId;if(i&&i!==n.streamId)continue;if(t?.streamId===n.streamId&&t.revision>=n.revision)continue;const s={type:xn,payload:{meta:{streamId:n.streamId,instanceId:n.instanceId,revision:n.revision,traceId:`ais_bootstrap_${Date.now().toString(36)}`,generatedAt:n.lastEventAt,reason:"startup"},snapshot:n.aiSessions}};this.apply(s)&&this.onRecoveredEvent?.(s)}}async refreshInstance(e){const t=this.snapshots.get(e),n=await this.recoverSnapshot(e);if(this.snapshots.get(e)!==t)return;const i=this.advertisedStreams.get(e)?.streamId;if(i&&i!==n.streamId)return;if(t?.streamId===n.streamId&&t.revision>=n.revision)return;const s={type:xn,payload:{meta:{streamId:n.streamId,instanceId:e,revision:n.revision,traceId:`ais_refresh_${Date.now().toString(36)}`,generatedAt:n.lastEventAt,reason:"startup"},snapshot:n.snapshot}};this.apply(s)&&this.onRecoveredEvent?.(s)}recoverStream(e,t,n){const i=this.recoveries.get(e);if(i)return i.streamId===t?i.highWater=Math.max(i.highWater,n):(i.streamId=t,i.highWater=n),i.promise;if(!this.recoverDelta||!this.recoverSnapshot)return Promise.resolve();const s={promise:Promise.resolve(),streamId:t,highWater:n},a=++this.recoveryCount;return this.logger?.info?.({instanceId:e,highWater:n,recoveryNumber:a},"ai-session.aggregator.recovery.started"),s.promise=(async()=>{for(;;){const t=this.advertisedStreams.get(e);if(!t)return;s.streamId!==t.streamId&&(s.streamId=t.streamId,s.highWater=t.latestRevision);const n=this.snapshots.get(e);if(n&&n.streamId===t.streamId){if(n.revision<Math.max(t.latestRevision,s.highWater)){const t=await this.recoverDelta(e,n.streamId,n.revision);if(this.advertisedStreams.get(e)?.streamId!==t.streamId||s.streamId!==t.streamId)continue;if(t.syncRequired){const t=await this.recoverSnapshot(e);if(this.advertisedStreams.get(e)?.streamId!==t.streamId)continue;const n={type:xn,payload:{meta:{streamId:t.streamId,instanceId:e,revision:t.revision,traceId:`ais_recovery_${Date.now().toString(36)}`,generatedAt:t.lastEventAt,reason:"startup"},snapshot:t.snapshot}};this.apply(n,!0)&&this.onRecoveredEvent?.(n),this.counters.snapshotRecoveries+=1,this.logger?.info?.({instanceId:e,streamId:t.streamId,revision:t.revision,recoveryNumber:a,outcome:"snapshot-fallback"},"ai-session.aggregator.recovery.snapshot")}else{for(const e of t.events)this.apply(e,!0)&&this.onRecoveredEvent?.(e);this.counters.deltaRecoveries+=1,s.highWater=Math.max(s.highWater,t.latestRevision),this.logger?.info?.({instanceId:e,streamId:t.streamId,sinceRevision:t.sinceRevision,latestRevision:t.latestRevision,eventCount:t.events.length,recoveryNumber:a,outcome:"delta"},"ai-session.aggregator.recovery.delta")}}}else{const t=await this.recoverSnapshot(e);if(this.advertisedStreams.get(e)?.streamId!==t.streamId)continue;const n={type:xn,payload:{meta:{streamId:t.streamId,instanceId:e,revision:t.revision,traceId:`ais_recovery_${Date.now().toString(36)}`,generatedAt:t.lastEventAt,reason:"startup"},snapshot:t.snapshot}};this.apply(n,!0)&&this.onRecoveredEvent?.(n),this.counters.snapshotRecoveries+=1,this.logger?.info?.({instanceId:e,streamId:t.streamId,revision:t.revision,recoveryNumber:a,outcome:"snapshot"},"ai-session.aggregator.recovery.snapshot")}const i=this.snapshots.get(e),o=this.advertisedStreams.get(e);if(i&&o&&i.streamId===o.streamId&&i.revision>=Math.max(o.latestRevision,s.highWater))return void this.logger?.info?.({instanceId:e,streamId:i.streamId,revision:i.revision,recoveryNumber:a,outcome:"success"},"ai-session.aggregator.recovery.completed")}})().finally(()=>this.recoveries.delete(e)),this.recoveries.set(e,s),s.promise}rememberEvent(e,t){const n=this.history.get(e)??[],i=n.length&&n[0].payload.meta.streamId!==t.payload.meta.streamId?[]:n;i.push({...t,createdAtMs:Date.now()}),this.history.set(e,i),this.pruneHistory(e)}pruneHistory(e){const t=this.history.get(e);if(!t?.length)return;const n=t.filter(e=>e.createdAtMs>=Date.now()-36e5);n.length?this.history.set(e,n):this.history.delete(e)}resolveDeltaInstanceId(e){if(e)return e;const t=[...this.snapshots.keys()];if(1===t.length)return t[0];throw new Error("AI_SESSION_DELTA_INSTANCE_ID_REQUIRED")}view(e){return{updatedAt:(new Date).toISOString(),instances:[...this.snapshots.entries()].filter(([t])=>!e||t===e).map(([e,t])=>({instanceId:e,streamId:t.streamId,aiSessions:t.snapshot,revision:t.revision,lastEventAt:t.lastEventAt}))}}}const jx=f.z.object({id:f.z.string().trim().min(1),instanceId:f.z.string().trim().min(1).max(160),sessionId:f.z.string().trim().min(1).max(120),unread:f.z.boolean(),lastStatus:f.z.enum(["running","waiting","idle","failed"]),sessionUpdatedAt:f.z.string().datetime(),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}).strict();class Px{records;bySession=new Map;listener;constructor(e,t={}){this.records=new Qd(e.aiSessionUnreadDir,{schema:jx}),this.listener=t.onChanged}init(){this.records.init(),this.bySession.clear();for(const e of this.records.list())this.bySession.set(Lx(e.instanceId,e.sessionId),e)}reconcile(e,t){const n=new Set;for(const i of t.sessions)n.add(i.id),this.reconcileSession(e,i);for(const t of[...this.bySession.values()])t.instanceId!==e||n.has(t.sessionId)||this.deleteRecord(t)}decorate(e,t){return{...t,sessions:t.sessions.map(t=>({...t,unread:this.bySession.get(Lx(e,t.id))?.unread||!1}))}}markRead(e,t,n){const i=this.bySession.get(Lx(e,t));return i&&i.sessionUpdatedAt===n&&i.unread?Dx(this.store({...i,unread:!1,updatedAt:(new Date).toISOString()},!1)):i?Dx(i):void 0}removeInstance(e){for(const t of[...this.bySession.values()])t.instanceId===e&&this.deleteRecord(t)}reconcileSession(e,t){const n=Lx(e,t.id),i=this.bySession.get(n),s=(new Date).toISOString();if(!i)return void this.store({id:Mx(e,t.id),instanceId:e,sessionId:t.id,unread:!1,lastStatus:t.status,sessionUpdatedAt:t.updatedAt,createdAt:s,updatedAt:s},!1);const a=function(e,t,n){return"running"!==n&&"waiting"!==n&&("running"===t||"waiting"===t||e)}(i.unread,i.lastStatus,t.status),o=a!==i.unread;(o||i.lastStatus!==t.status||i.sessionUpdatedAt!==t.updatedAt)&&this.store({...i,unread:a,lastStatus:t.status,sessionUpdatedAt:t.updatedAt,updatedAt:s},o)}store(e,t){const n=this.records.put(e);return this.bySession.set(Lx(n.instanceId,n.sessionId),n),t&&this.listener?.(Dx(n)),n}deleteRecord(e){this.records.delete(e.id),this.bySession.delete(Lx(e.instanceId,e.sessionId))}}function Dx(e){return Bn.parse({instanceId:e.instanceId,sessionId:e.sessionId,unread:e.unread,sessionUpdatedAt:e.sessionUpdatedAt,updatedAt:e.updatedAt})}function Lx(e,t){return`${e}\0${t}`}function Mx(e,t){return`ais_unread_${i.createHash("sha256").update(Lx(e,t)).digest("hex").slice(0,32)}`}class qx{snapshots=new Map;history=new Map;advertisedStreams=new Map;recoveries=new Map;bootstrap;logger;recoverDelta;recoverSnapshot;onRecoveredEvent;recoveryCount=0;counters={streamResets:0,gaps:0,deltaRecoveries:0,snapshotRecoveries:0,recoveryFailures:0};constructor(e){this.bootstrap=e.bootstrap,this.logger=e.logger,this.recoverDelta=e.recoverDelta,this.recoverSnapshot=e.recoverSnapshot,this.onRecoveredEvent=e.onRecoveredEvent}handleEvent(e){const t=e.type===As?Ds:e.type===Es?Ls:e.type===_s?Ms:void 0;if(!t)return!1;const n=pl(t,e.payload);return n.success?e.type===As?this.applySnapshot(n.data):e.type===Es?this.applyPatch(n.data):this.applyRemoved(n.data):(this.logger?.warn?.({eventType:e.type,issues:n.error.issues,errorCode:"APP_SESSION_EVENT_INVALID"},"app-session.aggregator.event.invalid"),!1)}applySnapshot(e){const t=this.advertisedStreams.get(e.meta.instanceId)?.streamId;return t&&t!==e.meta.streamId?(this.logger?.warn?.({instanceId:e.meta.instanceId,advertisedStreamId:t,streamId:e.meta.streamId,revision:e.meta.revision},"app-session.aggregator.snapshot.obsolete-stream"),!1):this.apply({type:As,payload:e})}advertiseStream(e,t){return this.advertisedStreams.set(e,t),this.recoverStream(e,t.streamId,t.latestRevision).catch(n=>{this.counters.recoveryFailures+=1,this.logger?.warn?.({instanceId:e,streamId:t.streamId,error:n instanceof Error?n.message:String(n)},"app-session.aggregator.recovery.failed")})}diagnostics(){return{...this.counters,recoveriesStarted:this.recoveryCount,activeRecoveries:this.recoveries.size}}removeInstance(e){this.snapshots.delete(e),this.history.delete(e),this.advertisedStreams.delete(e)}applyPatch(e){return this.apply({type:Es,payload:e})}applyRemoved(e){return this.apply({type:_s,payload:e})}async list(e={}){return e.refresh&&e.instanceId&&this.recoverSnapshot?await this.refreshInstance(e.instanceId):(e.refresh||0===this.snapshots.size)&&await this.bootstrapFromInstances(),this.view(e.instanceId)}async streamDescriptors(){return 0===this.snapshots.size&&await this.bootstrapFromInstances(),[...this.snapshots.entries()].map(([e,t])=>({topic:"app.sessions",instanceId:e,streamId:t.streamId,latestRevision:t.revision,earliestRetainedRevision:this.history.get(e)?.[0]?.payload.meta.revision??t.revision+1}))}async delta(e){0===this.snapshots.size&&await this.bootstrapFromInstances();const t=this.resolveDeltaInstanceId(e.instanceId);this.pruneHistory(t);const n=this.snapshots.get(t)?.revision??0,i=this.snapshots.get(t)?.streamId||"unavailable",s=this.history.get(t)?.[0]?.payload.meta.revision??n+1;if(e.streamId!==i||e.sinceRevision>n)return qs.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:!0,events:[]});if(e.sinceRevision===n)return qs.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:!1,events:[]});const a=(this.history.get(t)??[]).filter(t=>t.payload.meta.revision>e.sinceRevision),o=!a.length||a[0].payload.meta.revision!==e.sinceRevision+1;return qs.parse({streamId:i,instanceId:t,sinceRevision:e.sinceRevision,latestRevision:n,earliestRetainedRevision:s,syncRequired:o,events:o?[]:a.map(({type:e,payload:t})=>({type:e,payload:t}))})}apply(e,t=!1){const{meta:n}=e.payload,i=this.advertisedStreams.get(n.instanceId)?.streamId;if(i&&i!==n.streamId)return this.logger?.warn?.({instanceId:n.instanceId,advertisedStreamId:i,streamId:n.streamId,revision:n.revision},"app-session.aggregator.event.obsolete-stream"),!1;const s=this.recoveries.get(n.instanceId);if(s&&!t)return s.streamId===n.streamId&&(s.highWater=Math.max(s.highWater,n.revision)),!1;const a=this.snapshots.get(n.instanceId);e.type===As&&a&&a.streamId!==n.streamId&&(this.counters.streamResets+=1,this.logger?.info?.({instanceId:n.instanceId,previousStreamId:a.streamId,streamId:n.streamId,previousRevision:a.revision,revision:n.revision,traceId:n.traceId,resetCount:this.counters.streamResets},"app-session.aggregator.stream-reset"));const o=function(e,t){const{meta:n}=t.payload;if(t.type===As)return e?.streamId===n.streamId&&n.revision===e.revision?{kind:"duplicate",projection:e}:e?.streamId===n.streamId&&n.revision<e.revision?{kind:"stale",projection:e}:{kind:"applied",projection:Os.parse({streamId:n.streamId,revision:n.revision,lastEventAt:n.generatedAt,snapshot:$s(t.payload.snapshot.sessions,t.payload.snapshot.updatedAt)})};if(!e||e.streamId!==n.streamId)return{kind:"snapshot-required",projection:e,streamId:n.streamId};if(n.revision===e.revision)return{kind:"duplicate",projection:e};if(n.revision<e.revision)return{kind:"stale",projection:e};if(n.revision!==e.revision+1||n.previousRevision!==e.revision)return{kind:"gap",projection:e,expectedRevision:e.revision+1,receivedRevision:n.revision};const i=[...e.snapshot.sessions];if(t.type===Es){const e=i.findIndex(e=>e.id===t.payload.session.id);Hs(t.payload.session.status)?e<0?i.push(t.payload.session):i[e]=t.payload.session:e>=0&&i.splice(e,1)}else{const e=i.findIndex(e=>e.id===t.payload.sessionId);e>=0&&i.splice(e,1)}const s=Us(i,n.generatedAt);return{kind:"applied",projection:Os.parse({streamId:n.streamId,revision:n.revision,lastEventAt:n.generatedAt,snapshot:s})}}(a,e);if("applied"!==o.kind)return this.logger?.warn?.({traceId:n.traceId,streamId:n.streamId,instanceId:n.instanceId,currentRevision:a?.revision,revision:n.revision,outcome:o.kind},`app-session.aggregator.event.${o.kind}`),"gap"!==o.kind&&"snapshot-required"!==o.kind||("gap"===o.kind&&(this.counters.gaps+=1),this.recoverStream(n.instanceId,n.streamId,n.revision).catch(e=>{this.logger?.warn?.({instanceId:n.instanceId,streamId:n.streamId,revision:n.revision,error:e instanceof Error?e.message:String(e)},"app-session.aggregator.recovery.failed")})),!1;const r=o.projection;return this.snapshots.set(n.instanceId,r),this.rememberEvent(n.instanceId,e),this.logger?.info?.({traceId:n.traceId,streamId:n.streamId,instanceId:n.instanceId,revision:n.revision,reason:n.reason,sessionCount:r.snapshot.sessions.length,runningCount:r.snapshot.runningCount,problemCount:r.snapshot.problemCount},"app-session.aggregator.event.accepted"),!0}async bootstrapFromInstances(){this.logger?.info?.({},"app-session.aggregator.bootstrap");const e=new Map(this.snapshots),t=await this.bootstrap(),n=new Set(t.instances.map(e=>e.instanceId));for(const[t,i]of e)n.has(t)||this.snapshots.get(t)!==i||(this.snapshots.delete(t),this.history.delete(t),this.advertisedStreams.delete(t));for(const n of t.instances){const t=this.snapshots.get(n.instanceId);if(t!==e.get(n.instanceId))continue;const i=this.advertisedStreams.get(n.instanceId)?.streamId;if(i&&i!==n.streamId)continue;if(t?.streamId===n.streamId&&t.revision>=n.revision)continue;const s={type:As,payload:{meta:{streamId:n.streamId,instanceId:n.instanceId,revision:n.revision,traceId:`aps_bootstrap_${Date.now().toString(36)}`,generatedAt:n.lastEventAt,reason:"startup"},snapshot:$s(n.appSessions.sessions,n.appSessions.updatedAt)}};this.apply(s)&&this.onRecoveredEvent?.(s)}}async refreshInstance(e){const t=this.snapshots.get(e),n=await this.recoverSnapshot(e);if(this.snapshots.get(e)!==t)return;const i=this.advertisedStreams.get(e)?.streamId;if(i&&i!==n.streamId)return;if(t?.streamId===n.streamId&&t.revision>=n.revision)return;const s={type:As,payload:{meta:{streamId:n.streamId,instanceId:e,revision:n.revision,traceId:`aps_refresh_${Date.now().toString(36)}`,generatedAt:n.lastEventAt,reason:"startup"},snapshot:n.snapshot}};this.apply(s)&&this.onRecoveredEvent?.(s)}recoverStream(e,t,n){const i=this.recoveries.get(e);if(i)return i.streamId===t?i.highWater=Math.max(i.highWater,n):(i.streamId=t,i.highWater=n),i.promise;if(!this.recoverDelta||!this.recoverSnapshot)return Promise.resolve();const s={promise:Promise.resolve(),streamId:t,highWater:n},a=++this.recoveryCount;return this.logger?.info?.({instanceId:e,highWater:n,recoveryNumber:a},"app-session.aggregator.recovery.started"),s.promise=(async()=>{for(;;){const t=this.advertisedStreams.get(e);if(!t)return;s.streamId!==t.streamId&&(s.streamId=t.streamId,s.highWater=t.latestRevision);const n=this.snapshots.get(e);if(n&&n.streamId===t.streamId){if(n.revision<Math.max(t.latestRevision,s.highWater)){const t=await this.recoverDelta(e,n.streamId,n.revision);if(this.advertisedStreams.get(e)?.streamId!==t.streamId||s.streamId!==t.streamId)continue;if(t.syncRequired){const t=await this.recoverSnapshot(e);if(this.advertisedStreams.get(e)?.streamId!==t.streamId)continue;const n={type:As,payload:{meta:{streamId:t.streamId,instanceId:e,revision:t.revision,traceId:`aps_recovery_${Date.now().toString(36)}`,generatedAt:t.lastEventAt,reason:"startup"},snapshot:t.snapshot}};this.apply(n,!0)&&this.onRecoveredEvent?.(n),this.counters.snapshotRecoveries+=1,this.logger?.info?.({instanceId:e,streamId:t.streamId,revision:t.revision,recoveryNumber:a,outcome:"snapshot-fallback"},"app-session.aggregator.recovery.snapshot")}else{for(const e of t.events)this.apply(e,!0)&&this.onRecoveredEvent?.(e);this.counters.deltaRecoveries+=1,s.highWater=Math.max(s.highWater,t.latestRevision),this.logger?.info?.({instanceId:e,streamId:t.streamId,sinceRevision:t.sinceRevision,latestRevision:t.latestRevision,eventCount:t.events.length,recoveryNumber:a,outcome:"delta"},"app-session.aggregator.recovery.delta")}}}else{const t=await this.recoverSnapshot(e);if(this.advertisedStreams.get(e)?.streamId!==t.streamId)continue;const n={type:As,payload:{meta:{streamId:t.streamId,instanceId:e,revision:t.revision,traceId:`aps_recovery_${Date.now().toString(36)}`,generatedAt:t.lastEventAt,reason:"startup"},snapshot:t.snapshot}};this.apply(n,!0)&&this.onRecoveredEvent?.(n),this.counters.snapshotRecoveries+=1,this.logger?.info?.({instanceId:e,streamId:t.streamId,revision:t.revision,recoveryNumber:a,outcome:"snapshot"},"app-session.aggregator.recovery.snapshot")}const i=this.snapshots.get(e),o=this.advertisedStreams.get(e);if(i&&o&&i.streamId===o.streamId&&i.revision>=Math.max(o.latestRevision,s.highWater))return void this.logger?.info?.({instanceId:e,streamId:i.streamId,revision:i.revision,recoveryNumber:a,outcome:"success"},"app-session.aggregator.recovery.completed")}})().finally(()=>this.recoveries.delete(e)),this.recoveries.set(e,s),s.promise}rememberEvent(e,t){const n=this.history.get(e)??[],i=n.length&&n[0].payload.meta.streamId!==t.payload.meta.streamId?[]:n;i.push({...t,createdAtMs:Date.now()}),this.history.set(e,i),this.pruneHistory(e)}pruneHistory(e){const t=this.history.get(e);if(!t?.length)return;const n=t.filter(e=>e.createdAtMs>=Date.now()-36e5);n.length?this.history.set(e,n):this.history.delete(e)}resolveDeltaInstanceId(e){if(e)return e;const t=[...this.snapshots.keys()];if(1===t.length)return t[0];throw new Error("APP_SESSION_DELTA_INSTANCE_ID_REQUIRED")}view(e){return{updatedAt:(new Date).toISOString(),instances:[...this.snapshots.entries()].filter(([t])=>!e||t===e).map(([e,t])=>({instanceId:e,streamId:t.streamId,appSessions:t.snapshot,revision:t.revision,lastEventAt:t.lastEventAt}))}}}function Ux(e){return e.raw[0].replace(/\\\$\{/g,"${")}class $x{states=new Map;events;constructor(e){this.events=e}handle(e){if(e.type===ud){const t=pl(md,e.payload);return void(t.success&&this.reconcileLifecycle(t.data))}if("instance.deleted"===e.type){const t=e.payload&&"object"==typeof e.payload&&"instanceId"in e.payload?String(e.payload.instanceId||""):"";return void(t&&this.deleteState(t))}if(e.type===Sc){const t=pl(_c,e.payload);return void(t.success&&this.applyOutput(t.data))}if(e.type===Ac){const t=pl(Tc,e.payload);t.success&&this.applyFinished(t.data)}}snapshots(){return[...this.states.values()].filter(e=>e.progress).map(e=>zc.parse({...e.progress,terminalTail:e.terminalTail,...e.terminalTruncated?{terminalTruncated:!0}:{}}))}close(){for(const e of this.states.values())e.timer&&clearTimeout(e.timer);this.states.clear()}deleteState(e){const t=this.states.get(e);t?.timer&&clearTimeout(t.timer),this.states.delete(e)}reconcileLifecycle(e){const t=this.states.get(e.instanceId),n=e.imageProvisioning;t&&(!n||n.generation>t.identity.generation||n.generation===t.identity.generation&&"ready"===n.phase)&&this.deleteState(e.instanceId)}applyOutput(e){const t=this.states.get(e.instanceId);if(t&&e.generation<t.identity.generation)return;if(t&&e.generation===t.identity.generation&&!e.replay&&e.sequence<=t.sequence)return;const n=this.requireState(e);e.replay&&(n.terminal=new Gx,n.terminalTail="",n.layers.clear(),n.terminalTruncated=!1),n.sequence=Math.max(n.sequence,e.sequence),n.observedAt=e.observedAt,n.terminal.write(e.data);const i=`${n.terminalTail}${e.data}`;n.terminalTruncated||=i.length>262144,n.terminalTail=i.slice(-262144),function(e,t){for(const n of t.split("\n")){const t=n.trim().match(/^([a-f0-9]{6,64}):\s+(.+)$/i);if(!t)continue;const[,i,s]=t,a=s.toLowerCase(),o=["pull complete","already exists","download complete","pulling fs layer","waiting","downloading","extracting"].find(e=>a.startsWith(e));if(!o)continue;const r=e.get(i)||{status:o},c=Fx(s);e.set(i,{...r,status:o,...c||{}})}}(n.layers,n.terminal.text()),n.progress=Bx(n),this.schedule(n)}applyFinished(e){const t=this.states.get(e.instanceId);if(t&&e.generation<t.identity.generation)return;if(t&&e.generation===t.identity.generation&&e.sequence<=t.sequence)return;const n=this.requireState(e);n.sequence=Math.max(n.sequence,e.sequence),n.observedAt=e.observedAt,n.outcome=e.outcome,n.progress=Bx(n),this.publish(n,!0)}requireState(e){const t=this.states.get(e.instanceId);if(t&&t.identity.generation===e.generation)return t;t?.timer&&clearTimeout(t.timer);const n={identity:{instanceId:e.instanceId,generation:e.generation,requestedReference:e.requestedReference},sequence:e.sequence,observedAt:e.observedAt,terminal:new Gx,terminalTail:"",terminalTruncated:!1,layers:new Map};return this.states.set(e.instanceId,n),n}schedule(e){e.timer||(e.timer=setTimeout(()=>this.publish(e,!1),250),e.timer.unref?.())}publish(e,t){e.timer&&clearTimeout(e.timer),e.timer=void 0,e.progress&&(e.progress=Bx(e),this.events.publish("image.pull.progress",e.progress,{topic:"instances",scope:{instanceId:e.identity.instanceId}}),t&&(e.progress=Bx(e)))}}function Bx(e){const t=[...e.layers.values()],n=t.filter(e=>["pull complete","already exists"].includes(e.status)).length,i=t.filter(e=>"download complete"===e.status).length,s=t.filter(e=>"downloading"===e.status).length,a=t.filter(e=>"extracting"===e.status).length;let o=0,r=0;for(const e of t)e.total&&(r+=e.total,o+=["pull complete","already exists","download complete"].includes(e.status)?e.total:Math.min(e.current||0,e.total));const c="failed"===e.outcome?"failed":"succeeded"===e.outcome?"complete":a>0?"extracting":t.length>0?"pulling":"connecting",d=t.filter(e=>"already exists"!==e.status),l=d.length>0&&d.every(e=>Boolean(e.total)),p=l&&r>0?Math.max(0,Math.min(100,o/r*100)):void 0,u="failed"===c?"Image pull failed":"complete"===c?"Image pull complete":t.length?`${n}/${t.length} layers ready${void 0===p?"":` · ${Math.round(p)}%`}`:"Connecting to image registry";return zc.parse({...e.identity,sequence:e.sequence,observedAt:e.observedAt,status:c,layers:{total:t.length,completed:n,downloaded:i,downloading:s,extracting:a},...l&&r>0?{bytes:{current:o,total:r},percent:p}:{},message:u})}function Fx(e){const t=e.match(/([\d.]+)\s*([kmgt]?i?b)\s*\/\s*([\d.]+)\s*([kmgt]?i?b)/i);if(t)return{current:Hx(t[1],t[2]),total:Hx(t[3],t[4])}}function Hx(e,t){return Number(e)*1024**({b:0,kb:1,kib:1,mb:2,mib:2,gb:3,gib:3,tb:4,tib:4}[t.toLowerCase()]||0)}class Gx{lines=[[]];row=0;col=0;pending="";write(e){const t=`${this.pending}${e}`;this.pending="";for(let e=0;e<t.length;){const n=t[e];if(""===n&&"["===t[e+1]){let n=e+2;for(;n<t.length&&!/[\x40-\x7e]/.test(t[n]);)n+=1;if(n>=t.length){this.pending=t.slice(e);break}this.csi(t.slice(e+2,n),t[n]),e=n+1;continue}"\r"===n?this.col=0:"\n"===n?(this.row+=1,this.col=0,this.ensureLine()):"\b"===n?this.col=Math.max(0,this.col-1):n>=" "&&(this.ensureLine(),this.lines[this.row][this.col]=n,this.col+=1),e+=1}this.trim()}text(){return this.lines.map(e=>e.join("").trimEnd()).join("\n")}csi(e,t){const n=e.replace(/^\?/,"").split(";").map(e=>Number(e||1)),i=n[0]||1;"A"===t?this.row=Math.max(0,this.row-i):"B"===t?(this.row+=i,this.ensureLine()):"C"===t?this.col+=i:"D"===t?this.col=Math.max(0,this.col-i):"G"===t?this.col=Math.max(0,i-1):"H"===t||"f"===t?(this.row=Math.max(0,i-1),this.col=Math.max(0,(n[1]||1)-1),this.ensureLine()):"K"===t?(this.ensureLine(),2===(n[0]||0)?this.lines[this.row]=[]:this.lines[this.row].splice(this.col)):"J"===t&&2===(n[0]||0)&&(this.lines=[[]],this.row=0,this.col=0)}ensureLine(){for(;this.lines.length<=this.row;)this.lines.push([])}trim(){if(this.lines.length<=500)return;const e=this.lines.length-500;this.lines.splice(0,e),this.row=Math.max(0,this.row-e)}}const Wx=oo.extend({credentialHash:f.z.string().trim().min(32).max(256)}).strict(),Vx=f.z.object({revision:f.z.number().int().nonnegative(),invites:f.z.array(f.z.unknown()).length(0).default([]),bindings:f.z.array(Wx)}).strict(),Kx={binding:new Set(Object.keys(Wx.shape))};function Yx(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e;return Object.fromEntries([...t].filter(e=>e in n).map(e=>[e,n[e]]))}function Xx(e){const{tokenHash:t,...n}=e;return no.parse(n)}function Jx(e){const{credentialHash:t,...n}=e;return oo.parse(n)}class Qx{authority;constructor(e,t){this.authority=new Zd(e,()=>({revision:0,invites:[],bindings:[]}),{schema:Vx,sanitize:e=>function(e,t){if(!e||"object"!=typeof e||Array.isArray(e))return e;const n=e,i=new Set(["revision","invites","bindings"]),s=Object.keys(n).filter(e=>!i.has(e));return s.length>0&&t?.({kind:"authority",fields:s}),{...void 0===n.revision?{}:{revision:n.revision},invites:[],bindings:Array.isArray(n.bindings)?n.bindings.map(e=>function(e,t,n){if(!t||"object"!=typeof t||Array.isArray(t))return t;const i=t,s=Kx[e],a=Object.keys(i).filter(e=>!s.has(e));a.length>0&&n?.({kind:e,fields:a});const o=Yx(i,s);return o.lastError&&(o.lastError=Yx(o.lastError,Object.keys(eo.shape))),o}("binding",e,t)).filter(e=>!e||"object"!=typeof e||"revoked"!==e.status):n.bindings}}(e,e=>t?.("unknown stored control-plane proxy fields were ignored",e)),logger:t,directoryMode:448,fileMode:384})}init(){this.authority.init();const e=this.authority.get();this.authority.put(e)}snapshot(){return this.authority.get()}transaction(e){const t=this.authority.get(),n=structuredClone(t),i=e(n);return JSON.stringify(n)!==JSON.stringify(t)&&this.authority.put({...n,revision:t.revision+1}),i}listBindings(){return this.snapshot().bindings}getBinding(e){return this.snapshot().bindings.find(t=>t.id===e)}}class Zx extends Error{code;statusCode;retryable;details;constructor(e,t,n,i=!1,s={}){super(t),this.name="ControlPlaneProxyServiceError",this.code=e,this.statusCode=n,this.retryable=i,this.details=s}}const ew=e=>i.createHash("sha256").update(e).digest("base64url"),tw=()=>i.randomBytes(32).toString("base64url");function nw(e,t,n,i=!1,s={}){throw new Zx(e,t,n,i,s)}class iw{store;targets;configuredProxyOrigin;proxyOriginProvider;now;createTokenValue;invites=new cg;constructor(e,t,n){this.store=e,this.targets=t,this.configuredProxyOrigin=n.proxyOrigin,this.proxyOriginProvider=n.proxyOriginProvider,this.now=n.now??(()=>new Date),this.createTokenValue=n.createToken??tw}init(){this.store.init()}createInvite(e,t){const n=this.resolveProxyOrigin();n||nw(Qa.Unavailable,"Configure an externally reachable HTTPS control-plane proxy origin before creating an invite.",409,!1);const i=io.parse(e);this.requireManageableTarget(i.targetNodeId);const s=this.createTokenValue(),a=this.nowIso(),o={id:Xd("proxy_invite"),targetNodeId:i.targetNodeId,tokenHash:ew(s),status:"active",createdBy:t,expiresAt:new Date(this.now().getTime()+Math.min(1e3*i.expiresInSeconds,6e5)).toISOString(),createdAt:a,updatedAt:a},r=so.parse({invite:Xx(o),token:s,proxyOrigin:n,protocolVersion:Ma});return this.invites.put(o.tokenHash,o,this.now().getTime()),r}resolveProxyOrigin(){const e=this.configuredProxyOrigin??this.proxyOriginProvider?.();if(!e)return;const t=Ha.safeParse(e);return t.success?t.data:void 0}listInvites(){return this.invites.list(this.now().getTime()).map(Xx)}revokeInvite(e){const t=this.listInviteRecords().find(t=>t.id===e);t||nw(Qa.InviteInvalid,"Proxy invite is unknown.",404,!1,{inviteId:e});const n=this.nowIso(),i={...t,status:"revoked",revokedAt:n,updatedAt:n};return this.invites.delete(t.tokenHash,this.now().getTime()),Xx(i)}claimInvite(e){const t=ro.parse(e);this.requireCurrentProtocol(t.protocolVersion);const n=ew(t.credential),i=this.store.listBindings().find(e=>e.claimId===t.claimId);if(i)return this.requireRecoveredIdentity(i,t,n),this.claimResult(i,this.requireKnownTarget(i.targetNodeId));t.inviteToken||nw(Qa.InviteInvalid,"Proxy invite token is required for the first claim.",401);const s=ew(t.inviteToken),a=this.invites.peek(s,this.now().getTime());a||nw(Qa.InviteInvalid,"Proxy invite is invalid or expired.",401),t.targetNodeId&&t.targetNodeId!==a.targetNodeId&&nw(Qa.TargetMismatch,"Proxy invite is bound to a different target.",409,!1,{inviteId:a.id,targetNodeId:t.targetNodeId});const o=this.requireManageableTarget(a.targetNodeId),r=this.store.transaction(e=>{const i=(s=a.id,`proxy_binding_${ew(s).slice(0,32)}`);var s;const r=this.nowIso(),c={id:i,claimId:t.claimId,sourceControlPlaneId:t.sourceControlPlaneId,targetNodeId:a.targetNodeId,bindingKeyId:t.bindingKeyId,credentialHash:n,status:"active",revision:1,createdAt:r,updatedAt:r};return e.bindings.push(c),this.claimResult(c,o)});return this.invites.delete(s,this.now().getTime()),r}listBindings(){return this.store.listBindings().map(Jx)}authenticateBinding(e,t){const n=co.parse(t),s=this.store.getBinding(e);return s||nw(Qa.BindingUnknown,"Proxy binding is unknown.",404,!1,{bindingId:e}),"active"!==s.status&&nw(Qa.BindingRevoked,"Proxy binding is revoked.",403,!1,{bindingId:e}),s.sourceControlPlaneId===n.sourceControlPlaneId&&s.bindingKeyId===n.bindingKeyId&&function(e,t){const n=ew(t),s=Buffer.from(e),a=Buffer.from(n);return s.length===a.length&&i.timingSafeEqual(s,a)}(s.credentialHash,n.credential)||nw(Qa.AuthenticationFailed,"Proxy binding authentication failed.",401,!1,{bindingId:e}),Jx(s)}revokeBinding(e){const t=this.requireBinding(e);if("revoked"===t.status)return Jx(t);const n=this.nowIso(),i={...t,status:"revoked",revision:t.revision+1,revokedAt:n,updatedAt:n};return this.store.transaction(t=>{t.bindings=t.bindings.filter(t=>t.id!==e)}),Jx(i)}revokeTarget(e){return this.store.transaction(t=>{const n=this.nowIso(),i=t.bindings.filter(t=>t.targetNodeId===e&&"active"===t.status).map(e=>Jx({...e,status:"revoked",revision:e.revision+1,revokedAt:n,updatedAt:n}));return t.bindings=t.bindings.filter(t=>t.targetNodeId!==e),{bindings:i,invites:this.revokeTargetInvites(e,n)}})}nowIso(){return this.now().toISOString()}requireCurrentProtocol(e){e!==Ma&&nw(Qa.ProtocolUnsupported,"Control-plane proxy protocol version is unsupported.",426,!1,{requestedVersion:e,supportedVersion:Ma})}requireKnownTarget(e){const t=this.targets.get(e);return t||nw(Qa.TargetUnavailable,"Proxy target no longer exists.",404,!1,{targetNodeId:e}),t}requireManageableTarget(e){const t=this.requireKnownTarget(e);return t.manageable&&"online"===t.status||nw(Qa.TargetUnavailable,"Proxy target is not currently manageable.",503,!0,{targetNodeId:e}),t}requireBinding(e){const t=this.store.getBinding(e);return t||nw(Qa.BindingUnknown,"Proxy binding is unknown.",404,!1,{bindingId:e}),t}requireRecoveredIdentity(e,t,n){(e.claimId!==t.claimId||e.sourceControlPlaneId!==t.sourceControlPlaneId||void 0!==t.targetNodeId&&e.targetNodeId!==t.targetNodeId||e.bindingKeyId!==t.bindingKeyId||e.credentialHash!==n)&&nw(Qa.BindingIdentityConflict,"Proxy claim conflicts with an existing binding identity.",409,!1,{claimId:t.claimId})}claimResult(e,t){const{manageable:n,...i}=t;return fo.parse({protocolVersion:Ma,binding:Jx(e),target:i})}listInviteRecords(){return this.invites.list(this.now().getTime())}revokeTargetInvites(e,t){const n=this.listInviteRecords().filter(t=>t.targetNodeId===e);for(const e of n)this.invites.delete(e.tokenHash,this.now().getTime());return n.map(e=>Xx({...e,status:"revoked",revokedAt:t,updatedAt:t}))}}class sw extends Error{statusCode=429;code=Qa.ResourceLimit;retryable=!0;details;constructor(e,t){super(e),this.name="NodeProxyRuntimeError",this.details=t}}class aw{maxRequestBodyBytes;maxConcurrentHttpPerBinding;maxConcurrentStreamsPerBinding;maxHttpRequestsPerMinutePerBinding;maxConcurrentWebSocketsPerBinding;maxHttpResponseBytes;httpStreamIdleTimeoutMs;maxWebSocketFrameBytes;maxWebSocketBytes;webSocketIdleTimeoutMs;httpRequestWindowMs;bindings=new Map;requestWindows=new Map;requestWindowTimers=new Map;constructor(e={}){this.maxConcurrentHttpPerBinding=e.maxConcurrentHttpPerBinding??32,this.maxConcurrentStreamsPerBinding=e.maxConcurrentStreamsPerBinding??16,this.maxHttpRequestsPerMinutePerBinding=e.maxHttpRequestsPerMinutePerBinding??600,this.maxConcurrentWebSocketsPerBinding=e.maxConcurrentWebSocketsPerBinding??16,this.maxRequestBodyBytes=e.maxRequestBodyBytes??8388608,this.maxHttpResponseBytes=e.maxHttpResponseBytes??268435456,this.httpStreamIdleTimeoutMs=e.httpStreamIdleTimeoutMs??12e4,this.maxWebSocketFrameBytes=e.maxWebSocketFrameBytes??8388608,this.maxWebSocketBytes=e.maxWebSocketBytes??268435456,this.webSocketIdleTimeoutMs=e.webSocketIdleTimeoutMs??3e5,this.httpRequestWindowMs=e.httpRequestWindowMs??6e4}reserveHttp(e){this.consumeRequestRate(e);const t=this.activity(e);if(t.controllers.size>=this.maxConcurrentHttpPerBinding)throw this.deleteIfEmpty(e,t),this.limit("Proxy HTTP concurrency limit exceeded.",e,"http-concurrency",this.maxConcurrentHttpPerBinding);const n=new AbortController;t.controllers.add(n);let i,s=!1,a=!1,o=0;const r=()=>{a&&!s&&(i&&clearTimeout(i),i=setTimeout(()=>{n.abort(Object.assign(new Error("Proxy HTTP stream idle timeout."),{code:Qa.ResourceLimit}))},this.httpStreamIdleTimeoutMs),i.unref?.())};return{controller:n,acceptRequestBody:t=>{if(t>this.maxRequestBodyBytes)throw this.limit("Proxy request body limit exceeded.",e,"request-body",this.maxRequestBodyBytes)},beginResponseStream:()=>{if(!s&&!a){if(t.streams.size>=this.maxConcurrentStreamsPerBinding)throw this.limit("Proxy HTTP stream concurrency limit exceeded.",e,"stream-concurrency",this.maxConcurrentStreamsPerBinding);a=!0,t.streams.add(n),r()}},acceptResponseChunk:t=>{if(!s){if(o+=ow(t),o>this.maxHttpResponseBytes){const t=this.limit("Proxy HTTP response byte limit exceeded.",e,"response-bytes",this.maxHttpResponseBytes);throw n.abort(t),t}r()}},release:()=>{s||(s=!0,i&&clearTimeout(i),t.controllers.delete(n),t.streams.delete(n),this.deleteIfEmpty(e,t))}}}openHttp(e,t){const n=this.reserveHttp(e);try{return n.acceptRequestBody(t),n}catch(e){throw n.release(),e}}openWebSocket(e,t,n){const i=this.activity(e);if(i.sockets.size>=this.maxConcurrentWebSocketsPerBinding)throw this.limit("Proxy WebSocket concurrency limit exceeded.",e,"websocket-concurrency",this.maxConcurrentWebSocketsPerBinding);let s,a=!1,o=0;const r=()=>{a||(a=!0,s&&clearTimeout(s),i.sockets.delete(p),this.deleteIfEmpty(e,i),n?.())},c=e=>{r(),t.close(1009,e)},d=()=>{s&&clearTimeout(s),s=setTimeout(()=>{r(),t.close(1001,"Proxy WebSocket idle timeout.")},this.webSocketIdleTimeoutMs),s.unref?.()},l=e=>{const t=ow(e);return t>this.maxWebSocketFrameBytes?(c("Proxy WebSocket frame limit exceeded."),!1):(o+=t,o>this.maxWebSocketBytes?(c("Proxy WebSocket byte limit exceeded."),!1):(d(),!0))};d();const p={get readyState(){return t.readyState},send:(e,n)=>{!a&&l(e)&&t.send(e,n)},close:(e,n)=>{r(),t.close(e,n)},on:(e,n)=>{"message"!==e?"close"!==e&&"error"!==e?t.on(e,n):t.on(e,(...e)=>{r(),n(...e)}):t.on(e,(e,...t)=>{!a&&l(e)&&n(e,...t)})}};return i.sockets.add(p),p}closeBinding(e,t="Proxy binding was revoked."){const n=this.bindings.get(e);if(!n)return this.clearRequestWindow(e),{abortedRequests:0,closedSockets:0};const i=[...n.controllers],s=[...n.sockets],a=[...n.cleanup];this.bindings.delete(e);for(const e of i)e.abort(Object.assign(new Error(t),{code:Qa.BindingRevoked}));for(const e of a)e();for(const e of s)e.close(1008,t);return n.controllers.clear(),n.streams.clear(),n.sockets.clear(),n.cleanup.clear(),this.clearRequestWindow(e),{abortedRequests:i.length,closedSockets:s.length}}diagnostics(e){if(e){const t=this.bindings.get(e);return{bindingId:e,activeHttp:t?.controllers.size??0,activeStreams:t?.streams.size??0,activeWebSockets:t?.sockets.size??0}}return[...this.bindings].map(([e,t])=>({bindingId:e,activeHttp:t.controllers.size,activeStreams:t.streams.size,activeWebSockets:t.sockets.size}))}registerBindingCleanup(e,t){const n=this.activity(e);return n.cleanup.add(t),()=>{n.cleanup.delete(t),this.deleteIfEmpty(e,n)}}activity(e){const t=this.bindings.get(e);if(t)return t;const n={controllers:new Set,streams:new Set,sockets:new Set,cleanup:new Set};return this.bindings.set(e,n),n}deleteIfEmpty(e,t){0===t.controllers.size&&0===t.streams.size&&0===t.sockets.size&&0===t.cleanup.size&&this.bindings.get(e)===t&&this.bindings.delete(e)}limit(e,t,n,i){return new sw(e,{bindingId:t,resource:n,limit:i})}consumeRequestRate(e){const t=Date.now(),n=t-this.httpRequestWindowMs,i=(this.requestWindows.get(e)||[]).filter(e=>e>n);if(i.length>=this.maxHttpRequestsPerMinutePerBinding)throw this.limit("Proxy HTTP request rate limit exceeded.",e,"request-rate",this.maxHttpRequestsPerMinutePerBinding);i.push(t),this.requestWindows.set(e,i),this.scheduleRequestWindowCleanup(e)}scheduleRequestWindowCleanup(e){const t=this.requestWindowTimers.get(e);t&&clearTimeout(t);const n=this.requestWindows.get(e);if(!n?.length)return this.requestWindows.delete(e),void this.requestWindowTimers.delete(e);const i=Math.max(1,n[0]+this.httpRequestWindowMs-Date.now()+1),s=setTimeout(()=>{this.requestWindowTimers.delete(e);const t=Date.now()-this.httpRequestWindowMs,n=(this.requestWindows.get(e)||[]).filter(e=>e>t);n.length?(this.requestWindows.set(e,n),this.scheduleRequestWindowCleanup(e)):this.requestWindows.delete(e)},i);s.unref?.(),this.requestWindowTimers.set(e,s)}clearRequestWindow(e){this.requestWindows.delete(e);const t=this.requestWindowTimers.get(e);t&&clearTimeout(t),this.requestWindowTimers.delete(e)}}function ow(e){return Buffer.isBuffer(e)||e instanceof ArrayBuffer||ArrayBuffer.isView(e)?e.byteLength:Buffer.byteLength("string"==typeof e?e:String(e),"utf8")}class rw{streams=new Map;historyLimit;maxEventBytes;maxHistoryBytes;createStreamId;projectTarget;unsubscribeBus;constructor(e,t){this.historyLimit=Math.max(1,t.historyLimit??256),this.maxEventBytes=Math.max(1024,t.maxEventBytes??524288),this.maxHistoryBytes=Math.max(this.maxEventBytes,t.maxHistoryBytes??16777216),this.createStreamId=t.createStreamId??(e=>`proxy_events_${e}_${i.randomUUID().replace(/-/g,"").slice(0,16)}`),this.projectTarget=t.projectTarget,this.unsubscribeBus=e.on(e=>this.accept(e))}stop(){this.unsubscribeBus();for(const e of this.streams.values())e.subscribers.clear();this.streams.clear()}cursor(e){const t=this.stream(e);return{streamId:t.streamId,revision:t.revision,earliestRetainedRevision:cw(t)}}subscribe(e,t,n,i=()=>{}){const{bindingId:s,sourceControlPlaneId:a,targetNodeId:o}=e,r=this.stream(o),c=cw(r);if(t>r.revision||t<c-1)return n(ho.parse({type:"control-plane-proxy.snapshot-required",protocolVersion:Ma,streamId:r.streamId,bindingId:s,sourceControlPlaneId:a,targetNodeId:o,sinceRevision:t,latestRevision:r.revision,earliestRetainedRevision:c,error:{code:Qa.SnapshotRequired,message:"Proxy target event history cannot continue from the requested revision; fetch a new snapshot.",retryable:!0,details:{targetNodeId:o}}})),{kind:"snapshot-required",close:()=>{}};n(mo.parse({type:"control-plane-proxy.events.ready",protocolVersion:Ma,streamId:r.streamId,bindingId:s,sourceControlPlaneId:a,targetNodeId:o,latestRevision:r.revision,earliestRetainedRevision:c}));for(const e of r.history)e.event.revision>t&&n(dw(e.event,s,a));const d={bindingId:s,sourceControlPlaneId:a,send:n,onDeliveryFailure:i};r.subscribers.add(d);let l=!1;return{kind:"subscribed",close:()=>{l||(l=!0,r.subscribers.delete(d))}}}diagnostics(e){const t=this.stream(e);return{targetNodeId:e,streamId:t.streamId,revision:t.revision,earliestRetainedRevision:cw(t),historySize:t.history.length,historyBytes:t.historyBytes,subscribers:t.subscribers.size,subscriberBindings:[...t.subscribers].map(({bindingId:e,sourceControlPlaneId:t})=>({bindingId:e,sourceControlPlaneId:t}))}}accept(e){const t=e.scope?.nodeId;if("string"!=typeof t||!t)return;let n;try{n=this.projectTarget(t)}catch{return}if(!n)return;const i=this.stream(t),s=i.revision+1,a=uo.safeParse({type:"control-plane-proxy.event",protocolVersion:Ma,streamId:i.streamId,bindingId:"proxy_projection",sourceControlPlaneId:"proxy_projection",targetNodeId:t,revision:s,source:{id:e.id,seq:e.seq},target:n,event:{type:e.type,topic:e.topic,createdAt:e.createdAt}});if(!a.success)return;const{bindingId:o,sourceControlPlaneId:r,...c}=a.data,d=lw(c);if(!(void 0===d||d>this.maxEventBytes-512)){for(i.revision=s,i.history.push({event:c,bytes:d}),i.historyBytes+=d;i.history.length>this.historyLimit||i.historyBytes>this.maxHistoryBytes;){const e=i.history.shift();e&&(i.historyBytes-=e.bytes)}for(const e of[...i.subscribers])try{const t=dw(c,e.bindingId,e.sourceControlPlaneId),n=lw(t);if(void 0===n||n>this.maxEventBytes)throw new Error("Proxy event byte limit exceeded.");e.send(t)}catch{i.subscribers.delete(e);try{e.onDeliveryFailure()}catch{}}}}stream(e){const t=this.streams.get(e);if(t)return t;const n={streamId:this.createStreamId(e),revision:0,history:[],historyBytes:0,subscribers:new Set};return this.streams.set(e,n),n}}function cw(e){return e.history[0]?.event.revision??e.revision+1}function dw(e,t,n){return uo.parse({...e,bindingId:t,sourceControlPlaneId:n})}function lw(e){try{return Buffer.byteLength(JSON.stringify(e),"utf8")}catch{return}}function pw(e,t){const n=new WeakSet;let i=t,s=0;const a=e=>{if(i-=Buffer.byteLength(e,"utf8"),i<0)throw uw("Proxy target projection byte limit exceeded.",{resource:"target-projection-bytes",limit:t})},o=(e,t)=>{if(s+=1,s>16384||t>24)throw uw("Proxy target projection complexity limit exceeded.");if(null===e||"boolean"==typeof e)return e;if("string"==typeof e)return a(e),e;if("number"==typeof e)return Number.isFinite(e)?e:null;if("object"!=typeof e)return;if(n.has(e))throw uw("Proxy target projection contains a cycle.",void 0,!1);if(n.add(e),Array.isArray(e)){const i=e.map(e=>o(e,t+1)??null);return n.delete(e),i}const i={};for(const[n,s]of Object.entries(e)){if("__proto__"===n||"constructor"===n||"prototype"===n)continue;a(n);const e=o(s,t+1);void 0!==e&&(i[n]=e)}return n.delete(e),i};return o(e,0)}function uw(e,t,n=!0){return Object.assign(new Error(e),{code:"CONTROL_PLANE_PROXY_RESOURCE_LIMIT",statusCode:429,retryable:n,...t?{details:t}:{}})}function mw(e){const{manageable:t,...n}=e;return n}const hw=f.z.object({bindingId:f.z.string().trim().min(1).max(160)}).passthrough(),gw=f.z.object({route:Ga}).strict(),fw=f.z.object({sinceRevision:f.z.coerce.number().int().nonnegative()}).strict(),yw=new Set(["connection","cookie","host","keep-alive","proxy-authorization","te","trailer","transfer-encoding","upgrade"]),bw=524288;function vw(e,t,n){const i=_w(n.headers,Ka);if(i!==Ma)throw Ew(Qa.ProtocolUnsupported,"Control-plane proxy protocol version is unsupported.",426,!1,{requestedVersion:i,supportedVersion:Ma});const s=_w(n.headers,Ya),a=_w(n.headers,Xa),o=_w(n.headers,Ja);if(!s||!a||!o)throw Ew(Qa.AuthenticationFailed,"Proxy binding authentication headers are incomplete.",401);return e.authenticateBinding(t,{sourceControlPlaneId:s,bindingKeyId:a,credential:o})}function Iw(e,t,n){const i=vw(e,t.id,n);if(i.id!==t.id||i.revision!==t.revision||i.sourceControlPlaneId!==t.sourceControlPlaneId||i.targetNodeId!==t.targetNodeId||i.bindingKeyId!==t.bindingKeyId||"active"!==i.status)throw Ew(Qa.BindingIdentityConflict,"Proxy binding changed while the request was being established.",409,!0,{bindingId:t.id,expectedRevision:t.revision,actualRevision:i.revision})}function xw(e,t){if(t.id!==e.targetNodeId)throw Ew(Qa.TargetMismatch,"Proxy target resolver returned another node.",409,!1,{bindingId:e.id,targetNodeId:e.targetNodeId})}function ww(e){for(const t of Object.keys(e)){const e=t.toLowerCase();if(e.startsWith("x-taskhandoff-node-")||e.startsWith("x-task-handoff-node-"))throw Ew(Qa.HeaderInvalid,"Caller-supplied node transport authentication headers are forbidden.",400,!1,{header:e})}const t=Object.fromEntries([...Wa].flatMap(t=>{if(yw.has(t))return[];const n=e[t];return void 0===n?[]:[[t,Array.isArray(n)?n.join(", "):String(n)]]}));if(void 0!==t["x-request-id"]){const e=Fa.safeParse(t["x-request-id"]);if(!e.success)throw Ew(Qa.HeaderInvalid,"Proxy request correlation id is invalid.",400,!1,{header:"x-request-id"});t["x-request-id"]=e.data}if(void 0!==t[eu]){const e=Fa.safeParse(t[eu]);if(!e.success)throw Ew(Qa.HeaderInvalid,"Proxy trace id is invalid.",400,!1,{header:eu});t[eu]=e.data}return t}function Sw(e,t,n){const i=Aw(t),s=Tw(n?.headers);return s&&e.header("x-request-id",s),e.code(i.statusCode).send({error:{code:i.code,message:i.message,retryable:i.retryable,...i.details?{details:i.details}:{}}})}function Aw(e){const t=e&&"object"==typeof e?e:{},n="number"==typeof t.statusCode?t.statusCode:502;return{statusCode:n,code:("string"==typeof t.code?t.code:void 0)||Qa.TransportFailed,message:e instanceof Error?e.message:"Control-plane proxy transport failed.",retryable:"boolean"==typeof t.retryable?t.retryable:n>=500,details:t.details&&"object"==typeof t.details&&!Array.isArray(t.details)?t.details:void 0}}function Ew(e,t,n,i=!1,s){return Object.assign(new Error(t),{code:e,statusCode:n,retryable:i,...s?{details:s}:{}})}function _w(e,t){const n=e[t];return Array.isArray(n)?n.join(","):"string"==typeof n?n:""}function Tw(e){if(!e)return;const t=Fa.safeParse(_w(e,"x-request-id"));return t.success?t.data:void 0}function zw(e){let t="";for(const n of e){if(Buffer.byteLength(t+n)>123)break;t+=n}return t}const kw=e=>eo.parse({code:Qa.Unavailable,message:e,retryable:!0});class Nw{service;subscriptions=new Map;fetchImpl;openWebSocket;onStateChanged;logger;running=!1;constructor(e,t={}){this.service=e,this.fetchImpl=t.fetchImpl??fetch,this.openWebSocket=t.openWebSocket??((e,t)=>new b.WebSocket(e,{headers:t})),this.onStateChanged=t.onStateChanged??(()=>{}),this.logger=t.logger}start(){this.running||(this.running=!0,this.syncNow())}syncNow(){if(!this.running)return;const e=new Map(this.service.listNodes().filter(e=>"control-plane-proxy"===e.connectionMode&&!1!==e.connectionEnabled).map(e=>[e.id,e]));for(const t of this.subscriptions.keys())e.has(t)||this.remove(t);for(const t of e.values()){const e=this.subscriptionIdentity(t),n=this.subscriptions.get(t.id);if(n?.identity===e)continue;n&&this.remove(t.id);const i={generation:1,identity:e,retry:new _v};this.subscriptions.set(t.id,i),this.connect(t.id,i.generation)}}stop(){this.running=!1;for(const e of[...this.subscriptions.keys()])this.remove(e)}remove(e){const t=this.subscriptions.get(e);t&&(t.generation+=1,t.reconnect&&clearTimeout(t.reconnect),t.socket?.close(),this.subscriptions.delete(e))}async connect(e,t){if(!this.current(e,t))return;const n=this.service.proxyPrivateStore.nodeCredential(e);if(n)try{const i=await this.fetchImpl(function(e){return new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}/snapshot`,e.proxyOrigin)}(n),{headers:$m(n)});if(!this.current(e,t))return;const s=await i.json().catch(()=>{});if(!i.ok){const n=pl(eo,s?.error),a=n.success?n.data:kw(`Proxy snapshot failed with HTTP ${i.status}.`);return a.code===Qa.BindingRevoked||a.code===Qa.BindingUnknown?void this.onStateChanged(this.service.markProxyBindingRevoked(e,a)):void this.fail(e,t,a,a.retryable)}const a=ul(po,s?.data);if(this.validateIdentity(n,a.binding.id,a.binding.targetNodeId),this.onStateChanged(this.service.applyProxyTargetSnapshot(e,a)),"revoked"===a.binding.status)return void this.onStateChanged(this.service.markProxyBindingRevoked(e,{code:Qa.BindingRevoked,message:"Control-plane proxy binding was revoked.",retryable:!1}));this.openEvents(e,t,n,a)}catch(n){if(!this.current(e,t))return;this.logger?.warn?.({nodeId:e,error:Cw(n)},"control-plane proxy state bootstrap failed"),this.fail(e,t,kw("Trusted control-plane proxy is unavailable."),!0)}else this.fail(e,t,kw("Control-plane proxy credential is unavailable."),!1)}openEvents(e,t,n,i){const s=this.current(e,t);if(!s)return;const a=this.openWebSocket(function(e,t){const n=new URL(`/api/node-proxy/bindings/${encodeURIComponent(e.proxyBindingId)}/events`,e.proxyOrigin);return n.protocol="wss:",n.searchParams.set("sinceRevision",String(t)),n.toString()}(n,i.revision),$m(n));s.socket=a;let o=!1;const r=n=>{o||(o=!0,this.fail(e,t,kw(n),!0))};a.on("message",a=>{if(this.current(e,t))try{const o=ul(go,JSON.parse(String(a)));if(o.bindingId!==n.proxyBindingId||o.sourceControlPlaneId!==n.sourceControlPlaneId||o.targetNodeId!==n.targetNodeId||o.streamId!==i.streamId)throw new Error("Proxy event stream identity changed.");if("control-plane-proxy.snapshot-required"===o.type)return void this.restart(e,t);if("control-plane-proxy.events.ready"===o.type)return void s.retry.reset();this.onStateChanged(this.service.applyProxyTargetEvent(e,o))}catch(n){this.logger?.warn?.({nodeId:e,error:Cw(n)},"control-plane proxy event requires a new snapshot"),this.restart(e,t)}}),a.on("error",()=>r("Control-plane proxy event stream failed.")),a.on("close",()=>r("Control-plane proxy event stream disconnected."))}restart(e,t){const n=this.current(e,t);n&&(n.generation+=1,n.socket?.close(),n.socket=void 0,this.connect(e,n.generation))}fail(e,t,n,i){const s=this.current(e,t);if(!s)return;if(this.onStateChanged(this.service.markProxyUnavailable(e,n)),!i)return s.generation+=1,s.socket?.close(),void this.subscriptions.delete(e);s.generation+=1,s.socket?.close(),s.socket=void 0;const a=s.retry.next();s.reconnect=setTimeout(()=>{s.reconnect=void 0,this.connect(e,s.generation)},a.delay),s.reconnect.unref?.()}current(e,t){const n=this.subscriptions.get(e);return this.running&&n?.generation===t?n:void 0}validateIdentity(e,t,n){if(t!==e.proxyBindingId||n!==e.targetNodeId){const e=new Error("Proxy snapshot identity does not match the private binding credential.");throw Object.assign(e,{code:Qa.BindingIdentityConflict}),e}}subscriptionIdentity(e){const t=this.service.proxyPrivateStore.nodeCredential(e.id);return JSON.stringify({connectionMode:e.connectionMode,connectionPath:e.connectionPath,credential:t&&{id:t.id,proxyOrigin:t.proxyOrigin,proxyBindingId:t.proxyBindingId,targetNodeId:t.targetNodeId,sourceControlPlaneId:t.sourceControlPlaneId,bindingKeyId:t.bindingKeyId,updatedAt:t.updatedAt}})}}function Cw(e){const t=e&&"object"==typeof e?e:{};return{name:e instanceof Error?e.name:"Error",message:e instanceof Error?e.message:String(e),..."string"==typeof t.code?{code:t.code}:{}}}const Rw=f.z.object({id:f.z.string().trim().min(1).max(160)}).strict(),Ow=f.z.object({}).strict(),jw=f.z.object({force:f.z.enum(["true","false"]).optional()}).strict(),Pw=f.z.object({id:f.z.string().trim().min(1)}).strict();function Dw(e){const t=_I(e);if(!t||"user"!==t.type)throw Object.assign(new Error("A Control Plane user is required."),{code:"CONTROL_PLANE_AUTH_REQUIRED",statusCode:401});return t}const Lw=f.z.object({id:f.z.string().trim().min(1).max(120)}).strict(),Mw=f.z.object({id:f.z.string().trim().min(1).max(120),credentialId:f.z.string().trim().min(1).max(120)}).strict();function qw(e){const t=_I(e);if(!t)throw Object.assign(new Error("Authentication is required."),{code:"CONTROL_PLANE_AUTH_REQUIRED",statusCode:401});$d(t,"manage-secrets",{type:"secret"})}const Uw=f.z.object({algorithm:f.z.literal("Ed25519"),publicKey:f.z.string().regex(/^[A-Za-z0-9_-]{43}$/),privateKeyPkcs8:f.z.string().regex(/^[A-Za-z0-9_-]{64}$/)}).strip();function $w(){const{publicKey:e,privateKey:t}=i.generateKeyPairSync("ed25519"),n=e.export({format:"jwk"});if(!n.x)throw new Error("Generated Control Plane identity did not contain an Ed25519 public key.");return{algorithm:"Ed25519",publicKey:n.x,privateKeyPkcs8:t.export({format:"der",type:"pkcs8"}).toString("base64url")}}function Bw(e){return`sha256:${i.createHash("sha256").update(Buffer.from(e,"base64url")).digest("base64url")}`}function Fw(e){return Array.isArray(e)?`[${e.map(Fw).join(",")}]`:e&&"object"==typeof e?`{${Object.entries(e).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${JSON.stringify(e)}:${Fw(t)}`).join(",")}}`:JSON.stringify(e)}class Hw{identity;controlPlaneId;constructor(e,t,n){this.controlPlaneId=t,this.identity=new Zd(e,$w,{schema:Uw,logger:n,directoryMode:448,fileMode:384})}init(){this.identity.init(),this.privateKey()}publicDocument(e,t=Date.now()){const n=this.identity.get(),s={authentication:e,aiSessions:!0,nodes:!0,instanceBoard:!0,triggers:!0,..."required"===e?{accessManagement:{userManagement:{users:!0,identities:!0,sessions:!0},authentication:{externalIdentity:{oidc:!0,oauthAdapters:["github"]}},authorization:{customRoles:!0,nodeScopes:!0,instanceScopes:!0,authorizationRevisions:!0}}}:{}},a=Fl.parse({version:1,kind:"control-plane",controlPlaneId:this.controlPlaneId(),publicKey:{algorithm:"Ed25519",encoding:"base64url",value:n.publicKey,fingerprint:Bw(n.publicKey)},capabilities:s,protocolVersion:"2026-08-23",issuedAt:new Date(t).toISOString(),expiresAt:new Date(t+3e5).toISOString()}),o=i.sign(null,Buffer.from((r=a,JSON.stringify(Fl.parse(r)))),this.privateKey()).toString("base64url");var r;return Hl.parse({data:{payload:a,signature:o}})}publicIdentity(){const e=this.identity.get();return{controlPlaneId:this.controlPlaneId(),algorithm:e.algorithm,publicKey:e.publicKey,fingerprint:Bw(e.publicKey)}}signCloudBindingChallenge(e){return i.sign(null,Buffer.from(`task-handoff:cloud-binding-challenge:v1\n${Fw(e)}`),this.privateKey()).toString("base64url")}signCloudOutboundRegistration(e){return i.sign(null,Buffer.from((t=e,`task-handoff:outbound-control-registration:v1\n${sa(ga.parse(t))}`)),this.privateKey()).toString("base64url");var t}acceptCloudAccessHandshake(e,t){return function(e){const t=fa.parse(e.ticket),n=va.parse(e.clientHello);if(t.ticketId!==n.ticketId||t.deviceSessionId!==n.deviceSessionId||t.targetPublicKeyFingerprint!==e.controlPlaneFingerprint)throw Ia();const s=i.generateKeyPairSync("x25519"),a=function(e){const t=e.export({format:"jwk"}).x;if(!t)throw Ia();return t}(s.publicKey),o=function(e,t,n){return i.createHash("sha256").update(sa({audience:e.audience,ticketId:e.ticketId,accountId:e.accountId,deviceSessionId:e.deviceSessionId,controlPlaneId:e.controlPlaneId,bindingId:e.bindingId,bindingRevision:e.bindingRevision,nonce:e.nonce,clientEphemeralPublicKey:t,serverEphemeralPublicKey:n})).digest("base64url")}(t,n.clientEphemeralPublicKey,a);var r;const c=function(e,t){return i.createHash("sha256").update(e).update(t).update("task-handoff:control-plane-access:e2e:v1").digest()}(i.diffieHellman({privateKey:s.privateKey,publicKey:(r=n.clientEphemeralPublicKey,i.createPublicKey({key:{kty:"OKP",crv:"X25519",x:r},format:"jwk"}))}),o);return{sessionKey:c,response:{serverEphemeralPublicKey:a,transcript:o,signature:i.sign(null,Buffer.from(o),e.controlPlanePrivateKey).toString("base64url")}}}({ticket:e,clientHello:t,controlPlaneFingerprint:this.publicIdentity().fingerprint,controlPlanePrivateKey:this.privateKey()})}privateKey(){const e=this.identity.get(),t=i.createPrivateKey({key:Buffer.from(e.privateKeyPkcs8,"base64url"),format:"der",type:"pkcs8"});if(i.createPublicKey(t).export({format:"jwk"}).x!==e.publicKey)throw new Error("Stored Control Plane signing identity public and private keys do not match.");return t}}class Gw{observations=new Map;listeners=new Set;begin(e,t,n="connecting"){const i=this.observations.get(e),s={nodeId:e,transport:t,generation:(i?.generation||0)+1,phase:n,changedAt:(new Date).toISOString(),consecutiveFailures:i?.transport===t?i.consecutiveFailures:0,controlReachability:i?.transport===t?i.controlReachability:"unknown",controlChangedAt:i?.transport===t?i.controlChangedAt:void 0,controlError:i?.transport===t?i.controlError:void 0};return this.observations.set(e,s),this.publish(s),s.generation}update(e,t,n,i=!0){const s=this.observations.get(e);if(!s||s.generation!==t)return!1;const a={...s,...n,changedAt:(new Date).toISOString()};return this.observations.set(e,a),i&&this.publish(a),!0}connected(e,t){const n=(new Date).toISOString();return this.update(e,t,{phase:"healthy",connectedAt:n,lastSeenAt:n,nextRetryAt:void 0,error:void 0})}pong(e,t,n={}){const i=(new Date).toISOString();return this.update(e,t,{lastSeenAt:i,lastPongAt:i,...void 0===n.pingRttMs?{}:{pingRttMs:n.pingRttMs},...void 0===n.pingRttP95Ms?{}:{pingRttP95Ms:n.pingRttP95Ms}},!1)}stable(e,t){return this.update(e,t,{consecutiveFailures:0},!1)}observedReachable(e){if("control-plane-proxy"===e.connectionMode)return!1;const t="reverse-wss"===e.connectionMode?"reverse-wss":"direct-http",n=this.observations.get(e.id),i=n?.transport===t?n.generation:this.begin(e.id,t,"handshaking");if("direct-http"===t){const t=(new Date).toISOString();return"reachable"===n?.controlReachability?this.update(e.id,i,{lastSeenAt:t},!1):this.update(e.id,i,{controlReachability:"reachable",controlChangedAt:t,controlError:void 0,lastSeenAt:t})}return"healthy"===n?.phase?this.update(e.id,i,{lastSeenAt:(new Date).toISOString()},!1):this.connected(e.id,i)}observedFailure(e,t){if("control-plane-proxy"===e.connectionMode)return!1;const n="reverse-wss"===e.connectionMode?"reverse-wss":"direct-http",i=this.observations.get(e.id),s=i?.transport===n?i.generation:this.begin(e.id,n,"connecting");return"direct-http"===n?"unreachable"===i?.controlReachability?this.update(e.id,s,{controlError:t},!1):this.update(e.id,s,{controlReachability:"unreachable",controlChangedAt:(new Date).toISOString(),controlError:t}):this.disconnected(e.id,s,{error:t})}disconnected(e,t,n={}){const i=this.observations.get(e);return!(!i||i.generation!==t)&&this.update(e,t,{phase:n.nextRetryAt?"reconnecting":"offline",consecutiveFailures:i.consecutiveFailures+1,closeCode:n.closeCode,error:n.error,nextRetryAt:n.nextRetryAt})}observation(e){return this.observations.get(e)}onChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}project(e){if(!1===e.connectionEnabled)return{...e,status:"offline",health:"failed",connectionPhase:"offline"};if("direct-http"!==e.connectionMode&&"reverse-wss"!==e.connectionMode&&"local-ipc"!==e.connectionMode&&"local-loopback"!==e.connectionMode)return e;const t=this.observations.get(e.id),n="reverse-wss"===e.connectionMode?"reverse-wss":"direct-http";if(!t||t.transport!==n)return"direct-http"===n?{...e,status:"unknown",health:"unknown",connectionPhase:"connecting"}:e;const i={...void 0===t.pingRttMs?{}:{pingRttMs:t.pingRttMs},...void 0===t.pingRttP95Ms?{}:{pingRttP95Ms:t.pingRttP95Ms},consecutiveReconnects:t.consecutiveFailures,...t.nextRetryAt?{nextRetryAt:t.nextRetryAt}:{}};return"direct-http"===n?"reachable"===t.controlReachability?{...e,connectionDiagnostics:i,status:"online",health:"unknown"===e.health||"failed"===e.health?"ok":e.health,lastSeenAt:t.lastSeenAt||e.lastSeenAt,connectionPhase:"healthy"}:{...e,connectionDiagnostics:i,status:"unreachable"===t.controlReachability?"offline":"unknown",health:"unreachable"===t.controlReachability?"failed":"unknown",lastSeenAt:t.lastSeenAt,connectionPhase:"unreachable"===t.controlReachability?"offline":"connecting"}:"healthy"===t.phase?{...e,connectionDiagnostics:i,status:"online",health:"unknown"===e.health?"ok":e.health,lastSeenAt:t.lastSeenAt||t.connectedAt,connectionPhase:t.phase}:"connecting"===t.phase||"handshaking"===t.phase||"reconnecting"===t.phase||"suspect"===t.phase?{...e,connectionDiagnostics:i,status:"offline",health:"degraded",lastSeenAt:t.lastSeenAt,connectionPhase:t.phase}:{...e,connectionDiagnostics:i,status:"offline",health:"failed",lastSeenAt:t.lastSeenAt,connectionPhase:t.phase}}diagnostics(){return[...this.observations.values()].map(e=>({...e}))}publish(e){for(const t of this.listeners)t({...e})}}function Ww(e,n){const i=t.extname(e);return`${i?e.slice(0,-i.length):e}.${n}${i}`}const Vw=1048576,Kw=52428800;function Yw(e){return e instanceof Error?{name:e.name,message:e.message,stack:e.stack}:e}function Xw(e){const i=[],s=e=>{if(n.existsSync(e))for(const a of n.readdirSync(e,{withFileTypes:!0})){const n=t.join(e,a.name);a.isSymbolicLink()||(a.isDirectory()?s(n):a.isFile()&&(a.name.endsWith(".log")||a.name.endsWith(".jsonl"))&&i.push(n))}};return s(e),i.sort()}function Jw(e,i,s){const a=n.statSync(e),o=Math.min(a.size,Vw,s);if(o<=0)return 0;const r=Buffer.allocUnsafe(o),c=n.openSync(e,"r");try{n.readSync(c,r,0,o,Math.max(0,a.size-o))}finally{n.closeSync(c)}return n.mkdirSync(t.dirname(i),{recursive:!0,mode:448}),n.writeFileSync(i,r,{mode:384}),o}const Qw=f.z.object({version:f.z.literal(1),serviceOrigin:f.z.string().url(),status:f.z.enum(["unbound","pending-claim","active","pending-revocation","clone-conflict"]),remoteAccessEnabled:f.z.boolean(),accountId:f.z.string().optional(),bindingId:f.z.string().optional(),bindingRevision:f.z.number().int().positive().optional(),backgroundCredential:f.z.string().min(32).optional(),updatedAt:f.z.string().datetime(),connectionEpoch:f.z.number().int().nonnegative().default(0)}).strip();class Zw{state;challenges=new Map;identity;serviceOrigin;clock;constructor(e){this.identity=e.identity,this.serviceOrigin=new URL(e.serviceOrigin).origin,this.clock=e.clock??Date.now,this.state=new Zd(e.statePath,()=>({version:1,serviceOrigin:this.serviceOrigin,status:"unbound",remoteAccessEnabled:!0,updatedAt:new Date(this.clock()).toISOString(),connectionEpoch:0}),{schema:Qw,directoryMode:448,fileMode:384})}init(){if(this.state.init(),this.state.get().serviceOrigin!==this.serviceOrigin)throw tS("CLOUD_SERVICE_ORIGIN_CHANGED","Cloud service origin does not match persisted binding authority.")}snapshot(){const{backgroundCredential:e,connectionEpoch:t,...n}=this.state.get();return{...n,identity:this.identity.publicIdentity(),hasBackgroundCredential:Boolean(e)}}createChallenge(){const e=this.state.get();if(["active","pending-revocation","clone-conflict"].includes(e.status))throw tS("active"===e.status?"CONTROL_PLANE_ALREADY_BOUND":"BINDING_STATE_CONFLICT","Existing cloud binding must be resolved first.");this.prune();const t=Xd("binding_challenge"),n=i.randomBytes(32).toString("base64url"),s=this.challengePayload(t);return this.challenges.set(t,{digest:eS(n),payload:s,expiresAtMs:Date.parse(s.expiresAt)}),this.state.put({...e,status:"pending-claim",updatedAt:new Date(this.clock()).toISOString()}),{challengeCode:`${t}.${n}`,authorizationUrl:`${this.serviceOrigin}/bindings/authorize`,payload:s,signature:this.identity.signCloudBindingChallenge(s)}}consumeChallenge(e){const t=e.challengeCode.indexOf("."),n=e.challengeCode.slice(0,t),s=e.challengeCode.slice(t+1),a=this.challenges.get(n);if(a&&this.challenges.delete(n),!a||a.expiresAtMs<=this.clock()||(o=a.digest,r=eS(s),o.length!==r.length||!i.timingSafeEqual(o,r)))throw tS("BINDING_CHALLENGE_INVALID_OR_CONSUMED","Binding challenge is invalid, expired, or consumed.");var o,r;if(a.payload.controlPlaneId!==e.controlPlaneId||a.payload.publicKeyFingerprint!==e.fingerprint)throw tS("BINDING_IDENTITY_CONFLICT","Binding challenge identity does not match.");return a.payload}activate(e){const t=this.state.get();if("active"===t.status){if(t.accountId===e.accountId&&t.bindingId===e.bindingId&&t.bindingRevision===e.bindingRevision)return this.snapshot();throw tS("CONTROL_PLANE_ALREADY_BOUND","Control Plane is already bound to another account.")}if("pending-claim"!==t.status)throw tS("BINDING_STATE_CONFLICT","Control Plane has no pending binding claim.");return this.state.put({...t,status:"active",remoteAccessEnabled:!0,...e,updatedAt:new Date(this.clock()).toISOString()}),this.snapshot()}setRemoteAccess(e){const t=this.state.get();return this.state.put({...t,remoteAccessEnabled:e,updatedAt:new Date(this.clock()).toISOString()}),this.snapshot()}beginRevocation(){const e=this.state.get();return"unbound"===e.status||(this.challenges.clear(),this.state.put({...e,status:"pending-revocation",remoteAccessEnabled:!1,updatedAt:new Date(this.clock()).toISOString()})),this.snapshot()}confirmRevocation(){const e=this.state.get();return this.state.put({version:1,serviceOrigin:e.serviceOrigin,status:"unbound",remoteAccessEnabled:!1,updatedAt:new Date(this.clock()).toISOString(),connectionEpoch:e.connectionEpoch}),this.snapshot()}markCloneConflict(){const e=this.state.get();return this.challenges.clear(),this.state.put({...e,status:"clone-conflict",remoteAccessEnabled:!1,backgroundCredential:void 0,updatedAt:new Date(this.clock()).toISOString()}),this.snapshot()}backgroundCredential(){const e=this.state.get();return"active"===e.status&&e.remoteAccessEnabled?e.backgroundCredential:void 0}nextConnectionEpoch(){const e=this.state.get(),t=e.connectionEpoch+1;return this.state.put({...e,connectionEpoch:t,updatedAt:new Date(this.clock()).toISOString()}),t}challengePayload(e){const t=this.identity.publicIdentity(),n=this.clock();return{protocolVersion:"2026-08-10",audience:"task-handoff:binding",serviceOrigin:this.serviceOrigin,challengeId:e,controlPlaneId:t.controlPlaneId,publicKey:t.publicKey,publicKeyFingerprint:t.fingerprint,nonce:i.randomBytes(24).toString("base64url"),issuedAt:new Date(n).toISOString(),expiresAt:new Date(n+3e5).toISOString()}}prune(){const e=this.clock();for(const[t,n]of this.challenges)n.expiresAtMs<=e&&this.challenges.delete(t)}}function eS(e){return i.createHash("sha256").update(e).digest()}function tS(e,t){return Object.assign(new Error(t),{code:e,statusCode:e.includes("CONFLICT")||e.includes("BOUND")?409:400})}class nS{revision=0;options;constructor(e){this.options=e}async apply(e){if(!Number.isSafeInteger(e.bindingRevision)||e.bindingRevision<this.revision)return{applied:!1,reason:"stale-revision"};if(this.revision=e.bindingRevision,"binding-revoked"===e.type||"account-disabled"===e.type||"background-credential-revoked"===e.type)this.options.state.beginRevocation(),await Promise.all([this.options.connections.stop(e.type),this.options.dataConnections.closeAll(e.type)]),this.options.state.confirmRevocation();else if("remote-access-changed"===e.type)this.options.state.setRemoteAccess(!0===e.enabled),e.enabled||await Promise.all([this.options.connections.stop("remote-access-disabled"),this.options.dataConnections.closeAll("remote-access-disabled")]);else{if("identity-clone-detected"!==e.type)return{applied:!1,reason:"unsupported-event"};this.options.state.markCloneConflict(),await Promise.all([this.options.connections.stop(e.type),this.options.dataConnections.closeAll(e.type)])}return{applied:!0}}}class iS{connection;processInstanceId=`control_plane_process_${i.randomUUID().replaceAll("-","_")}`;backoff;options;constructor(e){this.options=e,this.backoff=e.backoff??new _v}async connectOnce(){const e=this.options.state.backgroundCredential(),t=this.options.state.snapshot();if(!t.remoteAccessEnabled||!("pending-claim"===t.status||"active"===t.status&&Boolean(e)))return{status:"disabled"};if(this.connection)return{status:"connected",reused:!0};const n=this.options.state.nextConnectionEpoch(),i=this.connection;return this.connection=await this.options.connector.connect({serviceOrigin:t.serviceOrigin,credential:e,bindingId:t.bindingId,bindingRevision:t.bindingRevision,controlPlaneId:t.identity.controlPlaneId,processInstanceId:this.processInstanceId,epoch:n,onEvent:this.options.onEvent}),await(i?.close("replaced-by-new-epoch")),this.backoff.reset(),{status:"connected",epoch:n}}reconnectDelay(){return this.backoff.next().delay}disconnected(){this.connection=void 0}async stop(e){const t=this.connection;this.connection=void 0,await(t?.close(e))}}class sS{connections=new Map;options;constructor(e){this.options=e}async attach(e){const t=await this.options.verifyAllocation(e),n=this.connections.get(t.allocationId);if(n&&t.epoch<=n.epoch)throw Object.assign(new Error("Cloud connection state is invalid."),{code:"STALE_CONNECTION_EPOCH"});const i=await this.options.connector.connect({relayUrl:t.relayUrl,allocation:e,epoch:t.epoch});return await(n?.connection.close("replaced-by-new-epoch")),this.connections.set(t.allocationId,{epoch:t.epoch,connection:i}),{status:"attached",allocationId:t.allocationId,epoch:t.epoch}}async closeAll(e){const t=[...this.connections.values()];this.connections.clear(),await Promise.allSettled(t.map(({connection:t})=>t.close(e)))}}class aS{options;constructor(e){this.options=e}async disconnect(){const e=this.options.state.snapshot();if(!e.bindingId)return e;this.options.state.beginRevocation(),await this.options.connections.stop("binding-pending-revocation");try{if("revoked"===(await this.options.remote.revoke({bindingId:e.bindingId})).status)return this.options.state.confirmRevocation()}catch{}return this.options.state.snapshot()}async setRemoteAccess(e){const t=this.options.state.snapshot();if(this.options.state.setRemoteAccess(e),e||await this.options.connections.stop("remote-access-disabled"),t.bindingId)try{await this.options.remote.setRemoteAccess({bindingId:t.bindingId,enabled:e})}catch{return{...this.options.state.snapshot(),remoteResult:"unknown"}}return{...this.options.state.snapshot(),remoteResult:"confirmed"}}}class oS{options;constructor(e){this.options=e}async connect(e){const t=e.allocation,n=ba.parse(t.attach),i=fa.parse(t.ticket),s=new(this.options.webSocket??b)(e.relayUrl,{followRedirects:!1,handshakeTimeout:1e4,perMessageDeflate:!1});return await function(e){return new Promise((t,n)=>{e.once("open",t),e.once("error",n),e.once("close",()=>n(lS("RELAY_SOCKET_CLOSED")))})}(s),s.send(JSON.stringify({type:"attach",capability:n})),async function(e,t,n,i,s){const a=await cS(e,e=>"frame"===e?.type&&"handshake"===e.frame?.kind);if(a.frame.channelId!==t||0!==a.frame.sequence)throw lS("RELAY_HANDSHAKE_SEQUENCE_INVALID");const o=JSON.parse(Buffer.from(a.frame.ciphertext,"base64url").toString("utf8")),r=i.acceptCloudAccessHandshake(n,o),c={...r.response,controlPlanePublicKey:i.publicIdentity().publicKey};e.send(JSON.stringify({type:"frame",frame:{protocolVersion:"2026-08-10",channelId:t,sequence:0,kind:"handshake",ciphertext:Buffer.from(JSON.stringify(c)).toString("base64url")}}));const d={type:"cloud-account",accountId:n.accountId,deviceSessionId:n.deviceSessionId,bindingId:n.bindingId,bindingRevision:n.bindingRevision},l=new rS(e,t,r.sessionKey,d,s);return l.start(),{close:(e="normal")=>l.close(e)}}(s,(await cS(s,e=>"attached"===e?.type)).channelId,i,this.options.identity,this.options.bridge)}}class rS{receiveSequence=1;sendSequence=1;receiveCounter=0;sendCounter=0;unsubscribe;ttys=new Map;socket;channelId;key;actor;bridge;constructor(e,t,n,i,s){this.socket=e,this.channelId=t,this.key=n,this.actor=i,this.bridge=s}start(){this.socket.on("message",e=>{this.receive(e).catch(()=>this.socket.close(4400,"encrypted-protocol-error"))}),this.socket.once("close",()=>{this.unsubscribe?.();for(const e of this.ttys.values())e.close();this.ttys.clear()})}async close(e){this.unsubscribe?.();for(const e of this.ttys.values())e.close();this.ttys.clear(),this.socket.readyState<b.CLOSING&&this.socket.close(1e3,e.slice(0,120))}async receive(e){const t=JSON.parse(e.toString()),n=t?.frame;if("frame"!==t?.type||n?.channelId!==this.channelId||n.sequence!==this.receiveSequence++)throw lS("RELAY_FRAME_SEQUENCE_INVALID");const i=T.secretbox.open(Buffer.from(n.ciphertext,"base64url"),dS(1,this.receiveCounter++),this.key);if(!i)throw lS("RELAY_E2E_DECRYPT_FAILED");const s=JSON.parse(Buffer.from(i).toString("utf8"));await this.dispatch(s)}async dispatch(e){if("request"===e.type&&e.id){try{const t=await this.bridge.request(this.actor,e.body);this.send({type:"response",id:e.id,status:t.status,body:t.body})}catch(t){this.send({type:"response",id:e.id,status:Number(t?.statusCode)||500,body:{error:{code:t?.code??"CONTROL_PLANE_ERROR",message:"Control Plane request failed."}}})}return}if("event-subscribe"===e.type){this.unsubscribe?.();const t=Array.isArray(e.body?.topics)?e.body.topics.map(String):["*"],n=Cd.safeParse(e.body?.aiSessionTransient);return void(this.unsubscribe=this.bridge.subscribe(this.actor,t,e=>this.send({type:"event",event:e}),n.success?n.data:void 0))}if("tty-open"===e.type&&e.streamId&&this.bridge.openTty){const t=e.streamId,n=await this.bridge.openTty(this.actor,e.body,e=>this.send({...e,streamId:t}));return this.ttys.set(t,n),void this.send({type:"tty-opened",streamId:t})}const t=e.streamId?this.ttys.get(e.streamId):void 0;if(t&&"tty-input"===e.type)return t.send(String(e.data??""));if(t&&"tty-resize"===e.type)return t.resize(Number(e.body?.cols),Number(e.body?.rows));if(t&&"tty-close"===e.type)return t.close(),this.ttys.delete(e.streamId),void this.send({type:"tty-closed",streamId:e.streamId});if("cancel"!==e.type)throw lS("RELAY_ENVELOPE_UNSUPPORTED")}send(e){if(this.socket.readyState!==b.OPEN||this.socket.bufferedAmount>2097152)throw lS("RELAY_BACKPRESSURE_LIMIT");const t=T.secretbox(Buffer.from(JSON.stringify(e)),dS(2,this.sendCounter++),this.key);this.socket.send(JSON.stringify({type:"frame",frame:{protocolVersion:"2026-08-10",channelId:this.channelId,sequence:this.sendSequence++,kind:"cancel"===e.type?"cancel":"data",ciphertext:Buffer.from(t).toString("base64url")}}))}}function cS(e,t){return new Promise((n,i)=>{const s=e=>{try{const i=JSON.parse(e.toString());t(i)&&(o(),n(i))}catch(e){o(),i(e)}},a=()=>{o(),i(lS("RELAY_SOCKET_CLOSED"))},o=()=>{e.off("message",s),e.off("close",a)};e.on("message",s),e.once("close",a)})}function dS(e,t){const n=new Uint8Array(24);return n[0]=e,new DataView(n.buffer).setBigUint64(16,BigInt(t),!1),n}function lS(e){return Object.assign(new Error("Cloud Relay session is invalid."),{code:e,retryable:!0})}class pS{current;options;constructor(e){this.options=e}async connect(e){const t=this.options.identity.publicIdentity(),n=Date.now(),s={protocolVersion:"2026-08-10",audience:"task-handoff:coordinator-control",connectionId:`connection_${i.randomUUID().replaceAll("-","_")}`,processInstanceId:e.processInstanceId,controlPlaneId:t.controlPlaneId,publicKey:t.publicKey,publicKeyFingerprint:t.fingerprint,...e.bindingId?{bindingId:e.bindingId,bindingRevision:e.bindingRevision}:{},epoch:e.epoch,capabilities:["request","stream","websocket"],issuedAt:new Date(n).toISOString(),expiresAt:new Date(n+3e5).toISOString()},a=new URL("/api/v1/control-plane/connect",e.serviceOrigin);a.protocol="https:"===a.protocol?"wss:":"ws:";const o=new(this.options.webSocket??b)(a.href,{followRedirects:!1,handshakeTimeout:1e4});let r;return r=await function(e,t){return new Promise((n,s)=>{const a=new Map;let o,r=!1,c=!1;const d=e=>{for(const t of a.values())t.reject(e);a.clear(),r||s(e)},l={request(t,n){if(e.readyState!==b.OPEN)return Promise.reject(mS("CLOUD_CONTROL_CONNECTION_UNAVAILABLE"));const s=`request_${i.randomUUID().replaceAll("-","_")}`;return e.send(JSON.stringify({type:"request",requestId:s,operation:t,payload:n})),new Promise((e,t)=>a.set(s,{resolve:e,reject:t}))},async close(t="normal"){c=!0,o&&clearInterval(o),e.close(1e3,t.slice(0,120))}};e.on("open",()=>e.send(JSON.stringify(t.register))),e.on("message",async i=>{let s;try{s=JSON.parse(i.toString())}catch{return e.close(1002,"invalid-json")}if("registered"===s.type)return r=!0,o=setInterval(()=>e.readyState===b.OPEN&&e.send(JSON.stringify({type:"heartbeat"})),1e4),o.unref(),n(l);if("event"===s.type)return t.onEvent(s.event);if("response"===s.type){const e=a.get(s.requestId);if(!e)return;return a.delete(s.requestId),s.error?e.reject(Object.assign(new Error(s.error.message),{code:s.error.code})):e.resolve(s.data)}if("request"===s.type&&t.onRequest)try{e.send(JSON.stringify({type:"response",requestId:s.requestId,data:await t.onRequest(s.operation,s.payload)}))}catch(t){e.send(JSON.stringify({type:"response",requestId:s.requestId,error:{code:t?.code??"REQUEST_FAILED",message:t instanceof Error?t.message:String(t)}}))}}),e.on("error",e=>d(e)),e.on("close",()=>{o&&clearInterval(o),d(mS("CLOUD_CONTROL_CONNECTION_CLOSED")),c||t.onDisconnected()})})}(o,{register:{type:"register",registration:{...s,signature:this.options.identity.signCloudOutboundRegistration(s)},backgroundCredential:e.credential},onEvent:e.onEvent,onRequest:this.options.onRequest,onDisconnected:()=>{this.current===r&&(this.current=void 0),this.options.onDisconnected()}}),this.current=r,r}async request(e,t){if(!this.current)throw mS("CLOUD_CONTROL_CONNECTION_UNAVAILABLE");return this.current.request(e,t)}}class uS{lifecycle;dataConnections;connector;control;events;timer;running=!1;connecting;options;constructor(e){this.options=e,this.connector=new pS({identity:e.identity,webSocket:e.webSocket,onDisconnected:()=>{this.control.disconnected(),this.schedule()},onRequest:(e,t)=>this.handleRequest(e,t)});const t=e.relayConnector??(e.relayBridge?new oS({identity:e.identity,bridge:e.relayBridge,webSocket:e.webSocket}):{async connect(){throw mS("CLOUD_RELAY_CONNECTOR_UNAVAILABLE")}});this.dataConnections=new sS({verifyAllocation:e.verifyAllocation??(t=>function(e,t){const n=e,i=ba.parse(n?.attach),s=fa.parse(n?.ticket),a=t.snapshot(),o=new URL(String(n?.relayUrl));if("relay-allocation"!==n?.type||n?.allocationId!==i.allocationId||"control-plane"!==i.role||i.ticketId!==s.ticketId||i.controlPlaneId!==s.controlPlaneId||i.accountId!==s.accountId||i.deviceSessionId!==s.deviceSessionId||i.bindingId!==s.bindingId||i.bindingRevision!==s.bindingRevision||"active"!==a.status||!a.remoteAccessEnabled||a.identity.controlPlaneId!==s.controlPlaneId||a.accountId!==s.accountId||a.bindingId!==s.bindingId||a.bindingRevision!==s.bindingRevision||s.targetPublicKeyFingerprint!==a.identity.fingerprint||Date.parse(i.expiresAt)<=Date.now())throw lS("RELAY_ALLOCATION_AUTHORITY_INVALID");if(!function(e,t){if("wss:"!==e.protocol)return!1;if("relay.thandoff.com"===e.hostname||e.hostname.endsWith(".relay.thandoff.com"))return!0;const n=new URL(t);return"cloud.thandoff.com"!==n.hostname&&e.hostname===n.hostname}(o,a.serviceOrigin))throw lS("UNTRUSTED_RELAY_URL");return{allocationId:i.allocationId,relayUrl:o.href,epoch:Date.parse(i.issuedAt),attach:i,ticket:s}}(t,e.state)),connector:t}),this.events=new nS({state:e.state,connections:{stop:e=>this.control.stop(e)},dataConnections:this.dataConnections}),this.control=new iS({state:e.state,connector:this.connector,onEvent:async e=>{await this.events.apply(e)}}),this.lifecycle=new aS({state:e.state,connections:this.control,remote:{revoke:async({bindingId:e})=>this.connector.request("revoke-binding",{bindingId:e}),setRemoteAccess:async({bindingId:e,enabled:t})=>{await this.connector.request("set-remote-access",{bindingId:e,enabled:t})}}})}start(){this.running=!0,"active"===this.options.state.snapshot().status&&this.schedule(0)}async stop(){this.running=!1,this.timer&&clearTimeout(this.timer),await Promise.all([this.control.stop("control-plane-stopping"),this.dataConnections.closeAll("control-plane-stopping")])}async publishBindingChallenge(e){await this.ensureConnected(),await this.connector.request("publish-binding-challenge",{payload:e.payload,signature:e.signature})}async request(e,t){return await this.ensureConnected(),this.connector.request(e,t)}async handleRequest(e,t){if("consume-binding-challenge"===e){const e=this.options.identity.publicIdentity();return this.options.state.consumeChallenge({challengeCode:t?.challengeCode,controlPlaneId:e.controlPlaneId,fingerprint:e.fingerprint})}if("deliver-binding-credential"===e)return this.options.state.activate(t);if("relay-allocation"===e)return this.dataConnections.attach(t);throw mS("CLOUD_CONTROL_OPERATION_UNSUPPORTED")}async ensureConnected(){if(this.connecting||(this.connecting=this.control.connectOnce().finally(()=>{this.connecting=void 0})),"connected"!==(await this.connecting).status)throw mS("CLOUD_CONTROL_CONNECTION_DISABLED")}schedule(e=this.control.reconnectDelay()){if(!this.running||this.timer)return;const t=this.options.state.snapshot();"active"===t.status&&t.remoteAccessEnabled&&(this.timer=setTimeout(()=>{this.timer=void 0,this.ensureConnected().catch(()=>this.schedule())},e),this.timer.unref())}}function mS(e){return Object.assign(new Error("Cloud background connection is unavailable."),{code:e,retryable:!0})}class hS{connections=new Set;track(e,t){const n={...e,close:t};return this.connections.add(n),()=>this.connections.delete(n)}invalidate(e,t){let n=0;for(const i of[...this.connections])if(i.userId===e&&i.authorizationRevision!==t){this.connections.delete(i);try{i.close()}catch{}n+=1}return n}size(){return this.connections.size}}const gS="x-task-handoff-cloud-internal-actor",fS=f.z.object({code:f.z.string().trim().min(1),message:f.z.string(),details:f.z.record(f.z.string(),f.z.unknown()).optional(),retryable:f.z.boolean().optional()}).strict(),yS=f.z.object({error:fS}).strict(),bS="https://cloud.thandoff.com";function vS(e,t={}){const n=new URL(e||bS).origin;if(n===bS)return n;if(t.production||!0!==t.allowNonProduction)throw Object.assign(new Error("Non-production cloud service origin is not trusted by this build."),{code:"UNTRUSTED_CLOUD_SERVICE_ORIGIN"});return n}function IS(e){return Pc.parse({nodeId:e.id,status:e.status,health:e.health,lastSeenAt:e.lastSeenAt??null,connectionPhase:e.connectionPhase??null,connectionDiagnostics:e.connectionDiagnostics??null,proxyState:e.proxyState??null})}function xS(e){const t=process.env[e]?.trim();return t||void 0}const wS=function(e,t=process.env,n=e){let i;return()=>{const s=t.TASK_HANDOFF_VERSION?.trim();return s||(i||=q(e,t,n),i)}}("@task-handoff/control-plane");function SS(){return{component:"control-plane",packageName:"@task-handoff/control-plane",packageVersion:wS(),protocolVersion:wo,buildId:xS("TASK_HANDOFF_BUILD_ID"),builtAt:xS("TASK_HANDOFF_BUILT_AT"),gitCommit:xS("TASK_HANDOFF_GIT_COMMIT"),imageRef:xS("TASK_HANDOFF_IMAGE_REF"),imageDigest:xS("TASK_HANDOFF_IMAGE_DIGEST")}}const AS={".css":"text/css; charset=utf-8",".html":"text/html; charset=utf-8",".ico":"image/x-icon",".js":"text/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".map":"application/json; charset=utf-8",".png":"image/png",".svg":"image/svg+xml",".webp":"image/webp"};function ES(e,i){const s=t.resolve(e),a=t.resolve(s,i);if(a===s||a.startsWith(`${s}${t.sep}`))return n.existsSync(a)&&n.statSync(a).isFile()?a:void 0}function _S(e,i,s){const a=ES(i,s);return a?(e.header("cache-control","no-store"),e.type(AS[t.extname(a).toLowerCase()]||"application/octet-stream"),e.send(n.createReadStream(a))):e.code(404).send({error:{code:"STATIC_FILE_NOT_FOUND",message:`${s} was not found in the Control Plane UI static directory.`}})}function TS(e){if(e instanceof f.z.ZodError)return{statusCode:400,code:"VALIDATION_ERROR",message:e.issues.map(e=>`${e.path.join(".")||"body"}: ${e.message}`).join("; ")};const t=e&&"object"==typeof e?e:{};return{statusCode:"number"==typeof t.statusCode?t.statusCode:500,code:"string"==typeof t.code?t.code:"CONTROL_PLANE_ERROR",message:e instanceof Error?e.message:String(e),...t.details&&"object"==typeof t.details&&!Array.isArray(t.details)?{details:t.details}:{},..."boolean"==typeof t.retryable?{retryable:t.retryable}:{},..."number"==typeof t.retryAfterSeconds?{retryAfterSeconds:t.retryAfterSeconds}:{}}}function zS(e){const t=e.headers.authorization;if(void 0!==t){const e=/^Bearer ([^\s]+)$/.exec(t);return{token:e?.[1],clientType:"mobile"}}return{token:e.cookies[Fp],clientType:"web"}}async function kS(e,t){return e.enabled()?e.authorizationForSessionToken(t.token,t.clientType):{type:"system",reason:"auth-disabled"}}const NS=new Set(["/api/auth/session","/api/auth/bootstrap-admin","/api/auth/login","/api/auth/logout","/api/auth/mobile/login","/api/control-plane/identity","/api/health","/api/events","/api/access/me","/api/auth/external/callback"]);function CS(e,t){const n=t.split("?")[0]||"/";if(!n.startsWith("/api/"))return;if(NS.has(n))return;const i=function(e){return"GET"===e||"HEAD"===e?"read":"POST"===e?"create":"PATCH"===e||"PUT"===e?"update":"DELETE"===e?"delete":"read"}(e);return"/api/control-plane/diagnostic-logs/export"===n||"/api/session-streams/diagnostics"===n?{action:"manage-settings",resource:{type:"control-plane-settings"}}:n.startsWith("/api/control-plane/settings")?{action:"GET"===e?"read":"manage-settings",resource:{type:"control-plane-settings"}}:"/api/auth/mobile/logout"===n||n.startsWith("/api/auth/mobile/sessions")||"/api/auth/password"===n||n.startsWith("/api/auth/external/")?void 0:n.startsWith("/api/users")?{action:"GET"===e?"read":"manage-members",resource:{type:n.includes("/sessions")?"user-session":"user"}}:n.startsWith("/api/roles")||"/api/permissions"===n?{action:"GET"===e?"read":"update",resource:{type:"role"}}:n.startsWith("/api/identity-providers")?{action:"GET"===e?"read":"update",resource:{type:"identity-provider"}}:n.startsWith("/api/external-identity-approvals")?{action:"GET"===e?"read":"manage-members",resource:{type:"identity-approval"}}:n.startsWith("/api/models")?{action:"GET"===e?"read":"manage-secrets",resource:{type:"model"}}:n.startsWith("/api/git-credentials")?{action:"manage-secrets",resource:{type:"secret"}}:n.startsWith("/api/chat-gateway/bridges")?{action:"GET"===e?"read":"manage-secrets",resource:{type:"chat-bridge"}}:"/api/chat-gateway/messages"===n||"/api/chat-gateway/actions"===n?{action:"send-message",resource:{type:"ai-session"}}:"/api/chat-gateway/poll-ai-sessions"===n?{action:"manage-settings",resource:{type:"chat-bridge"}}:"/api/ai-session-attachments"===n?{action:"send-message",resource:{type:"ai-session"}}:"/api/node-join/invites"===n?{action:"manage-node-auth",resource:{type:"node"}}:n.startsWith("/api/control-plane-proxy")?{action:"GET"===e?"read":"manage-node-auth",resource:{type:"node"}}:n.startsWith("/api/nodes")?/\/(runtimes|local-folders)(\/|$)/.test(n)?{action:i,resource:{type:"runtime"}}:{action:"GET"===e?"read":"manage-node-auth",resource:{type:"node"}}:n.startsWith("/api/controlled-instances")?/\/apps\/sessions\/[^/]+\/access$/.test(n)?{action:"interactive-access",resource:{type:"app-session"}}:n.includes("/ai-sessions")?n.includes("/triggers")?{action:i,resource:{type:"trigger-deployment"}}:/\/messages\/[^/]+\/attachments\/[^/]+\/content$/.test(n)?{action:"read-file-content",resource:{type:"attachment"}}:"POST"===e&&/\/ai-sessions$/.test(n)?{action:"send-message",resource:{type:"ai-session"}}:n.endsWith("/approval")?{action:"approve",resource:{type:"ai-session"}}:n.endsWith("/interrupt")?{action:"interrupt",resource:{type:"ai-session"}}:n.endsWith("/resume")||n.endsWith("/fork")||n.endsWith("/commands")||n.includes("/messages")||n.includes("/queue/")?{action:"send-message",resource:{type:"ai-session"}}:n.endsWith("/read")||n.endsWith("/mentions/files")?{action:"read",resource:{type:"ai-session"}}:n.endsWith("/open-app")||n.endsWith("/close")?{action:"update",resource:{type:"ai-session"}}:"GET"===e||"HEAD"===e?{action:"read",resource:{type:"ai-session"}}:{action:"manage-settings",resource:{type:"control-plane-settings"}}:n.includes("/start")?{action:"start",resource:{type:"instance"}}:n.includes("/stop")?{action:"stop",resource:{type:"instance"}}:n.includes("/restart")?{action:"restart",resource:{type:"instance"}}:/\/config-sync(?:\/|$)/.test(n)?{action:"update",resource:{type:"instance"}}:{action:i,resource:{type:"instance"}}:n.startsWith("/api/projects")?{action:i,resource:{type:"project"}}:n.startsWith("/api/images")||n.startsWith("/api/image-options")||n.startsWith("/api/market")?{action:i,resource:{type:"image"}}:n.startsWith("/api/triggers")?n.endsWith("/apply")?{action:"create",resource:{type:"trigger-deployment"}}:{action:i,resource:{type:"trigger-template"}}:"GET"===e||"HEAD"===e?{action:"read",resource:{type:"public-directory"}}:{action:i,resource:{type:"control-plane-settings"}}}async function RS(e={}){const a=Xv(e.dataDir),o=s({logger:e.logger??!0});await o.register(an,{encodings:["br","gzip","deflate"],globalDecompression:!1,threshold:1024}),o.addContentTypeParser("application/octet-stream",(e,t,n)=>n(null,t));const c=new Zb,d=new hS,l=e.cloudConnectivityEnabled??"0"!==process.env.TASK_HANDOFF_CLOUD_CONNECTIVITY_ENABLED;let p=(u=process.env.TASK_HANDOFF_DIAGNOSTIC_LOGS,["1","true","yes","on"].includes(String(u||"").trim().toLowerCase()));var u;const y=function(e,i,s,a={}){const o=(o,r,c)=>{if(i()){s[o]?.(r,c);try{!function(e,i,s=10485760,a=2){const o=Buffer.isBuffer(i)?i:Buffer.from(i),r=o.byteLength>s?o.subarray(o.byteLength-s):o;if(n.mkdirSync(t.dirname(e),{recursive:!0,mode:448}),n.existsSync(e)){const t=n.lstatSync(e);if(!t.isFile()||t.isSymbolicLink())throw new Error(`Managed log path must be a regular file: ${e}`);t.size+r.byteLength>s&&(function(e,t){if(!(t<=0)){n.rmSync(Ww(e,t),{force:!0});for(let i=t-1;i>=1;i-=1){const t=Ww(e,i);n.existsSync(t)&&n.renameSync(t,Ww(e,i+1))}}}(e,a),a>0?t.size>s?(n.writeFileSync(Ww(e,1),function(e,t){const i=n.statSync(e),s=Math.min(i.size,t),a=Buffer.allocUnsafe(s),o=n.openSync(e,"r");let r=0;try{for(;r<s;){const e=n.readSync(o,a,r,s-r,i.size-s+r);if(0===e)break;r+=e}}finally{n.closeSync(o)}return r===s?a:a.subarray(0,r)}(e,s),{mode:384}),n.rmSync(e,{force:!0})):n.renameSync(e,Ww(e,1)):n.rmSync(e,{force:!0}))}n.appendFileSync(e,r,{mode:384}),n.chmodSync(e,384)}(t.join(e,"control-plane.log"),`${JSON.stringify({time:(new Date).toISOString(),level:o,message:c,data:Yw(r)},(e,t)=>Yw(t))}\n`,a.maxBytes??10485760,a.backupCount??2)}catch{}}};return{info:(e,t)=>o("info",e,t),warn:(e,t)=>o("warn",e,t),error:(e,t)=>o("error",e,t)}}(a.logsDir,()=>p,o.log),b=new Gw,v=new Kf(a,{...e.service,logger:y,nodeConnectionRuntime:b,onFleetStateChanged:t=>{e.service?.onFleetStateChanged?.(t),c.publish("node.fleet.updated",t,{topic:"instances"===t.resource?"instances":"models"===t.resource?"models":"node.runtime",scope:{nodeId:t.nodeId}})}});b.onChange(e=>c.publish("node.connection.updated",IS(v.requirePublicNode(e.nodeId)),{topic:"node.state",scope:{nodeId:e.nodeId}}));const I=new Gp(a,{...e.auth,onUserAuthorizationChanged:t=>{c.invalidateUserAuthorization(t.userId,t.authorizationRevision),d.invalidate(t.userId,t.authorizationRevision),e.auth?.onUserAuthorizationChanged?.(t)}}),x=new Hw(a.identitySigningPath,()=>v.proxyPrivateStore.controlPlaneId(),(e,t)=>o.log.warn(t,e)),w=new Zw({statePath:a.cloudConnectivityPath,identity:x,serviceOrigin:vS(e.cloudServiceOrigin||process.env.TASK_HANDOFF_CLOUD_SERVICE_ORIGIN,{production:"production"===process.env.NODE_ENV,allowNonProduction:!0===e.allowNonProductionCloudOrigin||"staging"===process.env.TASK_HANDOFF_CLOUD_ENV})}),S=new Map,A=new uS({state:w,identity:x,relayBridge:{async request(e,t){const n=String(t?.method||"GET").toUpperCase(),s=String(t?.path||""),a=CS(n,s);if(!s.startsWith("/api/")||!a||NS.has(s.split("?")[0]))throw Object.assign(new Error("Cloud access route is not available."),{code:"CLOUD_ROUTE_FORBIDDEN",statusCode:403});$d(e,a.action,a.resource);const r=i.randomBytes(32).toString("base64url");S.set(r,e);try{const e=Object.fromEntries(Object.entries(t.headers??{}).filter(([e])=>{const t=e.toLowerCase();return!function(e){return mn.has(e.toLowerCase())}(t)&&!["host","connection","upgrade",gS].includes(t)}).map(([e,t])=>[e,String(t)])),i=await o.inject({method:n,url:s,headers:{...e,[gS]:r},...void 0===t.body?{}:{payload:t.body}});let a;try{a=i.json()}catch{a=i.body}return{status:i.statusCode,body:a}}finally{S.delete(r)}},subscribe(e,t,n,i){if("cloud-account"!==e.type)throw Object.assign(new Error("Cloud account actor required."),{code:"CLOUD_ACTOR_REQUIRED"});const s=new Set(t);if(!s.size)return()=>{};const a=c.on(e=>{(s.has("*")||s.has(e.topic)||s.has(e.type))&&Rd(i,e)&&n(e)}),o=i?c.registerAiSessionTransientDemand(i):c.registerLegacyAiSessionTransientDemand(s);return()=>{a(),o()}},async openTty(e,t,n){const i=String(t?.instanceId||""),s=String(t?.sessionId||"");if($d(e,"proxy",{type:"instance",id:i}),!i||!s)throw Object.assign(new Error("TTY target is required."),{code:"TTY_TARGET_REQUIRED",statusCode:400});const a=new Map,o=(e,...t)=>{for(const n of a.get(e)??[])n(...t)};let r=!1;const c={readyState:1,on(e,t){const n=a.get(e)??new Set;n.add(t),a.set(e,n)},send(e){try{const t=JSON.parse(String(e));if("snapshot"===t.type){const e=Ss.parse(t);n(ha.parse({type:"tty-snapshot",data:e.data,pendingEscape:e.pendingEscape,cols:e.cols,rows:e.rows}))}else"output"===t.type?n({type:"tty-output",data:t.data}):"resize"===t.type?n({type:"tty-resize",body:{cols:t.cols,rows:t.rows}}):"exit"===t.type?n({type:"tty-exit",code:t.code,signal:t.signal}):"error"===t.type&&n({type:"tty-error"})}catch{n({type:"tty-error"})}},close(){r||(r=!0,o("close"),n({type:"tty-closed"}))}};return await v.proxyInstanceWebSocket(i,c,`/api/apps/sessions/${encodeURIComponent(s)}/tty`,[],{}),{send(e){r||o("message",Buffer.from(JSON.stringify({type:"input",data:e})))},resize(e,t){!r&&Number.isInteger(e)&&Number.isInteger(t)&&e>0&&t>0&&o("message",Buffer.from(JSON.stringify({type:"resize",cols:e,rows:t})))},close(){c.close()}}}}}),E=e.cloudConnectivityLifecycle?.(w)??A.lifecycle,_=e.publishCloudBindingChallenge??(e=>A.publishBindingChallenge(e)),T=new $x(c),z=new Px(a,{onChanged:e=>queueMicrotask(()=>c.publish(_n,e,{topic:"ai.sessions",scope:{instanceId:e.instanceId,sessionId:e.sessionId}}))});z.init();const k=new Ox({bootstrap:()=>v.bootstrapAiSessionsFromInstances(),logger:y,recoverDelta:(e,t,n)=>v.recoverAiSessionDelta(e,t,n),recoverSnapshot:e=>v.recoverAiSessionSnapshot(e),onRecoveredEvent:e=>c.publish(e.type,e.payload)});k.onSnapshot(e=>z.reconcile(e.instanceId,e.aiSessions));const N=new qx({bootstrap:()=>v.bootstrapAppSessionsFromInstances(),logger:y,recoverDelta:(e,t,n)=>v.recoverAppSessionDelta(e,t,n),recoverSnapshot:e=>v.recoverAppSessionSnapshot(e),onRecoveredEvent:e=>c.publish(e.type,e.payload)});v.setAppSessionSnapshotProvider(e=>N.list(e)),v.setAiSessionSnapshotProvider(e=>k.list(e));const C=new bv(a.dataDir,{onWarning:e=>o.log.warn(e)});c.on(e=>{if(T.handle(e),"instance.deleted"===e.type||"instance.updated"===e.type){const t=e.payload&&"object"==typeof e.payload&&"instanceId"in e.payload?String(e.payload.instanceId||""):"";t&&("instance.deleted"===e.type&&(N.removeInstance(t),k.removeInstance(t),z.removeInstance(t)),C.removeInstance(t))}});const R=new gv;o.addHook("onClose",async()=>{R.dispose()});const O=new Kv(c,{connectionRuntime:b,validateInstanceScope:(e,t)=>v.nodeOwnsInstance(e,t),onStreamsHello:(e,t)=>{for(const n of t.streams)"ai.sessions"===n.topic&&k.advertiseStream(e,n),"app.sessions"===n.topic&&N.advertiseStream(e,n)},onSessionEvent:e=>e.type.startsWith("app-session.")?N.handleEvent(e):k.handleEvent(e)}),j=e.proxyOrigin||process.env.TASK_HANDOFF_CONTROL_PLANE_PROXY_ORIGIN,P=e=>{const t=v.nodes.get(e);return t?function(e,t){const n="reverse-wss"===e.connectionMode&&t,i=n?"online":e.status;return{id:e.id,name:e.name||e.id,status:i,health:e.health,...e.lastSeenAt?{lastSeenAt:e.lastSeenAt}:{},capabilities:pw(e.capabilities||{},262144),manageable:!1!==e.connectionEnabled&&(n||"online"===i)}}(t,O.connected(t.id)):void 0},L=new iw(new Qx(a.proxyAuthorityPath,(e,t)=>o.log.warn(t,e)),{get:P},{proxyOrigin:j,proxyOriginProvider:()=>v.getSettings().publicBaseUrl}),M=new aw,q=new rw(c,{projectTarget:e=>{const t=P(e);return t?mw(t):void 0}}),U=new Nw(v,{fetchImpl:e.service?.fetchImpl,logger:y,onStateChanged:e=>c.publish("node.proxy-state.updated",IS(e),{topic:"node.state",scope:{nodeId:e.id}})});let $,B,F;c.on(e=>{if("node.created"!==e.type&&"node.updated"!==e.type&&"node.deleted"!==e.type||U.syncNow(),"instance.created"===e.type||"instance.updated"===e.type||"instance.deleted"===e.type){const t=e.payload&&"object"==typeof e.payload&&"instanceId"in e.payload?String(e.payload.instanceId||""):"";t&&O.invalidateInstanceScope({instanceId:t})}if("node.deleted"===e.type){const t=e.payload&&"object"==typeof e.payload&&"nodeId"in e.payload?String(e.payload.nodeId||""):"";if(t){O.invalidateInstanceScope({nodeId:t});const e=L.revokeTarget(t);for(const n of e.bindings)M.closeBinding(n.id,"Proxy target was deleted."),c.publish("control-plane-proxy.binding.updated",{binding:n},{topic:"control-plane-proxy",scope:{nodeId:t}})}}}),v.setNodeAgentTransport(O),await I.init(),v.init(),p=v.diagnosticLogsEnabled(),x.init(),w.init(),l&&A.start();const H=()=>{if($)return $;const e=v.recoverPendingPairingRevokes().then(()=>{});return $=e,e.then(()=>{$===e&&($=void 0)},()=>{$===e&&($=void 0)}),e};await H().catch(e=>o.log.warn({error:e},"pending node pairing recovery failed")),L.init(),U.start(),await v.syncLocalNodeConnection().catch(()=>{});const G=new wb(v,e.service?.fetchImpl,{aiSessions:k,logger:y,diagnosticLogsEnabled:()=>p});G.startEnabled();const W=new Yv(v,O,{safetyIntervalMs:Number(process.env.TASK_HANDOFF_EVENT_CONNECTION_SAFETY_INTERVAL_MS)||void 0,logger:y,connectionRuntime:b}),V=c.onAiSessionTransientDemand(e=>{W.setAiSessionTransientDemand(e)});W.start(),await o.register(h),await o.register(g,{options:on}),o.addHook("onClose",async()=>{await A.stop(),B&&clearInterval(B),F&&clearInterval(F),await($?.catch(()=>{})),T.close(),q.stop(),U.stop(),W.stop(),V(),G.stopAll(),v.dispose(),await I.close()}),o.setErrorHandler((e,t,n)=>{const i=TS(e);void 0!==i.retryAfterSeconds&&n.header("retry-after",String(i.retryAfterSeconds)),(p||i.statusCode>=500)&&(i.statusCode>=500?o.log.error.bind(o.log):o.log.warn.bind(o.log))({method:t.method,url:t.url,statusCode:i.statusCode,errorCode:i.code,error:i.message},"control plane request failed"),n.code(i.statusCode).send(yS.parse({error:{code:i.code,message:i.message,...i.details?{details:i.details}:{},...void 0!==i.retryable?{retryable:i.retryable}:{}}}))}),o.addHook("preHandler",async(e,t)=>{const n=e.routeOptions.url,i=n&&"*"!==n?n:e.url,s=e.routeOptions.config.controlPlaneAuthBoundary,a=e.headers[gS],o="string"==typeof a?S.get(a):void 0;if(o){S.delete(a),EI(e,o);const t=CS(e.method,i);if(!t)throw Object.assign(new Error("Cloud access route is not authorized."),{code:"CLOUD_ROUTE_FORBIDDEN",statusCode:403});return void $d(o,t.action,t.resource)}if("proxy-binding"===s||"node-tunnel"===s)return;const r="public"===s||"public-ui"===s&&function(e){const t=e.split("?")[0]||"/";return!t.startsWith("/api/")&&"/api"!==t&&!t.startsWith("/instances/")&&"/instances"!==t}(e.url);if(!I.enabled()||r){const t=await kS(I,zS(e));EI(e,t||{type:"system",reason:"auth-disabled"});const n=CS(e.method,i);return void(n&&$d(t||{type:"system",reason:"auth-disabled"},n.action,n.resource))}const c=await kS(I,zS(e));if(!c)return t.code(401).send({error:{code:"CONTROL_PLANE_AUTH_REQUIRED",message:"Sign in to access the Control Plane."}});if(EI(e,c),"user"===c.type&&c.requiresPasswordChange&&"/api/auth/password"!==i)throw Object.assign(new Error("Change the temporary password before accessing the Control Plane."),{code:"AUTH_PASSWORD_CHANGE_REQUIRED",statusCode:403});const d=CS(e.method,i);if(d)if("user"===c.type){let t;$d(c,d.action,d.resource);try{t=await async function(e,t,n,i,s,a){const o=II(t.params),r=II(t.body);if(["user","role","identity-provider","user-session","identity-approval","user-audit","secret","chat-bridge","control-plane-settings"].includes(i.type))return[{kind:"global-admin"}];if("trigger-template"===i.type)return[{kind:"global-shared"}];if("public-directory"===i.type)return[{kind:"global-public"}];if("image"===i.type)return[{kind:"global-public"}];if("model"===i.type&&!n.startsWith("/api/nodes/"))return[{kind:"global-public"}];const c=xI(o.nodeId)||(n.startsWith("/api/nodes/")?xI(o.id):void 0);if(c&&["node","runtime","template","model"].includes(i.type))return e.requireNode(c),[wI(c)];if("project"===i.type){const t=xI(o.id);if(!t)return;const n=e.requireProject(t);if("local-folder"!==n.source.type)return[{kind:"global-public"}];if(!n.source.ownerNodeId)throw Object.assign(new Error("The requested resource is not visible."),{code:"CONTROL_PLANE_RESOURCE_NOT_VISIBLE",statusCode:404});return e.requireNode(n.source.ownerNodeId),[wI(n.source.ownerNodeId)]}if("instance"===i.type&&"/api/controlled-instances"===n&&"create"===a){const t=e.resolveControlledInstanceTargetNodeId(r);return e.requireNode(t),[wI(t)]}if("trigger-deployment"===i.type&&n.endsWith("/apply")){const t=Array.isArray(r.instanceIds)?r.instanceIds.map(xI).filter(e=>Boolean(e)):[];if(!t.length)return;return Promise.all([...new Set(t)].map(t=>SI(e,t,s)))}const d=n.startsWith("/api/controlled-instances/")?xI(o.id):xI(r.instanceId);return d&&["instance","app-session","ai-session","trigger-deployment","repository","attachment","template"].includes(i.type)?[await SI(e,d,s)]:["node","runtime","template"].includes(i.type)&&c?[wI(c)]:void 0}(v,e,i,d.resource,c,d.action)}catch(e){if(e&&"object"==typeof e&&404===e.statusCode)throw Object.assign(new Error("The requested resource is not visible."),{statusCode:404,code:"CONTROL_PLANE_RESOURCE_NOT_VISIBLE"});throw e}if(t?.length)for(const e of t)Bd(c,d.action,d.resource,e)}else $d(c,d.action,d.resource)});const K=t.resolve(e.staticDir||process.env.TASK_HANDOFF_CONTROL_PLANE_STATIC_DIR||t.resolve(process.cwd(),"packages","control-plane-ui","dist"));n.existsSync(K)&&(o.get("/assets/*",{config:xv},async(e,n)=>{const i=e.params["*"];return _S(n,K,t.join("assets",i||""))}),o.get("/favicon.ico",{config:xv},async(e,t)=>ES(K,"favicon.ico")?_S(t,K,"favicon.ico"):t.code(204).send())),o.get("/api/health",{config:xv},async()=>kr.parse({data:{ok:!0,role:"control-plane",protocolVersion:wo,build:SS(),serverTime:(new Date).toISOString()}})),o.get("/api/control-plane/identity",{config:xv},async()=>x.publicDocument(I.enabled()?"required":"disabled"));const Y=async e=>{if(!l)throw Object.assign(new Error("Cloud connectivity is disabled by feature flag."),{code:"CLOUD_CONNECTIVITY_DISABLED",statusCode:503});$d(await kS(I,zS(e))||{type:"system",reason:"auth-disabled"},"manage-settings",{type:"control-plane-settings"})};return o.get("/api/cloud-connectivity",async e=>(await Y(e),{data:w.snapshot()})),o.post("/api/cloud-connectivity/challenges",async(e,t)=>{await Y(e),t.header("cache-control","no-store");const n=w.createChallenge();return await _(n),{data:n}}),o.post("/api/cloud-connectivity/remote-access",async e=>{await Y(e);const t=f.z.object({enabled:f.z.boolean()}).strict().parse(e.body);return{data:E?await E.setRemoteAccess(t.enabled):w.setRemoteAccess(t.enabled)}}),o.post("/api/cloud-connectivity/disconnect",async e=>(await Y(e),{data:E?await E.disconnect():w.beginRevocation()})),o.get("/api/session-streams/diagnostics",async()=>({data:{aiSessions:k.diagnostics(),aiSessionActions:v.aiSessionActionDiagnostics(),appSessions:N.diagnostics(),nodeConnections:{...W.diagnostics(),runtime:b.diagnostics()},eventAuthorization:c.authorizationDiagnostics()}})),o.get("/install-node-agent.sh",{config:xv},async(e,t)=>(t.header("cache-control","no-store"),t.type("text/x-shellscript; charset=utf-8"),Ux`#!/bin/sh
2
2
  set -eu
3
3
 
4
+ MIN_NODE_VERSION="24.15.0"
4
5
  CONTROL_PLANE_URL=""
5
6
  JOIN_TOKEN=""
6
7
  SERVICE_USER="root"
@@ -33,9 +34,18 @@ Options:
33
34
  --service-user <user> systemd service user
34
35
  --host <host> Node-agent HTTP bind host, default 127.0.0.1
35
36
  --port <port> Node-agent HTTP port, default 8091
37
+
38
+ On Debian, Ubuntu, RHEL 8/9, and compatible dnf-based hosts, the installer
39
+ can also install a compatible Node.js 24 and npm. Existing compatible Node.js
40
+ and npm installations are used without invoking a system package manager.
36
41
  USAGE
37
42
  }
38
43
 
44
+ die() {
45
+ echo "Error: $*" >&2
46
+ exit 1
47
+ }
48
+
39
49
  need_root() {
40
50
  if [ "$(id -u)" != "0" ]; then
41
51
  echo "This installer must run as root. Re-run with sudo." >&2
@@ -50,6 +60,81 @@ require_command() {
50
60
  fi
51
61
  }
52
62
 
63
+ node_is_compatible() {
64
+ command -v node >/dev/null 2>&1 || return 1
65
+ current_node_version="$(node -p 'process.versions.node' 2>/dev/null || true)"
66
+ case "$current_node_version" in
67
+ 24.*) version_is_at_least "$current_node_version" "$MIN_NODE_VERSION" ;;
68
+ *) return 1 ;;
69
+ esac
70
+ }
71
+
72
+ version_is_at_least() {
73
+ awk -v current="$1" -v minimum="$2" 'BEGIN {
74
+ split(current, left, "."); split(minimum, right, ".");
75
+ for (i = 1; i <= 3; i++) {
76
+ if ((left[i] + 0) > (right[i] + 0)) exit 0;
77
+ if ((left[i] + 0) < (right[i] + 0)) exit 1;
78
+ }
79
+ exit 0;
80
+ }'
81
+ }
82
+
83
+ install_node_prerequisites() {
84
+ if command -v apt-get >/dev/null 2>&1; then
85
+ export DEBIAN_FRONTEND=noninteractive
86
+ echo "Refreshing apt package metadata"
87
+ apt-get update
88
+ apt-get install -y ca-certificates curl xz-utils
89
+ elif command -v dnf >/dev/null 2>&1; then
90
+ echo "Installing Node.js archive prerequisites with dnf"
91
+ dnf install -y ca-certificates curl tar xz
92
+ else
93
+ die "automatic Node.js installation requires apt-get or dnf; install Node.js $MIN_NODE_VERSION with npm manually"
94
+ fi
95
+ }
96
+
97
+ ensure_supported_linux_runtime() {
98
+ for command in awk getconf uname; do require_command "$command"; done
99
+ [ "$(uname -s)" = "Linux" ] || die "runtime packages support Linux hosts only"
100
+ case "$(uname -m)" in
101
+ x86_64|amd64) node_arch="x64" ;;
102
+ aarch64|arm64) node_arch="arm64" ;;
103
+ *) die "runtime packages support x86_64 and arm64 Linux hosts only" ;;
104
+ esac
105
+ glibc_version="$(getconf GNU_LIBC_VERSION 2>/dev/null | awk '{ print $2 }')"
106
+ [ -n "$glibc_version" ] && version_is_at_least "$glibc_version" "2.28" \
107
+ || die "runtime packages require glibc 2.28 or newer; found \${glibc_version:-unknown}"
108
+ }
109
+
110
+ ensure_node_environment() {
111
+ if node_is_compatible && command -v npm >/dev/null 2>&1; then
112
+ ensure_supported_linux_runtime
113
+ echo "Using existing Node.js $(node --version) and npm $(npm --version)"
114
+ return
115
+ fi
116
+
117
+ echo "Installing the current official Node.js 24 build with its bundled npm."
118
+ install_node_prerequisites
119
+ for command in awk curl getconf mktemp sha256sum tar uname; do require_command "$command"; done
120
+ ensure_supported_linux_runtime
121
+ node_tmp="$(mktemp -d)"
122
+ trap 'rm -rf "$node_tmp"' EXIT HUP INT TERM
123
+ curl -fsSL https://nodejs.org/dist/latest-v24.x/SHASUMS256.txt -o "$node_tmp/SHASUMS256.txt"
124
+ node_archive="$(awk -v suffix="linux-$node_arch.tar.xz" '$2 ~ suffix "$" { print $2; exit }' "$node_tmp/SHASUMS256.txt")"
125
+ [ -n "$node_archive" ] || die "could not find the official Node.js 24 archive for $node_arch"
126
+ curl -fsSL "https://nodejs.org/dist/latest-v24.x/$node_archive" -o "$node_tmp/$node_archive"
127
+ expected_checksum="$(awk -v archive="$node_archive" '$2 == archive { print $1; exit }' "$node_tmp/SHASUMS256.txt")"
128
+ actual_checksum="$(sha256sum "$node_tmp/$node_archive" | awk '{ print $1 }')"
129
+ [ "$actual_checksum" = "$expected_checksum" ] || die "Node.js archive checksum verification failed"
130
+ tar -xJf "$node_tmp/$node_archive" --strip-components=1 -C /usr/local
131
+ rm -rf "$node_tmp"
132
+ trap - EXIT HUP INT TERM
133
+
134
+ node_is_compatible || die "Node.js $MIN_NODE_VERSION or newer within the Node.js 24 release line is required; found $(node --version 2>/dev/null || echo none)"
135
+ command -v npm >/dev/null 2>&1 || die "npm was not installed with Node.js"
136
+ }
137
+
53
138
  while [ "$#" -gt 0 ]; do
54
139
  case "$1" in
55
140
  --control-plane) CONTROL_PLANE_URL="\${2:-}"; shift 2 ;;
@@ -70,7 +155,6 @@ while [ "$#" -gt 0 ]; do
70
155
  done
71
156
 
72
157
  need_root
73
- require_command curl
74
158
 
75
159
  if [ -z "$CONTROL_PLANE_URL" ]; then
76
160
  echo "--control-plane is required." >&2
@@ -84,6 +168,9 @@ if ! command -v systemctl >/dev/null 2>&1; then
84
168
  exit 1
85
169
  fi
86
170
 
171
+ ensure_node_environment
172
+ require_command curl
173
+
87
174
  if [ "$SERVICE_USER" != "root" ] && ! id "$SERVICE_USER" >/dev/null 2>&1; then
88
175
  useradd --system --create-home --home-dir /var/lib/task-handoff --shell /usr/sbin/nologin "$SERVICE_USER"
89
176
  fi
@@ -186,14 +273,18 @@ WantedBy=multi-user.target
186
273
  EOF
187
274
 
188
275
  systemctl daemon-reload
189
- systemctl enable --now task-handoff-node-agent.service
276
+ # Compatibility for v0.0.24: enable --now left an already-running process on
277
+ # the old package, environment, and unit after a repeated installation.
278
+ systemctl enable task-handoff-node-agent.service
279
+ systemctl restart task-handoff-node-agent.service
190
280
 
191
281
  for i in $(seq 1 30); do
192
- if curl -fsS "http://$HOST:$PORT/api/node-agent/health" >/dev/null 2>&1; then
282
+ if [ -S "$IPC_PATH" ] && curl --unix-socket "$IPC_PATH" -fsS "http://localhost/api/node-agent/health" >/dev/null 2>&1; then
193
283
  break
194
284
  fi
195
285
  if [ "$i" = "30" ]; then
196
286
  systemctl status --no-pager task-handoff-node-agent.service || true
287
+ curl --unix-socket "$IPC_PATH" -sS "http://localhost/api/node-agent/health" >&2 || true
197
288
  echo "Node agent did not become healthy." >&2
198
289
  exit 1
199
290
  fi
@@ -203,9 +294,10 @@ done
203
294
  if [ -n "$JOIN_TOKEN" ]; then
204
295
  payload="$(mktemp)"
205
296
  status="$(curl -sS -o "$payload" -w '%{http_code}' \
297
+ --unix-socket "$IPC_PATH" \
206
298
  -H 'content-type: application/json' \
207
299
  -d "{\"controlPlaneUrl\":\"$CONTROL_PLANE_URL\",\"joinToken\":\"$JOIN_TOKEN\",\"controlPlaneName\":\"TaskHandoff Control Plane\",\"activate\":true}" \
208
- "http://$HOST:$PORT/api/node-agent/control-plane-connections")"
300
+ "http://localhost/api/node-agent/control-plane-connections")"
209
301
  if [ "$status" != "201" ]; then
210
302
  cat "$payload" >&2 || true
211
303
  rm -f "$payload"
@@ -220,4 +312,5 @@ fi
220
312
  echo "TaskHandoff node-agent is installed and running."
221
313
  echo "Service: task-handoff-node-agent.service"
222
314
  echo "Pairing token: sudo task-handoff-node-agent invite --ipc-path $IPC_PATH"
223
- `)),c.get("/api/events",{websocket:!0},async(e,t)=>{const n=t.query,i="string"==typeof n.instanceId?n.instanceId.trim():"",s=[];let r=!1;const o={get readyState(){return e.readyState},OPEN:e.OPEN,send(t){r?e.send(t):s.push(t)},on(t,n){e.on(t,n)}};l.connect(o,{instanceIds:i?[i]:void 0});const[a,d]=await Promise.all([x.streamDescriptors(),N.streamDescriptors()]);l.send(e,"streams.hello",{protocolVersion:1,streams:[...a,...d].filter(e=>!i||e.instanceId===i)}),r=!0;for(const t of s)e.send(t);for(const t of E.snapshots().filter(e=>!i||e.instanceId===i))l.send(e,"image.pull.snapshot",t,{topic:"instances",scope:{instanceId:t.instanceId}})}),c.get("/api/auth/session",{config:Ig},async e=>{const t=Jy(e);return{data:await b.currentSession(t.token,t.clientType)}}),c.post("/api/auth/bootstrap-admin",{config:Ig},async(e,t)=>{const n=await b.bootstrapAdmin(e.body);return t.code(201).send({data:n})}),c.post("/api/auth/login",{config:Ig},async(e,t)=>{const n=await b.login(e.body,{sourceId:e.ip});return t.setCookie(bo,n.sessionToken,{path:"/",httpOnly:!0,sameSite:"lax",expires:new Date(n.expiresAt)}),{data:{user:n.user}}}),c.post("/api/auth/mobile/login",{config:Ig},async e=>({data:await b.loginMobile(e.body,{sourceId:e.ip})})),c.patch("/api/auth/password",async(e,t)=>{const n=await b.changePassword(e.cookies[bo],e.body,{sourceId:e.ip});return t.setCookie(bo,n.sessionToken,{path:"/",httpOnly:!0,sameSite:"lax",expires:new Date(n.expiresAt)}),{data:{user:n.user}}}),c.post("/api/auth/mobile/logout",async e=>{const t=Jy(e);return{data:b.logout("mobile"===t.clientType?t.token:void 0)}}),c.get("/api/auth/mobile/sessions",async(e,t)=>{const n=b.mobileSessions(Jy(e).token);return n?{data:n}:t.code(401).send({error:{code:"CONTROL_PLANE_AUTH_REQUIRED",message:"Sign in to access mobile sessions."}})}),c.delete("/api/auth/mobile/sessions/:id",async(e,t)=>{const n=a.z.object({id:a.z.string().trim().min(1)}).parse(e.params),i=b.revokeMobileSession(Jy(e).token,n.id);return void 0===i?t.code(401).send({error:{code:"CONTROL_PLANE_AUTH_REQUIRED",message:"Sign in to revoke mobile sessions."}}):{data:{revoked:i}}}),c.post("/api/auth/logout",{config:Ig},async(e,t)=>{const n=b.logout(e.cookies[bo]);return t.clearCookie(bo,{path:"/"}),{data:n}}),c.get("/api/control-plane/status",async()=>({data:{protocolVersion:li,build:Hy(),storage:d}})),c.get("/api/control-plane/settings",async()=>({data:I.getSettings()})),c.patch("/api/control-plane/settings",async e=>{const t=I.updateSettings(e.body||{});return u=t.diagnosticLogs,{data:t}}),c.get("/api/control-plane/diagnostic-logs/export",async(e,i)=>{const s=await async function(e){const i=n.mkdtempSync(t.join(y.tmpdir(),"task-handoff-diagnostic-logs-")),s=t.resolve(e.nodeAgentDataDir||t.join(e.dataDir,"node-agent")),r=t.join(s,"local-instances"),o=n.existsSync(r)?n.readdirSync(r,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.isSymbolicLink()).map(e=>({label:t.join("local-instances",e.name),root:t.join(r,e.name,"logs")})):[],a=[{label:"control-plane",root:t.join(e.dataDir,"logs")},{label:"desktop",root:t.join(e.dataDir,"log")},{label:"node-agent",root:t.join(s,"logs")},...o],d=[];let c=0;for(const e of a)for(const s of by(e.root)){if(c>=fy)break;const r=t.relative(e.root,s);if(!r||r.startsWith("..")||t.isAbsolute(r))continue;const o=t.join("logs",e.label,r),a=n.statSync(s).size,l=vy(s,t.join(i,o),fy-c);l&&(c+=l,d.push({source:s,archivePath:o,bytes:l,originalBytes:a}))}n.writeFileSync(t.join(i,"manifest.json"),`${JSON.stringify({createdAt:(new Date).toISOString(),diagnosticLogsEnabled:e.diagnosticLogsEnabled,limits:{perFileBytes:yy,totalBytes:fy},files:d.map(({archivePath:e,bytes:t,originalBytes:n})=>({archivePath:e,bytes:t,originalBytes:n,truncated:t<n}))},null,2)}\n`,{mode:384});const l=["manifest.json",...n.existsSync(t.join(i,"logs"))?["logs"]:[]],p=A.create({cwd:i,gzip:!0,portable:!0,noMtime:!0},l),u=()=>n.rmSync(i,{recursive:!0,force:!0});return p.once("close",u),p.once("error",u),{filename:`task-handoff-diagnostic-logs-${(new Date).toISOString().replace(/[:.]/g,"-")}.tar.gz`,stream:p}}({dataDir:d.dataDir,nodeAgentDataDir:process.env.TASK_HANDOFF_DESKTOP_NODE_AGENT_DATA_DIR||process.env.TASK_HANDOFF_NODE_AGENT_DATA_DIR,diagnosticLogsEnabled:u});return i.header("content-type","application/gzip"),i.header("content-disposition",`attachment; filename="${s.filename}"`),i.send(s.stream)}),c.post("/api/ai-session-attachments",{bodyLimit:33554432},async(e,t)=>{try{return t.code(201).send({data:O.upload(e.body)})}catch(e){return t.code(400).send({error:{code:"AI_SESSION_ATTACHMENT_INVALID",message:e instanceof Error?e.message:String(e)}})}}),Gh({app:c,service:I,events:l,appSessionAggregator:N,aiSessionAggregator:x,aiSessionUnread:C,chatGateway:H,aiSessionAttachments:O,nodeAgentTunnel:_,nodeEventSubscriber:W,errorPayload:Ky}),function(e){const{app:t,authority:n,resolveTarget:i,projectTarget:s,eventHub:r}=e,o=e.runtime??new Rm,a=new WeakMap,d=(e,t)=>{const n=a.get(e);n&&(a.delete(e),n.tracked.release(),e.raw.removeListener("aborted",n.abort),t.raw.removeListener("close",n.abort))};t.all("/api/node-proxy/bindings/:bindingId/http/*",{config:vg,bodyLimit:o.maxRequestBodyBytes,logLevel:"silent",async onRequest(e,t){try{const i=Um.parse(e.params).bindingId,s=Vm(n,i,e),r=function(e){const t=e.raw.url||e.url,n=/^\/api\/node-proxy\/bindings\/[^/]+\/http(\/[^#]*)$/.exec(t);if(!n||/%(?:2f|5c)/i.test(n[1]))throw Zm(Hn.RouteInvalid,"Proxy route is invalid.",400);const i=Mn.safeParse(n[1]);if(!i.success)throw Zm(Hn.RouteInvalid,i.error.issues[0]?.message||"Proxy route is invalid.",400);return i.data}(e),c=Ym(e.headers),l=o.reserveHttp(s.id),p=()=>{l.controller.abort(Object.assign(new Error("Proxy HTTP consumer disconnected."),{name:"AbortError",code:"ABORT_ERR"})),d(e,t)};a.set(e,{binding:s,route:r,forwardedHeaders:c,tracked:l,abort:p}),e.raw.once("aborted",p),t.raw.once("close",p)}catch(n){return Qm(t,n,e)}},async onError(e,t){d(e,t);const n=ty(e.headers);n&&t.header("x-request-id",n)},async onResponse(e,t){d(e,t)}},async(e,t)=>{try{const r=a.get(e);if(!r)throw Zm(Hn.TransportFailed,"Proxy request context is unavailable.",500,!0);const{binding:o,route:c,forwardedHeaders:l,tracked:p,abort:u}=r;!function(e,t,n){const i=new URL(t,"https://node-agent.invalid").searchParams,s=[i.get("nodeId"),i.get("targetNodeId")];if(n&&"object"==typeof n&&!Array.isArray(n)){const e=n;"string"==typeof e.nodeId&&s.push(e.nodeId),"string"==typeof e.targetNodeId&&s.push(e.targetNodeId)}const r=s.find(t=>null!==t&&t!==e.targetNodeId);if(void 0!==r)throw Zm(Hn.TargetMismatch,"Proxy request attempts to select a target outside its binding.",409,!1,{bindingId:e.id,targetNodeId:e.targetNodeId})}(o,c,e.body);const h=null==(s=e.body)?void 0:Buffer.isBuffer(s)?s:s instanceof Uint8Array||"string"==typeof s?Buffer.from(s):Buffer.from(JSON.stringify(s));p.acceptRequestBody(h?.byteLength??0);try{const{node:s,transport:r}=await i(o.targetNodeId);return Km(n,o,e),Jm(o,s),function(e,t,n,i,s,r){t.body&&n.beginResponseStream();for(const[n,i]of Object.entries(function(e,t){const n=Object.fromEntries([...qn].flatMap(t=>{const n=e.headers.get(t);return null===n?[]:[[t,n]]}));return t&&(n["x-request-id"]=t),n}(t,r)))e.header(n,i);const o=()=>{n.release(),s.raw.removeListener("aborted",i),e.raw.removeListener("close",i)};if(!t.body)return o(),e.code(t.status).send();const a=g.Readable.fromWeb(t.body);return n.controller.signal.addEventListener("abort",()=>{const e=n.controller.signal.reason;a.destroy(e instanceof Error?e:new Error("Proxy HTTP stream aborted."))},{once:!0}),a.on("data",e=>{try{n.acceptResponseChunk(e)}catch(e){a.destroy(e)}}),a.once("end",o),a.once("error",o),a.once("close",o),e.raw.once("close",()=>a.destroy()),e.code(t.status).send(a)}(t,await r.requestStream(s,c,{method:e.method,headers:l,...h?{body:h}:{},signal:p.controller.signal}),p,u,e,l["x-request-id"])}catch(n){throw d(e,t),n}}catch(n){return d(e,t),Qm(t,n,e)}var s}),t.get("/api/node-proxy/bindings/:bindingId/websocket",{websocket:!0,logLevel:"silent",config:vg},async(e,t)=>{let s;try{const r=Um.parse(t.params).bindingId,a=Vm(n,r,t),d=Fm.parse(t.query).route,{node:c,transport:l}=await i(a.targetNodeId);Km(n,a,t),Jm(a,c),s=o.openWebSocket(a.id,e),l.proxyWebSocket(c,s,d,function(e){const t=ey(e,"sec-websocket-protocol").split(",").map(e=>e.trim()).filter(Boolean);return t.length?t:void 0}(t.headers),Ym(t.headers))}catch(t){const n=Xm(t);s?.close(1008,n.message),s||e.close(429===n.statusCode?1013:n.statusCode<500?1008:1011,ny(n.message))}}),t.get("/api/node-proxy/bindings/:bindingId/snapshot",{config:vg},async(e,t)=>{try{const t=Um.parse(e.params).bindingId,a=Vm(n,t,e),{node:d}=await i(a.targetNodeId);Km(n,a,e),Jm(a,d);const c=s(a.targetNodeId);if(!c)throw Zm(Hn.TargetUnavailable,"Proxy target no longer exists.",404,!1,{targetNodeId:a.targetNodeId});const l=r.cursor(a.targetNodeId),p=ni.parse({protocolVersion:Nn,binding:a,streamId:l.streamId,revision:l.revision,observedAt:(new Date).toISOString(),target:Bm(c)});if(o=p,Buffer.byteLength(JSON.stringify(o),"utf8")>Gm)throw Zm(Hn.ResourceLimit,"Proxy target snapshot byte limit exceeded.",429,!0,{bindingId:a.id,resource:"snapshot-bytes",limit:Gm});return{data:p}}catch(n){return Qm(t,n,e)}var o}),t.get("/api/node-proxy/bindings/:bindingId/events",{websocket:!0,logLevel:"silent",config:vg},async(e,t)=>{let s,a,d;try{const c=Um.parse(t.params).bindingId,l=Vm(n,c,t),p=Hm.parse(t.query),{node:u}=await i(l.targetNodeId);Km(n,l,t),Jm(l,u),s=o.openWebSocket(l.id,e,()=>a?.()),s.on("message",()=>s?.close(1008,"Proxy event streams do not accept client messages."));const g=r.subscribe({bindingId:l.id,sourceControlPlaneId:l.sourceControlPlaneId,targetNodeId:l.targetNodeId},p.sinceRevision,e=>{s?.send(JSON.stringify(e))},()=>{s?.close(1011,"Proxy event delivery failed.")});a=g.close,d=o.registerBindingCleanup(l.id,a);const h=()=>{a?.(),d?.()};s.on("close",h),s.on("error",h),"snapshot-required"===g.kind?(a(),s.close(1008,"Proxy target snapshot is required.")):1!==s.readyState&&a()}catch(t){a?.(),d?.();const n=Xm(t);s?.close(1008,n.message),s||e.close(429===n.statusCode?1013:n.statusCode<500?1008:1011,ny(n.message))}}),t.delete("/api/node-proxy/bindings/:bindingId",{config:vg},async(t,i)=>{try{const i=Um.parse(t.params).bindingId;Vm(n,i,t);const s=n.revokeBinding(i),r=o.closeBinding(i);return e.onBindingRevoked?.(s),{data:{binding:s,closed:r}}}catch(e){return Qm(i,e,t)}})}({app:c,authority:D,resolveTarget:e=>{const t=I.requireNode(e);return{node:t,transport:I.resolveNodeAgentTransport(t)}},projectTarget:P,runtime:M,eventHub:L,onBindingRevoked:e=>l.publish("control-plane-proxy.binding.updated",{binding:e,audit:{action:"binding.revoke",actor:`control-plane:${e.sourceControlPlaneId}`}},{topic:"control-plane-proxy",scope:{nodeId:e.targetNodeId}})}),function(e){const{app:t,service:n,proxy:i,runtime:s,events:r,syncNodeEvents:o,actorId:a}=e;t.get("/api/control-plane-proxy/invites",async()=>({data:i.listInvites()})),t.post("/api/control-plane-proxy/invites",async(e,t)=>{const n=await a(e),s=i.createInvite(e.body,n);return r.publish("control-plane-proxy.invite.created",{invite:s.invite,audit:{action:"invite.create",actor:n}},{topic:"control-plane-proxy",scope:{nodeId:s.invite.targetNodeId}}),t.code(201).send({data:s})}),t.delete("/api/control-plane-proxy/invites/:id",async e=>{const t=await a(e),n=i.revokeInvite(oy.parse(e.params).id);return r.publish("control-plane-proxy.invite.updated",{invite:n,audit:{action:"invite.revoke",actor:t}},{topic:"control-plane-proxy",scope:{nodeId:n.targetNodeId}}),{data:n}}),t.get("/api/control-plane-proxy/bindings",async()=>({data:i.listBindings()})),t.delete("/api/control-plane-proxy/bindings/:id",async e=>{const t=await a(e),n=oy.parse(e.params).id,o=i.revokeBinding(n),d=s.closeBinding(n);return r.publish("control-plane-proxy.binding.updated",{binding:o,audit:{action:"binding.revoke",actor:t}},{topic:"control-plane-proxy",scope:{nodeId:o.targetNodeId}}),{data:{binding:o,closed:d}}}),t.get("/api/control-plane-proxy/diagnostics",async()=>({data:s.diagnostics()})),t.post("/api/node-proxy/claims",{config:Ig},async(e,t)=>{const n=i.claimInvite(e.body);return r.publish("control-plane-proxy.binding.created",{binding:n.binding,audit:{action:"binding.claim",actor:`control-plane:${n.binding.sourceControlPlaneId}`}},{topic:"control-plane-proxy",scope:{nodeId:n.binding.targetNodeId}}),t.code(201).send({data:n})}),t.get("/api/control-plane-proxy/pending-claims",async()=>({data:n.listPendingProxyClaims()})),t.post("/api/control-plane-proxy/claims",async(e,t)=>{const i=await n.claimProxyNode(e.body);return o?.(),r.publish("node.created",{nodeId:i.node.id}),t.code(201).send({data:i})}),t.post("/api/control-plane-proxy/pending-claims/:id/resume",async e=>{const t=oy.parse(e.params).id;ay.parse(e.body||{});const i=await n.resumeProxyClaim(t);return o?.(),r.publish("node.created",{nodeId:i.node.id}),{data:i}}),t.delete("/api/control-plane-proxy/pending-claims/:id",async e=>{const t=dy.parse(e.query||{});return{data:await n.cancelProxyClaim(oy.parse(e.params).id,"true"===t.force)}})}({app:c,service:I,proxy:D,runtime:M,events:l,syncNodeEvents:()=>W.syncNow(),actorId:async e=>{const t=await Yy(b,Jy(e));return t?"user"===t.type?`user:${t.userId}`:"system"===t.type?`system:${t.reason}`:"cloud-account"===t.type?`cloud-account:${t.accountId}:${t.deviceSessionId}`:`chat-bridge:${t.bridgeId}`:"system:unknown"}}),function({app:e,service:t}){!function(e){for(const t of["application/octet-stream","application/x-www-form-urlencoded"])sm(e,t);sm(e,/^multipart\/form-data(?:;.*)?$/i)}(e),e.get("/api/app-access/session",{config:Ig},async e=>{const n=rm(e.url),i="vnc"===e.query.mode?"vnc":"web"===e.query.mode?"web":"tty",s=await t.appAccessProxyTarget(n,i);return{data:{mode:i,instance:{id:s.instance.id,name:s.instance.name,projectId:s.instance.projectId,projectName:"string"==typeof s.instance.sourceSnapshot.name?s.instance.sourceSnapshot.name:void 0},session:s.session,expiresAt:s.access.expiresAt,ttySocketPath:"tty"===i?`/apps/access/tty/ws?token=${encodeURIComponent(n)}`:void 0,vncFramePath:"vnc"===i?om(n,s.access.sessionId,s.session):void 0}}}),e.get("/apps/access/tty/ws",{websocket:!0,config:Ig},async(e,n)=>{try{const i=await t.appAccessProxyTarget(rm(n.url),"tty");await t.proxyInstanceWebSocket(i.instance.id,e,i.path,Xh(n.headers),Qh(n.headers))}catch{e.close(1011,"TTY access link is invalid or expired.")}});const n=async(e,n)=>{const i=n.params;try{const s=await t.appAccessProxyTarget(i.token||rm(n.url),"vnc",i["*"]||"");await t.proxyInstanceWebSocket(s.instance.id,e,s.path,Xh(n.headers),Qh(n.headers))}catch{e.close(1011,"VNC access link is invalid or expired.")}};e.route({method:"GET",url:"/apps/access/vnc/proxy/*",config:Ig,wsHandler:n,handler:async(e,n)=>{const i=e.params,s=await t.appAccessProxyTarget(rm(e.url),"vnc",i["*"]||"");return nm(n,await Zh(t,n,s.instance.id,s.path,{method:e.method,headers:Yh(e.headers)}),s.instance.id,s.path)}}),e.route({method:"GET",url:"/apps/access/vnc/:token/proxy/*",config:Ig,wsHandler:n,handler:async(e,n)=>{const i=e.params,s=await t.appAccessProxyTarget(i.token,"vnc",i["*"]||"");return nm(n,await Zh(t,n,s.instance.id,s.path,{method:e.method,headers:Yh(e.headers)}),s.instance.id,s.path)}}),e.all("/instances/:id",{bodyLimit:67108864},async(e,n)=>{const i=e.params;return"GET"===e.method||"HEAD"===e.method?n.redirect(`${tm(i.id)}/`):nm(n,await Zh(t,n,i.id,"/",{method:e.method,headers:Yh(e.headers),body:im(e.body)}),i.id,"/")}),e.route({method:"GET",url:"/instances/:id/*",wsHandler:async(e,n)=>{const i=n.params,s=i["*"]||"",r=n.url.indexOf("?"),o=r>=0?n.url.slice(r):"";try{await t.proxyInstanceWebSocket(i.id,e,`/${s}${o}`,Xh(n.headers),Qh(n.headers))}catch{e.close(1011,"Instance websocket endpoint is not reachable.")}},handler:async(e,n)=>{const i=e.params,s=i["*"]||"",r=e.url.indexOf("?"),o=`/${s}${r>=0?e.url.slice(r):""}`;return nm(n,await Zh(t,n,i.id,o,{method:e.method,headers:Yh(e.headers)}),i.id,o)}}),e.route({method:["POST","PUT","PATCH","DELETE","OPTIONS"],url:"/instances/:id/*",bodyLimit:67108864,handler:async(e,n)=>{const i=e.params,s=i["*"]||"",r=e.url.indexOf("?"),o=r>=0?e.url.slice(r):"";return em(n,await Zh(t,n,i.id,`/${s}${o}`,{method:e.method,headers:Yh(e.headers),body:im(e.body)}))}})}({app:c,service:I}),c.get("*",{config:bg},async(e,t)=>n.existsSync(G)?Vy(t,G,"index.html"):t.code(404).send({error:{code:"CONTROL_PLANE_UI_NOT_BUILT",message:"Control plane API is running, but the Web UI static directory was not found."}})),B=setInterval(()=>{F().catch(e=>c.log.warn({error:e},"pending node pairing recovery failed"))},3e4),B.unref(),U=setInterval(()=>{I.runPersistenceMaintenance()},216e5),U.unref(),c}function ef(e){const t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw new Error("Port must be a valid TCP port.");return t}function tf(e){if("disabled"!==e&&"password"!==e)throw new Error("Auth mode must be disabled or password.");return e}(async function(){const n=new e.Command;n.name("task-handoff-control-plane").description("Run the TaskHandoff control plane.").version(T("@task-handoff/cli")).option("--host <host>","Control plane host",process.env.TASK_HANDOFF_CONTROL_PLANE_HOST||"127.0.0.1").option("-p, --port <port>","Control plane port",ef,Number(process.env.TASK_HANDOFF_CONTROL_PLANE_PORT)||8081).option("--data-dir <path>","Control plane data directory").option("--static-dir <path>","Control plane Web UI static directory",process.env.TASK_HANDOFF_CONTROL_PLANE_STATIC_DIR||t.resolve(__dirname,"..","ui")).option("--auth-mode <mode>","Control plane auth mode: disabled or password",tf,process.env.TASK_HANDOFF_CONTROL_PLANE_AUTH_MODE||"password").action(async e=>{await async function(e){const t=Wg(e.dataDir),n=uh(ph(),{dataDir:t.dataDir,host:e.host,port:e.port});try{const t=await Zy(e);t.addHook("onClose",async()=>{n.release()}),await t.listen({host:e.host,port:e.port})}catch(t){if(n.release(),t&&"object"==typeof t&&"EADDRINUSE"===t.code)throw Object.assign(new Error(`Control plane port ${e.host}:${e.port} is already in use.`),{statusCode:409,code:"CONTROL_PLANE_PORT_IN_USE",cause:t});throw t}}({host:e.host,port:e.port,dataDir:e.dataDir,staticDir:e.staticDir,auth:{mode:e.authMode}})}),n.command("credentials").description("Replace the Control Plane administrator username and password while the service is stopped.").requiredOption("--username <username>","New administrator username").requiredOption("--password-stdin","Read the new password from standard input").option("--data-dir <path>","Control plane data directory").action(async e=>{if(process.stdin.isTTY)throw new Error("Pipe the new password to standard input when using --password-stdin.");const t=[];for await(const e of process.stdin)t.push(Buffer.isBuffer(e)?e:Buffer.from(e));const n=Buffer.concat(t).toString("utf8").replace(/\r?\n$/,""),i=await async function(e,t,n={}){const i=Wg(e),s=uh(n.lockPath||ph(),{dataDir:i.dataDir});try{const e=new qo(i,{mode:"password"});return e.init(),await e.replaceCredentials(t)}finally{s.release()}}(e.dataDir,{username:e.username,password:n});console.log(`Updated Control Plane credentials for ${i.username}. Existing sessions were revoked.`)}),await n.parseAsync(process.argv)})().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});
315
+ echo "Uninstall: sudo task-handoff-node-agent uninstall"
316
+ `)),o.get("/api/events",{websocket:!0},async(e,t)=>{const n=t.query,i="string"==typeof n.instanceId?n.instanceId.trim():"",s=_I(t),a="user"===s?.type?(await v.listControlledInstances()).filter(e=>qd(s.nodeScope,s.instanceScope,e.id,e.nodeId)):void 0,o=a?new Set(a.map(e=>e.id)):void 0;if(i&&o&&!o.has(i))return void e.close(4003,"The requested event scope is not visible.");const r=[];let d=!1;const l={get readyState(){return e.readyState},get bufferedAmount(){return e.bufferedAmount},OPEN:e.OPEN,send(t){d?e.send(t):r.push(t)},ping(){e.ping()},on(t,n){e.on(t,n)},close(t,n){e.close(t,n)}};c.connect(l,{instanceIds:i?[i]:void 0,expectsTransientSubscription:"1"===n.aiSessionTransient,expectsMetricSubscription:"1"===n.resourceMetricsScope,..."user"===s?.type?{authorization:{userId:s.userId,authorizationRevision:s.authorizationRevision,permissionIds:s.permissionIds,..."selected"===s.nodeScope.kind?{allowedNodeIds:new Set(s.nodeScope.nodeIds)}:{},..."selected"===s.instanceScope?.kind||"selected"===s.nodeScope.kind?{allowedInstanceIds:o}:{}}}:{}});const[p,u]=await Promise.all([k.streamDescriptors(),N.streamDescriptors()]);c.send(e,"streams.hello",{protocolVersion:1,streams:[...p,...u].filter(e=>(!o||o.has(e.instanceId))&&(!i||e.instanceId===i))}),d=!0;for(const t of r)e.send(t);for(const t of T.snapshots().filter(e=>(!o||o.has(e.instanceId))&&(!i||e.instanceId===i)))c.send(e,"image.pull.snapshot",t,{topic:"instances",scope:{instanceId:t.instanceId}})}),o.get("/api/auth/session",{config:xv},async e=>{const t=zS(e);return{data:await I.currentSession(t.token,t.clientType)}}),o.post("/api/auth/bootstrap-admin",{config:xv},async(e,t)=>{const n=await I.bootstrapAdmin(e.body);return t.code(201).send({data:n})}),o.post("/api/auth/login",{config:xv},async(e,t)=>{const n=await I.login(e.body,{sourceId:e.ip});return t.setCookie(Fp,n.sessionToken,{path:"/",httpOnly:!0,sameSite:"lax",expires:new Date(n.expiresAt)}),{data:{user:n.user}}}),o.post("/api/auth/mobile/login",{config:xv},async e=>({data:await I.loginMobile(e.body,{sourceId:e.ip})})),o.patch("/api/auth/password",async(e,t)=>{const n=await I.changePassword(e.cookies[Fp],e.body);return t.setCookie(Fp,n.sessionToken,{path:"/",httpOnly:!0,sameSite:"lax",expires:new Date(n.expiresAt)}),{data:{user:n.user}}}),o.post("/api/auth/mobile/logout",async e=>{const t=zS(e);return{data:await I.logout("mobile"===t.clientType?t.token:void 0)}}),o.get("/api/auth/mobile/sessions",async(e,t)=>{const n=await I.mobileSessions(zS(e).token);return n?{data:n}:t.code(401).send({error:{code:"CONTROL_PLANE_AUTH_REQUIRED",message:"Sign in to access mobile sessions."}})}),o.delete("/api/auth/mobile/sessions/:id",async(e,t)=>{const n=f.z.object({id:f.z.string().trim().min(1)}).parse(e.params),i=await I.revokeMobileSession(zS(e).token,n.id);return void 0===i?t.code(401).send({error:{code:"CONTROL_PLANE_AUTH_REQUIRED",message:"Sign in to revoke mobile sessions."}}):{data:{revoked:i}}}),o.post("/api/auth/logout",{config:xv},async(e,t)=>{const n=await I.logout(e.cookies[Fp]);return t.clearCookie(Fp,{path:"/"}),{data:n}}),o.get("/api/access/me",async(e,t)=>{const n=zS(e),i=await I.currentAccess(n.token,n.clientType);return i?{data:i}:t.code(401).send({error:{code:"CONTROL_PLANE_AUTH_REQUIRED",message:"Sign in to read Control Plane access."}})}),function(e,t){e.get("/api/users",async e=>{const n=f.z.object({search:f.z.string().trim().max(160).optional(),includeArchived:f.z.coerce.boolean().optional()}).strict().parse(e.query);return{data:await t.users.list(n)}}),e.post("/api/users",async(e,n)=>n.code(201).send({data:await t.users.createLocalUser(e.body)})),e.get("/api/users/:id",async e=>({data:await t.users.detail(Pw.parse(e.params).id)})),e.patch("/api/users/:id",async e=>{const n=Pw.parse(e.params).id,i=await t.users.updateUser(n,e.body);return await t.notifyAuthorizationChanged(n),{data:i}}),e.put("/api/users/:id/access",async e=>{const n=Pw.parse(e.params).id,i=await t.users.setAccess(n,e.body);return await t.notifyAuthorizationChanged(n),{data:i}}),e.post("/api/users/:id/password-reset",async e=>{const n=f.z.object({password:f.z.string().min(8).max(4096),requirePasswordChange:f.z.boolean().optional()}).strict().parse(e.body),i=Pw.parse(e.params).id,s=await t.users.resetLocalPassword(i,n.password,!1!==n.requirePasswordChange);return await t.notifyAuthorizationChanged(i),{data:s}}),e.get("/api/users/:id/sessions",async e=>{const n=Dw(e);return{data:await t.sessions.listSessions(n.userId,Pw.parse(e.params).id)}}),e.delete("/api/users/:id/sessions",async e=>{const n=Pw.parse(e.params).id;return{data:{revokedSessions:await t.users.revokeSessions(n)}}}),e.delete("/api/users/:id/sessions/:sessionId",async e=>{const n=Dw(e),i=f.z.object({id:f.z.string().trim().min(1),sessionId:f.z.string().trim().min(1)}).strict().parse(e.params);return{data:{revoked:await t.sessions.revokeSession(n.userId,i.sessionId)}}}),e.delete("/api/users/:id/identities/:identityId",async e=>{const n=f.z.object({id:f.z.string().trim().min(1),identityId:f.z.string().trim().min(1)}).strict().parse(e.params),i=await t.users.unbindExternalIdentity(n.id,n.identityId);return await t.notifyAuthorizationChanged(n.id),{data:i}}),e.get("/api/roles",async()=>({data:await t.users.roleSummaries()})),e.get("/api/permissions",async()=>({data:Nl})),e.post("/api/roles",async(e,n)=>n.code(201).send({data:await t.users.createRole(e.body)})),e.patch("/api/roles/:id",async e=>{const n=Pw.parse(e.params).id,i=(await t.users.store.grants.listByRole(n)).map(e=>e.userId),s=await t.users.updateRole(n,e.body);for(const e of i)await t.notifyAuthorizationChanged(e);return{data:s}}),e.delete("/api/roles/:id",async e=>({data:await t.users.archiveRole(Pw.parse(e.params).id)})),e.get("/api/identity-providers",async()=>({data:await t.identityProviders.list()})),e.post("/api/identity-providers",async(e,n)=>n.code(201).send({data:await t.identityProviders.create(e.body)})),e.patch("/api/identity-providers/:id",async e=>({data:await t.identityProviders.update(Pw.parse(e.params).id,e.body)})),e.delete("/api/identity-providers/:id",async e=>({data:{deleted:await t.identityProviders.remove(Pw.parse(e.params).id)}})),e.get("/api/external-identity-approvals",async()=>({data:await t.users.store.approvals.list()})),e.post("/api/external-identity-approvals/:id/approve",async e=>{const n=Dw(e);return{data:await t.users.approveExternalIdentity(n.userId,Pw.parse(e.params).id,e.body)}}),e.post("/api/external-identity-approvals/:id/reject",async e=>{const n=Dw(e);return{data:await t.users.rejectExternalIdentity(n.userId,Pw.parse(e.params).id)}}),e.post("/api/auth/external/:id/begin",{config:xv},async(e,n)=>(n.header("cache-control","no-store"),{data:await t.external.begin(Pw.parse(e.params).id)})),e.post("/api/auth/external/callback",{config:xv},async(e,n)=>{n.header("cache-control","no-store");const i=await t.external.callback(e.body);return"session"===i.kind?(n.setCookie(Fp,i.sessionToken,{path:"/",httpOnly:!0,sameSite:"lax",expires:new Date(i.expiresAt)}),{data:{kind:i.kind,user:i.user,authorization:i.authorization}}):{data:i}})}(o,I),function(e,t){e.get("/api/git-credentials",async()=>({data:{items:t.gitCredentials.list()}})),e.post("/api/git-credentials",async(e,n)=>{const i=t.gitCredentials.create(e.body);return n.code(201).send({data:i})}),e.get("/api/git-credentials/:id",async e=>{const n=Lw.parse(e.params).id,i=t.gitCredentials.get(n);if(!i)throw Object.assign(new Error(`Git credential ${n} was not found.`),{code:"GIT_CREDENTIAL_NOT_FOUND",statusCode:404});return{data:i}}),e.patch("/api/git-credentials/:id",async e=>({data:await t.updateGitCredential(Lw.parse(e.params).id,e.body)})),e.delete("/api/git-credentials/:id",async e=>({data:{deleted:t.gitCredentials.remove(Lw.parse(e.params).id)}})),e.get("/api/controlled-instances/:id/git-credential-assignments",async e=>{qw(e);const n=Lw.parse(e.params).id;return await t.requireControlledInstance(n,!0),{data:t.listInstanceGitCredentialAssignments(n)}}),e.post("/api/controlled-instances/:id/git-credential-assignments",async(e,n)=>{qw(e);const i=Lw.parse(e.params).id,s=f.z.object({credentialId:f.z.string().trim().min(1).max(120)}).strict().parse(e.body);return n.code(201).send({data:await t.authorizeInstanceGitCredential(i,s.credentialId)})}),e.delete("/api/controlled-instances/:id/git-credential-assignments/:credentialId",async e=>{qw(e);const n=Mw.parse(e.params);return{data:{revoked:await t.revokeInstanceGitCredential(n.id,n.credentialId)}}})}(o,v),o.get("/api/control-plane/status",async()=>({data:{protocolVersion:wo,build:SS(),storage:a}})),o.get("/api/control-plane/settings",async()=>({data:v.getSettings()})),o.patch("/api/control-plane/settings",async e=>{const t=v.updateSettings(e.body||{});return p=t.diagnosticLogs,{data:t}}),o.get("/api/control-plane/diagnostic-logs/export",async(e,i)=>{const s=await async function(e){const i=n.mkdtempSync(t.join(m.tmpdir(),"task-handoff-diagnostic-logs-")),s=t.resolve(e.nodeAgentDataDir||t.join(e.dataDir,"node-agent")),a=t.join(s,"local-instances"),o=n.existsSync(a)?n.readdirSync(a,{withFileTypes:!0}).filter(e=>e.isDirectory()&&!e.isSymbolicLink()).map(e=>({label:t.join("local-instances",e.name),root:t.join(a,e.name,"logs")})):[],r=[{label:"control-plane",root:t.join(e.dataDir,"logs")},{label:"desktop",root:t.join(e.dataDir,"log")},{label:"node-agent",root:t.join(s,"logs")},...o],c=[];let d=0;for(const e of r)for(const s of Xw(e.root)){if(d>=Kw)break;const a=t.relative(e.root,s);if(!a||a.startsWith("..")||t.isAbsolute(a))continue;const o=t.join("logs",e.label,a),r=n.statSync(s).size,l=Jw(s,t.join(i,o),Kw-d);l&&(d+=l,c.push({source:s,archivePath:o,bytes:l,originalBytes:r}))}n.writeFileSync(t.join(i,"manifest.json"),`${JSON.stringify({createdAt:(new Date).toISOString(),diagnosticLogsEnabled:e.diagnosticLogsEnabled,limits:{perFileBytes:Vw,totalBytes:Kw},files:c.map(({archivePath:e,bytes:t,originalBytes:n})=>({archivePath:e,bytes:t,originalBytes:n,truncated:t<n}))},null,2)}\n`,{mode:384});const l=["manifest.json",...n.existsSync(t.join(i,"logs"))?["logs"]:[]],p=D.create({cwd:i,gzip:!0,portable:!0,noMtime:!0},l),u=()=>n.rmSync(i,{recursive:!0,force:!0});return p.once("close",u),p.once("error",u),{filename:`task-handoff-diagnostic-logs-${(new Date).toISOString().replace(/[:.]/g,"-")}.tar.gz`,stream:p}}({dataDir:a.dataDir,nodeAgentDataDir:process.env.TASK_HANDOFF_DESKTOP_NODE_AGENT_DATA_DIR||process.env.TASK_HANDOFF_NODE_AGENT_DATA_DIR,diagnosticLogsEnabled:p});return i.header("content-type","application/gzip"),i.header("content-disposition",`attachment; filename="${s.filename}"`),i.send(s.stream)}),o.post("/api/ai-session-attachments",{bodyLimit:33554432},async(e,t)=>{try{return t.code(201).send({data:R.upload(e.body)})}catch(e){return t.code(400).send({error:{code:"AI_SESSION_ATTACHMENT_INVALID",message:e instanceof Error?e.message:String(e)}})}}),bx({app:o,service:v,events:c,appSessionAggregator:N,aiSessionAggregator:k,aiSessionUnread:z,chatGateway:G,aiSessionAttachments:R,aiSessionAttachmentCache:C,nodeAgentTunnel:O,nodeEventSubscriber:W,errorPayload:TS,onInstanceDeleted:async e=>{if(!I.enabled())return;const t=await I.users.removeInstanceFromAccessScopes(e);for(const e of t)await I.notifyAuthorizationChanged(e)}}),function(e){const{app:t,authority:n,resolveTarget:i,projectTarget:s,eventHub:a}=e,o=e.runtime??new aw,c=new WeakMap,d=(e,t)=>{const n=c.get(e);n&&(c.delete(e),n.tracked.release(),e.raw.removeListener("aborted",n.abort),t.raw.removeListener("close",n.abort))};t.all("/api/node-proxy/bindings/:bindingId/http/*",{config:Sv,bodyLimit:o.maxRequestBodyBytes,logLevel:"silent",async onRequest(e,t){try{const i=hw.parse(e.params).bindingId,s=vw(n,i,e),a=function(e){const t=e.raw.url||e.url,n=/^\/api\/node-proxy\/bindings\/[^/]+\/http(\/[^#]*)$/.exec(t);if(!n||/%(?:2f|5c)/i.test(n[1]))throw Ew(Qa.RouteInvalid,"Proxy route is invalid.",400);const i=Ga.safeParse(n[1]);if(!i.success)throw Ew(Qa.RouteInvalid,i.error.issues[0]?.message||"Proxy route is invalid.",400);return i.data}(e),r=ww(e.headers),l=o.reserveHttp(s.id),p=()=>{l.controller.abort(Object.assign(new Error("Proxy HTTP consumer disconnected."),{name:"AbortError",code:"ABORT_ERR"})),d(e,t)};c.set(e,{binding:s,route:a,forwardedHeaders:r,tracked:l,abort:p,startedAt:performance.now()}),e.raw.once("aborted",p),t.raw.once("close",p)}catch(n){return Sw(t,n,e)}},async onError(e,t){d(e,t);const n=Tw(e.headers);n&&t.header("x-request-id",n)},async onResponse(e,t){d(e,t)}},async(e,s)=>{try{const o=c.get(e);if(!o)throw Ew(Qa.TransportFailed,"Proxy request context is unavailable.",500,!0);const{binding:l,route:p,forwardedHeaders:u,tracked:m,abort:h,startedAt:g}=o;!function(e,t,n){const i=new URL(t,"https://node-agent.invalid").searchParams,s=[i.get("nodeId"),i.get("targetNodeId")];if(n&&"object"==typeof n&&!Array.isArray(n)){const e=n;"string"==typeof e.nodeId&&s.push(e.nodeId),"string"==typeof e.targetNodeId&&s.push(e.targetNodeId)}const a=s.find(t=>null!==t&&t!==e.targetNodeId);if(void 0!==a)throw Ew(Qa.TargetMismatch,"Proxy request attempts to select a target outside its binding.",409,!1,{bindingId:e.id,targetNodeId:e.targetNodeId})}(l,p,e.body);const f=null==(a=e.body)?void 0:Buffer.isBuffer(a)?a:a instanceof Uint8Array||"string"==typeof a?Buffer.from(a):Buffer.from(JSON.stringify(a));m.acceptRequestBody(f?.byteLength??0);try{const{node:a,transport:o}=await i(l.targetNodeId);Iw(n,l,e),xw(l,a);const c=await o.requestStream(a,p,{method:e.method,headers:u,...f?{body:f}:{},signal:m.controller.signal}),d=performance.now()-g;return t.log.info({traceId:u[eu],requestId:u["x-request-id"],bindingId:l.id,targetNodeId:l.targetNodeId,routePath:new URL(p,"https://node-agent.invalid").pathname,statusCode:c.status,proxyForwardMs:d},"control-plane proxy request timing"),function(e,t,n,i,s,a,o,c){t.body&&n.beginResponseStream();const d=function(e,t){const n=Object.fromEntries([...Va].flatMap(t=>{const n=e.headers.get(t);return null===n?[]:[[t,n]]}));return t&&(n["x-request-id"]=t),n}(t,a);d["server-timing"]=nu(d["server-timing"],tu("proxy_forward",c??0)),o&&!d[eu]&&(d[eu]=o);for(const[t,n]of Object.entries(d))e.header(t,n);const l=()=>{n.release(),s.raw.removeListener("aborted",i),e.raw.removeListener("close",i)};if(!t.body)return l(),e.code(t.status).send();const p=r.Readable.fromWeb(t.body);return n.controller.signal.addEventListener("abort",()=>{const e=n.controller.signal.reason;p.destroy(e instanceof Error?e:new Error("Proxy HTTP stream aborted."))},{once:!0}),p.on("data",e=>{try{n.acceptResponseChunk(e)}catch(e){p.destroy(e)}}),p.once("end",l),p.once("error",l),p.once("close",l),e.raw.once("close",()=>p.destroy()),e.code(t.status).send(p)}(s,c,m,h,e,u["x-request-id"],u[eu],d)}catch(t){throw d(e,s),t}}catch(t){return d(e,s),Sw(s,t,e)}var a}),t.get("/api/node-proxy/bindings/:bindingId/websocket",{websocket:!0,logLevel:"silent",config:Sv},async(e,t)=>{let s;try{const a=hw.parse(t.params).bindingId,r=vw(n,a,t),c=gw.parse(t.query).route,{node:d,transport:l}=await i(r.targetNodeId);Iw(n,r,t),xw(r,d),s=o.openWebSocket(r.id,e),l.proxyWebSocket(d,s,c,function(e){const t=_w(e,"sec-websocket-protocol").split(",").map(e=>e.trim()).filter(Boolean);return t.length?t:void 0}(t.headers),ww(t.headers))}catch(t){const n=Aw(t);s?.close(1008,n.message),s||e.close(429===n.statusCode?1013:n.statusCode<500?1008:1011,zw(n.message))}}),t.get("/api/node-proxy/bindings/:bindingId/snapshot",{config:Sv},async(e,t)=>{try{const t=hw.parse(e.params).bindingId,r=vw(n,t,e),{node:c}=await i(r.targetNodeId);Iw(n,r,e),xw(r,c);const d=s(r.targetNodeId);if(!d)throw Ew(Qa.TargetUnavailable,"Proxy target no longer exists.",404,!1,{targetNodeId:r.targetNodeId});const l=a.cursor(r.targetNodeId),p=po.parse({protocolVersion:Ma,binding:r,streamId:l.streamId,revision:l.revision,observedAt:(new Date).toISOString(),target:mw(d)});if(o=p,Buffer.byteLength(JSON.stringify(o),"utf8")>bw)throw Ew(Qa.ResourceLimit,"Proxy target snapshot byte limit exceeded.",429,!0,{bindingId:r.id,resource:"snapshot-bytes",limit:bw});return{data:p}}catch(n){return Sw(t,n,e)}var o}),t.get("/api/node-proxy/bindings/:bindingId/events",{websocket:!0,logLevel:"silent",config:Sv},async(e,t)=>{let s,r,c;try{const d=hw.parse(t.params).bindingId,l=vw(n,d,t),p=fw.parse(t.query),{node:u}=await i(l.targetNodeId);Iw(n,l,t),xw(l,u),s=o.openWebSocket(l.id,e,()=>r?.()),s.on("message",()=>s?.close(1008,"Proxy event streams do not accept client messages."));const m=a.subscribe({bindingId:l.id,sourceControlPlaneId:l.sourceControlPlaneId,targetNodeId:l.targetNodeId},p.sinceRevision,e=>{s?.send(JSON.stringify(e))},()=>{s?.close(1011,"Proxy event delivery failed.")});r=m.close,c=o.registerBindingCleanup(l.id,r);const h=()=>{r?.(),c?.()};s.on("close",h),s.on("error",h),"snapshot-required"===m.kind?(r(),s.close(1008,"Proxy target snapshot is required.")):1!==s.readyState&&r()}catch(t){r?.(),c?.();const n=Aw(t);s?.close(1008,n.message),s||e.close(429===n.statusCode?1013:n.statusCode<500?1008:1011,zw(n.message))}}),t.delete("/api/node-proxy/bindings/:bindingId",{config:Sv},async(t,i)=>{try{const i=hw.parse(t.params).bindingId;vw(n,i,t);const s=n.revokeBinding(i),a=o.closeBinding(i);return e.onBindingRevoked?.(s),{data:{binding:s,closed:a}}}catch(e){return Sw(i,e,t)}})}({app:o,authority:L,resolveTarget:e=>{const t=v.requireNode(e);return{node:t,transport:v.resolveNodeAgentTransport(t)}},projectTarget:P,runtime:M,eventHub:q,onBindingRevoked:e=>c.publish("control-plane-proxy.binding.updated",{binding:e,audit:{action:"binding.revoke",actor:`control-plane:${e.sourceControlPlaneId}`}},{topic:"control-plane-proxy",scope:{nodeId:e.targetNodeId}})}),function(e){const{app:t,service:n,proxy:i,runtime:s,events:a,syncNodeEvents:o,actorId:r}=e;t.get("/api/control-plane-proxy/invites",async()=>({data:i.listInvites()})),t.post("/api/control-plane-proxy/invites",async(e,t)=>{const n=await r(e),s=i.createInvite(e.body,n);return a.publish("control-plane-proxy.invite.created",{invite:s.invite,audit:{action:"invite.create",actor:n}},{topic:"control-plane-proxy",scope:{nodeId:s.invite.targetNodeId}}),t.code(201).send({data:s})}),t.delete("/api/control-plane-proxy/invites/:id",async e=>{const t=await r(e),n=i.revokeInvite(Rw.parse(e.params).id);return a.publish("control-plane-proxy.invite.updated",{invite:n,audit:{action:"invite.revoke",actor:t}},{topic:"control-plane-proxy",scope:{nodeId:n.targetNodeId}}),{data:n}}),t.get("/api/control-plane-proxy/bindings",async()=>({data:i.listBindings()})),t.delete("/api/control-plane-proxy/bindings/:id",async e=>{const t=await r(e),n=Rw.parse(e.params).id,o=i.revokeBinding(n),c=s.closeBinding(n);return a.publish("control-plane-proxy.binding.updated",{binding:o,audit:{action:"binding.revoke",actor:t}},{topic:"control-plane-proxy",scope:{nodeId:o.targetNodeId}}),{data:{binding:o,closed:c}}}),t.get("/api/control-plane-proxy/diagnostics",async()=>({data:s.diagnostics()})),t.post("/api/node-proxy/claims",{config:xv},async(e,t)=>{const n=i.claimInvite(e.body);return a.publish("control-plane-proxy.binding.created",{binding:n.binding,audit:{action:"binding.claim",actor:`control-plane:${n.binding.sourceControlPlaneId}`}},{topic:"control-plane-proxy",scope:{nodeId:n.binding.targetNodeId}}),t.code(201).send({data:n})}),t.get("/api/control-plane-proxy/pending-claims",async()=>({data:n.listPendingProxyClaims()})),t.post("/api/control-plane-proxy/claims",async(e,t)=>{const i=await n.claimProxyNode(e.body);return o?.(),a.publish("node.created",{nodeId:i.node.id}),t.code(201).send({data:i})}),t.post("/api/control-plane-proxy/pending-claims/:id/resume",async e=>{const t=Rw.parse(e.params).id;Ow.parse(e.body||{});const i=await n.resumeProxyClaim(t);return o?.(),a.publish("node.created",{nodeId:i.node.id}),{data:i}}),t.delete("/api/control-plane-proxy/pending-claims/:id",async e=>{const t=jw.parse(e.query||{});return{data:await n.cancelProxyClaim(Rw.parse(e.params).id,"true"===t.force)}})}({app:o,service:v,proxy:L,runtime:M,events:c,syncNodeEvents:()=>W.syncNow(),actorId:async e=>{const t=await kS(I,zS(e));return t?"user"===t.type?`user:${t.userId}`:"system"===t.type?`system:${t.reason}`:"cloud-account"===t.type?`cloud-account:${t.accountId}:${t.deviceSessionId}`:`chat-bridge:${t.bridgeId}`:"system:unknown"}}),function({app:e,service:t,auth:n,authorizationConnections:i}){!function(e){for(const t of["application/octet-stream","application/x-www-form-urlencoded"])Nx(e,t);Nx(e,/^multipart\/form-data(?:;.*)?$/i)}(e);const s=async(e,i,s="")=>{const a=await t.appAccessProxyTarget(e,i,s);return a.access.authorization&&await n.assertAppAccessAuthorization({...a.access.authorization,instanceId:a.instance.id,nodeId:a.instance.nodeId}),a},a=(e,t)=>{if(!t)return;const n=i.track(t,()=>e.close(4001,"Authorization changed."));e.on("close",n)};e.get("/api/app-access/session",{config:xv},async e=>{const t=Cx(e.url),n="vnc"===e.query.mode?"vnc":"web"===e.query.mode?"web":"tty",i=await s(t,n);return{data:{mode:n,instance:{id:i.instance.id,name:i.instance.name,projectId:i.instance.projectId,projectName:"string"==typeof i.instance.sourceSnapshot.name?i.instance.sourceSnapshot.name:void 0},session:i.session,expiresAt:i.access.expiresAt,ttySocketPath:"tty"===n?`/apps/access/tty/ws?token=${encodeURIComponent(t)}`:void 0,vncFramePath:"vnc"===n?Rx(t,i.access.sessionId,i.session):void 0}}}),e.get("/apps/access/tty/ws",{websocket:!0,config:xv},async(e,n)=>{try{const i=await s(Cx(n.url),"tty");a(e,i.access.authorization),await t.proxyInstanceWebSocket(i.instance.id,e,i.path,Ix(n.headers),Ax(n.headers))}catch{e.close(1011,"TTY access link is invalid or expired.")}});const o=async(e,n)=>{const i=n.params;try{const o=await s(i.token||Cx(n.url),"vnc",i["*"]||"");a(e,o.access.authorization),await t.proxyInstanceWebSocket(o.instance.id,e,o.path,Ix(n.headers),Ax(n.headers))}catch{e.close(1011,"VNC access link is invalid or expired.")}};e.route({method:"GET",url:"/apps/access/vnc/proxy/*",config:xv,wsHandler:o,handler:async(e,n)=>{const i=e.params,a=await s(Cx(e.url),"vnc",i["*"]||"");return zx(n,await Ex(t,n,a.instance.id,a.path,{method:e.method,headers:Sx(e.headers)}),a.instance.id,a.path)}}),e.route({method:"GET",url:"/apps/access/vnc/:token/proxy/*",config:xv,wsHandler:o,handler:async(e,n)=>{const i=e.params,a=await s(i.token,"vnc",i["*"]||"");return zx(n,await Ex(t,n,a.instance.id,a.path,{method:e.method,headers:Sx(e.headers)}),a.instance.id,a.path)}}),e.all("/instances/:id",{bodyLimit:67108864},async(e,n)=>{const i=e.params;return"GET"===e.method||"HEAD"===e.method?n.redirect(`${Tx(i.id)}/`):zx(n,await Ex(t,n,i.id,"/",{method:e.method,headers:Sx(e.headers),body:await kx(e.body)}),i.id,"/")}),e.route({method:"GET",url:"/instances/:id/*",wsHandler:async(e,n)=>{const i=n.params,s=i["*"]||"",o=n.url.indexOf("?"),r=o>=0?n.url.slice(o):"";try{const o=_I(n);a(e,"user"===o?.type?o:void 0),await t.proxyInstanceWebSocket(i.id,e,`/${s}${r}`,Ix(n.headers),Ax(n.headers))}catch{e.close(1011,"Instance websocket endpoint is not reachable.")}},handler:async(e,n)=>{const i=e.params,s=i["*"]||"",a=e.url.indexOf("?"),o=`/${s}${a>=0?e.url.slice(a):""}`;return zx(n,await Ex(t,n,i.id,o,{method:e.method,headers:Sx(e.headers)}),i.id,o)}}),e.route({method:["POST","PUT","PATCH","DELETE","OPTIONS"],url:"/instances/:id/*",bodyLimit:67108864,handler:async(e,n)=>{const i=e.params,s=i["*"]||"",a=e.url.indexOf("?"),o=a>=0?e.url.slice(a):"";return _x(n,await Ex(t,n,i.id,`/${s}${o}`,{method:e.method,headers:Sx(e.headers),body:await kx(e.body)}))}})}({app:o,service:v,auth:I,authorizationConnections:d}),o.get("*",{config:wv},async(e,t)=>n.existsSync(K)?_S(t,K,"index.html"):t.code(404).send({error:{code:"CONTROL_PLANE_UI_NOT_BUILT",message:"Control plane API is running, but the Web UI static directory was not found."}})),B=setInterval(()=>{H().catch(e=>o.log.warn({error:e},"pending node pairing recovery failed"))},3e4),B.unref(),F=setInterval(()=>{v.runPersistenceMaintenance()},216e5),F.unref(),o}function OS(e){const t=Number(e);if(!Number.isInteger(t)||t<=0||t>65535)throw new Error("Port must be a valid TCP port.");return t}function jS(e){if("disabled"!==e&&"password"!==e)throw new Error("Auth mode must be disabled or password.");return e}function PS(e,t){return{id:e,sql:t,checksum:i.createHash("sha256").update(t).digest("hex")}}(async function(){const n=new e.Command;n.name("task-handoff-control-plane").description("Run the TaskHandoff control plane.").version(q("@task-handoff/cli")).option("--host <host>","Control plane host",process.env.TASK_HANDOFF_CONTROL_PLANE_HOST||"127.0.0.1").option("-p, --port <port>","Control plane port",OS,Number(process.env.TASK_HANDOFF_CONTROL_PLANE_PORT)||8081).option("--data-dir <path>","Control plane data directory").option("--static-dir <path>","Control plane Web UI static directory",process.env.TASK_HANDOFF_CONTROL_PLANE_STATIC_DIR||t.resolve(__dirname,"..","ui")).option("--auth-mode <mode>","Control plane auth mode: disabled or password",jS,process.env.TASK_HANDOFF_CONTROL_PLANE_AUTH_MODE||"password").action(async e=>{await async function(e){const t=Xv(e.dataDir),n=vI(bI(),{dataDir:t.dataDir,host:e.host,port:e.port});try{const t=await RS(e);t.addHook("onClose",async()=>{n.release()}),await t.listen({host:e.host,port:e.port})}catch(t){if(n.release(),t&&"object"==typeof t&&"EADDRINUSE"===t.code)throw Object.assign(new Error(`Control plane port ${e.host}:${e.port} is already in use.`),{statusCode:409,code:"CONTROL_PLANE_PORT_IN_USE",cause:t});throw t}}({host:e.host,port:e.port,dataDir:e.dataDir,staticDir:e.staticDir,auth:{mode:e.authMode}})}),n.command("credentials").description("Initialize or replace Control Plane administrator credentials while the service is stopped.").requiredOption("--username <username>","New administrator username").requiredOption("--password-stdin","Read the new password from standard input").option("--user-id <userId>","Select the account by its local user ID").option("--target-username <username>","Select the account by its current username").option("--initialize-if-needed","Create the administrator only when none exists").option("--data-dir <path>","Control plane data directory").action(async e=>{if(process.stdin.isTTY)throw new Error("Pipe the new password to standard input when using --password-stdin.");const t=[];for await(const e of process.stdin)t.push(Buffer.isBuffer(e)?e:Buffer.from(e));const n=Buffer.concat(t).toString("utf8").replace(/\r?\n$/,"");if(e.initializeIfNeeded){const t=await async function(e,t,n={}){const i=Xv(e),s=vI(n.lockPath||bI(),{dataDir:i.dataDir}),a=new Bp(i);try{return await a.init(),a.store.state().initialized&&(await a.store.users.list()).length>0?{created:!1}:{created:!0,user:await a.bootstrapAdmin(t)}}finally{try{await a.store.close()}finally{s.release()}}}(e.dataDir,{username:e.username,password:n});return void console.log(t.created?"created":"unchanged")}const i=await async function(e,t,n={}){const i=Xv(e),s=vI(n.lockPath||bI(),{dataDir:i.dataDir}),a=new Bp(i);try{return await a.init(),await a.recoverLocalCredentials(t)}finally{try{await a.store.close()}finally{s.release()}}}(e.dataDir,{username:e.username,password:n,userId:e.userId,targetUsername:e.targetUsername});console.log(`Updated Control Plane credentials for ${i.primaryUsername||i.displayName}. Existing sessions were revoked.`)}),await n.parseAsync(process.argv)})().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exitCode=1});const DS=[PS("0001_user_access","\nCREATE TABLE cp_metadata (key TEXT PRIMARY KEY NOT NULL, value TEXT NOT NULL);\nCREATE TABLE cp_users (\n id TEXT PRIMARY KEY NOT NULL, display_name TEXT NOT NULL, status TEXT NOT NULL CHECK(status IN ('active','disabled','archived')),\n last_login_at TEXT, archived_at TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE TABLE cp_login_identities (\n id TEXT PRIMARY KEY NOT NULL, user_id TEXT NOT NULL REFERENCES cp_users(id) ON DELETE CASCADE,\n kind TEXT NOT NULL CHECK(kind IN ('local-password','oidc','oauth')), normalized_login_name TEXT, password_hash TEXT,\n requires_password_change INTEGER, provider_id TEXT, subject TEXT, verified_email TEXT, last_used_at TEXT,\n created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX cp_login_identities_login_name_uq ON cp_login_identities(normalized_login_name);\nCREATE UNIQUE INDEX cp_login_identities_provider_subject_uq ON cp_login_identities(provider_id, subject);\nCREATE INDEX cp_login_identities_user_idx ON cp_login_identities(user_id);\nCREATE TABLE cp_roles (\n id TEXT PRIMARY KEY NOT NULL, name TEXT NOT NULL, description TEXT, system INTEGER NOT NULL,\n status TEXT NOT NULL CHECK(status IN ('active','archived')), permission_ids TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX cp_roles_active_name_uq ON cp_roles(lower(name)) WHERE status = 'active';\nCREATE TABLE cp_user_access_grants (\n user_id TEXT PRIMARY KEY NOT NULL REFERENCES cp_users(id) ON DELETE CASCADE,\n node_scope TEXT NOT NULL,\n instance_scope TEXT NOT NULL, authorization_revision INTEGER NOT NULL CHECK(authorization_revision > 0),\n created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE TABLE cp_user_roles (\n user_id TEXT NOT NULL REFERENCES cp_users(id) ON DELETE CASCADE,\n role_id TEXT NOT NULL REFERENCES cp_roles(id) ON DELETE RESTRICT,\n PRIMARY KEY (user_id, role_id)\n);\nCREATE INDEX cp_user_roles_role_idx ON cp_user_roles(role_id);\nCREATE TABLE cp_user_sessions (\n id TEXT PRIMARY KEY NOT NULL, identity_id TEXT NOT NULL REFERENCES cp_login_identities(id) ON DELETE CASCADE,\n authorization_revision INTEGER NOT NULL,\n token_hash TEXT NOT NULL, expires_at TEXT NOT NULL, last_seen_at TEXT, client_type TEXT NOT NULL CHECK(client_type IN ('web','mobile')),\n device TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX cp_user_sessions_token_hash_uq ON cp_user_sessions(token_hash);\nCREATE INDEX cp_user_sessions_identity_idx ON cp_user_sessions(identity_id);\nCREATE INDEX cp_user_sessions_expiry_idx ON cp_user_sessions(expires_at);\nCREATE TABLE cp_identity_providers (\n id TEXT PRIMARY KEY NOT NULL, name TEXT NOT NULL, kind TEXT NOT NULL CHECK(kind IN ('oidc','github')),\n status TEXT NOT NULL CHECK(status IN ('enabled','disabled')), login_policy TEXT NOT NULL,\n issuer TEXT, client_id TEXT NOT NULL, client_secret_ciphertext TEXT NOT NULL, callback_url TEXT NOT NULL,\n created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE TABLE cp_external_identity_approvals (\n id TEXT PRIMARY KEY NOT NULL, provider_id TEXT NOT NULL REFERENCES cp_identity_providers(id) ON DELETE CASCADE,\n subject TEXT NOT NULL, verified_email TEXT, display_name TEXT, status TEXT NOT NULL, expires_at TEXT NOT NULL,\n decided_at TEXT, decided_by_user_id TEXT REFERENCES cp_users(id), created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE INDEX cp_external_identity_approvals_lookup_idx ON cp_external_identity_approvals(provider_id, subject, status);\nCREATE TABLE cp_user_audit (\n id TEXT PRIMARY KEY NOT NULL, action TEXT NOT NULL, actor_user_id TEXT, target_type TEXT NOT NULL,\n target_id TEXT, details TEXT NOT NULL, created_at TEXT NOT NULL\n);\nCREATE INDEX cp_user_audit_created_idx ON cp_user_audit(created_at);\n")],LS=[PS("0001_user_access","\nCREATE TABLE cp_metadata (key TEXT PRIMARY KEY NOT NULL, value JSONB NOT NULL);\nCREATE TABLE cp_users (\n id TEXT PRIMARY KEY NOT NULL, display_name TEXT NOT NULL, status TEXT NOT NULL CHECK(status IN ('active','disabled','archived')),\n last_login_at TEXT, archived_at TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE TABLE cp_login_identities (\n id TEXT PRIMARY KEY NOT NULL, user_id TEXT NOT NULL REFERENCES cp_users(id) ON DELETE CASCADE,\n kind TEXT NOT NULL CHECK(kind IN ('local-password','oidc','oauth')), normalized_login_name TEXT, password_hash TEXT,\n requires_password_change BOOLEAN, provider_id TEXT, subject TEXT, verified_email TEXT, last_used_at TEXT,\n created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX cp_login_identities_login_name_uq ON cp_login_identities(normalized_login_name);\nCREATE UNIQUE INDEX cp_login_identities_provider_subject_uq ON cp_login_identities(provider_id, subject);\nCREATE INDEX cp_login_identities_user_idx ON cp_login_identities(user_id);\nCREATE TABLE cp_roles (\n id TEXT PRIMARY KEY NOT NULL, name TEXT NOT NULL, description TEXT, system BOOLEAN NOT NULL,\n status TEXT NOT NULL CHECK(status IN ('active','archived')), permission_ids JSONB NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX cp_roles_active_name_uq ON cp_roles(lower(name)) WHERE status = 'active';\nCREATE TABLE cp_user_access_grants (\n user_id TEXT PRIMARY KEY NOT NULL REFERENCES cp_users(id) ON DELETE CASCADE,\n node_scope JSONB NOT NULL,\n instance_scope JSONB NOT NULL, authorization_revision INTEGER NOT NULL CHECK(authorization_revision > 0),\n created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE TABLE cp_user_roles (\n user_id TEXT NOT NULL REFERENCES cp_users(id) ON DELETE CASCADE,\n role_id TEXT NOT NULL REFERENCES cp_roles(id) ON DELETE RESTRICT,\n PRIMARY KEY (user_id, role_id)\n);\nCREATE INDEX cp_user_roles_role_idx ON cp_user_roles(role_id);\nCREATE TABLE cp_user_sessions (\n id TEXT PRIMARY KEY NOT NULL, identity_id TEXT NOT NULL REFERENCES cp_login_identities(id) ON DELETE CASCADE,\n authorization_revision INTEGER NOT NULL,\n token_hash TEXT NOT NULL, expires_at TEXT NOT NULL, last_seen_at TEXT, client_type TEXT NOT NULL CHECK(client_type IN ('web','mobile')),\n device JSONB, created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE UNIQUE INDEX cp_user_sessions_token_hash_uq ON cp_user_sessions(token_hash);\nCREATE INDEX cp_user_sessions_identity_idx ON cp_user_sessions(identity_id);\nCREATE INDEX cp_user_sessions_expiry_idx ON cp_user_sessions(expires_at);\nCREATE TABLE cp_identity_providers (\n id TEXT PRIMARY KEY NOT NULL, name TEXT NOT NULL, kind TEXT NOT NULL CHECK(kind IN ('oidc','github')),\n status TEXT NOT NULL CHECK(status IN ('enabled','disabled')), login_policy TEXT NOT NULL,\n issuer TEXT, client_id TEXT NOT NULL, client_secret_ciphertext TEXT NOT NULL, callback_url TEXT NOT NULL,\n created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE TABLE cp_external_identity_approvals (\n id TEXT PRIMARY KEY NOT NULL, provider_id TEXT NOT NULL REFERENCES cp_identity_providers(id) ON DELETE CASCADE,\n subject TEXT NOT NULL, verified_email TEXT, display_name TEXT, status TEXT NOT NULL, expires_at TEXT NOT NULL,\n decided_at TEXT, decided_by_user_id TEXT REFERENCES cp_users(id), created_at TEXT NOT NULL, updated_at TEXT NOT NULL\n);\nCREATE INDEX cp_external_identity_approvals_lookup_idx ON cp_external_identity_approvals(provider_id, subject, status);\nCREATE TABLE cp_user_audit (\n id TEXT PRIMARY KEY NOT NULL, action TEXT NOT NULL, actor_user_id TEXT, target_type TEXT NOT NULL,\n target_id TEXT, details JSONB NOT NULL, created_at TEXT NOT NULL\n);\nCREATE INDEX cp_user_audit_created_idx ON cp_user_audit(created_at);\n")],MS=f.z.object({id:f.z.string().trim().min(1),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}),qS={users:MS.extend({displayName:f.z.string().trim().min(1).max(160),status:vl,lastLoginAt:f.z.string().datetime().optional(),archivedAt:f.z.string().datetime().optional()}).strict().superRefine((e,t)=>{"archived"!==e.status||e.archivedAt||t.addIssue({code:"custom",path:["archivedAt"],message:"Archived users require archivedAt."}),"archived"!==e.status&&e.archivedAt&&t.addIssue({code:"custom",path:["archivedAt"],message:"Only archived users can have archivedAt."})}),identities:MS.extend({userId:f.z.string().trim().min(1),kind:Il,normalizedLoginName:f.z.string().trim().min(1).max(160).optional(),passwordHash:f.z.string().trim().min(1).optional(),requiresPasswordChange:f.z.boolean().optional(),providerId:f.z.string().trim().min(1).optional(),subject:f.z.string().trim().min(1).max(500).optional(),verifiedEmail:f.z.string().email().optional(),lastUsedAt:f.z.string().datetime().optional()}).strict().superRefine((e,t)=>{"local-password"===e.kind?(e.normalizedLoginName||t.addIssue({code:"custom",path:["normalizedLoginName"],message:"Local identity requires normalizedLoginName."}),e.passwordHash||t.addIssue({code:"custom",path:["passwordHash"],message:"Local identity requires passwordHash."}),(e.providerId||e.subject)&&t.addIssue({code:"custom",path:["providerId"],message:"Local identity cannot reference a provider."})):(e.providerId&&e.subject||t.addIssue({code:"custom",path:["providerId"],message:"External identity requires providerId and subject."}),(e.passwordHash||e.normalizedLoginName)&&t.addIssue({code:"custom",path:["passwordHash"],message:"External identity cannot contain local credentials."}))}),roles:MS.extend({name:f.z.string().trim().min(1).max(120),description:f.z.string().trim().max(500).optional(),system:f.z.boolean(),status:xl,permissionIds:f.z.array(bl)}).strict(),grants:f.z.object({userId:f.z.string().trim().min(1),roleIds:f.z.array(f.z.string().trim().min(1)).min(1).max(100),nodeScope:_l,instanceScope:Tl.default({kind:"inherit-node-scope"}),authorizationRevision:f.z.number().int().positive(),createdAt:f.z.string().datetime(),updatedAt:f.z.string().datetime()}).strict(),sessions:MS.extend({userId:f.z.string().trim().min(1),identityId:f.z.string().trim().min(1),authorizationRevision:f.z.number().int().positive(),tokenHash:f.z.string().trim().min(1),expiresAt:f.z.string().datetime(),lastSeenAt:f.z.string().datetime().optional(),clientType:f.z.enum(["web","mobile"]),device:f.z.object({id:f.z.string().trim().min(1),name:f.z.string().trim().min(1),platform:f.z.enum(["ios","android"]),appVersion:f.z.string().trim().min(1).optional()}).strict().optional()}).strict().refine(e=>"mobile"!==e.clientType||Boolean(e.device),{path:["device"],message:"Mobile sessions require device metadata."}),providers:MS.extend({name:f.z.string().trim().min(1).max(120),kind:wl,status:Sl,loginPolicy:Al,issuer:f.z.string().url().optional(),clientId:f.z.string().trim().min(1).max(500),clientSecretCiphertext:f.z.string().trim().min(1),callbackUrl:f.z.string().url()}).strict().superRefine((e,t)=>{"oidc"!==e.kind||e.issuer||t.addIssue({code:"custom",path:["issuer"],message:"OIDC provider requires issuer."})}),approvals:MS.extend({providerId:f.z.string().trim().min(1),subject:f.z.string().trim().min(1).max(500),verifiedEmail:f.z.string().email().optional(),displayName:f.z.string().trim().min(1).max(160).optional(),status:f.z.enum(["pending","approved","rejected","expired"]),expiresAt:f.z.string().datetime(),decidedAt:f.z.string().datetime().optional(),decidedByUserId:f.z.string().trim().min(1).optional()}).strict(),audit:f.z.object({id:f.z.string().trim().min(1),action:f.z.string().trim().min(1).max(160),actorUserId:f.z.string().trim().min(1).optional(),targetType:f.z.string().trim().min(1).max(120),targetId:f.z.string().trim().min(1).optional(),details:f.z.record(f.z.string(),f.z.unknown()),createdAt:f.z.string().datetime()}).strict()};function US(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,void 0===t?null:t]))}function $S(e,t){return e.parse(Object.fromEntries(Object.entries(t).filter(([,e])=>null!==e)))}function BS(e,t,n){const i=n instanceof Error?n:new Error(String(n));return Object.assign(new Error(`Control Plane ${e} database ${t} failed: ${i.message}`,{cause:i}),{code:`CONTROL_PLANE_DATABASE_${t.toUpperCase()}_FAILED`,dialect:e,phase:t})}const FS={createdAt:C.text("created_at").notNull(),updatedAt:C.text("updated_at").notNull()},HS=C.pgTable("cp_metadata",{key:C.text("key").primaryKey(),value:C.jsonb("value").notNull()}),GS=C.pgTable("cp_users",{id:C.text("id").primaryKey(),displayName:C.text("display_name").notNull(),status:C.text("status").notNull(),lastLoginAt:C.text("last_login_at"),archivedAt:C.text("archived_at"),...FS}),WS=C.pgTable("cp_login_identities",{id:C.text("id").primaryKey(),userId:C.text("user_id").notNull().references(()=>GS.id,{onDelete:"cascade"}),kind:C.text("kind").notNull(),normalizedLoginName:C.text("normalized_login_name"),passwordHash:C.text("password_hash"),requiresPasswordChange:C.boolean("requires_password_change"),providerId:C.text("provider_id"),subject:C.text("subject"),verifiedEmail:C.text("verified_email"),lastUsedAt:C.text("last_used_at"),...FS},e=>[C.uniqueIndex("cp_login_identities_login_name_uq").on(e.normalizedLoginName),C.uniqueIndex("cp_login_identities_provider_subject_uq").on(e.providerId,e.subject),C.index("cp_login_identities_user_idx").on(e.userId)]),VS=C.pgTable("cp_roles",{id:C.text("id").primaryKey(),name:C.text("name").notNull(),description:C.text("description"),system:C.boolean("system").notNull(),status:C.text("status").notNull(),permissionIds:C.jsonb("permission_ids").$type().notNull(),...FS},e=>[C.uniqueIndex("cp_roles_active_name_uq").on(z.sql`lower(${e.name})`).where(z.sql`${e.status} = 'active'`)]),KS=C.pgTable("cp_user_access_grants",{userId:C.text("user_id").primaryKey().references(()=>GS.id,{onDelete:"cascade"}),nodeScope:C.jsonb("node_scope").$type().notNull(),instanceScope:C.jsonb("instance_scope").$type().notNull(),authorizationRevision:C.integer("authorization_revision").notNull(),...FS}),YS=C.pgTable("cp_user_roles",{userId:C.text("user_id").notNull().references(()=>GS.id,{onDelete:"cascade"}),roleId:C.text("role_id").notNull().references(()=>VS.id,{onDelete:"restrict"})},e=>[C.primaryKey({columns:[e.userId,e.roleId]}),C.index("cp_user_roles_role_idx").on(e.roleId)]),XS=C.pgTable("cp_user_sessions",{id:C.text("id").primaryKey(),identityId:C.text("identity_id").notNull().references(()=>WS.id,{onDelete:"cascade"}),authorizationRevision:C.integer("authorization_revision").notNull(),tokenHash:C.text("token_hash").notNull(),expiresAt:C.text("expires_at").notNull(),lastSeenAt:C.text("last_seen_at"),clientType:C.text("client_type").notNull(),device:C.jsonb("device").$type(),...FS},e=>[C.uniqueIndex("cp_user_sessions_token_hash_uq").on(e.tokenHash),C.index("cp_user_sessions_identity_idx").on(e.identityId),C.index("cp_user_sessions_expiry_idx").on(e.expiresAt)]),JS=C.pgTable("cp_identity_providers",{id:C.text("id").primaryKey(),name:C.text("name").notNull(),kind:C.text("kind").notNull(),status:C.text("status").notNull(),loginPolicy:C.text("login_policy").notNull(),issuer:C.text("issuer"),clientId:C.text("client_id").notNull(),clientSecretCiphertext:C.text("client_secret_ciphertext").notNull(),callbackUrl:C.text("callback_url").notNull(),...FS}),QS=C.pgTable("cp_external_identity_approvals",{id:C.text("id").primaryKey(),providerId:C.text("provider_id").notNull().references(()=>JS.id,{onDelete:"cascade"}),subject:C.text("subject").notNull(),verifiedEmail:C.text("verified_email"),displayName:C.text("display_name"),status:C.text("status").notNull(),expiresAt:C.text("expires_at").notNull(),decidedAt:C.text("decided_at"),decidedByUserId:C.text("decided_by_user_id").references(()=>GS.id),...FS},e=>[C.index("cp_external_identity_approvals_lookup_idx").on(e.providerId,e.subject,e.status)]),ZS=C.pgTable("cp_user_audit",{id:C.text("id").primaryKey(),action:C.text("action").notNull(),actorUserId:C.text("actor_user_id"),targetType:C.text("target_type").notNull(),targetId:C.text("target_id"),details:C.jsonb("details").$type().notNull(),createdAt:C.text("created_at").notNull()},e=>[C.index("cp_user_audit_created_idx").on(e.createdAt)]),eA=C.pgTable("cp_migration_ledger",{id:C.text("id").primaryKey(),checksum:C.text("checksum").notNull(),appliedAt:C.text("applied_at").notNull(),details:C.jsonb("details").$type().notNull()});function tA(e){return`"${e.replaceAll('"','""')}"`}function nA(e,t,n){return{list:async()=>(await e.select().from(t)).map(e=>$S(n,e)),async get(i){const s=await e.select().from(t).where(z.eq(t.id,i)).limit(1);return s[0]?$S(n,s[0]):void 0},async put(i){const s=US(n.parse(i)),a=Object.fromEntries(Object.entries(s).filter(([e])=>"id"!==e));return await e.insert(t).values(s).onConflictDoUpdate({target:t.id,set:a}),$S(n,s)},delete:async n=>(await e.delete(t).where(z.eq(t.id,n)).returning({id:t.id})).length>0}}function iA(e){const t=nA(e,WS,qS.identities),n=async t=>{const n=await e.select().from(WS).where(t).limit(1);return n[0]?$S(qS.identities,n[0]):void 0};return{...t,findByLoginName:e=>n(z.eq(WS.normalizedLoginName,e)),findByProviderSubject:(e,t)=>n(z.and(z.eq(WS.providerId,e),z.eq(WS.subject,t))),listByUser:async t=>(await e.select().from(WS).where(z.eq(WS.userId,t))).map(e=>$S(qS.identities,e)),existsForProvider:async t=>(await e.select({id:WS.id}).from(WS).where(z.eq(WS.providerId,t)).limit(1)).length>0}}function sA(e){const t=new Map;for(const n of e){const e=n.grant.userId,i=t.get(e)||{grant:n.grant,roleIds:[]};i.roleIds.push(n.roleId),t.set(e,i)}return[...t.values()].map(({grant:e,roleIds:t})=>qS.grants.parse({...e,roleIds:t.sort()}))}function aA(e,t,n){const i=t=>{const n=e.select({grant:KS,roleId:YS.roleId}).from(KS).innerJoin(YS,z.eq(KS.userId,YS.userId));return t?n.where(z.inArray(KS.userId,t)):n};return{list:async()=>sA(await i()),get:async e=>sA(await i([e]))[0],async listByRole(t){const n=(await e.select({userId:YS.userId}).from(YS).where(z.eq(YS.roleId,t))).map(e=>e.userId);return 0===n.length?[]:sA(await i(n))},put:i=>n?(async t=>{const n=qS.grants.parse(t),{roleIds:i,...s}=n;return await e.insert(KS).values(s).onConflictDoUpdate({target:KS.userId,set:Object.fromEntries(Object.entries(s).filter(([e])=>"userId"!==e))}),await e.delete(YS).where(z.eq(YS.userId,n.userId)),await e.insert(YS).values(i.map(e=>({userId:n.userId,roleId:e}))),n})(i):t(e=>e.grants.put(i)),delete:async t=>(await e.delete(KS).where(z.eq(KS.userId,t)).returning({userId:KS.userId})).length>0}}function oA(e){const t=e=>e.map(e=>$S(qS.sessions,{...e.session,userId:e.userId})),n=()=>e.select({session:XS,userId:WS.userId}).from(XS).innerJoin(WS,z.eq(XS.identityId,WS.id));return{list:async()=>t(await n()),get:async e=>t(await n().where(z.eq(XS.id,e)).limit(1))[0],listByUser:async e=>t(await n().where(z.eq(WS.userId,e))),async put(t){const n=qS.sessions.parse(t),i=await e.select({userId:WS.userId}).from(WS).where(z.eq(WS.id,n.identityId)).limit(1);if(i[0]?.userId!==n.userId)throw new Error("Session identity does not belong to the requested user.");const{userId:s,...a}=n;return await e.insert(XS).values(a).onConflictDoUpdate({target:XS.id,set:Object.fromEntries(Object.entries(a).filter(([e])=>"id"!==e))}),n},delete:async t=>(await e.delete(XS).where(z.eq(XS.id,t)).returning({id:XS.id})).length>0}}function rA(e){return{...nA(e,QS,qS.approvals),async findActivePending(t,n,i){const s=await e.select().from(QS).where(z.and(z.eq(QS.providerId,t),z.eq(QS.subject,n),z.eq(QS.status,"pending"),z.gt(QS.expiresAt,i))).limit(1);return s[0]?$S(qS.approvals,s[0]):void 0},hasActivePendingForProvider:async(t,n)=>(await e.select({id:QS.id}).from(QS).where(z.and(z.eq(QS.providerId,t),z.eq(QS.status,"pending"),z.gt(QS.expiresAt,n))).limit(1)).length>0}}function cA(e,t,n=!1){let i;const s=async t=>n?t(i):e.transaction(async e=>t(cA(e,async()=>{},!0)));return i={dialect:"postgresql",users:nA(e,GS,qS.users),identities:iA(e),roles:nA(e,VS,qS.roles),grants:aA(e,s,n),sessions:oA(e),providers:nA(e,JS,qS.providers),approvals:rA(e),audit:nA(e,ZS,qS.audit),async metadata(){const t=await e.select().from(HS).where(z.eq(HS.key,"user_store")).limit(1);return t[0]?.value||{schemaVersion:1}},async putMetadata(t){await e.insert(HS).values({key:"user_store",value:t}).onConflictDoUpdate({target:HS.key,set:{value:t}})},migration:async t=>(await e.select().from(eA).where(z.eq(eA.id,t)).limit(1))[0],async putMigration(t){await e.insert(eA).values(t).onConflictDoUpdate({target:eA.id,set:{checksum:t.checksum,appliedAt:t.appliedAt,details:t.details}})},transaction:s,close:t},i}var dA=Object.freeze({__proto__:null,createPostgresqlUserRepository:async function(e){const t=new N.Pool({connectionString:e.connectionString,options:`-c search_path=${e.schema}`,application_name:"task-handoff-control-plane"});try{await t.query("SELECT 1")}catch(e){throw await t.end().catch(()=>{}),BS("postgresql","connect",e)}try{return await async function(e,t){const n=await e.connect();try{await n.query("BEGIN"),await n.query("SELECT pg_advisory_xact_lock(hashtext($1))",[`task-handoff:user-access:${t}`]),await n.query(`CREATE SCHEMA IF NOT EXISTS ${tA(t)}`),await n.query(`SET LOCAL search_path TO ${tA(t)}`),await n.query("CREATE TABLE IF NOT EXISTS cp_migration_ledger (\n id TEXT PRIMARY KEY NOT NULL, checksum TEXT NOT NULL, applied_at TEXT NOT NULL, details JSONB NOT NULL\n )");for(const e of LS){const t=await n.query("SELECT checksum FROM cp_migration_ledger WHERE id = $1",[e.id]);if(t.rows[0]){if(t.rows[0].checksum!==e.checksum)throw new Error(`Migration checksum mismatch for ${e.id}.`)}else await n.query(e.sql),await n.query("INSERT INTO cp_migration_ledger (id, checksum, applied_at, details) VALUES ($1, $2, $3, $4)",[e.id,e.checksum,(new Date).toISOString(),{dialect:"postgresql"}])}await n.query("COMMIT")}catch(e){throw await n.query("ROLLBACK"),e}finally{n.release()}}(t,e.schema),cA(k.drizzle({client:t}),()=>t.end())}catch(e){throw await t.end().catch(()=>{}),BS("postgresql","migrate",e)}}});const lA={createdAt:j.text("created_at").notNull(),updatedAt:j.text("updated_at").notNull()},pA=j.sqliteTable("cp_metadata",{key:j.text("key").primaryKey(),value:j.text("value",{mode:"json"}).notNull()}),uA=j.sqliteTable("cp_users",{id:j.text("id").primaryKey(),displayName:j.text("display_name").notNull(),status:j.text("status",{enum:["active","disabled","archived"]}).notNull(),lastLoginAt:j.text("last_login_at"),archivedAt:j.text("archived_at"),...lA}),mA=j.sqliteTable("cp_login_identities",{id:j.text("id").primaryKey(),userId:j.text("user_id").notNull().references(()=>uA.id,{onDelete:"cascade"}),kind:j.text("kind",{enum:["local-password","oidc","oauth"]}).notNull(),normalizedLoginName:j.text("normalized_login_name"),passwordHash:j.text("password_hash"),requiresPasswordChange:j.integer("requires_password_change",{mode:"boolean"}),providerId:j.text("provider_id"),subject:j.text("subject"),verifiedEmail:j.text("verified_email"),lastUsedAt:j.text("last_used_at"),...lA},e=>[j.uniqueIndex("cp_login_identities_login_name_uq").on(e.normalizedLoginName),j.uniqueIndex("cp_login_identities_provider_subject_uq").on(e.providerId,e.subject),j.index("cp_login_identities_user_idx").on(e.userId)]),hA=j.sqliteTable("cp_roles",{id:j.text("id").primaryKey(),name:j.text("name").notNull(),description:j.text("description"),system:j.integer("system",{mode:"boolean"}).notNull(),status:j.text("status",{enum:["active","archived"]}).notNull(),permissionIds:j.text("permission_ids",{mode:"json"}).$type().notNull(),...lA},e=>[j.uniqueIndex("cp_roles_active_name_uq").on(z.sql`lower(${e.name})`).where(z.sql`${e.status} = 'active'`)]),gA=j.sqliteTable("cp_user_access_grants",{userId:j.text("user_id").primaryKey().references(()=>uA.id,{onDelete:"cascade"}),nodeScope:j.text("node_scope",{mode:"json"}).$type().notNull(),instanceScope:j.text("instance_scope",{mode:"json"}).$type().notNull(),authorizationRevision:j.integer("authorization_revision").notNull(),...lA}),fA=j.sqliteTable("cp_user_roles",{userId:j.text("user_id").notNull().references(()=>uA.id,{onDelete:"cascade"}),roleId:j.text("role_id").notNull().references(()=>hA.id,{onDelete:"restrict"})},e=>[j.primaryKey({columns:[e.userId,e.roleId]}),j.index("cp_user_roles_role_idx").on(e.roleId)]),yA=j.sqliteTable("cp_user_sessions",{id:j.text("id").primaryKey(),identityId:j.text("identity_id").notNull().references(()=>mA.id,{onDelete:"cascade"}),authorizationRevision:j.integer("authorization_revision").notNull(),tokenHash:j.text("token_hash").notNull(),expiresAt:j.text("expires_at").notNull(),lastSeenAt:j.text("last_seen_at"),clientType:j.text("client_type",{enum:["web","mobile"]}).notNull(),device:j.text("device",{mode:"json"}).$type(),...lA},e=>[j.uniqueIndex("cp_user_sessions_token_hash_uq").on(e.tokenHash),j.index("cp_user_sessions_identity_idx").on(e.identityId),j.index("cp_user_sessions_expiry_idx").on(e.expiresAt)]),bA=j.sqliteTable("cp_identity_providers",{id:j.text("id").primaryKey(),name:j.text("name").notNull(),kind:j.text("kind",{enum:["oidc","github"]}).notNull(),status:j.text("status",{enum:["enabled","disabled"]}).notNull(),loginPolicy:j.text("login_policy",{enum:["existing-only","admin-approved-create"]}).notNull(),issuer:j.text("issuer"),clientId:j.text("client_id").notNull(),clientSecretCiphertext:j.text("client_secret_ciphertext").notNull(),callbackUrl:j.text("callback_url").notNull(),...lA}),vA=j.sqliteTable("cp_external_identity_approvals",{id:j.text("id").primaryKey(),providerId:j.text("provider_id").notNull().references(()=>bA.id,{onDelete:"cascade"}),subject:j.text("subject").notNull(),verifiedEmail:j.text("verified_email"),displayName:j.text("display_name"),status:j.text("status",{enum:["pending","approved","rejected","expired"]}).notNull(),expiresAt:j.text("expires_at").notNull(),decidedAt:j.text("decided_at"),decidedByUserId:j.text("decided_by_user_id").references(()=>uA.id),...lA},e=>[j.index("cp_external_identity_approvals_lookup_idx").on(e.providerId,e.subject,e.status)]),IA=j.sqliteTable("cp_user_audit",{id:j.text("id").primaryKey(),action:j.text("action").notNull(),actorUserId:j.text("actor_user_id"),targetType:j.text("target_type").notNull(),targetId:j.text("target_id"),details:j.text("details",{mode:"json"}).$type().notNull(),createdAt:j.text("created_at").notNull()},e=>[j.index("cp_user_audit_created_idx").on(e.createdAt)]),xA=j.sqliteTable("cp_migration_ledger",{id:j.text("id").primaryKey(),checksum:j.text("checksum").notNull(),appliedAt:j.text("applied_at").notNull(),details:j.text("details",{mode:"json"}).$type().notNull()});class wA{tail=Promise.resolve();run(e){const t=this.tail.then(e,e);return this.tail=t.then(()=>{},()=>{}),t}}function SA(e,t,n,i){return{list:async()=>(await e.select().from(t)).map(e=>$S(n,e)),async get(i){const s=await e.select().from(t).where(z.eq(t.id,i)).limit(1);return s[0]?$S(n,s[0]):void 0},put:async s=>i(async()=>{const i=US(n.parse(s)),a=Object.fromEntries(Object.entries(i).filter(([e])=>"id"!==e));return await e.insert(t).values(i).onConflictDoUpdate({target:t.id,set:a}),$S(n,i)}),delete:async n=>i(async()=>{const i=await e.delete(t).where(z.eq(t.id,n));return Number(i.changes)>0})}}function AA(e,t){const n=SA(e,mA,qS.identities,t),i=async t=>{const n=await e.select().from(mA).where(t).limit(1);return n[0]?$S(qS.identities,n[0]):void 0};return{...n,findByLoginName:e=>i(z.eq(mA.normalizedLoginName,e)),findByProviderSubject:(e,t)=>i(z.and(z.eq(mA.providerId,e),z.eq(mA.subject,t))),listByUser:async t=>(await e.select().from(mA).where(z.eq(mA.userId,t))).map(e=>$S(qS.identities,e)),existsForProvider:async t=>(await e.select({id:mA.id}).from(mA).where(z.eq(mA.providerId,t)).limit(1)).length>0}}function EA(e){const t=new Map;for(const n of e){const e=n.grant.userId,i=t.get(e)||{grant:n.grant,roleIds:[]};i.roleIds.push(n.roleId),t.set(e,i)}return[...t.values()].map(({grant:e,roleIds:t})=>qS.grants.parse({...e,roleIds:t.sort()}))}function _A(e,t,n,i){const s=t=>{const n=e.select({grant:gA,roleId:fA.roleId}).from(gA).innerJoin(fA,z.eq(gA.userId,fA.userId));return t?n.where(z.inArray(gA.userId,t)):n};return{list:async()=>EA(await s()),get:async e=>EA(await s([e]))[0],async listByRole(t){const n=(await e.select({userId:fA.userId}).from(fA).where(z.eq(fA.roleId,t))).map(e=>e.userId);return 0===n.length?[]:EA(await s(n))},put:n=>i?(async t=>{const n=qS.grants.parse(t),{roleIds:i,...s}=n;return await e.insert(gA).values(s).onConflictDoUpdate({target:gA.userId,set:Object.fromEntries(Object.entries(s).filter(([e])=>"userId"!==e))}),await e.delete(fA).where(z.eq(fA.userId,n.userId)),await e.insert(fA).values(i.map(e=>({userId:n.userId,roleId:e}))),n})(n):t(e=>e.grants.put(n)),delete:async t=>n(async()=>{const n=await e.delete(gA).where(z.eq(gA.userId,t));return Number(n.changes)>0})}}function TA(e,t){const n=e=>e.map(e=>$S(qS.sessions,{...e.session,userId:e.userId})),i=()=>e.select({session:yA,userId:mA.userId}).from(yA).innerJoin(mA,z.eq(yA.identityId,mA.id));return{list:async()=>n(await i()),get:async e=>n(await i().where(z.eq(yA.id,e)).limit(1))[0],listByUser:async e=>n(await i().where(z.eq(mA.userId,e))),put:async n=>t(async()=>{const t=qS.sessions.parse(n),i=await e.select({userId:mA.userId}).from(mA).where(z.eq(mA.id,t.identityId)).limit(1);if(i[0]?.userId!==t.userId)throw new Error("Session identity does not belong to the requested user.");const{userId:s,...a}=t;return await e.insert(yA).values(a).onConflictDoUpdate({target:yA.id,set:Object.fromEntries(Object.entries(a).filter(([e])=>"id"!==e))}),t}),delete:async n=>t(async()=>{const t=await e.delete(yA).where(z.eq(yA.id,n));return Number(t.changes)>0})}}function zA(e,t){return{...SA(e,vA,qS.approvals,t),async findActivePending(t,n,i){const s=await e.select().from(vA).where(z.and(z.eq(vA.providerId,t),z.eq(vA.subject,n),z.eq(vA.status,"pending"),z.gt(vA.expiresAt,i))).limit(1);return s[0]?$S(qS.approvals,s[0]):void 0},hasActivePendingForProvider:async(t,n)=>(await e.select({id:vA.id}).from(vA).where(z.and(z.eq(vA.providerId,t),z.eq(vA.status,"pending"),z.gt(vA.expiresAt,n))).limit(1)).length>0}}function kA(e,t,n,i=!1,s=new wA){let a;const o=e=>i?e():s.run(e),r=async t=>i?t(a):o(async()=>{n.exec("BEGIN IMMEDIATE");try{const i=await t(kA(e,async()=>{},n,!0,s));return n.exec("COMMIT"),i}catch(e){throw n.exec("ROLLBACK"),e}});return a={dialect:"sqlite",users:SA(e,uA,qS.users,o),identities:AA(e,o),roles:SA(e,hA,qS.roles,o),grants:_A(e,r,o,i),sessions:TA(e,o),providers:SA(e,bA,qS.providers,o),approvals:zA(e,o),audit:SA(e,IA,qS.audit,o),async metadata(){const t=await e.select().from(pA).where(z.eq(pA.key,"user_store")).limit(1);return t[0]?.value||{schemaVersion:1}},async putMetadata(t){await o(()=>e.insert(pA).values({key:"user_store",value:t}).onConflictDoUpdate({target:pA.key,set:{value:t}}))},migration:async t=>(await e.select().from(xA).where(z.eq(xA.id,t)).limit(1))[0],async putMigration(t){await o(()=>e.insert(xA).values(t).onConflictDoUpdate({target:xA.id,set:{checksum:t.checksum,appliedAt:t.appliedAt,details:t.details}}))},transaction:r,close:t},a}var NA=Object.freeze({__proto__:null,createSqliteUserRepository:async function(e){try{n.mkdirSync(t.dirname(e),{recursive:!0});const i=new R.DatabaseSync(e);try{!function(e){e.exec("PRAGMA foreign_keys = ON; PRAGMA journal_mode = WAL; PRAGMA busy_timeout = 5000;"),e.exec("CREATE TABLE IF NOT EXISTS cp_migration_ledger (\n id TEXT PRIMARY KEY NOT NULL, checksum TEXT NOT NULL, applied_at TEXT NOT NULL, details TEXT NOT NULL\n )"),e.exec("BEGIN IMMEDIATE");try{const t=e.prepare("SELECT checksum FROM cp_migration_ledger WHERE id = ?"),n=e.prepare("INSERT INTO cp_migration_ledger (id, checksum, applied_at, details) VALUES (?, ?, ?, ?)");for(const i of DS){const s=t.get(i.id);if(s){if(s.checksum!==i.checksum)throw new Error(`Migration checksum mismatch for ${i.id}.`)}else e.exec(i.sql),n.run(i.id,i.checksum,(new Date).toISOString(),JSON.stringify({dialect:"sqlite"}))}e.exec("COMMIT")}catch(t){throw e.exec("ROLLBACK"),t}}(i)}catch(e){throw i.close(),BS("sqlite","migrate",e)}return kA(O.drizzle({client:i}),async()=>i.close(),i)}catch(e){if("CONTROL_PLANE_DATABASE_MIGRATE_FAILED"===e.code)throw e;throw BS("sqlite","connect",e)}}});