@tangle-network/agent-app 0.43.55 → 0.43.57

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 (352) hide show
  1. package/dist/DesignCanvas-UNL34LS2.js +12 -0
  2. package/dist/DesignCanvasEditor-FJIVYOA2.js +13 -0
  3. package/dist/IntakeInterview-3ZIQMZS6.js +8 -0
  4. package/dist/InvitationsPanel-CJ7DR4F7.js +8 -0
  5. package/dist/MembersPanel-BB4OD2KB.js +8 -0
  6. package/dist/{TimelineEditor-I35SJJAJ.js → TimelineEditor-2ECKSU6P.js} +3 -3
  7. package/dist/{VaultPane-DrQ_tH6c.d.ts → VaultPane-BDP6SB_K.d.ts} +1 -0
  8. package/dist/{access-BZ81Btt5.d.ts → access-490O6aOU.d.ts} +16 -1
  9. package/dist/app-auth/index.d.ts +6 -1
  10. package/dist/app-auth/index.js +3 -3
  11. package/dist/app-auth/index.js.map +1 -1
  12. package/dist/{apply-Gk4raT2j.d.ts → apply-6wlMOLf8.d.ts} +30 -1
  13. package/dist/assets/index.d.ts +41 -0
  14. package/dist/assets/index.js +1 -1
  15. package/dist/assistant/index.d.ts +26 -6
  16. package/dist/assistant/index.js +13 -12
  17. package/dist/assistant/index.js.map +1 -1
  18. package/dist/{attachment-validation-D0csjCvz.d.ts → attachment-validation-tPRp-PP1.d.ts} +7 -1
  19. package/dist/{auth-DuptSkWh.d.ts → auth-_FU8w01b.d.ts} +4 -1
  20. package/dist/billing/index.d.ts +8 -0
  21. package/dist/billing/index.js +1 -1
  22. package/dist/brand/index.d.ts +2 -0
  23. package/dist/brand/index.js.map +1 -1
  24. package/dist/brand-extraction/index.d.ts +3 -0
  25. package/dist/brand-extraction/index.js.map +1 -1
  26. package/dist/catalog/index.d.ts +2 -0
  27. package/dist/catalog/index.js +1 -1
  28. package/dist/chat-routes/index.d.ts +41 -10
  29. package/dist/chat-routes/index.js +15 -15
  30. package/dist/chat-routes/index.js.map +1 -1
  31. package/dist/chat-store/index.d.ts +18 -4
  32. package/dist/chat-store/index.js +4 -4
  33. package/dist/chat-store/index.js.map +1 -1
  34. package/dist/{chunk-H5FM75MR.js → chunk-22GLESKE.js} +3 -3
  35. package/dist/chunk-22GLESKE.js.map +1 -0
  36. package/dist/{chunk-WEBBJBDH.js → chunk-2DRYTJHI.js} +1 -1
  37. package/dist/chunk-2DRYTJHI.js.map +1 -0
  38. package/dist/{chunk-7EVZUIHW.js → chunk-3EJ6SFJI.js} +1 -1
  39. package/dist/chunk-3EJ6SFJI.js.map +1 -0
  40. package/dist/{chunk-HRJJH3RX.js → chunk-3OFQFW5K.js} +4 -4
  41. package/dist/chunk-3OFQFW5K.js.map +1 -0
  42. package/dist/{chunk-7SUPA2YT.js → chunk-4KKXZQPT.js} +2 -2
  43. package/dist/chunk-4KKXZQPT.js.map +1 -0
  44. package/dist/{chunk-5PTGEJZL.js → chunk-5SD6HT2V.js} +1 -1
  45. package/dist/chunk-5SD6HT2V.js.map +1 -0
  46. package/dist/{chunk-7C64WKAH.js → chunk-5SXS3YAB.js} +2 -2
  47. package/dist/{chunk-L2TG5DBW.js → chunk-5TESA4SN.js} +1 -1
  48. package/dist/chunk-5TESA4SN.js.map +1 -0
  49. package/dist/{chunk-63CE7FEZ.js → chunk-6XIAPIW6.js} +1 -1
  50. package/dist/chunk-6XIAPIW6.js.map +1 -0
  51. package/dist/{chunk-MFRCM32T.js → chunk-7CTIUCQ4.js} +1 -1
  52. package/dist/chunk-7CTIUCQ4.js.map +1 -0
  53. package/dist/{chunk-6KVH5SP5.js → chunk-7YW6EBDX.js} +2 -2
  54. package/dist/chunk-7YW6EBDX.js.map +1 -0
  55. package/dist/{chunk-ZXNXAQAH.js → chunk-AP2UXKUK.js} +1 -1
  56. package/dist/chunk-AP2UXKUK.js.map +1 -0
  57. package/dist/{chunk-K63OWUDJ.js → chunk-BPSV5AA2.js} +2 -2
  58. package/dist/chunk-BPSV5AA2.js.map +1 -0
  59. package/dist/{chunk-MFI4ZM7W.js → chunk-BT4QFCTB.js} +1 -1
  60. package/dist/chunk-BT4QFCTB.js.map +1 -0
  61. package/dist/{chunk-ZYBWGSAZ.js → chunk-BVKQKGRK.js} +1 -1
  62. package/dist/chunk-BVKQKGRK.js.map +1 -0
  63. package/dist/{chunk-RVUISYUE.js → chunk-C3NSB66C.js} +7 -7
  64. package/dist/chunk-C3NSB66C.js.map +1 -0
  65. package/dist/{chunk-BQV42AFK.js → chunk-CCVWR33L.js} +1 -1
  66. package/dist/chunk-CCVWR33L.js.map +1 -0
  67. package/dist/{chunk-MCJSS6SM.js → chunk-CQZSAR77.js} +1 -1
  68. package/dist/chunk-CQZSAR77.js.map +1 -0
  69. package/dist/{chunk-3SVAA3MA.js → chunk-DJ4VJIH5.js} +1 -1
  70. package/dist/chunk-DJ4VJIH5.js.map +1 -0
  71. package/dist/{chunk-XKBIYSSM.js → chunk-DTSPS2HV.js} +3 -3
  72. package/dist/chunk-DTSPS2HV.js.map +1 -0
  73. package/dist/{chunk-4QN75UHX.js → chunk-E7N67FYI.js} +8 -8
  74. package/dist/chunk-E7N67FYI.js.map +1 -0
  75. package/dist/{chunk-2QI7XV2T.js → chunk-FBVLEGEG.js} +1 -1
  76. package/dist/{chunk-2QI7XV2T.js.map → chunk-FBVLEGEG.js.map} +1 -1
  77. package/dist/{chunk-5RMIUJDI.js → chunk-FKCB5FTD.js} +1 -1
  78. package/dist/chunk-FKCB5FTD.js.map +1 -0
  79. package/dist/{chunk-EEPJGZJW.js → chunk-GPBRL2XR.js} +1 -1
  80. package/dist/chunk-GPBRL2XR.js.map +1 -0
  81. package/dist/{chunk-G3HCU7TA.js → chunk-GXE6KHTS.js} +1 -1
  82. package/dist/chunk-GXE6KHTS.js.map +1 -0
  83. package/dist/{chunk-65P3HJY3.js → chunk-HCOROIRT.js} +1 -1
  84. package/dist/chunk-HCOROIRT.js.map +1 -0
  85. package/dist/{chunk-54GSK2KK.js → chunk-HYTIHYNV.js} +2 -2
  86. package/dist/chunk-HYTIHYNV.js.map +1 -0
  87. package/dist/{chunk-5MG74GVQ.js → chunk-IG46XCZM.js} +3 -3
  88. package/dist/chunk-IG46XCZM.js.map +1 -0
  89. package/dist/{chunk-ND3XEGBE.js → chunk-JDEGS53O.js} +1 -1
  90. package/dist/chunk-JDEGS53O.js.map +1 -0
  91. package/dist/{chunk-7W5XSTUF.js → chunk-JML7WKWU.js} +1 -1
  92. package/dist/chunk-JML7WKWU.js.map +1 -0
  93. package/dist/{chunk-Q4TKVF3L.js → chunk-JTLYXUEV.js} +1 -1
  94. package/dist/chunk-JTLYXUEV.js.map +1 -0
  95. package/dist/{chunk-CCRVDLV3.js → chunk-JWBZ74TW.js} +2 -2
  96. package/dist/chunk-JWBZ74TW.js.map +1 -0
  97. package/dist/{chunk-ZU5GNSOJ.js → chunk-K3LIPKFV.js} +3 -3
  98. package/dist/chunk-K3LIPKFV.js.map +1 -0
  99. package/dist/{chunk-GQRL6VNU.js → chunk-LGBO24FL.js} +1 -1
  100. package/dist/chunk-LGBO24FL.js.map +1 -0
  101. package/dist/{chunk-SWUVTGMR.js → chunk-MEUNTJL5.js} +3 -3
  102. package/dist/{chunk-SWUVTGMR.js.map → chunk-MEUNTJL5.js.map} +1 -1
  103. package/dist/{chunk-YNALYIQ3.js → chunk-NLSSFLLS.js} +1 -1
  104. package/dist/chunk-NLSSFLLS.js.map +1 -0
  105. package/dist/{chunk-HFC4BTWJ.js → chunk-PTUMBMVH.js} +1 -1
  106. package/dist/chunk-PTUMBMVH.js.map +1 -0
  107. package/dist/{chunk-R4NOKZMD.js → chunk-ROLFDOMJ.js} +3 -3
  108. package/dist/{chunk-NYATNLRK.js → chunk-RT5RKAFX.js} +1 -1
  109. package/dist/chunk-RT5RKAFX.js.map +1 -0
  110. package/dist/{chunk-GNL3MG5J.js → chunk-S564OFTL.js} +2 -2
  111. package/dist/{chunk-GUSCYE3S.js → chunk-TQOFR6XY.js} +1 -1
  112. package/dist/chunk-TQOFR6XY.js.map +1 -0
  113. package/dist/{chunk-47C6PJCW.js → chunk-TZO3SOUL.js} +1 -1
  114. package/dist/chunk-TZO3SOUL.js.map +1 -0
  115. package/dist/{chunk-YGUNTIT5.js → chunk-UKTYKG57.js} +1 -1
  116. package/dist/chunk-UKTYKG57.js.map +1 -0
  117. package/dist/{chunk-23LUHHHN.js → chunk-VCOD5AOR.js} +1 -1
  118. package/dist/chunk-VCOD5AOR.js.map +1 -0
  119. package/dist/{chunk-5I72FRZY.js → chunk-VOJB7MVG.js} +2 -2
  120. package/dist/{chunk-XWJXZ6WE.js → chunk-VTWKH4YU.js} +2 -2
  121. package/dist/chunk-VTWKH4YU.js.map +1 -0
  122. package/dist/{chunk-4K7BZYO7.js → chunk-VWAEWOWK.js} +3 -3
  123. package/dist/chunk-VWAEWOWK.js.map +1 -0
  124. package/dist/{chunk-M2EBUDZ7.js → chunk-VWOPOLVO.js} +2 -2
  125. package/dist/chunk-VWOPOLVO.js.map +1 -0
  126. package/dist/{chunk-BN2USWIR.js → chunk-VYECQAGM.js} +2 -2
  127. package/dist/chunk-VYECQAGM.js.map +1 -0
  128. package/dist/{chunk-SIXYZ2FB.js → chunk-YJMCRXQQ.js} +1 -1
  129. package/dist/chunk-YJMCRXQQ.js.map +1 -0
  130. package/dist/{chunk-PJC4NXPA.js → chunk-YKBDH2UY.js} +3 -3
  131. package/dist/chunk-YKBDH2UY.js.map +1 -0
  132. package/dist/{chunk-XAWFPMAR.js → chunk-YKOM4ZLQ.js} +1 -1
  133. package/dist/chunk-YKOM4ZLQ.js.map +1 -0
  134. package/dist/{chunk-TKVJE63N.js → chunk-YRMLYFVR.js} +3 -3
  135. package/dist/chunk-YRMLYFVR.js.map +1 -0
  136. package/dist/{chunk-USYXHDKE.js → chunk-YZ6KQULN.js} +2 -2
  137. package/dist/{command-stack-B_-WNfZU.d.ts → command-stack-TNPWJCzW.d.ts} +14 -2
  138. package/dist/{completion-Kaqp_tWk.d.ts → completion-CvcNUz07.d.ts} +1 -1
  139. package/dist/config/index.d.ts +1 -1
  140. package/dist/{contract-KfqJh_au.d.ts → contract-TjB68uqA.d.ts} +17 -0
  141. package/dist/design-canvas/drizzle.d.ts +10 -2
  142. package/dist/design-canvas/drizzle.js.map +1 -1
  143. package/dist/design-canvas/index.d.ts +29 -11
  144. package/dist/design-canvas/index.js +1070 -17
  145. package/dist/design-canvas/index.js.map +1 -1
  146. package/dist/design-canvas-react/engine.d.ts +42 -6
  147. package/dist/design-canvas-react/engine.js +4 -4
  148. package/dist/design-canvas-react/index.d.ts +12 -7
  149. package/dist/design-canvas-react/index.js +11 -11
  150. package/dist/design-canvas-react/index.js.map +1 -1
  151. package/dist/design-canvas-react/lazy.d.ts +4 -4
  152. package/dist/design-canvas-react/lazy.js +1 -1
  153. package/dist/durable-chat/index.d.ts +46 -1
  154. package/dist/durable-chat/index.js +3 -3
  155. package/dist/eval/index.d.ts +1 -1
  156. package/dist/{export-presets-DAsU5Wal.d.ts → export-presets-mgVulRaV.d.ts} +10 -1
  157. package/dist/{flow-types-Cb_AblZs.d.ts → flow-types-CqomVAUN.d.ts} +1 -0
  158. package/dist/harness/index.d.ts +5 -0
  159. package/dist/harness/index.js +1 -1
  160. package/dist/index.d.ts +10 -18
  161. package/dist/index.js +30 -231
  162. package/dist/intakes/api.d.ts +3 -2
  163. package/dist/intakes/api.js +3 -3
  164. package/dist/intakes/api.js.map +1 -1
  165. package/dist/intakes/drizzle.d.ts +10 -2
  166. package/dist/intakes/drizzle.js +3 -3
  167. package/dist/intakes/drizzle.js.map +1 -1
  168. package/dist/intakes/index.d.ts +2 -2
  169. package/dist/intakes/index.js +2 -2
  170. package/dist/intakes-react/index.d.ts +2 -1
  171. package/dist/intakes-react/index.js +2 -2
  172. package/dist/intakes-react/lazy.d.ts +2 -1
  173. package/dist/intakes-react/lazy.js +1 -1
  174. package/dist/intakes-react/lazy.js.map +1 -1
  175. package/dist/integrations/index.d.ts +4 -0
  176. package/dist/integrations/index.js +1 -1
  177. package/dist/interactions/index.d.ts +13 -2
  178. package/dist/interactions/index.js +2 -2
  179. package/dist/{invitations-CZ5G2tIn.d.ts → invitations-DoYMvXea.d.ts} +11 -1
  180. package/dist/{invitations-schema-DaMO4hZE.d.ts → invitations-schema-_fI7HkJP.d.ts} +5 -1
  181. package/dist/knowledge/index.d.ts +2 -0
  182. package/dist/knowledge/index.js +1 -1
  183. package/dist/knowledge-loop/index.d.ts +4 -1
  184. package/dist/knowledge-loop/index.js +1 -1
  185. package/dist/{lazy-C7LiVeFt.d.ts → lazy-DrkVyDpe.d.ts} +2 -2
  186. package/dist/{mcp-BHfIoGLW.d.ts → mcp-BjPqQ-3C.d.ts} +4 -2
  187. package/dist/{mcp-rpc-DLw_r9PQ.d.ts → mcp-rpc-BfUOsalw.d.ts} +3 -0
  188. package/dist/missions/index.d.ts +25 -0
  189. package/dist/missions/index.js +1 -1
  190. package/dist/{model-Bzi5i63l.d.ts → model-C8U0HZxL.d.ts} +1 -0
  191. package/dist/{model-dF2h4xT9.d.ts → model-DmdkIteM.d.ts} +19 -0
  192. package/dist/{model-BBwyOuWG.d.ts → model-DnfO_PdJ.d.ts} +25 -1
  193. package/dist/model-resolution/index.d.ts +10 -0
  194. package/dist/model-resolution/index.js.map +1 -1
  195. package/dist/{operations-DLIvvD00.d.ts → operations-ByJ6yXOW.d.ts} +20 -2
  196. package/dist/{parts-1sRYSPjF.d.ts → parts-n9XUon0a.d.ts} +29 -1
  197. package/dist/plans/index.d.ts +6 -0
  198. package/dist/plans/index.js +1 -1
  199. package/dist/platform/index.d.ts +24 -2
  200. package/dist/platform/index.js +3 -3
  201. package/dist/platform/index.js.map +1 -1
  202. package/dist/preflight/index.d.ts +3 -0
  203. package/dist/preflight/index.js +1 -1
  204. package/dist/preset-cloudflare/index.d.ts +4 -1
  205. package/dist/preset-cloudflare/index.js +2 -2
  206. package/dist/redact/index.d.ts +5 -0
  207. package/dist/redact/index.js +1 -1
  208. package/dist/{roles-BC1n4t37.d.ts → roles-B4nU3jDi.d.ts} +12 -0
  209. package/dist/run/index.d.ts +3 -0
  210. package/dist/run/index.js +1 -1
  211. package/dist/run/index.js.map +1 -1
  212. package/dist/runtime/index.d.ts +11 -4
  213. package/dist/runtime/index.js +4 -4
  214. package/dist/sandbox/index.d.ts +96 -3
  215. package/dist/sandbox/index.js +6 -6
  216. package/dist/{sandbox-terminal-BIIC__CP.d.ts → sandbox-terminal-ChNEdHF8.d.ts} +5 -0
  217. package/dist/sequences/drizzle.d.ts +11 -1
  218. package/dist/sequences/drizzle.js +1 -1
  219. package/dist/sequences/drizzle.js.map +1 -1
  220. package/dist/sequences/index.d.ts +32 -7
  221. package/dist/sequences/index.js +1562 -47
  222. package/dist/sequences/index.js.map +1 -1
  223. package/dist/sequences-react/index.d.ts +32 -2
  224. package/dist/sequences-react/index.js +3 -3
  225. package/dist/sequences-react/index.js.map +1 -1
  226. package/dist/{sso-CNOsARMJ.d.ts → sso-Cm00S61u.d.ts} +13 -0
  227. package/dist/{stale-turn-lock-C8Na1cFZ.d.ts → stale-turn-lock-DucQzvXu.d.ts} +2 -0
  228. package/dist/store/index.d.ts +5 -0
  229. package/dist/store/index.js.map +1 -1
  230. package/dist/{store-gckrNq-g.d.ts → store-B7LLlk9p.d.ts} +22 -1
  231. package/dist/{store-CFyxgTlD.d.ts → store-CqfDtnPQ.d.ts} +8 -2
  232. package/dist/stream/index.d.ts +10 -4
  233. package/dist/stream/index.js +4 -4
  234. package/dist/{stream-normalizer-DWvtmY6F.d.ts → stream-normalizer-C3M--r6y.d.ts} +17 -1
  235. package/dist/studio/index.d.ts +37 -0
  236. package/dist/studio/index.js +1 -1
  237. package/dist/studio-react/index.d.ts +3 -0
  238. package/dist/studio-react/index.js +1 -1
  239. package/dist/studio-react/index.js.map +1 -1
  240. package/dist/tangle/index.d.ts +3 -0
  241. package/dist/tangle/index.js +1 -1
  242. package/dist/teams/drizzle.d.ts +8 -4
  243. package/dist/teams/drizzle.js +1 -1
  244. package/dist/teams/drizzle.js.map +1 -1
  245. package/dist/teams/index.d.ts +4 -2
  246. package/dist/teams/index.js +3 -3
  247. package/dist/teams/invitations-api.d.ts +10 -4
  248. package/dist/teams/invitations-api.js +4 -4
  249. package/dist/teams/invitations-api.js.map +1 -1
  250. package/dist/teams/members-api.d.ts +4 -2
  251. package/dist/teams/members-api.js +3 -3
  252. package/dist/teams/resend.d.ts +5 -4
  253. package/dist/teams/resend.js +1 -1
  254. package/dist/teams/resend.js.map +1 -1
  255. package/dist/teams-react/index.d.ts +7 -2
  256. package/dist/teams-react/index.js +3 -3
  257. package/dist/teams-react/lazy.d.ts +5 -2
  258. package/dist/teams-react/lazy.js +2 -2
  259. package/dist/teams-react/lazy.js.map +1 -1
  260. package/dist/theme/index.d.ts +2 -0
  261. package/dist/theme/index.js +1 -1
  262. package/dist/theme/tailwind-preset.d.ts +1 -0
  263. package/dist/theme/tailwind-preset.js.map +1 -1
  264. package/dist/theme-contract/cli.js +1 -1
  265. package/dist/theme-contract/index.d.ts +3 -0
  266. package/dist/theme-contract/index.js +1 -1
  267. package/dist/tools/index.d.ts +13 -6
  268. package/dist/tools/index.js +3 -3
  269. package/dist/trace/index.d.ts +6 -1
  270. package/dist/trace/index.js +2 -2
  271. package/dist/{turn-buffer-C9mEgoop.d.ts → turn-buffer-DGnAPKwa.d.ts} +6 -0
  272. package/dist/turn-stream/index.d.ts +28 -2
  273. package/dist/turn-stream/index.js +1 -1
  274. package/dist/turn-stream/index.js.map +1 -1
  275. package/dist/{types-BEOvc_ue.d.ts → types-CBRyqijY.d.ts} +10 -0
  276. package/dist/vault/index.d.ts +1 -1
  277. package/dist/vault/lazy.d.ts +3 -2
  278. package/dist/vault/lazy.js.map +1 -1
  279. package/dist/web/index.d.ts +4 -0
  280. package/dist/web/index.js +1 -1
  281. package/dist/web-react/index.d.ts +51 -8
  282. package/dist/web-react/index.js +9 -9
  283. package/dist/web-react/terminal.d.ts +2 -2
  284. package/dist/web-react/terminal.js +1 -1
  285. package/package.json +3 -2
  286. package/dist/DesignCanvas-5DJAFDNC.js +0 -12
  287. package/dist/DesignCanvasEditor-XUJZARSN.js +0 -13
  288. package/dist/IntakeInterview-WHVKMNQW.js +0 -8
  289. package/dist/InvitationsPanel-XUUWZBPV.js +0 -8
  290. package/dist/MembersPanel-FOVHWUQ3.js +0 -8
  291. package/dist/chunk-23LUHHHN.js.map +0 -1
  292. package/dist/chunk-3SVAA3MA.js.map +0 -1
  293. package/dist/chunk-47C6PJCW.js.map +0 -1
  294. package/dist/chunk-4K7BZYO7.js.map +0 -1
  295. package/dist/chunk-4QN75UHX.js.map +0 -1
  296. package/dist/chunk-54GSK2KK.js.map +0 -1
  297. package/dist/chunk-5MG74GVQ.js.map +0 -1
  298. package/dist/chunk-5PTGEJZL.js.map +0 -1
  299. package/dist/chunk-5RMIUJDI.js.map +0 -1
  300. package/dist/chunk-63CE7FEZ.js.map +0 -1
  301. package/dist/chunk-65P3HJY3.js.map +0 -1
  302. package/dist/chunk-6KVH5SP5.js.map +0 -1
  303. package/dist/chunk-7EVZUIHW.js.map +0 -1
  304. package/dist/chunk-7SUPA2YT.js.map +0 -1
  305. package/dist/chunk-7W5XSTUF.js.map +0 -1
  306. package/dist/chunk-BN2USWIR.js.map +0 -1
  307. package/dist/chunk-BQV42AFK.js.map +0 -1
  308. package/dist/chunk-CCRVDLV3.js.map +0 -1
  309. package/dist/chunk-EEPJGZJW.js.map +0 -1
  310. package/dist/chunk-G3HCU7TA.js.map +0 -1
  311. package/dist/chunk-GQRL6VNU.js.map +0 -1
  312. package/dist/chunk-GUSCYE3S.js.map +0 -1
  313. package/dist/chunk-H5FM75MR.js.map +0 -1
  314. package/dist/chunk-HFC4BTWJ.js.map +0 -1
  315. package/dist/chunk-HRJJH3RX.js.map +0 -1
  316. package/dist/chunk-K63OWUDJ.js.map +0 -1
  317. package/dist/chunk-L2TG5DBW.js.map +0 -1
  318. package/dist/chunk-M2EBUDZ7.js.map +0 -1
  319. package/dist/chunk-MCJSS6SM.js.map +0 -1
  320. package/dist/chunk-MFI4ZM7W.js.map +0 -1
  321. package/dist/chunk-MFRCM32T.js.map +0 -1
  322. package/dist/chunk-ND3XEGBE.js.map +0 -1
  323. package/dist/chunk-NEOV2NQ3.js +0 -1617
  324. package/dist/chunk-NEOV2NQ3.js.map +0 -1
  325. package/dist/chunk-NYATNLRK.js.map +0 -1
  326. package/dist/chunk-PJC4NXPA.js.map +0 -1
  327. package/dist/chunk-Q4TKVF3L.js.map +0 -1
  328. package/dist/chunk-RVUISYUE.js.map +0 -1
  329. package/dist/chunk-SIXYZ2FB.js.map +0 -1
  330. package/dist/chunk-TKVJE63N.js.map +0 -1
  331. package/dist/chunk-WEBBJBDH.js.map +0 -1
  332. package/dist/chunk-WFMUDX5J.js +0 -1092
  333. package/dist/chunk-WFMUDX5J.js.map +0 -1
  334. package/dist/chunk-XAWFPMAR.js.map +0 -1
  335. package/dist/chunk-XKBIYSSM.js.map +0 -1
  336. package/dist/chunk-XWJXZ6WE.js.map +0 -1
  337. package/dist/chunk-YGUNTIT5.js.map +0 -1
  338. package/dist/chunk-YNALYIQ3.js.map +0 -1
  339. package/dist/chunk-ZU5GNSOJ.js.map +0 -1
  340. package/dist/chunk-ZXNXAQAH.js.map +0 -1
  341. package/dist/chunk-ZYBWGSAZ.js.map +0 -1
  342. /package/dist/{DesignCanvas-5DJAFDNC.js.map → DesignCanvas-UNL34LS2.js.map} +0 -0
  343. /package/dist/{DesignCanvasEditor-XUJZARSN.js.map → DesignCanvasEditor-FJIVYOA2.js.map} +0 -0
  344. /package/dist/{IntakeInterview-WHVKMNQW.js.map → IntakeInterview-3ZIQMZS6.js.map} +0 -0
  345. /package/dist/{InvitationsPanel-XUUWZBPV.js.map → InvitationsPanel-CJ7DR4F7.js.map} +0 -0
  346. /package/dist/{MembersPanel-FOVHWUQ3.js.map → MembersPanel-BB4OD2KB.js.map} +0 -0
  347. /package/dist/{TimelineEditor-I35SJJAJ.js.map → TimelineEditor-2ECKSU6P.js.map} +0 -0
  348. /package/dist/{chunk-7C64WKAH.js.map → chunk-5SXS3YAB.js.map} +0 -0
  349. /package/dist/{chunk-R4NOKZMD.js.map → chunk-ROLFDOMJ.js.map} +0 -0
  350. /package/dist/{chunk-GNL3MG5J.js.map → chunk-S564OFTL.js.map} +0 -0
  351. /package/dist/{chunk-5I72FRZY.js.map → chunk-VOJB7MVG.js.map} +0 -0
  352. /package/dist/{chunk-USYXHDKE.js.map → chunk-YZ6KQULN.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/plans/index.ts"],"sourcesContent":["/**\n * Durable-plan application-shell contract.\n *\n * The sandbox SDK owns the authoritative plan lifecycle and decision APIs.\n * This module only projects that substrate state into chat events and\n * persisted message parts that products can render and restore.\n */\n\nexport const PLAN_SUBMITTED_EVENT = 'plan.submitted' as const\n\n/** Sandbox plan lifecycle. `preparing` is the transient submission state and\n * is retained in the projection even though the chat card normally starts at\n * `pending`. */\nexport type ChatPlanStatus = 'preparing' | 'pending' | 'approved' | 'rejected' | 'superseded' | 'withdrawn'\n\ntype ChatPlanBase = {\n /** The sandbox SDK calls this field `id`; the transcript projection names\n * it explicitly so it cannot collide with a message-part id. */\n planId: string\n revision: number\n title?: string\n body: string\n submittedAt: string\n /** Provider/Sandbox metadata is deliberately opaque to this package. */\n metadata?: Record<string, unknown>\n decidedBy?: string\n}\n\n/** Browser/persisted projection of the sandbox SDK's durable-plan union. */\nexport type ChatPlan = ChatPlanBase & (\n | { status: 'preparing' }\n | { status: 'pending' }\n | { status: 'approved'; decidedAt: string }\n | { status: 'rejected'; decidedAt: string; feedback: string }\n | { status: 'superseded'; supersededAt: string; supersededByPlanId: string }\n | { status: 'withdrawn'; withdrawnAt: string; withdrawnReason: string }\n)\n\n/** Canonical transcript part for one durable plan. */\nexport type ChatPlanPersistedPart = ChatPlan & { type: 'plan' }\n\nexport type ParsePlanSubmittedResult =\n | { succeeded: true; value: ChatPlan }\n | { succeeded: false; error: string }\n\nconst PLAN_STATUSES: ReadonlySet<string> = new Set([\n 'preparing',\n 'pending',\n 'approved',\n 'rejected',\n 'superseded',\n 'withdrawn',\n])\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? value as Record<string, unknown>\n : null\n}\n\nfunction requiredString(record: Record<string, unknown>, key: string): string | null {\n const value = record[key]\n return typeof value === 'string' && value ? value : null\n}\n\nfunction parsePlan(record: Record<string, unknown>, defaultStatus?: ChatPlanStatus): ChatPlan | null {\n const planId = requiredString(record, 'planId') ?? requiredString(record, 'id')\n const revision = record.revision\n const body = requiredString(record, 'body')\n const submittedAt = requiredString(record, 'submittedAt')\n const status = typeof record.status === 'string' ? record.status : defaultStatus\n if (\n !planId ||\n typeof revision !== 'number' ||\n !Number.isInteger(revision) ||\n revision < 1 ||\n !body ||\n !submittedAt ||\n !status ||\n !PLAN_STATUSES.has(status)\n ) {\n return null\n }\n\n const common = {\n planId,\n revision,\n ...(typeof record.title === 'string' && record.title ? { title: record.title } : {}),\n body,\n submittedAt,\n ...(record.metadata && typeof record.metadata === 'object' && !Array.isArray(record.metadata)\n ? { metadata: record.metadata as Record<string, unknown> }\n : {}),\n ...(typeof record.decidedBy === 'string' && record.decidedBy ? { decidedBy: record.decidedBy } : {}),\n }\n\n if (status === 'preparing') return { ...common, status: 'preparing' }\n if (status === 'pending') return { ...common, status: 'pending' }\n if (status === 'approved') {\n const decidedAt = requiredString(record, 'decidedAt')\n return decidedAt ? { ...common, status, decidedAt } : null\n }\n if (status === 'rejected') {\n const decidedAt = requiredString(record, 'decidedAt')\n const feedback = requiredString(record, 'feedback')\n return decidedAt && feedback ? { ...common, status, decidedAt, feedback } : null\n }\n if (status === 'superseded') {\n const supersededAt = requiredString(record, 'supersededAt')\n const supersededByPlanId = requiredString(record, 'supersededByPlanId')\n return supersededAt && supersededByPlanId\n ? { ...common, status, supersededAt, supersededByPlanId }\n : null\n }\n\n const withdrawnAt = requiredString(record, 'withdrawnAt')\n const withdrawnReason = requiredString(record, 'withdrawnReason') ?? requiredString(record, 'reason')\n return withdrawnAt && withdrawnReason\n ? { ...common, status: 'withdrawn', withdrawnAt, withdrawnReason }\n : null\n}\n\nexport function planPartKey(planId: string): string {\n return `plan:${planId}`\n}\n\nexport function planRevisionKey(planId: string, revision: number): string {\n return `plan:${planId}:revision:${revision}`\n}\n\nexport function planFollowUpTurnId(planId: string, outcome: 'approved' | 'rejected'): string {\n return `plan:${planId}:${outcome}`\n}\n\n/** Plan status is monotonic: only a pending plan can settle. */\nexport function canTransitionPlanStatus(from: ChatPlanStatus, to: ChatPlanStatus): boolean {\n if (from === to) return true\n if (from === 'preparing') return to === 'pending' || to === 'superseded' || to === 'withdrawn'\n if (from === 'pending') return to === 'approved' || to === 'rejected' || to === 'superseded' || to === 'withdrawn'\n return false\n}\n\nexport function planToPersistedPart(plan: ChatPlan): ChatPlanPersistedPart {\n return { type: 'plan', ...plan }\n}\n\nexport function persistedPartToPlan(part: Record<string, unknown>): ChatPlan | null {\n if (String(part.type ?? '') !== 'plan') return null\n return parsePlan(part)\n}\n\n/** Parses both direct sandbox events (`data.plan`) and session envelopes\n * (`properties.plan`). Session identity is carried by the surrounding stream\n * and is deliberately not required in the payload. */\nexport function parsePlanSubmittedEvent(event: unknown): ParsePlanSubmittedResult {\n const root = asRecord(event)\n if (!root || root.type !== PLAN_SUBMITTED_EVENT) {\n return { succeeded: false, error: 'event is not plan.submitted' }\n }\n const plan = asRecord(asRecord(root.properties)?.plan) ?? asRecord(asRecord(root.data)?.plan)\n if (!plan) {\n return { succeeded: false, error: 'plan.submitted event carried no plan' }\n }\n const parsed = parsePlan(plan, 'pending')\n return parsed\n ? { succeeded: true, value: parsed }\n : { succeeded: false, error: 'plan.submitted event carried a malformed plan' }\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/platform/sso.ts","../src/platform/guards.ts"],"sourcesContent":["/**\n * Cross-site Tangle SSO for agent apps: signed-state CSRF cookies plus the\n * full start/callback orchestration against the platform's /cross-site\n * bridge. The platform wire client and account persistence are structural\n * seams (`TangleSsoAuthClient` / `TangleSsoAccountStore`), so this module\n * never imports agent-runtime, an auth framework, or a database driver.\n * WebCrypto only — runs in workerd without node compatibility flags.\n */\n\nimport { clearCookieHeader, readCookieValue, serializeCookie } from '../web/index'\n\nconst DEFAULT_STATE_TTL_SECONDS = 600\nconst DEFAULT_SESSION_TTL_SECONDS = 60 * 60 * 24 * 7\nconst DEFAULT_REDIRECT_PATH = '/app'\nconst DEFAULT_LOGIN_PATH = '/login'\nconst DEFAULT_SESSION_COOKIE = 'better-auth.session_token'\n\n// ── Signed state ────────────────────────────────────────────────────────────\n\nexport interface SsoStateConfig {\n /** HMAC-SHA256 secret (e.g. the app's auth secret). */\n secret: string\n /** State lifetime in ms. Default 600 000. */\n ttlMs?: number\n /** Injectable clock (ms since epoch). Default Date.now. */\n now?: () => number\n}\n\nfunction randomHex(bytes: number): string {\n const buf = new Uint8Array(bytes)\n crypto.getRandomValues(buf)\n return Array.from(buf, (b) => b.toString(16).padStart(2, '0')).join('')\n}\n\nasync function hmacBytes(secret: string, value: string): Promise<Uint8Array> {\n const key = await crypto.subtle.importKey(\n 'raw',\n new TextEncoder().encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n )\n return new Uint8Array(await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(value)))\n}\n\nasync function hmacHex(secret: string, value: string): Promise<string> {\n return Array.from(await hmacBytes(secret, value), (b) => b.toString(16).padStart(2, '0')).join('')\n}\n\nfunction constantTimeEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false\n let diff = 0\n for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i)\n return diff === 0\n}\n\n/** Mint a `<randomHex32>.<timestamp36>.<hmacHex>` state value. The timestamp\n * is inside the signed payload, so expiry survives cookie-attribute tampering. */\nexport async function createSignedSsoState(config: SsoStateConfig): Promise<string> {\n if (!config.secret) throw new Error('SsoStateConfig.secret is required')\n const now = config.now ?? Date.now\n const payload = `${randomHex(16)}.${now().toString(36)}`\n return `${payload}.${await hmacHex(config.secret, payload)}`\n}\n\n/** Verify the MAC (constant-time) and the signed TTL. */\nexport async function verifySignedSsoState(state: string, config: SsoStateConfig): Promise<boolean> {\n if (!config.secret) throw new Error('SsoStateConfig.secret is required')\n const parts = state.split('.')\n if (parts.length !== 3) return false\n const [random, timestamp, mac] = parts\n if (!random || !timestamp || !mac) return false\n const expected = await hmacHex(config.secret, `${random}.${timestamp}`)\n if (!constantTimeEqual(mac, expected)) return false\n const mintedAt = parseInt(timestamp, 36)\n if (!Number.isFinite(mintedAt)) return false\n const now = config.now ?? Date.now\n const ttlMs = config.ttlMs ?? DEFAULT_STATE_TTL_SECONDS * 1000\n return now() - mintedAt <= ttlMs\n}\n\n// ── Seams ───────────────────────────────────────────────────────────────────\n\nexport interface TangleSsoExchangeResult {\n apiKey: string\n user: { id: string; email: string; name?: string | null }\n plan?: { tier: string } | null\n}\n\n/** Structural mirror of the platform auth wire client — any object with these\n * two methods satisfies it without this module importing the concrete class. */\nexport interface TangleSsoAuthClient {\n authorizeUrl(options: { state: string; redirectUri?: string }): string\n exchange(code: string): Promise<TangleSsoExchangeResult>\n}\n\n/** Thrown by `upsertUserByEmail` when the app-local user row cannot be\n * created; the callback handler maps it to `?error=tangle_user_create_failed`.\n * Any other store error propagates. */\nexport class TangleSsoUserCreateError extends Error {\n constructor(message = 'Failed to create local user for Tangle SSO') {\n super(message)\n this.name = 'TangleSsoUserCreateError'\n }\n}\n\n/**\n * Account persistence seam. Covers both storage styles in use: link-table\n * apps (a per-user platform-link row) and session-column apps (the key on the\n * session row) — `saveTangleLink` receives both `userId` and `sessionToken`,\n * and each app persists with the key it needs. `createSession` runs first so\n * the token is always available to `saveTangleLink`.\n */\nexport interface TangleSsoAccountStore {\n /** Find-or-create the app-local user. `tangleUserId` is the platform's\n * stable user id — match on it first when the app stores it (emails are\n * mutable on the platform; the id is not), falling back to email for\n * first-time logins. */\n upsertUserByEmail(input: { email: string; name: string | null; tangleUserId: string }): Promise<{ userId: string }>\n /** Create an app session row; returns the session-cookie token value. */\n createSession(input: {\n userId: string\n expiresAt: Date\n ipAddress: string | null\n userAgent: string | null\n }): Promise<{ token: string }>\n /** Persist the platform link (API key + platform identity). */\n saveTangleLink(input: {\n userId: string\n sessionToken: string\n tangleUserId: string\n email: string\n name: string | null\n apiKey: string\n planTier: string | null\n }): Promise<void>\n}\n\n// ── Session cookie ──────────────────────────────────────────────────────────\n\n/** Successful-login context handed to the `setSessionCookie` seam. */\nexport interface TangleSsoSessionCookieArgs {\n /** Session token returned by `store.createSession`. */\n token: string\n /** Session expiry (now + `sessionTtlSeconds`). */\n expiresAt: Date\n /** Mirrors `sessionTtlSeconds` after defaulting. */\n ttlSeconds: number\n /** Mirrors `TangleSsoHandlerOptions.secureCookies`. */\n secure: boolean\n}\n\n/**\n * Sign a session token to better-call's signed-cookie contract — the value\n * better-auth's `getSignedCookie` verifies: `<token>.<signature>` where the\n * signature is the raw HMAC-SHA256 of the token under `secret`, encoded as\n * STANDARD base64 WITH padding (32 bytes → 44 chars ending `=`; better-call\n * rejects any other length or suffix, so url-safe/unpadded variants read back\n * as a null session). The joined value is percent-encoded once at cookie\n * serialization, matching better-call's `serializeSignedCookie` byte-exactly.\n */\nexport async function signSessionCookieValue(token: string, secret: string): Promise<string> {\n if (!secret) throw new Error('signSessionCookieValue requires a non-empty secret')\n const sig = await hmacBytes(secret, token)\n let bin = ''\n for (const byte of sig) bin += String.fromCharCode(byte)\n return `${token}.${btoa(bin)}`\n}\n\n/** Structural slice of a `betterAuth()` instance — only what cookie minting\n * reads. No better-auth import: the signing contract is implemented by\n * `signSessionCookieValue`, byte-compatible with better-auth's own\n * `makeSignature`. */\nexport interface BetterAuthSessionCookieSource {\n $context: PromiseLike<{\n secret: string\n authCookies: {\n sessionToken: {\n /** Final cookie name — better-auth decides the `__Secure-` prefix\n * (and any `advanced.cookiePrefix`) once at `betterAuth()` init. */\n name: string\n attributes: {\n secure?: boolean\n sameSite?: string\n path?: string\n httpOnly?: boolean\n domain?: string\n }\n }\n }\n }>\n}\n\nexport interface BetterAuthSessionCookieMinterOptions {\n /** Receives the shadowed-cookie-name warning (see below). Default\n * console.warn. */\n warn?: (message: string) => void\n}\n\n/**\n * Canonical `setSessionCookie` wiring for better-auth apps: mint the session\n * Set-Cookie exactly as better-auth's own login flows do — name + attributes\n * from `auth.$context.authCookies.sessionToken` (better-auth stays\n * authoritative over prefix/name/attributes) and the value signed to\n * better-call's `getSignedCookie` contract. A raw unprefixed\n * `better-auth.session_token` left by an earlier login is explicitly expired\n * so it cannot shadow the real cookie.\n *\n * Warns when the app's session cookie still has better-auth's DEFAULT name:\n * the Tangle platform (id.tangle.tools) sets a `Domain=.tangle.tools` cookie\n * under that exact name, and equal-path cookies are sent oldest-first — the\n * platform's cookie is always older (the user signs in there before the app's\n * callback runs), so the app reads the platform's token, fails its own\n * signature check, and every fresh login lands logged-out. Per-app\n * `advanced.cookiePrefix` is the fix.\n *\n * Throws on a domain-scoped session cookie for the same reason: a\n * `Domain=`-wide session cookie is exactly the shadowing footgun.\n */\nexport function createBetterAuthSessionCookieMinter(\n auth: BetterAuthSessionCookieSource,\n options: BetterAuthSessionCookieMinterOptions = {},\n): (args: TangleSsoSessionCookieArgs) => Promise<string[]> {\n const warn = options.warn ?? ((message: string) => console.warn(message))\n return async ({ token, ttlSeconds }) => {\n const ctx = await auth.$context\n if (!ctx.secret) {\n throw new Error('createBetterAuthSessionCookieMinter: auth context has no secret')\n }\n const { name, attributes } = ctx.authCookies.sessionToken\n if (attributes.domain) {\n throw new Error(\n `createBetterAuthSessionCookieMinter: refusing a domain-scoped session cookie (Domain=${attributes.domain}) — ` +\n 'a domain-wide session cookie shadows sibling apps that share the parent domain',\n )\n }\n if (name === DEFAULT_SESSION_COOKIE || name === `__Secure-${DEFAULT_SESSION_COOKIE}`) {\n warn(\n `[tangle-sso] session cookie is named \"${name}\" — better-auth's default. ` +\n 'The Tangle platform (id.tangle.tools) sets a Domain=.tangle.tools cookie under the same name, ' +\n \"and the platform's (older) cookie wins the Cookie-header order, so this app's sessions read back null. \" +\n \"Set a per-app prefix: betterAuth({ advanced: { cookiePrefix: '<app>' } }).\",\n )\n }\n const sameSite = typeof attributes.sameSite === 'string' ? attributes.sameSite : 'lax'\n const cookieOptions = {\n name,\n path: typeof attributes.path === 'string' ? attributes.path : '/',\n httpOnly: attributes.httpOnly !== false,\n sameSite: (sameSite.charAt(0).toUpperCase() + sameSite.slice(1)) as 'Lax' | 'Strict' | 'None',\n secure: Boolean(attributes.secure) || name.startsWith('__Secure-'),\n maxAgeSeconds: ttlSeconds,\n }\n const cookies = [serializeCookie(await signSessionCookieValue(token, ctx.secret), cookieOptions)]\n if (name !== DEFAULT_SESSION_COOKIE) {\n cookies.push(clearCookieHeader({ ...cookieOptions, name: DEFAULT_SESSION_COOKIE }))\n }\n return cookies\n }\n}\n\n// ── Handlers ────────────────────────────────────────────────────────────────\n\nexport interface TangleSsoHandlerOptions {\n auth: TangleSsoAuthClient\n store: TangleSsoAccountStore\n /** HMAC secret for the state cookie. */\n stateSecret: string\n /** Absolute callback URL registered with the platform. */\n callbackUrl: string\n stateCookieName: string\n /** Default 'better-auth.session_token'. Ignored when `setSessionCookie` is\n * provided. The default path prepends `__Secure-` iff `secureCookies`. */\n sessionCookieName?: string\n /** Mint the host auth framework's own session cookie(s); return complete\n * Set-Cookie header values (the handler appends them verbatim and sets no\n * session cookie itself). Supply this when the framework should stay\n * authoritative over name/prefix/signing/attributes — e.g. better-auth:\n * `auth.$context.authCookies.sessionToken` + `makeSignature`. */\n setSessionCookie?: (\n args: TangleSsoSessionCookieArgs,\n ) => readonly string[] | Promise<readonly string[]>\n /** HMAC-SHA256 secret the host auth framework verifies session cookies with\n * (better-auth: its `secret`). Required when `setSessionCookie` is absent —\n * the default cookie is minted to better-call's signed contract via\n * `signSessionCookieValue`; an unsigned or mis-signed value reads back as a\n * null session, so there is deliberately no fallback to `stateSecret`\n * (which is not guaranteed to be the auth secret). */\n sessionCookieSecret?: string\n /** Adds `Secure` to every cookie this module sets, and (default session\n * cookie only) the `__Secure-` name prefix. Must match the auth\n * framework's own secure-cookie decision (better-auth: https `baseURL` /\n * `advanced.useSecureCookies`), or it will look up a different cookie name\n * than the one set here. */\n secureCookies: boolean\n /** Default 604 800 (7 days). */\n sessionTtlSeconds?: number\n /** Default 600. Applies to both the cookie Max-Age and the signed TTL. */\n stateTtlSeconds?: number\n /** Default '/app'. */\n defaultRedirectPath?: string\n /** Default '/login'. */\n loginPath?: string\n /** Failure log hook (e.g. console.error). Default no-op. */\n log?: (message: string, error?: unknown) => void\n now?: () => number\n}\n\nexport interface TangleSsoHandlers {\n /** GET start route: mint + sign state, set the state cookie, 302 to the\n * platform authorize URL. `?redirect=` carries the post-login path. */\n start(request: Request): Promise<Response>\n /** GET callback route: verify state, exchange the code, upsert the user,\n * create the session, save the platform link, set the session cookie\n * (via the `setSessionCookie` seam, else signed to better-call's contract\n * with `sessionCookieSecret`), 302 to the saved redirect. Every failure\n * 302s to `loginPath?error=…` with the state cookie cleared. */\n callback(request: Request): Promise<Response>\n}\n\n/** Accept only same-origin absolute paths (rejects `//host` protocol-relative URLs). */\nfunction sanitizeRedirectPath(value: string | null, fallback: string): string {\n if (value && value.startsWith('/') && !value.startsWith('//')) return value\n return fallback\n}\n\nfunction redirectResponse(location: string, headers = new Headers()): Response {\n headers.set('Location', location)\n return new Response(null, { status: 302, headers })\n}\n\n/** Real client IP: `CF-Connecting-IP` behind Cloudflare, else the first\n * `x-forwarded-for` hop (the rest of the list is sender-controlled). */\nfunction clientIp(request: Request): string | null {\n return (\n request.headers.get('CF-Connecting-IP') ??\n request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ??\n null\n )\n}\n\ninterface StateCookiePayload {\n s: string\n r: string\n}\n\nfunction parseStateCookiePayload(raw: string | null): StateCookiePayload | null {\n if (!raw) return null\n try {\n const parsed = JSON.parse(raw) as unknown\n if (parsed === null || typeof parsed !== 'object') return null\n const { s, r } = parsed as Record<string, unknown>\n if (typeof s !== 'string' || typeof r !== 'string') return null\n return { s, r }\n } catch {\n return null\n }\n}\n\nexport function createTangleSsoHandlers(opts: TangleSsoHandlerOptions): TangleSsoHandlers {\n if (!opts.stateSecret) throw new Error('TangleSsoHandlerOptions.stateSecret is required')\n if (!opts.callbackUrl) throw new Error('TangleSsoHandlerOptions.callbackUrl is required')\n if (!opts.stateCookieName) throw new Error('TangleSsoHandlerOptions.stateCookieName is required')\n\n const sessionCookieName = opts.sessionCookieName ?? DEFAULT_SESSION_COOKIE\n\n let mintSessionCookies: (args: TangleSsoSessionCookieArgs) => Promise<readonly string[]>\n if (opts.setSessionCookie) {\n const seam = opts.setSessionCookie\n mintSessionCookies = async (args) => await seam(args)\n } else if (opts.sessionCookieSecret) {\n const secret = opts.sessionCookieSecret\n mintSessionCookies = async ({ token, secure, ttlSeconds }) => [\n serializeCookie(await signSessionCookieValue(token, secret), {\n name: secure ? `__Secure-${sessionCookieName}` : sessionCookieName,\n secure,\n maxAgeSeconds: ttlSeconds,\n }),\n ]\n } else {\n throw new Error(\n 'TangleSsoHandlerOptions requires setSessionCookie or sessionCookieSecret: ' +\n 'better-auth only accepts HMAC-signed (and, on https, __Secure--prefixed) session cookies, ' +\n 'so an unsigned default would mint sessions that read back null',\n )\n }\n const sessionTtlSeconds = opts.sessionTtlSeconds ?? DEFAULT_SESSION_TTL_SECONDS\n const stateTtlSeconds = opts.stateTtlSeconds ?? DEFAULT_STATE_TTL_SECONDS\n const defaultRedirectPath = opts.defaultRedirectPath ?? DEFAULT_REDIRECT_PATH\n const loginPath = opts.loginPath ?? DEFAULT_LOGIN_PATH\n const log = opts.log ?? (() => {})\n const now = opts.now ?? Date.now\n const stateConfig: SsoStateConfig = { secret: opts.stateSecret, ttlMs: stateTtlSeconds * 1000, now }\n\n const stateCookieOpts = { name: opts.stateCookieName, secure: opts.secureCookies }\n\n function loginErrorRedirect(code: string): Response {\n const headers = new Headers()\n headers.append('Set-Cookie', clearCookieHeader(stateCookieOpts))\n return redirectResponse(`${loginPath}?error=${code}`, headers)\n }\n\n return {\n async start(request) {\n const url = new URL(request.url)\n const redirectPath = sanitizeRedirectPath(url.searchParams.get('redirect'), defaultRedirectPath)\n const state = await createSignedSsoState(stateConfig)\n const cookie = serializeCookie(JSON.stringify({ s: state, r: redirectPath }), {\n ...stateCookieOpts,\n maxAgeSeconds: stateTtlSeconds,\n })\n const headers = new Headers()\n headers.append('Set-Cookie', cookie)\n return redirectResponse(opts.auth.authorizeUrl({ state, redirectUri: opts.callbackUrl }), headers)\n },\n\n async callback(request) {\n const url = new URL(request.url)\n const code = url.searchParams.get('code')\n const stateFromPlatform = url.searchParams.get('state')\n if (!code || !stateFromPlatform) return loginErrorRedirect('tangle_callback_missing')\n\n const payload = parseStateCookiePayload(readCookieValue(request.headers.get('cookie'), opts.stateCookieName))\n if (!payload || payload.s !== stateFromPlatform) return loginErrorRedirect('tangle_state_mismatch')\n if (!(await verifySignedSsoState(payload.s, stateConfig))) return loginErrorRedirect('tangle_state_mismatch')\n\n let exchanged: TangleSsoExchangeResult\n try {\n exchanged = await opts.auth.exchange(code)\n } catch (err) {\n log('[tangle-sso] exchange failed', err)\n return loginErrorRedirect('tangle_exchange_failed')\n }\n\n let userId: string\n try {\n ;({ userId } = await opts.store.upsertUserByEmail({\n email: exchanged.user.email,\n name: exchanged.user.name ?? null,\n tangleUserId: exchanged.user.id,\n }))\n } catch (err) {\n if (err instanceof TangleSsoUserCreateError) return loginErrorRedirect('tangle_user_create_failed')\n throw err\n }\n\n const expiresAt = new Date(now() + sessionTtlSeconds * 1000)\n const { token } = await opts.store.createSession({\n userId,\n expiresAt,\n ipAddress: clientIp(request),\n userAgent: request.headers.get('user-agent'),\n })\n\n await opts.store.saveTangleLink({\n userId,\n sessionToken: token,\n tangleUserId: exchanged.user.id,\n email: exchanged.user.email,\n name: exchanged.user.name ?? null,\n apiKey: exchanged.apiKey,\n planTier: exchanged.plan?.tier ?? null,\n })\n\n const headers = new Headers()\n headers.append('Set-Cookie', clearCookieHeader(stateCookieOpts))\n const sessionCookies = await mintSessionCookies({\n token,\n expiresAt,\n ttlSeconds: sessionTtlSeconds,\n secure: opts.secureCookies,\n })\n for (const cookie of sessionCookies) headers.append('Set-Cookie', cookie)\n return redirectResponse(sanitizeRedirectPath(payload.r, defaultRedirectPath), headers)\n },\n }\n}\n","/**\n * Request guards for agent-app routes: session auth (302 redirect for pages,\n * JSON 401 for APIs), admin allowlisting (404 — the route stays invisible to\n * non-admins), and the billable-balance gate (402 with a stable code).\n * Session resolution is a seam; thrown Responses follow the router convention\n * of surfacing a thrown Response as the route result.\n */\n\nimport { isTangleBillingEnforcementDisabled } from '../runtime/model'\n\nexport interface AuthGuardOptions<Session> {\n /** e.g. a better-auth `auth.api.getSession` wrapped by the app. */\n getSession(request: Request): Promise<Session | null | undefined>\n /** Default '/login'. */\n loginPath?: string\n}\n\nexport interface AuthGuard<Session> {\n /** Page guard — throws a 302 redirect Response to `loginPath`. */\n requireUser(request: Request): Promise<Session>\n /** API guard — throws JSON 401 `{ error: 'Unauthorized', code: 'auth.unauthenticated' }`. */\n requireApiUser(request: Request): Promise<Session>\n /** `apiResponse` selects the 401 JSON path over the redirect. */\n requireSession(request: Request, opts?: { apiResponse?: boolean }): Promise<Session>\n getOptionalSession(request: Request): Promise<Session | null>\n}\n\nexport function createAuthGuard<Session>(opts: AuthGuardOptions<Session>): AuthGuard<Session> {\n const loginPath = opts.loginPath ?? '/login'\n\n async function requireSession(request: Request, o: { apiResponse?: boolean } = {}): Promise<Session> {\n const session = await opts.getSession(request)\n if (!session) {\n if (o.apiResponse) {\n throw Response.json({ error: 'Unauthorized', code: 'auth.unauthenticated' }, { status: 401 })\n }\n throw new Response(null, { status: 302, headers: { Location: loginPath } })\n }\n return session\n }\n\n return {\n requireSession,\n requireUser: (request) => requireSession(request),\n requireApiUser: (request) => requireSession(request, { apiResponse: true }),\n getOptionalSession: async (request) => (await opts.getSession(request)) ?? null,\n }\n}\n\nexport type GuardResolution<T> = { ok: true; value: T } | { ok: false; response: Response }\n\n/**\n * Adapt a guard that THROWS a Response (the quartet above — the router\n * convention) to the `{ok: true, value} | {ok: false, response}` resolution\n * shape the route factories take (`/chat-routes` `authorize`,\n * `/interactions` `resolveConnection`, `/chat-routes` upload `authorize`).\n * Every product wrote this try/catch by hand; it lives here once.\n */\nexport async function guardResolution<T>(run: () => Promise<T>): Promise<GuardResolution<T>> {\n try {\n return { ok: true, value: await run() }\n } catch (err) {\n if (err instanceof Response) return { ok: false, response: err }\n throw err\n }\n}\n\n/** Comma/whitespace separated → trimmed, lowercased, empties dropped. */\nexport function parseAdminEmails(raw: string | null | undefined): string[] {\n return (raw ?? '')\n .split(/[,\\s]+/)\n .map((e) => e.trim().toLowerCase())\n .filter(Boolean)\n}\n\nexport interface AdminGuardOptions<Session> {\n requireUser(request: Request): Promise<Session>\n emailOf(session: Session): string | null | undefined\n /** Resolved per request; an EMPTY allowlist refuses everyone. */\n allowedEmails(): string[]\n}\n\n/** Non-admins (and empty allowlists) get 404, keeping the route invisible —\n * better than a \"forbidden\" footprint that advertises its existence. */\nexport function createAdminGuard<Session>(opts: AdminGuardOptions<Session>): (request: Request) => Promise<Session> {\n return async (request) => {\n const session = await opts.requireUser(request)\n const allowed = opts.allowedEmails()\n if (allowed.length === 0) throw new Response('Not found', { status: 404 })\n const email = (opts.emailOf(session) ?? '').toLowerCase()\n if (!allowed.includes(email)) throw new Response('Not found', { status: 404 })\n return session\n }\n}\n\nexport interface BillableBalanceState {\n overageAllowed: boolean\n remainingBalanceUsd: number\n}\n\nexport interface AssertBillableBalanceOptions {\n env?: Record<string, string | undefined>\n /** App-specific enforcement override flag (e.g. 'GTM_BILLING_ENFORCEMENT'),\n * fed to `isTangleBillingEnforcementDisabled`. */\n enforcementEnvVar?: string\n /** Default 'Add balance or upgrade your plan to invoke this agent.'. */\n errorMessage?: string\n /** Merged into the 402 JSON body (e.g. `{ organizationId }`). */\n errorBody?: Record<string, unknown>\n}\n\n/**\n * Gate a billable turn: passes when enforcement is disabled (dev default),\n * the tier allows overage, or remaining balance is positive. Otherwise throws\n * a 402 Response with the stable `billing.balance_required` code so clients\n * can route to the billing screen.\n */\nexport function assertBillableBalance(state: BillableBalanceState, opts: AssertBillableBalanceOptions = {}): void {\n if (isTangleBillingEnforcementDisabled({ env: opts.env, enforcementEnvVar: opts.enforcementEnvVar })) return\n if (state.overageAllowed || state.remainingBalanceUsd > 0) return\n // errorBody first: the stable error/code contract always wins over caller extras.\n throw Response.json(\n {\n ...opts.errorBody,\n error: opts.errorMessage ?? 'Add balance or upgrade your plan to invoke this agent.',\n code: 'billing.balance_required',\n },\n { status: 402 },\n )\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/teams/invitations.ts"],"sourcesContent":["/**\n * Pure invitation helpers + email-template renderer for the teams capability.\n * Zero dependencies: no drizzle, no env, no react, no network. The lifecycle API\n * (`./invitations-api`) and an app's own mail transport build on these; this leaf\n * imports nothing back, so a consumer can pull just the token/expiry math or the\n * template renderer without dragging in drizzle or a mail client.\n *\n * `renderInvitationEmail` is deliberately transport-free: it returns the\n * `{ from, subject, html, text }` an app hands to its own Resend/SES/etc. The\n * secret (API key) and the network call stay in the app's seam — agent-app ships\n * only the deterministic template.\n */\n\nimport type { AssignableWorkspaceRole } from './roles'\n\n/** The role an invitation grants — the assignable workspace ladder (never owner). */\nexport type InvitationPermission = AssignableWorkspaceRole\n\nexport type InvitationStatus = 'pending' | 'accepted' | 'expired' | 'revoked'\nexport type InvitationEmailStatus = 'not_sent' | 'sent' | 'failed'\n\nexport const INVITATION_EXPIRY_DAYS = 7\n\nconst INVITATION_PERMISSIONS = ['admin', 'editor', 'viewer'] as const\nconst TOKEN_BYTE_LENGTH = 32\n\nexport function normalizeInvitationEmail(email: string): string {\n return email.trim().toLowerCase()\n}\n\nexport function parseInvitationPermission(value: string | undefined): InvitationPermission | null {\n return INVITATION_PERMISSIONS.includes(value as InvitationPermission) ? (value as InvitationPermission) : null\n}\n\nexport function getInvitationExpiresAt(now: Date = new Date()): Date {\n return new Date(now.getTime() + INVITATION_EXPIRY_DAYS * 24 * 60 * 60 * 1000)\n}\n\n/**\n * A cryptographically-random, URL-safe invitation token. `inv_`-prefixed so a\n * token is self-identifying and never collides with the workspaceMember invite\n * tokens minted by `members-api` (`generateInviteToken`).\n */\nexport function generateInvitationToken(): string {\n const bytes = new Uint8Array(TOKEN_BYTE_LENGTH)\n globalThis.crypto.getRandomValues(bytes)\n const token = Array.from(bytes, (byte) => String.fromCharCode(byte)).join('')\n return `inv_${btoa(token).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/g, '')}`\n}\n\nexport function inviteUrlForToken(origin: string, token: string): string {\n return `${origin.replace(/\\/+$/, '')}/invite/${encodeURIComponent(token)}`\n}\n\n// ── email template (pure; no transport) ──\n\nexport interface RenderInvitationEmailInput {\n to: string\n workspaceName: string\n inviterEmail: string\n permission: string\n inviteUrl: string\n expiresAt: Date\n}\n\nexport interface InvitationEmailBrand {\n /** RFC-5322 From header, e.g. `GTM Agent <noreply@gtm.tangle.tools>`. */\n fromAddress: string\n}\n\nexport interface RenderedInvitationEmail {\n from: string\n subject: string\n html: string\n text: string\n}\n\n/**\n * Render the invitation email body — pure, deterministic, transport-free. The\n * caller passes the result to its own mail client; this never reads a secret or\n * touches the network.\n */\nexport function renderInvitationEmail(\n input: RenderInvitationEmailInput,\n brand: InvitationEmailBrand,\n): RenderedInvitationEmail {\n const role = input.permission.toLowerCase()\n const expiry = input.expiresAt.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n })\n return {\n from: brand.fromAddress,\n subject: `${input.inviterEmail} invited you to ${input.workspaceName}`,\n html: [\n `<p>${escapeHtml(input.inviterEmail)} invited you to join <strong>${escapeHtml(input.workspaceName)}</strong> as ${escapeHtml(role)}.</p>`,\n `<p><a href=\"${input.inviteUrl}\">Accept the invitation</a></p>`,\n `<p>This invitation expires on ${expiry}.</p>`,\n ].join(''),\n text: [\n `${input.inviterEmail} invited you to join ${input.workspaceName} as ${role}.`,\n `Accept the invitation: ${input.inviteUrl}`,\n `This invitation expires on ${expiry}.`,\n ].join('\\n\\n'),\n }\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;')\n}\n"],"mappings":";AAqBO,IAAM,yBAAyB;AAEtC,IAAM,yBAAyB,CAAC,SAAS,UAAU,QAAQ;AAC3D,IAAM,oBAAoB;AAEnB,SAAS,yBAAyB,OAAuB;AAC9D,SAAO,MAAM,KAAK,EAAE,YAAY;AAClC;AAEO,SAAS,0BAA0B,OAAwD;AAChG,SAAO,uBAAuB,SAAS,KAA6B,IAAK,QAAiC;AAC5G;AAEO,SAAS,uBAAuB,MAAY,oBAAI,KAAK,GAAS;AACnE,SAAO,IAAI,KAAK,IAAI,QAAQ,IAAI,yBAAyB,KAAK,KAAK,KAAK,GAAI;AAC9E;AAOO,SAAS,0BAAkC;AAChD,QAAM,QAAQ,IAAI,WAAW,iBAAiB;AAC9C,aAAW,OAAO,gBAAgB,KAAK;AACvC,QAAM,QAAQ,MAAM,KAAK,OAAO,CAAC,SAAS,OAAO,aAAa,IAAI,CAAC,EAAE,KAAK,EAAE;AAC5E,SAAO,OAAO,KAAK,KAAK,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,QAAQ,EAAE,CAAC;AACvF;AAEO,SAAS,kBAAkB,QAAgB,OAAuB;AACvE,SAAO,GAAG,OAAO,QAAQ,QAAQ,EAAE,CAAC,WAAW,mBAAmB,KAAK,CAAC;AAC1E;AA8BO,SAAS,sBACd,OACA,OACyB;AACzB,QAAM,OAAO,MAAM,WAAW,YAAY;AAC1C,QAAM,SAAS,MAAM,UAAU,mBAAmB,SAAS;AAAA,IACzD,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,EACR,CAAC;AACD,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,SAAS,GAAG,MAAM,YAAY,mBAAmB,MAAM,aAAa;AAAA,IACpE,MAAM;AAAA,MACJ,MAAM,WAAW,MAAM,YAAY,CAAC,gCAAgC,WAAW,MAAM,aAAa,CAAC,gBAAgB,WAAW,IAAI,CAAC;AAAA,MACnI,eAAe,MAAM,SAAS;AAAA,MAC9B,iCAAiC,MAAM;AAAA,IACzC,EAAE,KAAK,EAAE;AAAA,IACT,MAAM;AAAA,MACJ,GAAG,MAAM,YAAY,wBAAwB,MAAM,aAAa,OAAO,IAAI;AAAA,MAC3E,0BAA0B,MAAM,SAAS;AAAA,MACzC,8BAA8B,MAAM;AAAA,IACtC,EAAE,KAAK,MAAM;AAAA,EACf;AACF;AAEA,SAAS,WAAW,OAAuB;AACzC,SAAO,MACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,OAAO;AAC1B;","names":[]}