@keystrokehq/platform 0.1.5 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/dist/{awk2-LA3USKJP-AIZOQ0nh.cjs → awk2-LA3USKJP-BX_f5xEm.cjs} +40 -40
  2. package/dist/{awk2-LA3USKJP-AIZOQ0nh.cjs.map → awk2-LA3USKJP-BX_f5xEm.cjs.map} +1 -1
  3. package/dist/{awk2-LA3USKJP-CPcab6tL.mjs → awk2-LA3USKJP-Og7WTTTV.mjs} +2 -2
  4. package/dist/{awk2-LA3USKJP-CPcab6tL.mjs.map → awk2-LA3USKJP-Og7WTTTV.mjs.map} +1 -1
  5. package/dist/{base64-C2AIWVNC-BU7vFrSz.mjs → base64-C2AIWVNC-CWnEsAFR.mjs} +2 -2
  6. package/dist/{base64-C2AIWVNC-BU7vFrSz.mjs.map → base64-C2AIWVNC-CWnEsAFR.mjs.map} +1 -1
  7. package/dist/{base64-C2AIWVNC-fWp5IaIt.cjs → base64-C2AIWVNC-xY0o1izr.cjs} +2 -2
  8. package/dist/{base64-C2AIWVNC-fWp5IaIt.cjs.map → base64-C2AIWVNC-xY0o1izr.cjs.map} +1 -1
  9. package/dist/{bash-YZ33HQZQ-B7vkAJM1.mjs → bash-YZ33HQZQ-CwBcNtq8.mjs} +2 -2
  10. package/dist/{bash-YZ33HQZQ-B7vkAJM1.mjs.map → bash-YZ33HQZQ-CwBcNtq8.mjs.map} +1 -1
  11. package/dist/{bash-YZ33HQZQ-BfFH_xKv.cjs → bash-YZ33HQZQ-DEgQkmLN.cjs} +5 -5
  12. package/dist/{bash-YZ33HQZQ-BfFH_xKv.cjs.map → bash-YZ33HQZQ-DEgQkmLN.cjs.map} +1 -1
  13. package/dist/{cat-TSFMZVYS-Lk2fLg0m.cjs → cat-TSFMZVYS-CE8iJIL3.cjs} +3 -3
  14. package/dist/{cat-TSFMZVYS-Lk2fLg0m.cjs.map → cat-TSFMZVYS-CE8iJIL3.cjs.map} +1 -1
  15. package/dist/{cat-TSFMZVYS-BoRCwL0X.mjs → cat-TSFMZVYS-DIffGanR.mjs} +3 -3
  16. package/dist/{cat-TSFMZVYS-BoRCwL0X.mjs.map → cat-TSFMZVYS-DIffGanR.mjs.map} +1 -1
  17. package/dist/{chunk-5H5SCKJM-Bf_pfjgz.cjs → chunk-5H5SCKJM-BqPkrOgR.cjs} +32 -32
  18. package/dist/{chunk-5H5SCKJM-Bf_pfjgz.cjs.map → chunk-5H5SCKJM-BqPkrOgR.cjs.map} +1 -1
  19. package/dist/{chunk-5H5SCKJM-CCkl-6iR.mjs → chunk-5H5SCKJM-CoKwUfnC.mjs} +2 -2
  20. package/dist/{chunk-5H5SCKJM-CCkl-6iR.mjs.map → chunk-5H5SCKJM-CoKwUfnC.mjs.map} +1 -1
  21. package/dist/{chunk-AQ6FYS2X-CaSbvwYS.mjs → chunk-AQ6FYS2X-CdU2NSVs.mjs} +2 -2
  22. package/dist/{chunk-AQ6FYS2X-CaSbvwYS.mjs.map → chunk-AQ6FYS2X-CdU2NSVs.mjs.map} +1 -1
  23. package/dist/{chunk-AQ6FYS2X-C_kf5YCJ.cjs → chunk-AQ6FYS2X-CgExDvHQ.cjs} +3 -3
  24. package/dist/{chunk-AQ6FYS2X-C_kf5YCJ.cjs.map → chunk-AQ6FYS2X-CgExDvHQ.cjs.map} +1 -1
  25. package/dist/{chunk-CHFEPBH4-Bk9Prhxt.mjs → chunk-CHFEPBH4-B8Yle41q.mjs} +2 -2
  26. package/dist/{chunk-CHFEPBH4-Bk9Prhxt.mjs.map → chunk-CHFEPBH4-B8Yle41q.mjs.map} +1 -1
  27. package/dist/{chunk-CHFEPBH4-Cdk9vq_c.cjs → chunk-CHFEPBH4-DkZruhqP.cjs} +3 -3
  28. package/dist/{chunk-CHFEPBH4-Cdk9vq_c.cjs.map → chunk-CHFEPBH4-DkZruhqP.cjs.map} +1 -1
  29. package/dist/{chunk-EBAPSGAO-BPVz-6BX.mjs → chunk-EBAPSGAO-Ba-I7RAs.mjs} +2 -2
  30. package/dist/{chunk-EBAPSGAO-BPVz-6BX.mjs.map → chunk-EBAPSGAO-Ba-I7RAs.mjs.map} +1 -1
  31. package/dist/{chunk-EBAPSGAO-9HAVo6nm.cjs → chunk-EBAPSGAO-CVyFc0vH.cjs} +3 -3
  32. package/dist/{chunk-EBAPSGAO-9HAVo6nm.cjs.map → chunk-EBAPSGAO-CVyFc0vH.cjs.map} +1 -1
  33. package/dist/{chunk-LEKBROJD-Bk_pJfFK.mjs → chunk-LEKBROJD-BCPXdvWw.mjs} +2 -2
  34. package/dist/{chunk-LEKBROJD-Bk_pJfFK.mjs.map → chunk-LEKBROJD-BCPXdvWw.mjs.map} +1 -1
  35. package/dist/{chunk-LEKBROJD-4MTnJXG3.cjs → chunk-LEKBROJD-DEy7k23L.cjs} +17 -17
  36. package/dist/{chunk-LEKBROJD-4MTnJXG3.cjs.map → chunk-LEKBROJD-DEy7k23L.cjs.map} +1 -1
  37. package/dist/{chunk-VPADYNBD-CS9VA1aJ.cjs → chunk-VPADYNBD-BtNErXh7.cjs} +3 -3
  38. package/dist/{chunk-VPADYNBD-CS9VA1aJ.cjs.map → chunk-VPADYNBD-BtNErXh7.cjs.map} +1 -1
  39. package/dist/{chunk-VPADYNBD-Bc5abqkF.mjs → chunk-VPADYNBD-D6W8m472.mjs} +2 -2
  40. package/dist/{chunk-VPADYNBD-Bc5abqkF.mjs.map → chunk-VPADYNBD-D6W8m472.mjs.map} +1 -1
  41. package/dist/{chunk-YCLFEX4T-Cz2QbPh0.mjs → chunk-YCLFEX4T-C5Zm6f-y.mjs} +2 -2
  42. package/dist/{chunk-YCLFEX4T-Cz2QbPh0.mjs.map → chunk-YCLFEX4T-C5Zm6f-y.mjs.map} +1 -1
  43. package/dist/{chunk-YCLFEX4T-D65vwGHr.cjs → chunk-YCLFEX4T-CVuOhI4h.cjs} +3 -3
  44. package/dist/{chunk-YCLFEX4T-D65vwGHr.cjs.map → chunk-YCLFEX4T-CVuOhI4h.cjs.map} +1 -1
  45. package/dist/{column-XT6UFXNQ-BsXqWbAP.mjs → column-XT6UFXNQ-CKR9qK7y.mjs} +2 -2
  46. package/dist/{column-XT6UFXNQ-BsXqWbAP.mjs.map → column-XT6UFXNQ-CKR9qK7y.mjs.map} +1 -1
  47. package/dist/{column-XT6UFXNQ-CwtLFuCh.cjs → column-XT6UFXNQ-CeiWNAzO.cjs} +4 -4
  48. package/dist/{column-XT6UFXNQ-CwtLFuCh.cjs.map → column-XT6UFXNQ-CeiWNAzO.cjs.map} +1 -1
  49. package/dist/{comm-VV2LDX2J-YL8m_4d1.cjs → comm-VV2LDX2J-5awXD4SJ.cjs} +3 -3
  50. package/dist/{comm-VV2LDX2J-YL8m_4d1.cjs.map → comm-VV2LDX2J-5awXD4SJ.cjs.map} +1 -1
  51. package/dist/{comm-VV2LDX2J-BZdS-Fqy.mjs → comm-VV2LDX2J-By6PvRFk.mjs} +2 -2
  52. package/dist/{comm-VV2LDX2J-BZdS-Fqy.mjs.map → comm-VV2LDX2J-By6PvRFk.mjs.map} +1 -1
  53. package/dist/{config-DF8H5mS5.d.mts → config-pCKnlcL-.d.mts} +2 -2
  54. package/dist/config.cjs +1 -1
  55. package/dist/config.d.mts +1 -1
  56. package/dist/config.mjs +1 -1
  57. package/dist/{cp-BISAAS7A-Dx6QG-P9.cjs → cp-BISAAS7A-Cs_viays.cjs} +3 -3
  58. package/dist/{cp-BISAAS7A-Dx6QG-P9.cjs.map → cp-BISAAS7A-Cs_viays.cjs.map} +1 -1
  59. package/dist/{cp-BISAAS7A-C0MVoZpt.mjs → cp-BISAAS7A-McE5zv9m.mjs} +2 -2
  60. package/dist/{cp-BISAAS7A-C0MVoZpt.mjs.map → cp-BISAAS7A-McE5zv9m.mjs.map} +1 -1
  61. package/dist/{cut-OKARJCCV-C1CAocst.cjs → cut-OKARJCCV-CNiRA71s.cjs} +4 -4
  62. package/dist/{cut-OKARJCCV-C1CAocst.cjs.map → cut-OKARJCCV-CNiRA71s.cjs.map} +1 -1
  63. package/dist/{cut-OKARJCCV-BKWEQwCZ.mjs → cut-OKARJCCV-VyVT0kyn.mjs} +3 -3
  64. package/dist/{cut-OKARJCCV-BKWEQwCZ.mjs.map → cut-OKARJCCV-VyVT0kyn.mjs.map} +1 -1
  65. package/dist/{diff-MWJFIG7X-YTniIfbL.mjs → diff-MWJFIG7X-B6ciCjQa.mjs} +2 -2
  66. package/dist/{diff-MWJFIG7X-YTniIfbL.mjs.map → diff-MWJFIG7X-B6ciCjQa.mjs.map} +1 -1
  67. package/dist/{diff-MWJFIG7X-D5nTdPdk.cjs → diff-MWJFIG7X-DJfHAQq4.cjs} +4 -4
  68. package/dist/{diff-MWJFIG7X-D5nTdPdk.cjs.map → diff-MWJFIG7X-DJfHAQq4.cjs.map} +1 -1
  69. package/dist/{dist-C3ioU2dM.cjs → dist-DCerSc01.cjs} +146 -24117
  70. package/dist/dist-DCerSc01.cjs.map +1 -0
  71. package/dist/{dist-CQMZgfp_.mjs → dist-Drb4M1g2.mjs} +11 -23852
  72. package/dist/dist-Drb4M1g2.mjs.map +1 -0
  73. package/dist/{du-572XNP42-CmxmrMJd.mjs → du-572XNP42-B5rNwUSo.mjs} +2 -2
  74. package/dist/{du-572XNP42-CmxmrMJd.mjs.map → du-572XNP42-B5rNwUSo.mjs.map} +1 -1
  75. package/dist/{du-572XNP42-B2vhVgxe.cjs → du-572XNP42-Iv7bX_J6.cjs} +2 -2
  76. package/dist/{du-572XNP42-B2vhVgxe.cjs.map → du-572XNP42-Iv7bX_J6.cjs.map} +1 -1
  77. package/dist/{env-36M5BO7M-Dj2YwzST.cjs → env-36M5BO7M-BcJWF_p3.cjs} +3 -3
  78. package/dist/{env-36M5BO7M-Dj2YwzST.cjs.map → env-36M5BO7M-BcJWF_p3.cjs.map} +1 -1
  79. package/dist/{env-36M5BO7M-DupdD4fz.mjs → env-36M5BO7M-Blzb5FzN.mjs} +2 -2
  80. package/dist/{env-36M5BO7M-DupdD4fz.mjs.map → env-36M5BO7M-Blzb5FzN.mjs.map} +1 -1
  81. package/dist/{expand-JSPG6VOP-BtD3fO-u.mjs → expand-JSPG6VOP-C_wueGj3.mjs} +2 -2
  82. package/dist/{expand-JSPG6VOP-BtD3fO-u.mjs.map → expand-JSPG6VOP-C_wueGj3.mjs.map} +1 -1
  83. package/dist/{expand-JSPG6VOP-C4VQzWfg.cjs → expand-JSPG6VOP-DMhqbYB4.cjs} +3 -3
  84. package/dist/{expand-JSPG6VOP-C4VQzWfg.cjs.map → expand-JSPG6VOP-DMhqbYB4.cjs.map} +1 -1
  85. package/dist/{expr-5JAACS4X-DX-k1Bjo.cjs → expr-5JAACS4X-CDzmynhc.cjs} +5 -5
  86. package/dist/{expr-5JAACS4X-DX-k1Bjo.cjs.map → expr-5JAACS4X-CDzmynhc.cjs.map} +1 -1
  87. package/dist/{expr-5JAACS4X-C75E9ncn.mjs → expr-5JAACS4X-GAOVSam5.mjs} +2 -2
  88. package/dist/{expr-5JAACS4X-C75E9ncn.mjs.map → expr-5JAACS4X-GAOVSam5.mjs.map} +1 -1
  89. package/dist/{find-INTH3OLC-2rIv2Sgt.cjs → find-INTH3OLC-CkFpi26_.cjs} +7 -7
  90. package/dist/{find-INTH3OLC-2rIv2Sgt.cjs.map → find-INTH3OLC-CkFpi26_.cjs.map} +1 -1
  91. package/dist/{find-INTH3OLC-B2oqqlwt.mjs → find-INTH3OLC-DAn3o_TH.mjs} +3 -3
  92. package/dist/{find-INTH3OLC-B2oqqlwt.mjs.map → find-INTH3OLC-DAn3o_TH.mjs.map} +1 -1
  93. package/dist/{fold-4TQNYMSW-DFQEjMsZ.cjs → fold-4TQNYMSW-CgU0z0Lb.cjs} +3 -3
  94. package/dist/{fold-4TQNYMSW-DFQEjMsZ.cjs.map → fold-4TQNYMSW-CgU0z0Lb.cjs.map} +1 -1
  95. package/dist/{fold-4TQNYMSW-DzA5SsAN.mjs → fold-4TQNYMSW-D3z6H_wP.mjs} +2 -2
  96. package/dist/{fold-4TQNYMSW-DzA5SsAN.mjs.map → fold-4TQNYMSW-D3z6H_wP.mjs.map} +1 -1
  97. package/dist/{grep-V3LQVMRQ-D--OXkar.cjs → grep-V3LQVMRQ-BKZqP55P.cjs} +5 -5
  98. package/dist/{grep-V3LQVMRQ-D--OXkar.cjs.map → grep-V3LQVMRQ-BKZqP55P.cjs.map} +1 -1
  99. package/dist/{grep-V3LQVMRQ-CUJiTsKp.mjs → grep-V3LQVMRQ-DsCks6zK.mjs} +4 -4
  100. package/dist/{grep-V3LQVMRQ-CUJiTsKp.mjs.map → grep-V3LQVMRQ-DsCks6zK.mjs.map} +1 -1
  101. package/dist/{gzip-O5ASJAFY-D8i6m9_W.mjs → gzip-O5ASJAFY-BhSGt17k.mjs} +2 -2
  102. package/dist/{gzip-O5ASJAFY-D8i6m9_W.mjs.map → gzip-O5ASJAFY-BhSGt17k.mjs.map} +1 -1
  103. package/dist/{gzip-O5ASJAFY-B3o0_eql.cjs → gzip-O5ASJAFY-CDdmGJoy.cjs} +2 -2
  104. package/dist/{gzip-O5ASJAFY-B3o0_eql.cjs.map → gzip-O5ASJAFY-CDdmGJoy.cjs.map} +1 -1
  105. package/dist/{head-442HYESI-Bztg6Xka.cjs → head-442HYESI-SA3F5DC4.cjs} +2 -2
  106. package/dist/{head-442HYESI-Bztg6Xka.cjs.map → head-442HYESI-SA3F5DC4.cjs.map} +1 -1
  107. package/dist/{head-442HYESI-BDYHKho-.mjs → head-442HYESI-lJuvsyI-.mjs} +2 -2
  108. package/dist/{head-442HYESI-BDYHKho-.mjs.map → head-442HYESI-lJuvsyI-.mjs.map} +1 -1
  109. package/dist/{help-HZ6M2CKN-CFA5POOW.cjs → help-HZ6M2CKN-DF6aW5QI.cjs} +3 -3
  110. package/dist/{help-HZ6M2CKN-CFA5POOW.cjs.map → help-HZ6M2CKN-DF6aW5QI.cjs.map} +1 -1
  111. package/dist/{help-HZ6M2CKN-C95bcvt_.mjs → help-HZ6M2CKN-Ds-v_img.mjs} +2 -2
  112. package/dist/{help-HZ6M2CKN-C95bcvt_.mjs.map → help-HZ6M2CKN-Ds-v_img.mjs.map} +1 -1
  113. package/dist/{html-to-markdown-JW4MSQZO-8YYzjAx0.mjs → html-to-markdown-JW4MSQZO-BKk0AOob.mjs} +3 -2
  114. package/dist/{html-to-markdown-JW4MSQZO-8YYzjAx0.mjs.map → html-to-markdown-JW4MSQZO-BKk0AOob.mjs.map} +1 -1
  115. package/dist/{html-to-markdown-JW4MSQZO-B3xkcb1w.cjs → html-to-markdown-JW4MSQZO-BckwnA2L.cjs} +4 -3
  116. package/dist/{html-to-markdown-JW4MSQZO-B3xkcb1w.cjs.map → html-to-markdown-JW4MSQZO-BckwnA2L.cjs.map} +1 -1
  117. package/dist/{join-TBRGI3LQ-CzBO0uid.cjs → join-TBRGI3LQ-C9BulcHm.cjs} +4 -4
  118. package/dist/{join-TBRGI3LQ-CzBO0uid.cjs.map → join-TBRGI3LQ-C9BulcHm.cjs.map} +1 -1
  119. package/dist/{join-TBRGI3LQ-Cb96ZaTF.mjs → join-TBRGI3LQ-CgQarzOH.mjs} +2 -2
  120. package/dist/{join-TBRGI3LQ-Cb96ZaTF.mjs.map → join-TBRGI3LQ-CgQarzOH.mjs.map} +1 -1
  121. package/dist/{jq-4XLYLOS5-QEF-9JGc.mjs → jq-4XLYLOS5-BYyExpBl.mjs} +4 -4
  122. package/dist/{jq-4XLYLOS5-QEF-9JGc.mjs.map → jq-4XLYLOS5-BYyExpBl.mjs.map} +1 -1
  123. package/dist/{jq-4XLYLOS5-Dmw7PtvC.cjs → jq-4XLYLOS5-D39tJb2U.cjs} +13 -13
  124. package/dist/{jq-4XLYLOS5-Dmw7PtvC.cjs.map → jq-4XLYLOS5-D39tJb2U.cjs.map} +1 -1
  125. package/dist/{js-exec-N5KEZBH7-BLGWy2LA.cjs → js-exec-N5KEZBH7-BJOFfHf8.cjs} +14 -14
  126. package/dist/{js-exec-N5KEZBH7-BLGWy2LA.cjs.map → js-exec-N5KEZBH7-BJOFfHf8.cjs.map} +1 -1
  127. package/dist/{js-exec-N5KEZBH7-DWi8fMhN.mjs → js-exec-N5KEZBH7-DxplSQRT.mjs} +4 -4
  128. package/dist/{js-exec-N5KEZBH7-DWi8fMhN.mjs.map → js-exec-N5KEZBH7-DxplSQRT.mjs.map} +1 -1
  129. package/dist/{lib-C8lgRYXp.mjs → lib-3ViR76Gd.mjs} +2 -2
  130. package/dist/{lib-C8lgRYXp.mjs.map → lib-3ViR76Gd.mjs.map} +1 -1
  131. package/dist/{lib-ux1xJJmr.cjs → lib-JWxj2-D3.cjs} +2 -2
  132. package/dist/{lib-ux1xJJmr.cjs.map → lib-JWxj2-D3.cjs.map} +1 -1
  133. package/dist/{ln-4LGSXXGD-BtA5nI4o.mjs → ln-4LGSXXGD-C78UmFEd.mjs} +2 -2
  134. package/dist/{ln-4LGSXXGD-BtA5nI4o.mjs.map → ln-4LGSXXGD-C78UmFEd.mjs.map} +1 -1
  135. package/dist/{ln-4LGSXXGD-CkQRVPru.cjs → ln-4LGSXXGD-CqxQarhQ.cjs} +3 -3
  136. package/dist/{ln-4LGSXXGD-CkQRVPru.cjs.map → ln-4LGSXXGD-CqxQarhQ.cjs.map} +1 -1
  137. package/dist/{ls-ZJGQER7M-H5DDO7bw.cjs → ls-ZJGQER7M-BY4afQpT.cjs} +2 -2
  138. package/dist/{ls-ZJGQER7M-H5DDO7bw.cjs.map → ls-ZJGQER7M-BY4afQpT.cjs.map} +1 -1
  139. package/dist/{ls-ZJGQER7M-Bm9zc4KC.mjs → ls-ZJGQER7M-DcW0UZMa.mjs} +2 -2
  140. package/dist/{ls-ZJGQER7M-Bm9zc4KC.mjs.map → ls-ZJGQER7M-DcW0UZMa.mjs.map} +1 -1
  141. package/dist/{lzma-CjqgTQ5J.cjs → lzma-BLOYSj5Z.cjs} +8 -8
  142. package/dist/{lzma-CjqgTQ5J.cjs.map → lzma-BLOYSj5Z.cjs.map} +1 -1
  143. package/dist/{lzma-BpK0w-SI.mjs → lzma-DtV0zx4R.mjs} +5 -5
  144. package/dist/{lzma-BpK0w-SI.mjs.map → lzma-DtV0zx4R.mjs.map} +1 -1
  145. package/dist/{md5sum-SPU24VSG-Dqy3agsE.mjs → md5sum-SPU24VSG-BSpePryl.mjs} +3 -3
  146. package/dist/{md5sum-SPU24VSG-Dqy3agsE.mjs.map → md5sum-SPU24VSG-BSpePryl.mjs.map} +1 -1
  147. package/dist/{md5sum-SPU24VSG-B6JGibcS.cjs → md5sum-SPU24VSG-Bm744Cs-.cjs} +3 -3
  148. package/dist/{md5sum-SPU24VSG-B6JGibcS.cjs.map → md5sum-SPU24VSG-Bm744Cs-.cjs.map} +1 -1
  149. package/dist/{mkdir-MEPGZOB6-CMrYu1Ht.mjs → mkdir-MEPGZOB6-B7hdGbmg.mjs} +2 -2
  150. package/dist/{mkdir-MEPGZOB6-CMrYu1Ht.mjs.map → mkdir-MEPGZOB6-B7hdGbmg.mjs.map} +1 -1
  151. package/dist/{mkdir-MEPGZOB6-BFwkd4Z7.cjs → mkdir-MEPGZOB6-D4EkMCni.cjs} +4 -4
  152. package/dist/{mkdir-MEPGZOB6-BFwkd4Z7.cjs.map → mkdir-MEPGZOB6-D4EkMCni.cjs.map} +1 -1
  153. package/dist/{mv-W5BIQ646-hheW03eh.cjs → mv-W5BIQ646-Bt5XMX7z.cjs} +3 -3
  154. package/dist/{mv-W5BIQ646-hheW03eh.cjs.map → mv-W5BIQ646-Bt5XMX7z.cjs.map} +1 -1
  155. package/dist/{mv-W5BIQ646-CWgyAnYE.mjs → mv-W5BIQ646-CSGqJxBv.mjs} +2 -2
  156. package/dist/{mv-W5BIQ646-CWgyAnYE.mjs.map → mv-W5BIQ646-CSGqJxBv.mjs.map} +1 -1
  157. package/dist/{nl-WSDW7I4O-DcVnQp-1.cjs → nl-WSDW7I4O-DRGfkJbS.cjs} +3 -3
  158. package/dist/{nl-WSDW7I4O-DcVnQp-1.cjs.map → nl-WSDW7I4O-DRGfkJbS.cjs.map} +1 -1
  159. package/dist/{nl-WSDW7I4O-hZyrJS6m.mjs → nl-WSDW7I4O-D_yBlUmI.mjs} +2 -2
  160. package/dist/{nl-WSDW7I4O-hZyrJS6m.mjs.map → nl-WSDW7I4O-D_yBlUmI.mjs.map} +1 -1
  161. package/dist/{od-WOKFDJTP-CIGKYa74.cjs → od-WOKFDJTP-Cg03Ruvo.cjs} +3 -3
  162. package/dist/{od-WOKFDJTP-CIGKYa74.cjs.map → od-WOKFDJTP-Cg03Ruvo.cjs.map} +1 -1
  163. package/dist/{od-WOKFDJTP-60QMVWxL.mjs → od-WOKFDJTP-uP7Llgn-.mjs} +2 -2
  164. package/dist/{od-WOKFDJTP-60QMVWxL.mjs.map → od-WOKFDJTP-uP7Llgn-.mjs.map} +1 -1
  165. package/dist/{paste-7JC6S4DX-CC0xWPbo.cjs → paste-7JC6S4DX-CqoX7bst.cjs} +3 -3
  166. package/dist/{paste-7JC6S4DX-CC0xWPbo.cjs.map → paste-7JC6S4DX-CqoX7bst.cjs.map} +1 -1
  167. package/dist/{paste-7JC6S4DX-QB7MigtV.mjs → paste-7JC6S4DX-D6z5xV4U.mjs} +2 -2
  168. package/dist/{paste-7JC6S4DX-QB7MigtV.mjs.map → paste-7JC6S4DX-D6z5xV4U.mjs.map} +1 -1
  169. package/dist/{printf-TWGXF445-bSICkDD6.cjs → printf-TWGXF445-BlK0hMdH.cjs} +6 -5
  170. package/dist/{printf-TWGXF445-BuI_jQx5.mjs.map → printf-TWGXF445-BlK0hMdH.cjs.map} +1 -1
  171. package/dist/{printf-TWGXF445-BuI_jQx5.mjs → printf-TWGXF445-Zy7nN7h0.mjs} +3 -2
  172. package/dist/{printf-TWGXF445-bSICkDD6.cjs.map → printf-TWGXF445-Zy7nN7h0.mjs.map} +1 -1
  173. package/dist/{python3-POMOR4OA-CQv_ljO3.mjs → python3-POMOR4OA-BouZk0El.mjs} +4 -4
  174. package/dist/{python3-POMOR4OA-CQv_ljO3.mjs.map → python3-POMOR4OA-BouZk0El.mjs.map} +1 -1
  175. package/dist/{python3-POMOR4OA-D8YyzdQy.cjs → python3-POMOR4OA-DKcZfsrx.cjs} +23 -23
  176. package/dist/{python3-POMOR4OA-D8YyzdQy.cjs.map → python3-POMOR4OA-DKcZfsrx.cjs.map} +1 -1
  177. package/dist/{rev-5EHFX4EJ-BCHr71Dm.mjs → rev-5EHFX4EJ-B3FQZayg.mjs} +2 -2
  178. package/dist/{rev-5EHFX4EJ-BCHr71Dm.mjs.map → rev-5EHFX4EJ-B3FQZayg.mjs.map} +1 -1
  179. package/dist/{rev-5EHFX4EJ-BS2n_x9V.cjs → rev-5EHFX4EJ-cFYVlRMT.cjs} +4 -4
  180. package/dist/{rev-5EHFX4EJ-BS2n_x9V.cjs.map → rev-5EHFX4EJ-cFYVlRMT.cjs.map} +1 -1
  181. package/dist/{rg-S4FXYXWB-C8PEpvTX.mjs → rg-S4FXYXWB-CKl0cbhA.mjs} +3 -3
  182. package/dist/{rg-S4FXYXWB-C8PEpvTX.mjs.map → rg-S4FXYXWB-CKl0cbhA.mjs.map} +1 -1
  183. package/dist/{rg-S4FXYXWB-Bol68AvR.cjs → rg-S4FXYXWB-Ht7rOUCy.cjs} +10 -10
  184. package/dist/{rg-S4FXYXWB-Bol68AvR.cjs.map → rg-S4FXYXWB-Ht7rOUCy.cjs.map} +1 -1
  185. package/dist/{rm-SSGETQVQ-BPv10nPA.cjs → rm-SSGETQVQ-DHWdd6XE.cjs} +4 -4
  186. package/dist/{rm-SSGETQVQ-BPv10nPA.cjs.map → rm-SSGETQVQ-DHWdd6XE.cjs.map} +1 -1
  187. package/dist/{rm-SSGETQVQ-C1OgRoSu.mjs → rm-SSGETQVQ-fhHj5N9k.mjs} +2 -2
  188. package/dist/{rm-SSGETQVQ-C1OgRoSu.mjs.map → rm-SSGETQVQ-fhHj5N9k.mjs.map} +1 -1
  189. package/dist/{rmdir-OC4ZLPYA-DngaXCWg.cjs → rmdir-OC4ZLPYA-D1NuXPa1.cjs} +3 -3
  190. package/dist/{rmdir-OC4ZLPYA-DngaXCWg.cjs.map → rmdir-OC4ZLPYA-D1NuXPa1.cjs.map} +1 -1
  191. package/dist/{rmdir-OC4ZLPYA-BFuqEQ5J.mjs → rmdir-OC4ZLPYA-DVoEJTP5.mjs} +2 -2
  192. package/dist/{rmdir-OC4ZLPYA-BFuqEQ5J.mjs.map → rmdir-OC4ZLPYA-DVoEJTP5.mjs.map} +1 -1
  193. package/dist/run.cjs +1 -1
  194. package/dist/run.mjs +1 -1
  195. package/dist/{sed-S5UIK574-C8OThvO-.mjs → sed-S5UIK574-2BJSJJLu.mjs} +2 -2
  196. package/dist/{sed-S5UIK574-C8OThvO-.mjs.map → sed-S5UIK574-2BJSJJLu.mjs.map} +1 -1
  197. package/dist/{sed-S5UIK574-CF78rdnK.cjs → sed-S5UIK574-ttFzHdIm.cjs} +27 -27
  198. package/dist/{sed-S5UIK574-CF78rdnK.cjs.map → sed-S5UIK574-ttFzHdIm.cjs.map} +1 -1
  199. package/dist/{sha1sum-2PTOAFR6-C48qu6hM.cjs → sha1sum-2PTOAFR6-BZQuSfLJ.cjs} +3 -3
  200. package/dist/{sha1sum-2PTOAFR6-C48qu6hM.cjs.map → sha1sum-2PTOAFR6-BZQuSfLJ.cjs.map} +1 -1
  201. package/dist/{sha1sum-2PTOAFR6-BgSg3k-0.mjs → sha1sum-2PTOAFR6-DkiDbM7V.mjs} +3 -3
  202. package/dist/{sha1sum-2PTOAFR6-BgSg3k-0.mjs.map → sha1sum-2PTOAFR6-DkiDbM7V.mjs.map} +1 -1
  203. package/dist/{sha256sum-NS7D3IXX-BML40mGR.mjs → sha256sum-NS7D3IXX-CZSi6sUb.mjs} +3 -3
  204. package/dist/{sha256sum-NS7D3IXX-BML40mGR.mjs.map → sha256sum-NS7D3IXX-CZSi6sUb.mjs.map} +1 -1
  205. package/dist/{sha256sum-NS7D3IXX-DTZ34xii.cjs → sha256sum-NS7D3IXX-CeRL0-VH.cjs} +3 -3
  206. package/dist/{sha256sum-NS7D3IXX-DTZ34xii.cjs.map → sha256sum-NS7D3IXX-CeRL0-VH.cjs.map} +1 -1
  207. package/dist/{sleep-X22JJINO-Dy9v8Z4n.cjs → sleep-X22JJINO-BpueuSM3.cjs} +5 -5
  208. package/dist/{sleep-X22JJINO-Dy9v8Z4n.cjs.map → sleep-X22JJINO-BpueuSM3.cjs.map} +1 -1
  209. package/dist/{sleep-X22JJINO-BzDRKdtv.mjs → sleep-X22JJINO-Dq8TwvQ6.mjs} +2 -2
  210. package/dist/{sleep-X22JJINO-BzDRKdtv.mjs.map → sleep-X22JJINO-Dq8TwvQ6.mjs.map} +1 -1
  211. package/dist/{sort-SW2YEO5B-ClyGJwMQ.mjs → sort-SW2YEO5B-C_BUqduL.mjs} +3 -3
  212. package/dist/{sort-SW2YEO5B-ClyGJwMQ.mjs.map → sort-SW2YEO5B-C_BUqduL.mjs.map} +1 -1
  213. package/dist/{sort-SW2YEO5B-DwbO0wml.cjs → sort-SW2YEO5B-DSdbpA5g.cjs} +4 -4
  214. package/dist/{sort-SW2YEO5B-DwbO0wml.cjs.map → sort-SW2YEO5B-DSdbpA5g.cjs.map} +1 -1
  215. package/dist/{split-4KKZZXXE-D3kKToq-.cjs → split-4KKZZXXE-Cfy-caAx.cjs} +3 -3
  216. package/dist/{split-4KKZZXXE-D3kKToq-.cjs.map → split-4KKZZXXE-Cfy-caAx.cjs.map} +1 -1
  217. package/dist/{split-4KKZZXXE-oyZFQtYU.mjs → split-4KKZZXXE-DgpfZxEv.mjs} +2 -2
  218. package/dist/{split-4KKZZXXE-oyZFQtYU.mjs.map → split-4KKZZXXE-DgpfZxEv.mjs.map} +1 -1
  219. package/dist/{sqlite3-CGOEFJAO-BedLxgf_.mjs → sqlite3-CGOEFJAO-B1k5gRse.mjs} +5 -4
  220. package/dist/sqlite3-CGOEFJAO-B1k5gRse.mjs.map +1 -0
  221. package/dist/{sqlite3-CGOEFJAO-DUW1XIou.cjs → sqlite3-CGOEFJAO-B_AeZJOw.cjs} +26 -25
  222. package/dist/sqlite3-CGOEFJAO-B_AeZJOw.cjs.map +1 -0
  223. package/dist/start-CSKzlyiU.cjs +26845 -0
  224. package/dist/start-CSKzlyiU.cjs.map +1 -0
  225. package/dist/start-xmxO-nhn.mjs +26711 -0
  226. package/dist/start-xmxO-nhn.mjs.map +1 -0
  227. package/dist/start.cjs +1 -1
  228. package/dist/start.d.cts +1 -1
  229. package/dist/start.d.mts +2 -2
  230. package/dist/start.mjs +1 -1
  231. package/dist/{strings-6WDHLGMX-DXaUbNpx.mjs → strings-6WDHLGMX-O26XgPLP.mjs} +2 -2
  232. package/dist/{strings-6WDHLGMX-DXaUbNpx.mjs.map → strings-6WDHLGMX-O26XgPLP.mjs.map} +1 -1
  233. package/dist/{strings-6WDHLGMX-5ObhNSGS.cjs → strings-6WDHLGMX-WrYHjmYR.cjs} +2 -2
  234. package/dist/{strings-6WDHLGMX-5ObhNSGS.cjs.map → strings-6WDHLGMX-WrYHjmYR.cjs.map} +1 -1
  235. package/dist/{tac-2STMMJYW-Ov0tcgNn.mjs → tac-2STMMJYW-B3nwHTgj.mjs} +2 -2
  236. package/dist/{tac-2STMMJYW-Ov0tcgNn.mjs.map → tac-2STMMJYW-B3nwHTgj.mjs.map} +1 -1
  237. package/dist/{tac-2STMMJYW-CLSjS7F2.cjs → tac-2STMMJYW-bH0PmIFC.cjs} +2 -2
  238. package/dist/{tac-2STMMJYW-CLSjS7F2.cjs.map → tac-2STMMJYW-bH0PmIFC.cjs.map} +1 -1
  239. package/dist/{tail-R4PCA2C4-C018_ZAk.cjs → tail-R4PCA2C4-CBJsd2wD.cjs} +2 -2
  240. package/dist/{tail-R4PCA2C4-C018_ZAk.cjs.map → tail-R4PCA2C4-CBJsd2wD.cjs.map} +1 -1
  241. package/dist/{tail-R4PCA2C4-KgqykSFz.mjs → tail-R4PCA2C4-t0agG73W.mjs} +2 -2
  242. package/dist/{tail-R4PCA2C4-KgqykSFz.mjs.map → tail-R4PCA2C4-t0agG73W.mjs.map} +1 -1
  243. package/dist/{tar-STHHZTZ6-CCPYnq7u.mjs → tar-STHHZTZ6-nTNd_mUA.mjs} +5 -4
  244. package/dist/{tar-STHHZTZ6-BcBkmdCH.cjs.map → tar-STHHZTZ6-nTNd_mUA.mjs.map} +1 -1
  245. package/dist/{tar-STHHZTZ6-BcBkmdCH.cjs → tar-STHHZTZ6-ol7sffwQ.cjs} +7 -6
  246. package/dist/{tar-STHHZTZ6-CCPYnq7u.mjs.map → tar-STHHZTZ6-ol7sffwQ.cjs.map} +1 -1
  247. package/dist/{tee-YUZ2FKCJ-Cce_gOKf.cjs → tee-YUZ2FKCJ-BItvCSLS.cjs} +2 -2
  248. package/dist/{tee-YUZ2FKCJ-Cce_gOKf.cjs.map → tee-YUZ2FKCJ-BItvCSLS.cjs.map} +1 -1
  249. package/dist/{tee-YUZ2FKCJ-D7LOkjQo.mjs → tee-YUZ2FKCJ-CRnAkzyY.mjs} +2 -2
  250. package/dist/{tee-YUZ2FKCJ-D7LOkjQo.mjs.map → tee-YUZ2FKCJ-CRnAkzyY.mjs.map} +1 -1
  251. package/dist/{time-D4LNBSWX-D9C8_lG9.cjs → time-D4LNBSWX-CRb0M_G6.cjs} +8 -8
  252. package/dist/{time-D4LNBSWX-D9C8_lG9.cjs.map → time-D4LNBSWX-CRb0M_G6.cjs.map} +1 -1
  253. package/dist/{time-D4LNBSWX-CvYHvswI.mjs → time-D4LNBSWX-DQ_s98Uj.mjs} +2 -2
  254. package/dist/{time-D4LNBSWX-CvYHvswI.mjs.map → time-D4LNBSWX-DQ_s98Uj.mjs.map} +1 -1
  255. package/dist/{timeout-YDCRSLPQ-CacPbawx.mjs → timeout-YDCRSLPQ-BffepZAF.mjs} +2 -2
  256. package/dist/{timeout-YDCRSLPQ-CacPbawx.mjs.map → timeout-YDCRSLPQ-BffepZAF.mjs.map} +1 -1
  257. package/dist/{timeout-YDCRSLPQ-Ccs9ipQM.cjs → timeout-YDCRSLPQ-D74y5y7z.cjs} +5 -5
  258. package/dist/{timeout-YDCRSLPQ-Ccs9ipQM.cjs.map → timeout-YDCRSLPQ-D74y5y7z.cjs.map} +1 -1
  259. package/dist/{touch-UA33VN3N-D2ndvYPZ.mjs → touch-UA33VN3N-78TDr_Cd.mjs} +2 -2
  260. package/dist/{touch-UA33VN3N-D2ndvYPZ.mjs.map → touch-UA33VN3N-78TDr_Cd.mjs.map} +1 -1
  261. package/dist/{touch-UA33VN3N-Dxlmlbm_.cjs → touch-UA33VN3N-CP3QIjbf.cjs} +3 -3
  262. package/dist/{touch-UA33VN3N-Dxlmlbm_.cjs.map → touch-UA33VN3N-CP3QIjbf.cjs.map} +1 -1
  263. package/dist/{tr-36LHWFRQ-Bzq2x5-h.cjs → tr-36LHWFRQ-BRvI2dHQ.cjs} +4 -4
  264. package/dist/{tr-36LHWFRQ-Bzq2x5-h.cjs.map → tr-36LHWFRQ-BRvI2dHQ.cjs.map} +1 -1
  265. package/dist/{tr-36LHWFRQ-CWCuChgL.mjs → tr-36LHWFRQ-SA2CA_S1.mjs} +2 -2
  266. package/dist/{tr-36LHWFRQ-CWCuChgL.mjs.map → tr-36LHWFRQ-SA2CA_S1.mjs.map} +1 -1
  267. package/dist/{tree-YLD52CNT-BQipj5RY.cjs → tree-YLD52CNT-C3_lLUpl.cjs} +2 -2
  268. package/dist/{tree-YLD52CNT-BQipj5RY.cjs.map → tree-YLD52CNT-C3_lLUpl.cjs.map} +1 -1
  269. package/dist/{tree-YLD52CNT-CDfF4vcr.mjs → tree-YLD52CNT-KZAShLek.mjs} +2 -2
  270. package/dist/{tree-YLD52CNT-CDfF4vcr.mjs.map → tree-YLD52CNT-KZAShLek.mjs.map} +1 -1
  271. package/dist/{unexpand-CADSA4VO-C4qGbx-B.cjs → unexpand-CADSA4VO-DJB8iOb2.cjs} +3 -3
  272. package/dist/{unexpand-CADSA4VO-C4qGbx-B.cjs.map → unexpand-CADSA4VO-DJB8iOb2.cjs.map} +1 -1
  273. package/dist/{unexpand-CADSA4VO-COvRSVlE.mjs → unexpand-CADSA4VO-QJhpquBs.mjs} +2 -2
  274. package/dist/{unexpand-CADSA4VO-COvRSVlE.mjs.map → unexpand-CADSA4VO-QJhpquBs.mjs.map} +1 -1
  275. package/dist/{uniq-XSIZR6PB-bJo9kdHr.cjs → uniq-XSIZR6PB--zd07u5J.cjs} +4 -4
  276. package/dist/{uniq-XSIZR6PB-bJo9kdHr.cjs.map → uniq-XSIZR6PB--zd07u5J.cjs.map} +1 -1
  277. package/dist/{uniq-XSIZR6PB-C8bN8gfm.mjs → uniq-XSIZR6PB-D8Uw2jAH.mjs} +3 -3
  278. package/dist/{uniq-XSIZR6PB-C8bN8gfm.mjs.map → uniq-XSIZR6PB-D8Uw2jAH.mjs.map} +1 -1
  279. package/dist/{wc-LF7NU4LA-D4xFJZxz.mjs → wc-LF7NU4LA-B-YAlUqD.mjs} +3 -3
  280. package/dist/{wc-LF7NU4LA-D4xFJZxz.mjs.map → wc-LF7NU4LA-B-YAlUqD.mjs.map} +1 -1
  281. package/dist/{wc-LF7NU4LA-NAR5lgIG.cjs → wc-LF7NU4LA-BEMBfNm9.cjs} +4 -4
  282. package/dist/{wc-LF7NU4LA-NAR5lgIG.cjs.map → wc-LF7NU4LA-BEMBfNm9.cjs.map} +1 -1
  283. package/dist/{xan-Y6WF3IRG-D16SQobd.mjs → xan-Y6WF3IRG-ByEdCuAi.mjs} +6 -6
  284. package/dist/{xan-Y6WF3IRG-D16SQobd.mjs.map → xan-Y6WF3IRG-ByEdCuAi.mjs.map} +1 -1
  285. package/dist/{xan-Y6WF3IRG-RigAd0GA.cjs → xan-Y6WF3IRG-DCru93RE.cjs} +11 -11
  286. package/dist/{xan-Y6WF3IRG-RigAd0GA.cjs.map → xan-Y6WF3IRG-DCru93RE.cjs.map} +1 -1
  287. package/dist/{xan-view-HDVKHFC2-pRqYeBi3.cjs → xan-view-HDVKHFC2-BPuiufGQ.cjs} +3 -3
  288. package/dist/{xan-view-HDVKHFC2-pRqYeBi3.cjs.map → xan-view-HDVKHFC2-BPuiufGQ.cjs.map} +1 -1
  289. package/dist/{xan-view-HDVKHFC2-CJ527xHS.mjs → xan-view-HDVKHFC2-HTtRuSIN.mjs} +3 -3
  290. package/dist/{xan-view-HDVKHFC2-CJ527xHS.mjs.map → xan-view-HDVKHFC2-HTtRuSIN.mjs.map} +1 -1
  291. package/dist/{xargs-MGZPH7AX-C0bVMPGM.cjs → xargs-MGZPH7AX-SGQW1zLf.cjs} +4 -4
  292. package/dist/{xargs-MGZPH7AX-C0bVMPGM.cjs.map → xargs-MGZPH7AX-SGQW1zLf.cjs.map} +1 -1
  293. package/dist/{xargs-MGZPH7AX-DWIn3Zwh.mjs → xargs-MGZPH7AX-w2W-Yyzf.mjs} +2 -2
  294. package/dist/{xargs-MGZPH7AX-DWIn3Zwh.mjs.map → xargs-MGZPH7AX-w2W-Yyzf.mjs.map} +1 -1
  295. package/dist/{yq-4QJW3EQG-CSTlai1q.cjs → yq-4QJW3EQG-Cx9pL4eC.cjs} +10 -10
  296. package/dist/{yq-4QJW3EQG-CSTlai1q.cjs.map → yq-4QJW3EQG-Cx9pL4eC.cjs.map} +1 -1
  297. package/dist/{yq-4QJW3EQG-CPcwcHbw.mjs → yq-4QJW3EQG-eornzh5f.mjs} +3 -3
  298. package/dist/{yq-4QJW3EQG-CPcwcHbw.mjs.map → yq-4QJW3EQG-eornzh5f.mjs.map} +1 -1
  299. package/package.json +1 -1
  300. package/dist/dist-C3ioU2dM.cjs.map +0 -1
  301. package/dist/dist-CQMZgfp_.mjs.map +0 -1
  302. package/dist/sqlite3-CGOEFJAO-BedLxgf_.mjs.map +0 -1
  303. package/dist/sqlite3-CGOEFJAO-DUW1XIou.cjs.map +0 -1
  304. package/dist/start-9_8ZcdaU.mjs +0 -2836
  305. package/dist/start-9_8ZcdaU.mjs.map +0 -1
  306. package/dist/start-CBrH4KOb.cjs +0 -2842
  307. package/dist/start-CBrH4KOb.cjs.map +0 -1
@@ -1,2842 +0,0 @@
1
- const require_dist = require("./dist-C3ioU2dM.cjs");
2
- let _keystrokehq_database = require("@keystrokehq/database");
3
- let zod = require("zod");
4
- require("node:path");
5
- require("node:fs");
6
- let node_async_hooks = require("node:async_hooks");
7
- require("node:url");
8
- let _keystrokehq_platform_database = require("@keystrokehq/platform-database");
9
- let _hono_node_server = require("@hono/node-server");
10
- let _keystrokehq_auth = require("@keystrokehq/auth");
11
- let _keystrokehq_runtime = require("@keystrokehq/runtime");
12
- let _keystrokehq_http = require("@keystrokehq/http");
13
- let hono = require("hono");
14
- let resend = require("resend");
15
- //#region ../../packages/manifest/dist/index.mjs
16
- function normalizeWebhookEndpoint(endpoint) {
17
- return endpoint.replace(/^\/+|\/+$/g, "").replace(/^triggers\/?/, "");
18
- }
19
- function webhookRouteFromEndpoint(endpoint) {
20
- const normalized = normalizeWebhookEndpoint(endpoint);
21
- if (!normalized) throw new Error("Webhook endpoint must not be empty");
22
- return `/triggers/${normalized}`;
23
- }
24
- const WORKFLOW = Symbol.for("keystroke.workflow");
25
- function isManifestWorkflow(value) {
26
- if (typeof value !== "object" || value === null) return false;
27
- if (!(WORKFLOW in value) || value[WORKFLOW] !== true) return false;
28
- const workflow = value;
29
- return typeof workflow.slug === "string" && workflow.slug.trim().length > 0 && workflow.input instanceof Object && "safeParse" in workflow.input && workflow.output instanceof Object && "safeParse" in workflow.output;
30
- }
31
- const zodSchema = zod.z.custom((value) => value instanceof zod.z.ZodType, "must be a Zod schema");
32
- const cronScheduleSchema = zod.z.string().trim().min(1, "cron schedule must be a non-empty string");
33
- const workflowSchema = zod.z.custom((value) => isManifestWorkflow(value), "must be defineWorkflow(...)");
34
- const agentSchema = zod.z.custom((value) => typeof value === "object" && value !== null && typeof value.slug === "string" && value.slug.trim().length > 0 && typeof value.prompt === "function", "must be defineAgent(...)");
35
- const promptSchema = zod.z.union([zod.z.string(), zod.z.function()]);
36
- const baseSourceShape = {
37
- key: zod.z.string().trim().min(1),
38
- attach: zod.z.function()
39
- };
40
- const webhookSourceSchema = zod.z.object({
41
- kind: zod.z.literal("webhook"),
42
- ...baseSourceShape,
43
- endpoint: zod.z.string().min(1),
44
- request: zodSchema,
45
- filter: zodSchema.optional(),
46
- passes: zod.z.function()
47
- });
48
- const cronSourceSchema = zod.z.object({
49
- kind: zod.z.literal("cron"),
50
- ...baseSourceShape,
51
- schedule: cronScheduleSchema
52
- });
53
- const pollSourceSchema = zod.z.object({
54
- kind: zod.z.literal("poll"),
55
- ...baseSourceShape,
56
- id: zod.z.string().optional(),
57
- schedule: cronScheduleSchema,
58
- run: zod.z.function(),
59
- filters: zod.z.array(zod.z.function()),
60
- passes: zod.z.function()
61
- });
62
- const triggerSourceSchema = zod.z.discriminatedUnion("kind", [
63
- webhookSourceSchema,
64
- cronSourceSchema,
65
- pollSourceSchema
66
- ]);
67
- const workflowAttachmentSchema = zod.z.object({
68
- key: zod.z.string().trim().min(1),
69
- source: triggerSourceSchema,
70
- target: zod.z.literal("workflow"),
71
- workflow: workflowSchema,
72
- transform: zod.z.function().optional()
73
- });
74
- const agentAttachmentSchema = zod.z.object({
75
- key: zod.z.string().trim().min(1),
76
- source: triggerSourceSchema,
77
- target: zod.z.literal("agent"),
78
- agent: agentSchema,
79
- prompt: promptSchema
80
- });
81
- zod.z.discriminatedUnion("target", [workflowAttachmentSchema, agentAttachmentSchema]);
82
- //#endregion
83
- //#region ../../packages/projects/dist/index.mjs
84
- async function resolveDeployManifest(input) {
85
- if (input.artifactManifest != null) return require_dist.parseStoredRouteManifest(input.artifactManifest);
86
- return require_dist.parseStoredRouteManifest(require_dist.extractRouteManifestFromArtifact(input.artifactBytes));
87
- }
88
- /** Cut over activeArtifactId, then sync org project registry from the artifact manifest. */
89
- async function promoteProjectDeploy(input) {
90
- const project = await (0, _keystrokehq_platform_database.selectProjectById)(input.projectId);
91
- if (!project) throw new Error(`Project ${input.projectId} not found`);
92
- const artifact = await (0, _keystrokehq_platform_database.selectProjectArtifactById)(input.artifactId);
93
- if (!artifact || artifact.projectId !== input.projectId) throw new Error(`Artifact ${input.artifactId} not found for project ${input.projectId}`);
94
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(project.organizationId);
95
- if (!organization) throw new Error(`Organization not found for project ${input.projectId}`);
96
- if (!input.artifactBytes && artifact.manifestJson == null) throw new require_dist.RouteManifestNotFoundError("Artifact has no stored route manifest; rebuild and redeploy");
97
- const manifest = await resolveDeployManifest({
98
- artifactId: input.artifactId,
99
- artifactManifest: artifact.manifestJson,
100
- artifactBytes: input.artifactBytes ?? Buffer.alloc(0)
101
- });
102
- if (artifact.manifestJson == null) await (0, _keystrokehq_platform_database.updateProjectArtifactManifest)({
103
- artifactId: input.artifactId,
104
- manifestJson: manifest
105
- });
106
- if (project.pendingArtifactId === input.artifactId) await (0, _keystrokehq_platform_database.promoteProjectArtifact)({
107
- projectId: input.projectId,
108
- artifactId: input.artifactId
109
- });
110
- else if (project.activeArtifactId !== input.artifactId) throw new Error(`Artifact ${input.artifactId} is not the pending deploy for project ${input.projectId}`);
111
- const ephemeralRoutes = [];
112
- await (0, _keystrokehq_database.runWithProjectDatabase)({
113
- url: (0, _keystrokehq_platform_database.resolveOrgDatabaseUrl)(organization),
114
- searchPath: organization.dbSchema
115
- }, async () => (0, _keystrokehq_database.runWithProjectScope)(project.id, async () => {
116
- await (0, _keystrokehq_runtime.syncRegistryFromStoredManifest)(manifest);
117
- const byRoute = /* @__PURE__ */ new Map();
118
- for (const row of await (0, _keystrokehq_database.selectEphemeralTriggerAttachments)()) {
119
- if (row.source.kind !== "webhook") continue;
120
- const route = webhookRouteFromEndpoint(row.source.endpoint);
121
- byRoute.set(route, [...byRoute.get(route) ?? [], row.slug]);
122
- }
123
- for (const [route, attachmentKeys] of byRoute) ephemeralRoutes.push({
124
- route,
125
- attachmentKeys
126
- });
127
- }));
128
- const webhookRoutes = [...(0, _keystrokehq_runtime.extractWebhookRoutesFromManifest)(manifest), ...ephemeralRoutes];
129
- if (webhookRoutes.length > 0) await (0, _keystrokehq_platform_database.ensureWebhookApiKeys)(project.id, webhookRoutes, project.id);
130
- }
131
- /** True when a project still needs an org worker rebuild after a runtime job finishes. */
132
- function projectNeedsRuntimeFollowUp(project) {
133
- if (project.status === "starting" && project.pendingArtifactId) return true;
134
- if (project.pendingArtifactId && project.activeArtifactId !== project.pendingArtifactId) return true;
135
- return false;
136
- }
137
- let runtimeQueue;
138
- let runtimeQueueInit;
139
- let runtimeSchedulerPlugin;
140
- function configureProjectRuntimeScheduler(plugin) {
141
- runtimeSchedulerPlugin = plugin;
142
- runtimeQueue = void 0;
143
- runtimeQueueInit = void 0;
144
- }
145
- async function getOrgRuntimeQueue() {
146
- if (runtimeQueue) return runtimeQueue;
147
- if (!runtimeQueueInit) runtimeQueueInit = (async () => {
148
- const queue = await require_dist.createJobQueue({
149
- scope: "platform",
150
- plugin: runtimeSchedulerPlugin ?? require_dist.defaultSchedulerPlugin()
151
- });
152
- runtimeQueue = queue;
153
- return queue;
154
- })();
155
- return runtimeQueueInit;
156
- }
157
- function toOrgRuntimeJob(payload) {
158
- const job = payload.payload;
159
- if (!job?.organizationId) throw new Error("Invalid org runtime job payload");
160
- return {
161
- organizationId: job.organizationId,
162
- triggerProjectId: job.triggerProjectId,
163
- triggerArtifactId: job.triggerArtifactId
164
- };
165
- }
166
- async function resolveOrgProjects(job) {
167
- const projects = await (0, _keystrokehq_platform_database.selectProjectsByOrganizationId)(job.organizationId);
168
- const deploys = [];
169
- for (const project of projects) {
170
- const artifactId = project.id === job.triggerProjectId && job.triggerArtifactId ? job.triggerArtifactId : project.pendingArtifactId ?? project.activeArtifactId;
171
- if (!artifactId) continue;
172
- const artifact = await (0, _keystrokehq_platform_database.selectProjectArtifactById)(artifactId);
173
- if (!artifact || artifact.projectId !== project.id || artifact.status !== "ready") {
174
- if (project.id === job.triggerProjectId) throw new Error(`Project ${project.id} pending artifact is not ready`);
175
- continue;
176
- }
177
- deploys.push({
178
- projectId: project.id,
179
- name: project.name,
180
- artifactId,
181
- artifactStorageKey: artifact.storageKey
182
- });
183
- }
184
- if (deploys.length === 0) throw new Error(`Organization ${job.organizationId} has no deployable projects`);
185
- return deploys;
186
- }
187
- async function orgNeedsRuntimeFollowUp(organizationId) {
188
- return (await (0, _keystrokehq_platform_database.selectProjectsByOrganizationId)(organizationId)).some(projectNeedsRuntimeFollowUp);
189
- }
190
- async function enqueueOrgRuntime(job) {
191
- return (await getOrgRuntimeQueue()).enqueue({
192
- kind: "runtime",
193
- targetId: job.organizationId,
194
- runId: crypto.randomUUID(),
195
- trigger: "api",
196
- payload: job,
197
- maxAttempts: 5,
198
- dedupeKey: job.organizationId
199
- });
200
- }
201
- async function enqueueProjectRuntime(job) {
202
- const project = await (0, _keystrokehq_platform_database.selectProjectById)(job.projectId);
203
- if (!project) throw new Error(`Project ${job.projectId} not found`);
204
- return enqueueOrgRuntime({
205
- organizationId: project.organizationId,
206
- triggerProjectId: job.projectId,
207
- triggerArtifactId: job.artifactId
208
- });
209
- }
210
- async function destroyOrgRuntime(runtime, input, runtimeId) {
211
- if (!runtime.destroy) return;
212
- try {
213
- await runtime.destroy({
214
- runtimeId,
215
- hosting: input.hosting
216
- });
217
- } catch (destroyError) {
218
- console.error(`[org.runtime] failed to destroy runtime ${runtimeId}`, destroyError);
219
- }
220
- }
221
- async function handleOrgRuntimeJob(runtime, resolveStartInput, payload) {
222
- if (payload.kind !== "runtime") return;
223
- const job = toOrgRuntimeJob(payload);
224
- try {
225
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(job.organizationId);
226
- if (!organization) throw new Error(`Organization ${job.organizationId} not found`);
227
- const projects = await resolveOrgProjects(job);
228
- const input = await resolveStartInput(job);
229
- const mergedInput = {
230
- ...input,
231
- organizationId: job.organizationId,
232
- projects,
233
- previousRuntimeId: input.previousRuntimeId ?? organization.runtimeId
234
- };
235
- let result;
236
- try {
237
- result = await runtime.start(mergedInput);
238
- for (const project of projects) {
239
- await promoteProjectDeploy({
240
- projectId: project.projectId,
241
- artifactId: project.artifactId,
242
- baseUrl: result.baseUrl
243
- });
244
- await (0, _keystrokehq_platform_database.updateProjectActive)(project.projectId, {
245
- baseUrl: result.baseUrl,
246
- runtimeId: result.runtimeId
247
- });
248
- }
249
- await (0, _keystrokehq_platform_database.updateOrganizationActive)(job.organizationId, {
250
- baseUrl: result.baseUrl,
251
- runtimeId: result.runtimeId
252
- });
253
- if (mergedInput.previousRuntimeId) await destroyOrgRuntime(runtime, mergedInput, mergedInput.previousRuntimeId);
254
- if (await orgNeedsRuntimeFollowUp(job.organizationId)) await enqueueOrgRuntime({ organizationId: job.organizationId });
255
- } catch (error) {
256
- if (result) await destroyOrgRuntime(runtime, mergedInput, result.runtimeId);
257
- throw error;
258
- }
259
- } catch (error) {
260
- console.error(`[org.runtime] ${job.organizationId} failed`, error);
261
- if (payload.exhaustedRetries) await (0, _keystrokehq_platform_database.updateOrganizationFailed)(job.organizationId, "Org runtime failed after retries");
262
- throw error;
263
- }
264
- }
265
- async function startProjectRuntimeWorker(runtime, options = {}) {
266
- const queue = await getOrgRuntimeQueue();
267
- const resolveStartInput = options.resolveStartInput ?? (async (job) => {
268
- throw new Error(`Org runtime for ${job.organizationId} requires resolveStartInput with database credentials`);
269
- });
270
- await queue.startWorker(async (payload) => {
271
- await handleOrgRuntimeJob(runtime, resolveStartInput, payload);
272
- });
273
- }
274
- //#endregion
275
- //#region src/auth/mount.ts
276
- function mountAuth(app, auth) {
277
- app.on(["POST", "GET"], _keystrokehq_auth.AUTH_API_PATH, (c) => (0, _keystrokehq_auth.handleAuthRequest)(auth, c.req.raw));
278
- }
279
- //#endregion
280
- //#region ../../packages/access-control/dist/index.mjs
281
- const apiKeysActions = {
282
- read: "apiKeys:read",
283
- create: "apiKeys:create"
284
- };
285
- const apiKeysGrants = Object.values(apiKeysActions);
286
- const apiKeysRoleGrants = {
287
- owner: [apiKeysActions.read, apiKeysActions.create],
288
- admin: [apiKeysActions.read, apiKeysActions.create],
289
- builder: [apiKeysActions.create]
290
- };
291
- const organizationActions = {
292
- update: "organization:update",
293
- delete: "organization:delete"
294
- };
295
- const organizationGrants = Object.values(organizationActions);
296
- const organizationRoleGrants = {
297
- owner: [organizationActions.update, organizationActions.delete],
298
- admin: [organizationActions.update],
299
- builder: []
300
- };
301
- const userActions = {
302
- manage: "users:manage",
303
- invite: "users:invite"
304
- };
305
- const userGrants = Object.values(userActions);
306
- const userRoleGrants = {
307
- owner: [userActions.manage, userActions.invite],
308
- admin: [userActions.manage, userActions.invite],
309
- builder: [userActions.invite]
310
- };
311
- /** Role ceiling: which roles each inviter may grant. Owner is never invitable (shared schema). */
312
- const invitableRolesByRole = {
313
- owner: ["admin", "builder"],
314
- admin: ["admin", "builder"],
315
- builder: ["builder"]
316
- };
317
- function canInviteRole(inviter, invited) {
318
- return invitableRolesByRole[inviter].includes(invited);
319
- }
320
- function mergeRoleGrants(role) {
321
- return [
322
- ...organizationRoleGrants[role],
323
- ...userRoleGrants[role],
324
- ...apiKeysRoleGrants[role]
325
- ];
326
- }
327
- const orgRolePermissions = {
328
- owner: mergeRoleGrants("owner"),
329
- admin: mergeRoleGrants("admin"),
330
- builder: mergeRoleGrants("builder")
331
- };
332
- const projectActions = {
333
- read: "project:read",
334
- deploy: "project:deploy",
335
- update: "project:update",
336
- delete: "project:delete",
337
- manageMembers: "project:manage-members",
338
- invite: "project:invite"
339
- };
340
- const projectGrants = Object.values(projectActions);
341
- const projectRoleGrants = {
342
- admin: Object.values(projectActions),
343
- builder: [projectActions.read, projectActions.deploy]
344
- };
345
- const orgAdminRoles = new Set(["owner", "admin"]);
346
- const projectActionSet = new Set(projectGrants);
347
- function isProjectAction(action) {
348
- return projectActionSet.has(action);
349
- }
350
- function checkPermission(action, ctx) {
351
- if (isProjectAction(action)) {
352
- if (orgAdminRoles.has(ctx.orgRole)) return true;
353
- return ctx.projectRole != null && projectRoleGrants[ctx.projectRole].includes(action);
354
- }
355
- return orgRolePermissions[ctx.orgRole].includes(action);
356
- }
357
- function projectListScope(ctx) {
358
- return checkPermission(projectActions.read, ctx) ? { kind: "all" } : { kind: "member-only" };
359
- }
360
- function canReadProject(ctx, hasMembership) {
361
- return checkPermission(projectActions.read, ctx) || hasMembership;
362
- }
363
- const agentListScope = projectListScope;
364
- const canAccessAgent = canReadProject;
365
- function canRevokeApiKey(ctx, input) {
366
- return input.userId === input.createdByUserId || checkPermission(userActions.manage, ctx);
367
- }
368
- function apiKeyListScope(ctx) {
369
- return checkPermission(apiKeysActions.read, ctx) ? { kind: "all" } : { kind: "creator-only" };
370
- }
371
- function canReadApiKey(ctx, input) {
372
- return checkPermission(apiKeysActions.read, ctx) || input.userId === input.createdByUserId;
373
- }
374
- [
375
- ...organizationGrants,
376
- ...userGrants,
377
- ...apiKeysGrants,
378
- ...projectGrants
379
- ];
380
- const historyListScope = projectListScope;
381
- const canAccessHistoryRun = canReadProject;
382
- function canInviteToProject(ctx, settings, invitedRole) {
383
- if (!(checkPermission(projectActions.invite, ctx) || settings.invitePermission === "all" && ctx.projectRole === "builder")) return false;
384
- if (checkPermission(projectActions.manageMembers, ctx)) return true;
385
- return invitedRole === "builder";
386
- }
387
- const skillListScope = projectListScope;
388
- const canAccessSkill = canReadProject;
389
- const workflowListScope = projectListScope;
390
- const canAccessWorkflow = canReadProject;
391
- //#endregion
392
- //#region src/auth/access-context.ts
393
- function accessContext(c) {
394
- const organization = c.get("organization");
395
- const projectMember = c.get("projectMember");
396
- return {
397
- orgRole: organization.role,
398
- projectRole: projectMember?.role
399
- };
400
- }
401
- function getProjectInvitePermission(c) {
402
- return c.get("project").invitePermission;
403
- }
404
- //#endregion
405
- //#region ../../packages/http/dist/require-session-BLPGA50N.mjs
406
- function resolveActiveOrganizationId(c) {
407
- const header = c.req.header(require_dist.ACTIVE_ORG_HEADER)?.trim();
408
- if (header) return header;
409
- return c.get("apiKeyAuth")?.organizationId;
410
- }
411
- async function resolveOrganizationContext(c) {
412
- const organizationId = resolveActiveOrganizationId(c);
413
- if (!organizationId) return {
414
- ok: false,
415
- response: c.json(require_dist.ErrorResponseSchema.parse({
416
- error: "Select an organization to continue",
417
- code: "needs_org_selection"
418
- }), 409)
419
- };
420
- const apiKeyAuth = c.get("apiKeyAuth");
421
- if (apiKeyAuth && apiKeyAuth.organizationId !== organizationId) return {
422
- ok: false,
423
- response: c.json(require_dist.ErrorResponseSchema.parse({ error: "Forbidden" }), 403)
424
- };
425
- const membership = await (0, _keystrokehq_platform_database.selectUserOrganizationMembership)(c.get("user").id, organizationId);
426
- if (!membership) return {
427
- ok: false,
428
- response: c.json(require_dist.ErrorResponseSchema.parse({ error: "Forbidden" }), 403)
429
- };
430
- return {
431
- ok: true,
432
- organization: {
433
- organizationId: membership.organization.id,
434
- organizationName: membership.organization.name,
435
- role: membership.role
436
- }
437
- };
438
- }
439
- function requireOrganization() {
440
- return async (c, next) => {
441
- const resolved = await resolveOrganizationContext(c);
442
- if (!resolved.ok) return resolved.response;
443
- c.set("organization", resolved.organization);
444
- await next();
445
- };
446
- }
447
- function requireProject() {
448
- return async (c, next) => {
449
- const organization = c.get("organization");
450
- const projectId = c.req.param("projectId")?.trim();
451
- if (!projectId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Project id is required" }), 400);
452
- const [project, organizationRow] = await Promise.all([(0, _keystrokehq_platform_database.selectProjectForOrganization)(organization.organizationId, projectId), (0, _keystrokehq_platform_database.selectOrganizationById)(organization.organizationId)]);
453
- if (!project) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Project not found" }), 404);
454
- if (!organizationRow) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Organization not found" }), 404);
455
- c.set("project", project);
456
- await (0, _keystrokehq_platform_database.runWithWorkspaceContext)({
457
- organizationId: organization.organizationId,
458
- role: organization.role,
459
- projectId: project.id,
460
- dbSchema: organizationRow.dbSchema
461
- }, () => next());
462
- };
463
- }
464
- function routeProject(project) {
465
- return require_dist.mapProject(project);
466
- }
467
- function forbidden(c) {
468
- return c.json(require_dist.ErrorResponseSchema.parse({ error: "Forbidden" }), 403);
469
- }
470
- function notFound(c, message = "Not found") {
471
- return c.json(require_dist.ErrorResponseSchema.parse({ error: message }), 404);
472
- }
473
- function requireProjectMembership() {
474
- return async (c, next) => {
475
- const { role: orgRole } = c.get("organization");
476
- const project = c.get("project");
477
- if (checkPermission(projectActions.read, { orgRole })) {
478
- await next();
479
- return;
480
- }
481
- const membership = await (0, _keystrokehq_platform_database.selectUserProjectMembership)(c.get("user").id, project.id);
482
- if (!membership) return notFound(c, "Project not found");
483
- c.set("projectMember", { role: membership.role });
484
- await next();
485
- };
486
- }
487
- function sessionFromApiKeyUser(user, token) {
488
- return {
489
- user: {
490
- id: user.id,
491
- email: user.email,
492
- name: user.name,
493
- image: user.image ?? null,
494
- emailVerified: user.emailVerified,
495
- createdAt: user.createdAt,
496
- updatedAt: user.updatedAt
497
- },
498
- session: {
499
- id: user.id,
500
- userId: user.id,
501
- token,
502
- expiresAt: new Date(Date.now() + 900 * 1e3),
503
- createdAt: /* @__PURE__ */ new Date(),
504
- updatedAt: /* @__PURE__ */ new Date()
505
- }
506
- };
507
- }
508
- function requireSession(jwtVerifier) {
509
- const verifier = jwtVerifier ?? (0, _keystrokehq_auth.createDefaultAuthJwtVerifier)();
510
- return async (c, next) => {
511
- const result = await (0, _keystrokehq_auth.resolveRequestAuth)(verifier, c.req.raw.headers);
512
- if (result) {
513
- c.set("user", result.user);
514
- c.set("session", result.session);
515
- await next();
516
- return;
517
- }
518
- const apiKeySecret = (0, _keystrokehq_auth.extractWebhookApiKeyFromRequest)(c.req.raw);
519
- if (apiKeySecret) {
520
- const verified = await (0, _keystrokehq_platform_database.verifyOrgPlatformApiKeySecret)(apiKeySecret);
521
- if (verified) {
522
- const user = await (0, _keystrokehq_platform_database.loadOrgPlatformApiKeyUser)(verified.userId);
523
- if (user) {
524
- const session = sessionFromApiKeyUser(user, apiKeySecret);
525
- c.set("user", session.user);
526
- c.set("session", session.session);
527
- c.set("apiKeyAuth", {
528
- apiKeyId: verified.apiKeyId,
529
- organizationId: verified.organizationId
530
- });
531
- await next();
532
- return;
533
- }
534
- }
535
- }
536
- return c.json({ error: "Unauthorized" }, 401);
537
- };
538
- }
539
- //#endregion
540
- //#region src/auth/authorize.ts
541
- function authorize(action) {
542
- return async (c, next) => {
543
- if (!checkPermission(action, accessContext(c))) return forbidden(c);
544
- await next();
545
- };
546
- }
547
- //#endregion
548
- //#region src/auth/authorize-payload.ts
549
- function authorizePayload(schema, allow) {
550
- return async (c, next) => {
551
- const parsed = schema.safeParse(await c.req.json().catch(() => null));
552
- if (parsed.success && !allow({
553
- c,
554
- ctx: accessContext(c),
555
- body: parsed.data
556
- })) return forbidden(c);
557
- await next();
558
- };
559
- }
560
- //#endregion
561
- //#region src/auth/require-organization-param.ts
562
- function requireOrganizationParam() {
563
- return async (c, next) => {
564
- const organizationId = c.req.param("organizationId")?.trim();
565
- if (!organizationId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Organization id is required" }), 400);
566
- const membership = await (0, _keystrokehq_platform_database.selectUserOrganizationMembership)(c.get("user").id, organizationId);
567
- if (!membership) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Forbidden" }), 403);
568
- c.set("organization", {
569
- organizationId: membership.organization.id,
570
- organizationName: membership.organization.name,
571
- role: membership.role
572
- });
573
- await next();
574
- };
575
- }
576
- //#endregion
577
- //#region ../../packages/http/dist/with-public-project-runtime-B7hmgjbi.mjs
578
- const requestBackgroundTasks = new node_async_hooks.AsyncLocalStorage();
579
- function runWithRequestBackgroundTasks(fn) {
580
- return requestBackgroundTasks.run([], fn);
581
- }
582
- function deferRequestBackgroundTask(task) {
583
- const tasks = requestBackgroundTasks.getStore();
584
- if (!tasks) return;
585
- tasks.push(task);
586
- }
587
- async function flushRequestBackgroundTasks() {
588
- const tasks = requestBackgroundTasks.getStore() ?? [];
589
- await Promise.allSettled(tasks);
590
- }
591
- /** Org DB connection options for `@keystrokehq/database` project scope (pg schema vs sqlite file). */
592
- function resolveOrgProjectDatabaseOptions(organization) {
593
- const url = (0, _keystrokehq_platform_database.resolveOrgDatabaseUrl)(organization);
594
- if ((0, _keystrokehq_database.inferDialect)(url) === "postgres") return {
595
- url,
596
- searchPath: organization.dbSchema
597
- };
598
- return { url };
599
- }
600
- /** Bind the org's shared Postgres schema (all projects in the org use this DB). */
601
- function withOrganizationProjectDatabase() {
602
- return async (c, next) => {
603
- const { organizationId } = c.get("organization");
604
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationId);
605
- if (!organization) return c.json({ error: "Organization not found" }, 404);
606
- const dbOptions = resolveOrgProjectDatabaseOptions(organization);
607
- await (0, _keystrokehq_platform_database.runWithOrganizationScope)(organizationId, () => (0, _keystrokehq_database.runWithProjectDatabase)(dbOptions, () => (0, _keystrokehq_database.runWithTenantScope)(organizationId, () => runWithRequestBackgroundTasks(async () => {
608
- await next();
609
- await flushRequestBackgroundTasks();
610
- }))));
611
- };
612
- }
613
- //#endregion
614
- //#region src/routes/account/users/me/avatar/GET.ts
615
- const handler$63 = async (c) => {
616
- const dbUser = await (0, _keystrokehq_platform_database.selectUserById)(c.get("user").id);
617
- if (!dbUser) return c.json(require_dist.ErrorResponseSchema.parse({ error: "User not found" }), 404);
618
- return c.json(require_dist.UserAvatarSchema.parse({ url: dbUser.image ?? null }));
619
- };
620
- //#endregion
621
- //#region src/lib/user-avatar-content-type.ts
622
- const ALLOWED_AVATAR_CONTENT_TYPES = {
623
- "image/jpeg": "jpg",
624
- "image/jpg": "jpg",
625
- "image/png": "png",
626
- "image/webp": "webp",
627
- "image/gif": "gif"
628
- };
629
- function avatarExtensionForContentType(contentType) {
630
- return ALLOWED_AVATAR_CONTENT_TYPES[contentType.split(";")[0]?.trim().toLowerCase() ?? ""] ?? null;
631
- }
632
- //#endregion
633
- //#region src/routes/account/users/me/avatar/presign/POST.ts
634
- const handler$62 = async (c) => {
635
- const parsed = require_dist.PresignUserAvatarRequestSchema.safeParse(await c.req.json().catch(() => null));
636
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid avatar upload request" }), 400);
637
- const extension = avatarExtensionForContentType(parsed.data.contentType);
638
- if (!extension) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Unsupported image type" }), 400);
639
- const storageKey = require_dist.userAvatarStorageKey(c.get("user").id, extension);
640
- const uploadUrl = await require_dist.createAssetsStorageClient().presignPut({
641
- key: storageKey,
642
- contentType: parsed.data.contentType
643
- });
644
- return c.json(require_dist.PresignUserAvatarResponseSchema.parse({
645
- uploadUrl,
646
- storageKey
647
- }));
648
- };
649
- //#endregion
650
- //#region src/lib/stored-image.ts
651
- async function finalizeStoredImageUpload(input) {
652
- if (!input.isValidStorageKey(input.storageKey)) return {
653
- ok: false,
654
- error: "Invalid storage key"
655
- };
656
- const head = await input.storage.headObject(input.storageKey);
657
- if (!head || head.contentLength <= 0) return {
658
- ok: false,
659
- error: "Upload not found"
660
- };
661
- return {
662
- ok: true,
663
- publicUrl: input.buildPublicUrl(input.storageKey)
664
- };
665
- }
666
- async function deleteStoredImageIfOwned(input) {
667
- if (!input.url || !input.isOwnedPublicUrl(input.url)) return;
668
- const key = input.keyFromPublicUrl(input.url);
669
- if (!key) return;
670
- await input.storage.deleteObject(key).catch(() => void 0);
671
- }
672
- //#endregion
673
- //#region src/routes/account/users/me/avatar/PATCH.ts
674
- const handler$61 = async (c) => {
675
- const parsed = require_dist.UserAvatarPatchSchema.safeParse(await c.req.json().catch(() => null));
676
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid avatar update" }), 400);
677
- const user = c.get("user");
678
- const dbUser = await (0, _keystrokehq_platform_database.selectUserById)(user.id);
679
- if (!dbUser) return c.json(require_dist.ErrorResponseSchema.parse({ error: "User not found" }), 404);
680
- const storage = require_dist.createAssetsStorageClient();
681
- const { storageKey } = parsed.data;
682
- if (storageKey === null) {
683
- await deleteStoredImageIfOwned({
684
- storage,
685
- url: dbUser.image,
686
- isOwnedPublicUrl: require_dist.isKeystrokeAssetsAvatarPublicUrl,
687
- keyFromPublicUrl: require_dist.keystrokeAssetsAvatarKeyFromPublicUrl
688
- });
689
- await (0, _keystrokehq_platform_database.updateUserById)(user.id, {
690
- image: null,
691
- updatedAt: /* @__PURE__ */ new Date()
692
- });
693
- return c.json(require_dist.UserAvatarSchema.parse({ url: null }));
694
- }
695
- const finalized = await finalizeStoredImageUpload({
696
- storage,
697
- storageKey,
698
- isValidStorageKey: (key) => require_dist.isUserAvatarStorageKey(key, user.id),
699
- buildPublicUrl: require_dist.publicKeystrokeAssetsObjectUrl
700
- });
701
- if (!finalized.ok) return c.json(require_dist.ErrorResponseSchema.parse({ error: finalized.error }), 400);
702
- if (dbUser.image && dbUser.image !== finalized.publicUrl) await deleteStoredImageIfOwned({
703
- storage,
704
- url: dbUser.image,
705
- isOwnedPublicUrl: require_dist.isKeystrokeAssetsAvatarPublicUrl,
706
- keyFromPublicUrl: require_dist.keystrokeAssetsAvatarKeyFromPublicUrl
707
- });
708
- await (0, _keystrokehq_platform_database.updateUserById)(user.id, {
709
- image: finalized.publicUrl,
710
- updatedAt: /* @__PURE__ */ new Date()
711
- });
712
- return c.json(require_dist.UserAvatarSchema.parse({ url: finalized.publicUrl }));
713
- };
714
- //#endregion
715
- //#region src/routes/account/users/me/preferences/GET.ts
716
- const handler$60 = async (c) => {
717
- const dbUser = await (0, _keystrokehq_platform_database.selectUserById)(c.get("user").id);
718
- if (!dbUser) return c.json(require_dist.ErrorResponseSchema.parse({ error: "User not found" }), 404);
719
- return c.json(require_dist.UserPreferencesSchema.parse(require_dist.normalizeUserPreferences(dbUser.preferences)));
720
- };
721
- //#endregion
722
- //#region src/routes/account/users/me/preferences/PATCH.ts
723
- const handler$59 = async (c) => {
724
- const parsed = require_dist.UserPreferencesPatchSchema.safeParse(await c.req.json().catch(() => null));
725
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid preferences update" }), 400);
726
- const user = c.get("user");
727
- const dbUser = await (0, _keystrokehq_platform_database.selectUserById)(user.id);
728
- if (!dbUser) return c.json(require_dist.ErrorResponseSchema.parse({ error: "User not found" }), 404);
729
- const next = require_dist.mergeUserPreferences(require_dist.normalizeUserPreferences(dbUser.preferences), parsed.data);
730
- await (0, _keystrokehq_platform_database.updateUserById)(user.id, {
731
- preferences: next,
732
- updatedAt: /* @__PURE__ */ new Date()
733
- });
734
- return c.json(require_dist.UserPreferencesSchema.parse(next));
735
- };
736
- //#endregion
737
- //#region src/routes/account/organizations/GET.ts
738
- const handler$58 = async (c) => {
739
- const memberships = await (0, _keystrokehq_platform_database.selectUserOrganizations)(c.get("user").id);
740
- return c.json(require_dist.ListOrganizationsResponseSchema.parse(memberships.map(require_dist.mapUserOrganization)));
741
- };
742
- //#endregion
743
- //#region src/services/create-organization.ts
744
- async function createOrganizationWithHosting(deps, userId, name, preferredSlug) {
745
- const { hosting, storage } = deps;
746
- const identity = await (0, _keystrokehq_platform_database.resolveNewOrganizationIdentity)(name, preferredSlug);
747
- let hostedAppName;
748
- let provisionedStorage;
749
- let organizationPersisted = false;
750
- try {
751
- if (hosting.provisionOrganization) hostedAppName = (await hosting.provisionOrganization({
752
- organizationId: identity.organizationId,
753
- name: name.trim()
754
- })).appName;
755
- provisionedStorage = await storage.provisionOrganization({
756
- organizationId: identity.organizationId,
757
- name: name.trim()
758
- });
759
- const membership = await (0, _keystrokehq_platform_database.createOrganizationForUser)(userId, name, preferredSlug, {
760
- organizationId: identity.organizationId,
761
- slug: identity.slug,
762
- hostingAppName: hostedAppName ?? null,
763
- storage: {
764
- bucket: provisionedStorage.bucket,
765
- endpoint: provisionedStorage.endpoint,
766
- accessKeyIdCiphertext: (0, _keystrokehq_platform_database.encryptCredentialPayload)(provisionedStorage.accessKeyId),
767
- secretAccessKeyCiphertext: (0, _keystrokehq_platform_database.encryptCredentialPayload)(provisionedStorage.secretAccessKey),
768
- region: provisionedStorage.region ?? null,
769
- forcePathStyle: provisionedStorage.forcePathStyle ?? null
770
- }
771
- });
772
- organizationPersisted = true;
773
- await (0, _keystrokehq_runtime.seedOAuthAppsFromEnvForOrganization)(identity.organizationId);
774
- return membership;
775
- } catch (error) {
776
- if (provisionedStorage && !organizationPersisted) {
777
- if (!await (0, _keystrokehq_platform_database.isOrganizationStorageBucketInUse)(provisionedStorage.bucket)) await storage.deprovisionOrganization(provisionedStorage).catch(() => void 0);
778
- }
779
- if (hostedAppName && hosting.deprovisionOrganization) await hosting.deprovisionOrganization({ appName: hostedAppName }).catch(() => void 0);
780
- throw error;
781
- }
782
- }
783
- //#endregion
784
- //#region src/routes/account/organizations/slug-errors.ts
785
- function organizationSlugErrorBody(error) {
786
- if (error instanceof _keystrokehq_platform_database.OrganizationSlugTakenError) return {
787
- error: error.message,
788
- code: "slug_taken"
789
- };
790
- const message = error.issues[0]?.message ?? "Invalid organization slug";
791
- return {
792
- error: message,
793
- code: require_dist.organizationSlugErrorCodeFromMessage(message)
794
- };
795
- }
796
- //#endregion
797
- //#region src/routes/account/organizations/POST.ts
798
- function createOrganizationHandler(deps) {
799
- return async (c) => {
800
- const user = c.get("user");
801
- const body = await c.req.json().catch(() => null);
802
- const parsed = require_dist.CreateOrganizationRequestSchema.safeParse(body);
803
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid organization request" }), 400);
804
- try {
805
- const membership = await createOrganizationWithHosting(deps, user.id, parsed.data.name, parsed.data.slug);
806
- return c.json(require_dist.CreateOrganizationResponseSchema.parse(require_dist.mapUserOrganization(membership)), 201);
807
- } catch (error) {
808
- if (error instanceof _keystrokehq_platform_database.OrganizationSlugTakenError) return c.json(require_dist.ErrorResponseSchema.parse(organizationSlugErrorBody(error)), 409);
809
- if (error instanceof zod.ZodError) return c.json(require_dist.ErrorResponseSchema.parse(organizationSlugErrorBody(error)), 400);
810
- throw error;
811
- }
812
- };
813
- }
814
- //#endregion
815
- //#region src/routes/account/organizations/slug-available/GET.ts
816
- const handler$57 = async (c) => {
817
- const parsed = require_dist.SlugAvailabilityQuerySchema.safeParse({
818
- slug: c.req.query("slug"),
819
- excludeOrganizationId: c.req.query("excludeOrganizationId")
820
- });
821
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid slug query" }), 400);
822
- const availability = await (0, _keystrokehq_platform_database.checkOrganizationSlugAvailability)(parsed.data.slug, parsed.data.excludeOrganizationId);
823
- return c.json(require_dist.SlugAvailabilityResponseSchema.parse(availability));
824
- };
825
- //#endregion
826
- //#region src/routes/account/organizations/[organizationId]/GET.ts
827
- const handler$56 = async (c) => {
828
- const { organizationId } = c.get("organization");
829
- const membership = await (0, _keystrokehq_platform_database.selectUserOrganizationMembership)(c.get("user").id, organizationId);
830
- if (!membership) throw new Error(`Organization membership missing after param guard: ${organizationId}`);
831
- return c.json(require_dist.ActiveOrganizationResponseSchema.parse(require_dist.mapUserOrganization(membership)));
832
- };
833
- //#endregion
834
- //#region src/routes/account/organizations/[organizationId]/PATCH.ts
835
- const handler$55 = async (c) => {
836
- const organization = c.get("organization");
837
- const body = await c.req.json().catch(() => null);
838
- const parsed = require_dist.UpdateOrganizationRequestSchema.safeParse(body);
839
- if (!parsed.success) {
840
- const errorBody = parsed.error.issues.some((issue) => issue.path[0] === "slug") ? organizationSlugErrorBody(parsed.error) : require_dist.validationErrorResponse(parsed.error, "Invalid organization update");
841
- return c.json(require_dist.ErrorResponseSchema.parse(errorBody), 400);
842
- }
843
- try {
844
- let updated;
845
- if (parsed.data.name !== void 0) updated = await (0, _keystrokehq_platform_database.updateOrganizationName)(organization.organizationId, parsed.data.name);
846
- if (parsed.data.slug !== void 0) updated = await (0, _keystrokehq_platform_database.updateOrganizationSlug)(organization.organizationId, parsed.data.slug);
847
- if (!updated) throw new Error(`Organization update produced no result: ${organization.organizationId}`);
848
- return c.json(require_dist.ActiveOrganizationResponseSchema.parse(require_dist.mapUserOrganization({
849
- organization: updated,
850
- role: organization.role
851
- })));
852
- } catch (error) {
853
- if (error instanceof _keystrokehq_platform_database.OrganizationSlugTakenError) return c.json(require_dist.ErrorResponseSchema.parse(organizationSlugErrorBody(error)), 409);
854
- if (error instanceof zod.ZodError) return c.json(require_dist.ErrorResponseSchema.parse(organizationSlugErrorBody(error)), 400);
855
- throw error;
856
- }
857
- };
858
- //#endregion
859
- //#region src/routes/account/organizations/[organizationId]/branding/GET.ts
860
- const handler$54 = async (c) => {
861
- const { organizationId } = c.get("organization");
862
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationId);
863
- if (!organization) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Organization not found" }), 404);
864
- return c.json(require_dist.OrganizationSidebarBrandingSchema.parse((0, _keystrokehq_platform_database.organizationRowToSidebarBranding)(organization)));
865
- };
866
- //#endregion
867
- //#region src/routes/account/organizations/[organizationId]/branding/PATCH.ts
868
- const LOGO_VARIANTS = [{
869
- variant: "light",
870
- storageKeyField: "logoLightStorageKey",
871
- urlField: "logoLightUrl"
872
- }, {
873
- variant: "dark",
874
- storageKeyField: "logoDarkStorageKey",
875
- urlField: "logoDarkUrl"
876
- }];
877
- async function finalizeOrgLogoVariant(input) {
878
- const storage = require_dist.createAssetsStorageClient();
879
- if (input.storageKey === null) {
880
- await deleteStoredImageIfOwned({
881
- storage,
882
- url: input.currentUrl,
883
- isOwnedPublicUrl: require_dist.isKeystrokeAssetsOrgLogoPublicUrl,
884
- keyFromPublicUrl: require_dist.keystrokeAssetsOrgLogoKeyFromPublicUrl
885
- });
886
- return {
887
- ok: true,
888
- publicUrl: null
889
- };
890
- }
891
- const finalized = await finalizeStoredImageUpload({
892
- storage,
893
- storageKey: input.storageKey,
894
- isValidStorageKey: (key) => require_dist.isOrgLogoStorageKey(key, input.organizationId, input.variant),
895
- buildPublicUrl: require_dist.publicKeystrokeAssetsObjectUrl
896
- });
897
- if (!finalized.ok) return finalized;
898
- if (input.currentUrl && input.currentUrl !== finalized.publicUrl) await deleteStoredImageIfOwned({
899
- storage,
900
- url: input.currentUrl,
901
- isOwnedPublicUrl: require_dist.isKeystrokeAssetsOrgLogoPublicUrl,
902
- keyFromPublicUrl: require_dist.keystrokeAssetsOrgLogoKeyFromPublicUrl
903
- });
904
- return {
905
- ok: true,
906
- publicUrl: finalized.publicUrl
907
- };
908
- }
909
- const handler$53 = async (c) => {
910
- const parsed = require_dist.OrganizationSidebarBrandingPatchSchema.safeParse(await c.req.json().catch(() => null));
911
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid branding update" }), 400);
912
- const { organizationId } = c.get("organization");
913
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationId);
914
- if (!organization) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Organization not found" }), 404);
915
- const dbUpdate = {
916
- customLogoEnabled: parsed.data.customLogoEnabled,
917
- customLogoExplicitlyDisabled: parsed.data.customLogoExplicitlyDisabled,
918
- logoHeightPx: parsed.data.logoHeightPx
919
- };
920
- for (const { variant, storageKeyField, urlField } of LOGO_VARIANTS) {
921
- const storageKey = parsed.data[storageKeyField];
922
- if (storageKey === void 0) continue;
923
- const result = await finalizeOrgLogoVariant({
924
- organizationId,
925
- variant,
926
- storageKey,
927
- currentUrl: organization[urlField]
928
- });
929
- if (!result.ok) return c.json(require_dist.ErrorResponseSchema.parse({ error: result.error }), 400);
930
- dbUpdate[urlField] = result.publicUrl;
931
- }
932
- const updated = await (0, _keystrokehq_platform_database.updateOrganizationSidebarBranding)(organizationId, dbUpdate);
933
- return c.json(require_dist.OrganizationSidebarBrandingSchema.parse((0, _keystrokehq_platform_database.organizationRowToSidebarBranding)(updated)));
934
- };
935
- //#endregion
936
- //#region src/routes/account/organizations/[organizationId]/branding/logo/presign/POST.ts
937
- const handler$52 = async (c) => {
938
- const parsed = require_dist.PresignOrgLogoRequestSchema.safeParse(await c.req.json().catch(() => null));
939
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid logo upload request" }), 400);
940
- const extension = avatarExtensionForContentType(parsed.data.contentType);
941
- if (!extension) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Unsupported image type" }), 400);
942
- const { organizationId } = c.get("organization");
943
- const storageKey = require_dist.orgLogoStorageKey(organizationId, parsed.data.variant, extension);
944
- const uploadUrl = await require_dist.createAssetsStorageClient().presignPut({
945
- key: storageKey,
946
- contentType: parsed.data.contentType
947
- });
948
- return c.json(require_dist.PresignOrgLogoResponseSchema.parse({
949
- uploadUrl,
950
- storageKey
951
- }));
952
- };
953
- //#endregion
954
- //#region src/auth/project-access.ts
955
- function adminViewRequested(c) {
956
- return c.req.query("admin") === "true";
957
- }
958
- /** Capability from policy, narrowed by the caller's view preference. */
959
- function listScope(c, capability) {
960
- return adminViewRequested(c) ? capability : { kind: "member-only" };
961
- }
962
- async function grantedProjectIds(c, scope) {
963
- if (scope.kind === "all") return;
964
- const { organizationId } = c.get("organization");
965
- return (0, _keystrokehq_platform_database.selectProjectIdsForUser)(organizationId, c.get("user").id);
966
- }
967
- async function resolveListProjectIds(c, scope, requested) {
968
- const granted = await grantedProjectIds(c, scope);
969
- const projectId = requested?.trim() || void 0;
970
- if (projectId) {
971
- if (granted !== void 0 && !granted.includes(projectId)) return "empty";
972
- return { projectIds: [projectId] };
973
- }
974
- if (granted === void 0) return {};
975
- if (granted.length === 0) return "empty";
976
- return { projectIds: granted };
977
- }
978
- async function canAccessProjectId(c, projectId, check) {
979
- const ctx = accessContext(c);
980
- const granted = await grantedProjectIds(c, projectListScope(ctx));
981
- return check(ctx, granted === void 0 ? false : granted.includes(projectId));
982
- }
983
- //#endregion
984
- //#region src/routes/account/history/enrich.ts
985
- async function resolveHistoryRunActor(ranByUserId) {
986
- if (!ranByUserId) return null;
987
- const user = await (0, _keystrokehq_platform_database.selectUserById)(ranByUserId);
988
- if (!user) return null;
989
- return {
990
- userId: user.id,
991
- name: user.name,
992
- avatarUrl: user.image ?? null
993
- };
994
- }
995
- async function enrichHistoryRun(run, projectNameById) {
996
- const { ranByUserId, ...rest } = run;
997
- return {
998
- ...rest,
999
- projectName: projectNameById.get(run.projectId) ?? "Project",
1000
- ranAs: await resolveHistoryRunActor(ranByUserId)
1001
- };
1002
- }
1003
- async function enrichHistoryRuns(runs, projectNameById) {
1004
- const actorByUserId = /* @__PURE__ */ new Map();
1005
- return Promise.all(runs.map(async (run) => {
1006
- const { ranByUserId, ...rest } = run;
1007
- let ranAs = null;
1008
- if (ranByUserId) {
1009
- if (!actorByUserId.has(ranByUserId)) actorByUserId.set(ranByUserId, await resolveHistoryRunActor(ranByUserId));
1010
- ranAs = actorByUserId.get(ranByUserId) ?? null;
1011
- }
1012
- return {
1013
- ...rest,
1014
- projectName: projectNameById.get(run.projectId) ?? "Project",
1015
- ranAs
1016
- };
1017
- }));
1018
- }
1019
- async function attachRanAsToDetail(detail, ranByUserId) {
1020
- const ranAs = await resolveHistoryRunActor(ranByUserId);
1021
- return {
1022
- ...detail,
1023
- ranAs
1024
- };
1025
- }
1026
- //#endregion
1027
- //#region src/routes/account/history/GET.ts
1028
- const handler$51 = async (c) => {
1029
- const organization = c.get("organization");
1030
- const ctx = accessContext(c);
1031
- const query = require_dist.HistoryRunListQuerySchema.parse({
1032
- project: c.req.query("project")?.trim() || void 0,
1033
- status: c.req.query("status")?.trim() || void 0,
1034
- kind: c.req.query("kind")?.trim() || void 0
1035
- });
1036
- const scope = listScope(c, historyListScope(ctx));
1037
- const filter = await resolveListProjectIds(c, scope, query.project);
1038
- if (filter === "empty") return c.json(require_dist.HistoryRunListResponseSchema.parse([]));
1039
- const runs = await (0, _keystrokehq_database.listHistoryRuns)({
1040
- ...filter,
1041
- ...query.status ? { status: query.status } : {},
1042
- ...query.kind ? { kind: query.kind } : {}
1043
- });
1044
- const grantedProjectIdsList = await grantedProjectIds(c, scope);
1045
- const projects = await (0, _keystrokehq_platform_database.selectProjectsByOrganizationId)(organization.organizationId, { grantedProjectIds: grantedProjectIdsList });
1046
- const historyRuns = await enrichHistoryRuns(runs, new Map(projects.map((project) => [project.id, project.name])));
1047
- return c.json(require_dist.HistoryRunListResponseSchema.parse(historyRuns));
1048
- };
1049
- //#endregion
1050
- //#region src/routes/account/history/[runId]/GET.ts
1051
- const handler$50 = async (c) => {
1052
- const runId = c.req.param("runId") ?? "";
1053
- if (!runId) return c.json(null, 404);
1054
- const core = await (0, _keystrokehq_database.findHistoryRunCore)(runId);
1055
- if (!core || !await canAccessProjectId(c, core.projectId, canAccessHistoryRun)) return c.json(null, 404);
1056
- const detail = await (0, _keystrokehq_database.runWithProjectScope)(core.projectId, async () => {
1057
- if (core.kind === "workflow") {
1058
- const row = await (0, _keystrokehq_database.selectWorkflowRunById)(runId);
1059
- if (!row) return null;
1060
- return (0, _keystrokehq_database.buildHistoryWorkflowRunDetail)(row.workflowSlug, runId);
1061
- }
1062
- const session = await (0, _keystrokehq_database.selectAgentSessionById)(runId);
1063
- if (!session) return null;
1064
- const agent = await (0, _keystrokehq_database.selectActiveAgentById)(session.agentId);
1065
- if (!agent) return null;
1066
- return (0, _keystrokehq_database.buildHistoryAgentSessionDetail)(agent.slug, runId);
1067
- });
1068
- if (!detail) return c.json(null, 404);
1069
- return c.json(require_dist.HistoryRunDetailResponseSchema.parse(await attachRanAsToDetail(detail, core.ranByUserId)));
1070
- };
1071
- //#endregion
1072
- //#region src/routes/account/resources/common.ts
1073
- /** Derive a human display name from a resource slug when no explicit name is stored. */
1074
- function titleCaseKey(slug) {
1075
- const normalized = slug.split(/[/_-]+/).filter(Boolean).join(" ");
1076
- if (!normalized) return require_dist.PLATFORM_RESOURCE_UNSUPPORTED_TEXT;
1077
- return normalized.replace(/\b\w/g, (char) => char.toUpperCase());
1078
- }
1079
- //#endregion
1080
- //#region src/routes/account/resources/agents.ts
1081
- function formatModel(model) {
1082
- if (!model) return;
1083
- return model;
1084
- }
1085
- function toAgentSummary(row, options) {
1086
- return require_dist.AgentSummarySchema.parse({
1087
- id: row.id,
1088
- slug: row.slug,
1089
- name: row.name?.trim() || titleCaseKey(row.slug),
1090
- description: row.description ?? void 0,
1091
- projectId: row.projectId,
1092
- updatedAt: row.updatedAt.toISOString(),
1093
- sourcePath: row.moduleFile,
1094
- model: formatModel(row.model),
1095
- toolCount: row.toolCount ?? void 0,
1096
- credentialCount: row.credentialCount ?? void 0,
1097
- lastRunAt: options?.lastRunAt?.toISOString()
1098
- });
1099
- }
1100
- //#endregion
1101
- //#region src/routes/account/agents/GET.ts
1102
- const handler$49 = async (c) => {
1103
- const filter = await resolveListProjectIds(c, listScope(c, agentListScope(accessContext(c))), c.req.query("projectId"));
1104
- if (filter === "empty") return c.json(require_dist.AgentSummaryListResponseSchema.parse([]));
1105
- const rows = await (0, _keystrokehq_database.listActiveAgents)(filter);
1106
- const lastRunAtById = await (0, _keystrokehq_database.selectAgentLastRunAtByIds)(rows.map((row) => row.id));
1107
- return c.json(require_dist.AgentSummaryListResponseSchema.parse(rows.map((row) => toAgentSummary(row, { lastRunAt: lastRunAtById.get(row.id) ?? null }))));
1108
- };
1109
- //#endregion
1110
- //#region src/routes/account/lib/touch-resource-activity.ts
1111
- function touchResourceActivityBestEffort(options) {
1112
- deferRequestBackgroundTask((0, _keystrokehq_database.touchResourceActivity)(options).catch(() => {}));
1113
- }
1114
- //#endregion
1115
- //#region src/routes/account/agents/[agentId]/GET.ts
1116
- const handler$48 = async (c) => {
1117
- const agentId = c.req.param("agentId") ?? "";
1118
- const row = agentId ? await (0, _keystrokehq_database.selectActiveAgentById)(agentId) : void 0;
1119
- if (!row || !await canAccessProjectId(c, row.projectId, canAccessAgent)) return c.json(require_dist.AgentSummaryDetailResponseSchema.parse(null));
1120
- touchResourceActivityBestEffort({
1121
- userId: c.get("user").id,
1122
- projectId: row.projectId,
1123
- resourceKind: "agent",
1124
- resourceId: row.id
1125
- });
1126
- const lastRunAtById = await (0, _keystrokehq_database.selectAgentLastRunAtByIds)([row.id]);
1127
- return c.json(require_dist.AgentSummaryDetailResponseSchema.parse(toAgentSummary(row, { lastRunAt: lastRunAtById.get(row.id) ?? null })));
1128
- };
1129
- //#endregion
1130
- //#region src/routes/account/history/cancel-run.ts
1131
- /** Shared body for the workflow-run and agent-session cancel endpoints. */
1132
- async function cancelHistoryRun(c, kind, cancel) {
1133
- const organizationContext = c.get("organization");
1134
- const id = c.req.param(kind === "workflow" ? "runId" : "sessionId") ?? "";
1135
- if (!id) return c.json(null, 404);
1136
- const core = await (0, _keystrokehq_database.findHistoryRunCore)(id);
1137
- if (!core || core.kind !== kind) return c.json(null, 404);
1138
- if (!await canAccessProjectId(c, core.projectId, canAccessHistoryRun)) return c.json(null, 404);
1139
- const run = await (0, _keystrokehq_database.runWithProjectScope)(core.projectId, () => cancel(id));
1140
- if (!run) return c.json(null, 404);
1141
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationContext.organizationId);
1142
- if (!organization) return c.json(null, 404);
1143
- await (await (0, _keystrokehq_http.getProjectScheduler)(organization, core.projectId)).publishCancel(id);
1144
- const grantedProjectIdsList = await grantedProjectIds(c, historyListScope(accessContext(c)));
1145
- const projects = await (0, _keystrokehq_platform_database.selectProjectsByOrganizationId)(organizationContext.organizationId, { grantedProjectIds: grantedProjectIdsList });
1146
- const historyRun = await enrichHistoryRun(run, new Map(projects.map((project) => [project.id, project.name])));
1147
- return c.json(require_dist.HistoryRunCancelResponseSchema.parse(historyRun));
1148
- }
1149
- //#endregion
1150
- //#region src/routes/account/agents/sessions/[sessionId]/cancel/POST.ts
1151
- const handler$47 = (c) => cancelHistoryRun(c, "agent", _keystrokehq_database.cancelAgentSession);
1152
- //#endregion
1153
- //#region src/routes/account/resources/workflows.ts
1154
- function toWorkflowSummary(row, options) {
1155
- return require_dist.WorkflowSummarySchema.parse({
1156
- id: row.id,
1157
- slug: row.slug,
1158
- name: row.name?.trim() || titleCaseKey(row.slug),
1159
- description: row.description ?? void 0,
1160
- projectId: row.projectId,
1161
- updatedAt: row.updatedAt.toISOString(),
1162
- sourcePath: row.moduleFile,
1163
- lastRunAt: options?.lastRunAt?.toISOString()
1164
- });
1165
- }
1166
- //#endregion
1167
- //#region src/routes/account/workflows/GET.ts
1168
- const handler$46 = async (c) => {
1169
- const filter = await resolveListProjectIds(c, listScope(c, workflowListScope(accessContext(c))), c.req.query("projectId"));
1170
- if (filter === "empty") return c.json(require_dist.WorkflowSummaryListResponseSchema.parse([]));
1171
- const rows = await (0, _keystrokehq_database.listActiveWorkflows)(filter);
1172
- const lastRunAtById = await (0, _keystrokehq_database.selectWorkflowLastRunAtByIds)(rows.map((row) => row.id));
1173
- return c.json(require_dist.WorkflowSummaryListResponseSchema.parse(rows.map((row) => toWorkflowSummary(row, { lastRunAt: lastRunAtById.get(row.id) ?? null }))));
1174
- };
1175
- //#endregion
1176
- //#region src/routes/account/workflows/[workflowId]/GET.ts
1177
- const handler$45 = async (c) => {
1178
- const workflowId = c.req.param("workflowId") ?? "";
1179
- const row = workflowId ? await (0, _keystrokehq_database.selectActiveWorkflowById)(workflowId) : void 0;
1180
- if (!row || !await canAccessProjectId(c, row.projectId, canAccessWorkflow)) return c.json(require_dist.WorkflowSummaryDetailResponseSchema.parse(null));
1181
- touchResourceActivityBestEffort({
1182
- userId: c.get("user").id,
1183
- projectId: row.projectId,
1184
- resourceKind: "workflow",
1185
- resourceId: row.id
1186
- });
1187
- const lastRunAtById = await (0, _keystrokehq_database.selectWorkflowLastRunAtByIds)([row.id]);
1188
- return c.json(require_dist.WorkflowSummaryDetailResponseSchema.parse(toWorkflowSummary(row, { lastRunAt: lastRunAtById.get(row.id) ?? null })));
1189
- };
1190
- //#endregion
1191
- //#region src/routes/account/workflows/runs/[runId]/cancel/POST.ts
1192
- const handler$44 = (c) => cancelHistoryRun(c, "workflow", _keystrokehq_database.cancelWorkflowRun);
1193
- //#endregion
1194
- //#region src/routes/account/resources/skills.ts
1195
- function toSkillSummary(row) {
1196
- return require_dist.SkillSummarySchema.parse({
1197
- id: row.id,
1198
- slug: row.slug,
1199
- name: row.name?.trim() || titleCaseKey(row.slug),
1200
- description: row.description ?? void 0,
1201
- projectId: row.projectId,
1202
- updatedAt: row.updatedAt.toISOString(),
1203
- sourcePath: row.moduleFile
1204
- });
1205
- }
1206
- //#endregion
1207
- //#region src/routes/account/skills/GET.ts
1208
- const handler$43 = async (c) => {
1209
- const filter = await resolveListProjectIds(c, listScope(c, skillListScope(accessContext(c))), c.req.query("projectId"));
1210
- if (filter === "empty") return c.json(require_dist.SkillSummaryListResponseSchema.parse([]));
1211
- const rows = await (0, _keystrokehq_database.listActiveSkills)(filter);
1212
- return c.json(require_dist.SkillSummaryListResponseSchema.parse(rows.map(toSkillSummary)));
1213
- };
1214
- //#endregion
1215
- //#region src/routes/account/skills/[skillId]/GET.ts
1216
- const handler$42 = async (c) => {
1217
- const skillId = c.req.param("skillId") ?? "";
1218
- const row = skillId ? await (0, _keystrokehq_database.selectActiveSkillById)(skillId) : void 0;
1219
- if (!row || !await canAccessProjectId(c, row.projectId, canAccessSkill)) return c.json(require_dist.SkillSummaryDetailResponseSchema.parse(null));
1220
- touchResourceActivityBestEffort({
1221
- userId: c.get("user").id,
1222
- projectId: row.projectId,
1223
- resourceKind: "skill",
1224
- resourceId: row.id
1225
- });
1226
- return c.json(require_dist.SkillSummaryDetailResponseSchema.parse(toSkillSummary(row)));
1227
- };
1228
- //#endregion
1229
- //#region src/routes/account/resources/recents.ts
1230
- function toRecentResource(activity, resource, projectName) {
1231
- return require_dist.RecentResourceSchema.parse({
1232
- id: activity.id,
1233
- resourceKind: activity.resourceKind,
1234
- resourceId: activity.resourceId,
1235
- name: resource.name,
1236
- projectId: resource.projectId,
1237
- projectName,
1238
- sourcePath: resource.sourcePath,
1239
- source: "owned",
1240
- lastOpenedAt: activity.lastOpenedAt.toISOString(),
1241
- lastModifiedAt: resource.lastModifiedAt.toISOString()
1242
- });
1243
- }
1244
- function hydrateRecentResource(activity, lookup, projectNameById) {
1245
- const resource = lookup[activity.resourceKind]?.get(activity.resourceId);
1246
- if (!resource) return null;
1247
- return toRecentResource(activity, resource, projectNameById.get(resource.projectId) ?? resource.projectId);
1248
- }
1249
- function hydratedResourceFromAgentRow(row) {
1250
- return {
1251
- name: row.name?.trim() || titleCaseKey(row.slug),
1252
- projectId: row.projectId,
1253
- sourcePath: row.moduleFile,
1254
- lastModifiedAt: row.updatedAt
1255
- };
1256
- }
1257
- function latestRecentInteractionAt(recent) {
1258
- return Math.max(new Date(recent.lastOpenedAt).getTime(), new Date(recent.lastModifiedAt).getTime());
1259
- }
1260
- //#endregion
1261
- //#region src/routes/account/recents/GET.ts
1262
- const RECENTS_LIMIT = 50;
1263
- const handler$41 = async (c) => {
1264
- const userId = c.get("user").id;
1265
- const organization = c.get("organization");
1266
- const grantedProjectIdsList = await grantedProjectIds(c, { kind: "member-only" });
1267
- const activities = await (0, _keystrokehq_database.listRecentResourceActivity)(userId, RECENTS_LIMIT);
1268
- const visibleActivities = grantedProjectIdsList === void 0 ? activities : activities.filter((activity) => grantedProjectIdsList.includes(activity.projectId));
1269
- const agentIds = visibleActivities.filter((activity) => activity.resourceKind === "agent").map((activity) => activity.resourceId);
1270
- const workflowIds = visibleActivities.filter((activity) => activity.resourceKind === "workflow").map((activity) => activity.resourceId);
1271
- const skillIds = visibleActivities.filter((activity) => activity.resourceKind === "skill").map((activity) => activity.resourceId);
1272
- const [agents, workflows, skills, projects] = await Promise.all([
1273
- (0, _keystrokehq_database.selectActiveAgentsByIds)(agentIds),
1274
- (0, _keystrokehq_database.selectActiveWorkflowsByIds)(workflowIds),
1275
- (0, _keystrokehq_database.selectActiveSkillsByIds)(skillIds),
1276
- (0, _keystrokehq_platform_database.selectProjectsByOrganizationId)(organization.organizationId, { grantedProjectIds: grantedProjectIdsList })
1277
- ]);
1278
- const projectNameById = new Map(projects.map((project) => [project.id, project.name]));
1279
- const lookup = {
1280
- agent: new Map(agents.map((row) => [row.id, hydratedResourceFromAgentRow(row)])),
1281
- workflow: new Map(workflows.map((row) => [row.id, hydratedResourceFromAgentRow(row)])),
1282
- skill: new Map(skills.map((row) => [row.id, hydratedResourceFromAgentRow(row)]))
1283
- };
1284
- const recents = visibleActivities.map((activity) => hydrateRecentResource(activity, lookup, projectNameById)).filter((recent) => recent !== null).sort((left, right) => latestRecentInteractionAt(right) - latestRecentInteractionAt(left));
1285
- return c.json(require_dist.RecentResourceListResponseSchema.parse(recents));
1286
- };
1287
- //#endregion
1288
- //#region src/routes/account/projects/GET.ts
1289
- const handler$40 = async (c) => {
1290
- const organization = c.get("organization");
1291
- const grantedProjectIdsList = await grantedProjectIds(c, listScope(c, projectListScope(accessContext(c))));
1292
- const projects = await (0, _keystrokehq_platform_database.selectProjectsByOrganizationId)(organization.organizationId, { grantedProjectIds: grantedProjectIdsList });
1293
- return c.json(require_dist.ListProjectsResponseSchema.parse(projects.map(require_dist.mapProject)));
1294
- };
1295
- //#endregion
1296
- //#region src/routes/account/projects/metrics/merge-project-list-metrics.ts
1297
- function mergeProjectListMetrics(input) {
1298
- const projectIds = new Set([...Object.keys(input.resourceCounts), ...Object.keys(input.lastDeploymentAtByProject)]);
1299
- const metrics = {};
1300
- for (const projectId of projectIds) {
1301
- const counts = input.resourceCounts[projectId];
1302
- const lastDeploymentAt = input.lastDeploymentAtByProject[projectId];
1303
- metrics[projectId] = {
1304
- agentCount: counts?.agentCount ?? 0,
1305
- workflowCount: counts?.workflowCount ?? 0,
1306
- skillCount: counts?.skillCount ?? 0,
1307
- credentialCount: counts?.credentialCount ?? 0,
1308
- lastDeploymentAt: lastDeploymentAt ? lastDeploymentAt.toISOString() : null
1309
- };
1310
- }
1311
- return metrics;
1312
- }
1313
- //#endregion
1314
- //#region src/routes/account/projects/metrics/GET.ts
1315
- const handler$39 = async (c) => {
1316
- const organization = c.get("organization");
1317
- const grantedProjectIdsList = await grantedProjectIds(c, listScope(c, projectListScope(accessContext(c))));
1318
- const [resourceCounts, lastDeploymentAtByProject] = await Promise.all([(0, _keystrokehq_database.selectProjectResourceCounts)(grantedProjectIdsList !== void 0 ? { projectIds: grantedProjectIdsList } : void 0), (0, _keystrokehq_platform_database.selectLastDeploymentAtByProject)(organization.organizationId)]);
1319
- let metrics = mergeProjectListMetrics({
1320
- resourceCounts,
1321
- lastDeploymentAtByProject
1322
- });
1323
- if (grantedProjectIdsList !== void 0) {
1324
- const allowed = new Set(grantedProjectIdsList);
1325
- metrics = Object.fromEntries(Object.entries(metrics).filter(([projectId]) => allowed.has(projectId)));
1326
- }
1327
- return c.json(require_dist.ListProjectMetricsResponseSchema.parse(metrics));
1328
- };
1329
- //#endregion
1330
- //#region src/routes/account/projects/POST.ts
1331
- const handler$38 = async (c) => {
1332
- const organization = c.get("organization");
1333
- const user = c.get("user");
1334
- const body = await c.req.json().catch(() => null);
1335
- const parsed = require_dist.CreateProjectRequestSchema.safeParse(body);
1336
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Project name is required" }), 400);
1337
- const project = await (0, _keystrokehq_platform_database.createProjectForOrganization)(organization.organizationId, parsed.data.name, parsed.data.description, user.id);
1338
- return c.json(require_dist.CreateProjectResponseSchema.parse(require_dist.mapProject(project)), 201);
1339
- };
1340
- //#endregion
1341
- //#region src/routes/account/projects/slug-available/GET.ts
1342
- const handler$37 = async (c) => {
1343
- const organization = c.get("organization");
1344
- const parsed = require_dist.ProjectSlugAvailabilityQuerySchema.safeParse({
1345
- slug: c.req.query("slug"),
1346
- excludeProjectId: c.req.query("excludeProjectId")
1347
- });
1348
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid slug query" }), 400);
1349
- const availability = await (0, _keystrokehq_platform_database.checkProjectSlugAvailability)(organization.organizationId, parsed.data.slug, parsed.data.excludeProjectId);
1350
- return c.json(require_dist.ProjectSlugAvailabilityResponseSchema.parse(availability));
1351
- };
1352
- //#endregion
1353
- //#region src/routes/account/projects/[projectId]/GET.ts
1354
- const handler$36 = async (c) => {
1355
- return c.json(require_dist.ProjectResponseSchema.parse(routeProject(c.get("project"))));
1356
- };
1357
- //#endregion
1358
- //#region src/routes/account/projects/[projectId]/PATCH.ts
1359
- const handler$35 = async (c) => {
1360
- const organization = c.get("organization");
1361
- const project = c.get("project");
1362
- const body = await c.req.json().catch(() => null);
1363
- const parsed = require_dist.UpdateProjectRequestSchema.safeParse(body);
1364
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid project update request" }), 400);
1365
- let updated;
1366
- try {
1367
- updated = await (0, _keystrokehq_platform_database.updateProjectForOrganization)(organization.organizationId, project.id, parsed.data);
1368
- } catch (error) {
1369
- if (error instanceof _keystrokehq_platform_database.ProjectSlugTakenError) return c.json(require_dist.ErrorResponseSchema.parse({ error: require_dist.PROJECT_SLUG_TAKEN_MESSAGE }), 409);
1370
- throw error;
1371
- }
1372
- if (!updated) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Project not found" }), 404);
1373
- return c.json(require_dist.ProjectResponseSchema.parse(require_dist.mapProject(updated)));
1374
- };
1375
- //#endregion
1376
- //#region src/routes/account/projects/[projectId]/DELETE.ts
1377
- const handler$34 = async (c) => {
1378
- const organization = c.get("organization");
1379
- const project = c.get("project");
1380
- if (!await (0, _keystrokehq_platform_database.deleteProjectForOrganization)(organization.organizationId, project.id)) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Project not found" }), 404);
1381
- return c.body(null, 204);
1382
- };
1383
- //#endregion
1384
- //#region src/routes/account/projects/[projectId]/deployments/GET.ts
1385
- const handler$33 = async (c) => {
1386
- const rows = await (0, _keystrokehq_platform_database.selectProjectDeployments)(c.get("project").id);
1387
- return c.json(require_dist.ListProjectDeploymentsResponseSchema.parse(rows.map(require_dist.mapProjectDeployment)));
1388
- };
1389
- //#endregion
1390
- //#region src/routes/account/projects/[projectId]/artifacts/POST.ts
1391
- const DEFAULT_PRESIGN_TTL_SECONDS$1 = 900;
1392
- const ARTIFACT_CONTENT_TYPE = "application/gzip";
1393
- const handler$32 = async (c) => {
1394
- const project = c.get("project");
1395
- const { organizationId } = c.get("organization");
1396
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationId);
1397
- if (!organization) return c.json({ error: "Organization not found" }, 404);
1398
- const artifactId = crypto.randomUUID();
1399
- const storageKey = require_dist.projectArtifactKey(project.id, artifactId);
1400
- const storage = (0, _keystrokehq_platform_database.createOrgStorageClient)(organization);
1401
- const artifact = await (0, _keystrokehq_platform_database.insertProjectArtifact)({
1402
- id: artifactId,
1403
- projectId: project.id,
1404
- storageKey,
1405
- createdByUserId: c.get("user").id
1406
- });
1407
- const uploadUrl = await storage.presignPut({
1408
- key: storageKey,
1409
- contentType: ARTIFACT_CONTENT_TYPE,
1410
- expiresInSeconds: DEFAULT_PRESIGN_TTL_SECONDS$1
1411
- });
1412
- return c.json(require_dist.CreateProjectArtifactResponseSchema.parse({
1413
- artifact: require_dist.mapProjectArtifact(artifact),
1414
- uploadUrl,
1415
- expiresInSeconds: DEFAULT_PRESIGN_TTL_SECONDS$1
1416
- }), 201);
1417
- };
1418
- //#endregion
1419
- //#region src/routes/account/projects/[projectId]/artifacts/active/download/GET.ts
1420
- const DEFAULT_PRESIGN_TTL_SECONDS = 900;
1421
- const handler$31 = async (c) => {
1422
- const project = c.get("project");
1423
- const { organizationId } = c.get("organization");
1424
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationId);
1425
- if (!organization) return c.json({ error: "Organization not found" }, 404);
1426
- const artifact = await (0, _keystrokehq_platform_database.selectActiveProjectArtifactForProject)(project.id);
1427
- if (!artifact) return c.json({ error: "No active artifact for project" }, 404);
1428
- const downloadUrl = await (0, _keystrokehq_platform_database.createOrgStorageClient)(organization).presignGet({
1429
- key: artifact.storageKey,
1430
- expiresInSeconds: DEFAULT_PRESIGN_TTL_SECONDS
1431
- });
1432
- return c.json(require_dist.DownloadActiveProjectArtifactResponseSchema.parse({
1433
- artifactId: artifact.id,
1434
- downloadUrl,
1435
- expiresInSeconds: DEFAULT_PRESIGN_TTL_SECONDS
1436
- }));
1437
- };
1438
- //#endregion
1439
- //#region src/routes/account/projects/[projectId]/artifacts/[artifactId]/complete/POST.ts
1440
- const handler$30 = async (c) => {
1441
- const project = c.get("project");
1442
- const artifactId = c.req.param("artifactId");
1443
- if (!artifactId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact id is required" }), 400);
1444
- const existing = await (0, _keystrokehq_platform_database.selectProjectArtifactForProject)(artifactId, project.id);
1445
- if (!existing) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact not found" }), 404);
1446
- if (existing.status === "ready") return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact already completed" }), 409);
1447
- const { organizationId } = c.get("organization");
1448
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationId);
1449
- if (!organization) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Organization not found" }), 404);
1450
- const storage = (0, _keystrokehq_platform_database.createOrgStorageClient)(organization);
1451
- const head = await storage.headObject(existing.storageKey);
1452
- if (!head || head.contentLength <= 0) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact upload not found in storage" }), 400);
1453
- try {
1454
- const artifactBytes = await storage.getObject(existing.storageKey);
1455
- if (!artifactBytes || artifactBytes.byteLength <= 0) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact upload not found in storage" }), 400);
1456
- const manifestJson = require_dist.parseStoredRouteManifest(require_dist.extractRouteManifestFromArtifact(Buffer.from(artifactBytes)));
1457
- const result = await (0, _keystrokehq_platform_database.completeProjectArtifact)({
1458
- artifactId,
1459
- projectId: project.id,
1460
- manifestJson
1461
- });
1462
- await enqueueProjectRuntime({
1463
- projectId: project.id,
1464
- name: project.name,
1465
- artifactId
1466
- });
1467
- return c.json(require_dist.CompleteProjectArtifactResponseSchema.parse({
1468
- artifact: require_dist.mapProjectArtifact(result.artifact),
1469
- project: require_dist.mapProject(result.project)
1470
- }));
1471
- } catch (error) {
1472
- const message = error instanceof Error ? error.message : "Failed to complete artifact";
1473
- return c.json(require_dist.ErrorResponseSchema.parse({ error: message }), 400);
1474
- }
1475
- };
1476
- //#endregion
1477
- //#region src/routes/account/projects/[projectId]/artifacts/[artifactId]/source/presign/POST.ts
1478
- const SOURCE_BLOB_CONTENT_TYPE = "text/plain; charset=utf-8";
1479
- const handler$29 = async (c) => {
1480
- const project = c.get("project");
1481
- const artifactId = c.req.param("artifactId");
1482
- if (!artifactId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact id is required" }), 400);
1483
- if (!await (0, _keystrokehq_platform_database.selectProjectArtifactForProject)(artifactId, project.id)) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact not found" }), 404);
1484
- const parsed = require_dist.PresignProjectSourceRequestSchema.safeParse(await c.req.json().catch(() => null));
1485
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid blob list" }), 400);
1486
- const { organizationId } = c.get("organization");
1487
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationId);
1488
- if (!organization) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Organization not found" }), 404);
1489
- const storage = (0, _keystrokehq_platform_database.createOrgStorageClient)(organization);
1490
- const hashes = [...new Set(parsed.data.blobs.map((blob) => blob.hash))];
1491
- const uploads = await Promise.all(hashes.map(async (hash) => {
1492
- const key = require_dist.projectSourceBlobKey(project.id, hash);
1493
- const head = await storage.headObject(key);
1494
- if (head && head.contentLength > 0) return null;
1495
- return {
1496
- hash,
1497
- url: await storage.presignPut({
1498
- key,
1499
- contentType: SOURCE_BLOB_CONTENT_TYPE
1500
- })
1501
- };
1502
- }));
1503
- return c.json(require_dist.PresignProjectSourceResponseSchema.parse({ uploads: uploads.filter((upload) => upload !== null) }));
1504
- };
1505
- //#endregion
1506
- //#region src/routes/account/projects/[projectId]/artifacts/[artifactId]/source/manifest/POST.ts
1507
- const handler$28 = async (c) => {
1508
- const project = c.get("project");
1509
- const artifactId = c.req.param("artifactId");
1510
- if (!artifactId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact id is required" }), 400);
1511
- if (!await (0, _keystrokehq_platform_database.selectProjectArtifactForProject)(artifactId, project.id)) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact not found" }), 404);
1512
- const parsed = require_dist.UploadProjectSourceManifestRequestSchema.safeParse(await c.req.json().catch(() => null));
1513
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid source manifest" }), 400);
1514
- const manifest = require_dist.StoredProjectSourceManifestSchema.parse({
1515
- files: parsed.data.files.map((file) => ({
1516
- id: require_dist.projectFileId(file.path),
1517
- path: file.path,
1518
- hash: file.hash
1519
- })),
1520
- generatedAt: (/* @__PURE__ */ new Date()).toISOString()
1521
- });
1522
- await (0, _keystrokehq_platform_database.updateProjectArtifactSourceManifest)({
1523
- artifactId,
1524
- projectId: project.id,
1525
- sourceManifestJson: manifest
1526
- });
1527
- return c.json(require_dist.UploadProjectSourceResponseSchema.parse({
1528
- ok: true,
1529
- fileCount: manifest.files.length
1530
- }), 201);
1531
- };
1532
- //#endregion
1533
- //#region src/routes/account/projects/[projectId]/files/GET.ts
1534
- /**
1535
- * Resolve registry moduleFile values to paths in the deploy source snapshot.
1536
- *
1537
- * New deploys store project-root-relative source paths (`src/agents/support.ts`),
1538
- * matched exactly. Rows synced by older runtimes hold module-dir-relative values
1539
- * (`support.ts` under `src/agents/`), matched by suffix. Resources without a
1540
- * match are dropped rather than emitting paths clients can't find in the tree.
1541
- */
1542
- function resolveSourcePaths(rows, kindDir, filePaths) {
1543
- return rows.flatMap((row) => {
1544
- const suffix = `${kindDir}/${row.moduleFile}`;
1545
- const path = filePaths.find((filePath) => filePath === row.moduleFile) ?? filePaths.find((filePath) => filePath === suffix || filePath.endsWith(`/${suffix}`));
1546
- return path ? [{
1547
- slug: row.slug,
1548
- path
1549
- }] : [];
1550
- });
1551
- }
1552
- const handler$27 = async (c) => {
1553
- const project = c.get("project");
1554
- const active = await (0, _keystrokehq_platform_database.selectActiveArtifactSourceManifestForProject)(project.id);
1555
- if (!active || !active.sourceManifestJson) return c.json(require_dist.ListProjectFilesResponseSchema.parse({
1556
- artifactId: active?.artifactId ?? null,
1557
- files: []
1558
- }));
1559
- const manifest = require_dist.StoredProjectSourceManifestSchema.parse(active.sourceManifestJson);
1560
- const [agents, workflows, skills] = await Promise.all([
1561
- (0, _keystrokehq_database.listActiveAgents)({ projectIds: [project.id] }),
1562
- (0, _keystrokehq_database.listActiveWorkflows)({ projectIds: [project.id] }),
1563
- (0, _keystrokehq_database.listActiveSkills)({ projectIds: [project.id] })
1564
- ]);
1565
- const filePaths = manifest.files.map((file) => file.path);
1566
- const resources = require_dist.ProjectSourceResourcesSchema.parse({
1567
- agents: resolveSourcePaths(agents, "agents", filePaths),
1568
- workflows: resolveSourcePaths(workflows, "workflows", filePaths),
1569
- skills: skills.map((row) => ({
1570
- slug: row.slug,
1571
- path: row.moduleFile
1572
- }))
1573
- });
1574
- return c.json(require_dist.ListProjectFilesResponseSchema.parse({
1575
- artifactId: active.artifactId,
1576
- files: manifest.files.map((file) => ({
1577
- id: file.id,
1578
- path: file.path,
1579
- hash: file.hash
1580
- })),
1581
- resources
1582
- }));
1583
- };
1584
- //#endregion
1585
- //#region src/routes/account/projects/[projectId]/artifacts/[artifactId]/files/content/GET.ts
1586
- const handler$26 = async (c) => {
1587
- const project = c.get("project");
1588
- const artifactId = c.req.param("artifactId");
1589
- if (!artifactId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact id is required" }), 400);
1590
- const path = c.req.query("path");
1591
- if (!path) return c.json(require_dist.ErrorResponseSchema.parse({ error: "File path is required" }), 400);
1592
- const artifact = await (0, _keystrokehq_platform_database.selectProjectArtifactForProject)(artifactId, project.id);
1593
- if (!artifact || !artifact.sourceManifestJson) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Artifact not found" }), 404);
1594
- const file = require_dist.StoredProjectSourceManifestSchema.parse(artifact.sourceManifestJson).files.find((entry) => entry.path === path);
1595
- if (!file) return c.json(require_dist.ErrorResponseSchema.parse({ error: "File not found" }), 404);
1596
- const { organizationId } = c.get("organization");
1597
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationId);
1598
- if (!organization) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Organization not found" }), 404);
1599
- const storage = (0, _keystrokehq_platform_database.createOrgStorageClient)(organization);
1600
- let bytes;
1601
- try {
1602
- bytes = await storage.getObject(require_dist.projectSourceBlobKey(project.id, file.hash));
1603
- } catch {
1604
- return c.json(require_dist.ErrorResponseSchema.parse({ error: "File contents not found" }), 404);
1605
- }
1606
- c.header("Content-Type", "text/plain; charset=utf-8");
1607
- return c.body(new TextDecoder().decode(bytes));
1608
- };
1609
- //#endregion
1610
- //#region src/routes/account/projects/[projectId]/reachability/GET.ts
1611
- function createProjectReachabilityHandler(hosting) {
1612
- return async (c) => {
1613
- const project = c.get("project");
1614
- if (project.status !== "active") return c.json(require_dist.ProjectReachabilityResponseSchema.parse({ reachable: false }));
1615
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(project.organizationId);
1616
- const reachable = await require_dist.pingProjectTarget({
1617
- baseUrl: organization?.baseUrl ?? project.baseUrl,
1618
- runtimeId: organization?.runtimeId ?? project.runtimeId
1619
- }, { plugin: hosting });
1620
- return c.json(require_dist.ProjectReachabilityResponseSchema.parse({ reachable }));
1621
- };
1622
- }
1623
- //#endregion
1624
- //#region src/routes/account/projects/[projectId]/members/GET.ts
1625
- const handler$25 = async (c) => {
1626
- const project = c.get("project");
1627
- const currentUserId = c.get("user").id;
1628
- const members = await (0, _keystrokehq_platform_database.selectProjectMembers)(project.id);
1629
- return c.json(require_dist.ListProjectMembersResponseSchema.parse(members.map((member) => require_dist.mapProjectMember(member, { isCurrentUser: member.id === currentUserId }))));
1630
- };
1631
- //#endregion
1632
- //#region src/routes/account/projects/[projectId]/members/POST.ts
1633
- const handler$24 = async (c) => {
1634
- const organization = c.get("organization");
1635
- const project = c.get("project");
1636
- const body = await c.req.json().catch(() => null);
1637
- const parsed = require_dist.InviteProjectMembersRequestSchema.safeParse(body);
1638
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid invite request" }), 400);
1639
- const results = await (0, _keystrokehq_platform_database.inviteProjectMembers)({
1640
- projectId: project.id,
1641
- organizationId: organization.organizationId,
1642
- emails: parsed.data.emails,
1643
- role: parsed.data.role
1644
- });
1645
- return c.json(require_dist.InviteProjectMembersResponseSchema.parse(results));
1646
- };
1647
- //#endregion
1648
- //#region src/routes/account/projects/[projectId]/members/[userId]/PATCH.ts
1649
- const handler$23 = async (c) => {
1650
- const project = c.get("project");
1651
- const userId = c.req.param("userId");
1652
- const body = await c.req.json().catch(() => null);
1653
- const parsed = require_dist.UpdateProjectMemberRequestSchema.safeParse(body);
1654
- if (!userId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "User id is required" }), 400);
1655
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid member update request" }), 400);
1656
- try {
1657
- const member = await (0, _keystrokehq_platform_database.updateProjectMemberRole)(project.id, userId, parsed.data.role);
1658
- return c.json(require_dist.UpdateProjectMemberResponseSchema.parse(require_dist.mapProjectMember(member)));
1659
- } catch (error) {
1660
- if (error instanceof _keystrokehq_platform_database.ProjectMemberNotFoundError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 400);
1661
- throw error;
1662
- }
1663
- };
1664
- //#endregion
1665
- //#region src/routes/account/projects/[projectId]/members/[userId]/DELETE.ts
1666
- const handler$22 = async (c) => {
1667
- const project = c.get("project");
1668
- const userId = c.req.param("userId");
1669
- if (!userId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "User id is required" }), 400);
1670
- try {
1671
- await (0, _keystrokehq_platform_database.removeProjectMember)(project.id, userId);
1672
- return c.body(null, 204);
1673
- } catch (error) {
1674
- if (error instanceof _keystrokehq_platform_database.ProjectMemberNotFoundError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 400);
1675
- throw error;
1676
- }
1677
- };
1678
- //#endregion
1679
- //#region src/routes/account/projects/[projectId]/members/me/DELETE.ts
1680
- const handler$21 = async (c) => {
1681
- const project = c.get("project");
1682
- const userId = c.get("user").id;
1683
- try {
1684
- await (0, _keystrokehq_platform_database.removeProjectMember)(project.id, userId);
1685
- return c.body(null, 204);
1686
- } catch (error) {
1687
- if (error instanceof _keystrokehq_platform_database.ProjectMemberNotFoundError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 400);
1688
- throw error;
1689
- }
1690
- };
1691
- //#endregion
1692
- //#region src/routes/account/projects/[projectId]/settings/GET.ts
1693
- const handler$20 = async (c) => {
1694
- const project = c.get("project");
1695
- return c.json(require_dist.ProjectSettingsResponseSchema.parse(require_dist.mapProjectSettings(project)));
1696
- };
1697
- //#endregion
1698
- //#region src/routes/account/projects/[projectId]/settings/PATCH.ts
1699
- const handler$19 = async (c) => {
1700
- const organization = c.get("organization");
1701
- const project = c.get("project");
1702
- const body = await c.req.json().catch(() => null);
1703
- const parsed = require_dist.UpdateProjectSettingsRequestSchema.safeParse(body);
1704
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid project settings request" }), 400);
1705
- const updated = await (0, _keystrokehq_platform_database.updateProjectSettings)(organization.organizationId, project.id, {
1706
- description: parsed.data.description,
1707
- defaultMemberRole: parsed.data.defaultRole,
1708
- invitePermission: parsed.data.invitePermission
1709
- });
1710
- if (!updated) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Project not found" }), 404);
1711
- return c.json(require_dist.ProjectSettingsResponseSchema.parse(require_dist.mapProjectSettings(updated)));
1712
- };
1713
- //#endregion
1714
- //#region src/routes/account/credentials/enrich.ts
1715
- const APP_CREDENTIAL_SCOPES = [
1716
- "user",
1717
- "project",
1718
- "organization"
1719
- ];
1720
- function toAppCredentialScope(scopeType) {
1721
- return APP_CREDENTIAL_SCOPES.includes(scopeType) ? scopeType : null;
1722
- }
1723
- /** Run `fn` with the row's project scope bound (no-op for org/user rows). */
1724
- function withCredentialRowScope(row, fn) {
1725
- if (row.scopeType === "project") return (0, _keystrokehq_database.runWithProjectScope)(row.projectId, fn);
1726
- return fn();
1727
- }
1728
- /** User-scoped credentials are only manageable by their owner. */
1729
- function canManageCredential(row, userId) {
1730
- if (row.scopeType === "user") return userId !== void 0 && row.scopeId === userId;
1731
- return true;
1732
- }
1733
- /** Display name derived from the app slug (org-custom slugs use the segment after `/`). */
1734
- function displayAppName(appId) {
1735
- try {
1736
- const parsed = require_dist.parseAppSlug(appId);
1737
- if (parsed.kind === "org") return require_dist.displayCredentialAppName(parsed.name);
1738
- } catch {}
1739
- return require_dist.displayCredentialAppName(appId);
1740
- }
1741
- /** Masked preview of a secret — last 4 chars revealed, the rest masked. Plaintext never returned. */
1742
- function maskSecretPreview(value) {
1743
- const trimmed = value.trim();
1744
- if (trimmed.length <= 4) return "•".repeat(Math.max(trimmed.length, 4));
1745
- return `${"•".repeat(Math.min(trimmed.length - 4, 20))}${trimmed.slice(-4)}`;
1746
- }
1747
- async function readSecretKeyPreviews(instanceId) {
1748
- const payload = await require_dist.readCredentialInstanceSecret(instanceId);
1749
- if (!payload) return null;
1750
- let parsed;
1751
- try {
1752
- parsed = JSON.parse(payload);
1753
- } catch {
1754
- return null;
1755
- }
1756
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
1757
- const keyPreviews = {};
1758
- for (const [key, value] of Object.entries(parsed)) keyPreviews[key] = maskSecretPreview(typeof value === "string" ? value : JSON.stringify(value));
1759
- const credentialKeys = Object.keys(keyPreviews);
1760
- return credentialKeys.length > 0 ? {
1761
- credentialKeys,
1762
- keyPreviews
1763
- } : null;
1764
- }
1765
- function ownerFields(owner) {
1766
- if (!owner) return {};
1767
- return {
1768
- ownerUserId: owner.id,
1769
- ownerName: owner.name,
1770
- ...owner.image && URL.canParse(owner.image) ? { ownerAvatarUrl: owner.image } : {}
1771
- };
1772
- }
1773
- function uniqueIds(rows, pick) {
1774
- return [...new Set(rows.map(pick).filter((id) => Boolean(id)))];
1775
- }
1776
- /** Cross-database lookups: instances live in the org DB; projects/users/connections in the platform DB. */
1777
- async function loadCredentialLookups(rows, organizationId) {
1778
- const [projects, owners, connections] = await Promise.all([
1779
- (0, _keystrokehq_platform_database.selectProjectsByOrganizationId)(organizationId),
1780
- (0, _keystrokehq_platform_database.selectUsersByIds)(uniqueIds(rows, (row) => row.scopeType === "user" ? row.scopeId : null)),
1781
- (0, _keystrokehq_platform_database.selectOAuthConnectionsByIds)(uniqueIds(rows, (row) => row.authKind === "oauth_managed" ? row.connectionId : null))
1782
- ]);
1783
- return {
1784
- projectNameById: new Map(projects.map((project) => [project.id, project.name])),
1785
- ownersById: new Map(owners.map((owner) => [owner.id, owner])),
1786
- connectionsById: new Map(connections.map((connection) => [connection.id, connection]))
1787
- };
1788
- }
1789
- async function toCredentialSummary(row, scope, lookups) {
1790
- const isOAuth = row.authKind === "oauth_managed";
1791
- const isKeystroke = row.authKind === "keystroke";
1792
- const appName = displayAppName(row.slug);
1793
- const connection = row.connectionId ? lookups.connectionsById.get(row.connectionId) : void 0;
1794
- const secretKeys = isOAuth || isKeystroke ? null : await readSecretKeyPreviews(row.id);
1795
- const projectId = scope === "project" ? row.scopeId ?? row.projectId : void 0;
1796
- const projectName = projectId ? lookups.projectNameById.get(projectId) : void 0;
1797
- return {
1798
- id: row.id,
1799
- appId: row.slug,
1800
- label: row.label ?? appName,
1801
- scope,
1802
- lastRefreshedAt: isOAuth ? connection?.updatedAt.toISOString() ?? null : null,
1803
- appName,
1804
- ...projectId ? { projectId } : {},
1805
- ...projectName ? { projectName } : {},
1806
- status: isOAuth && !connection ? "Disconnected" : "Active",
1807
- createdAt: row.createdAt.toISOString(),
1808
- lastUsedAt: null,
1809
- isDefault: Boolean(row.isDefault),
1810
- connectionKind: isOAuth ? "oauth" : isKeystroke ? "oauth" : "manual",
1811
- ...scope === "user" && row.scopeId ? ownerFields(lookups.ownersById.get(row.scopeId)) : {},
1812
- ...connection?.grantedScopes?.length ? { grantedScopes: connection.grantedScopes } : {},
1813
- ...secretKeys ?? {},
1814
- ...connection?.accessTokenExpiresAt ? { expiresAt: connection.accessTokenExpiresAt.toISOString() } : {}
1815
- };
1816
- }
1817
- /** Build `AppCredentialSummary` rows from org-database instances plus platform lookups. */
1818
- async function enrichCredentialInstances(rows, organizationId) {
1819
- const visible = rows.filter((row) => toAppCredentialScope(row.scopeType) !== null);
1820
- const lookups = await loadCredentialLookups(visible, organizationId);
1821
- return (await Promise.all(visible.map((row) => toCredentialSummary(row, toAppCredentialScope(row.scopeType), lookups)))).sort((a, b) => new Date(b.createdAt ?? 0).getTime() - new Date(a.createdAt ?? 0).getTime());
1822
- }
1823
- //#endregion
1824
- //#region src/routes/account/credentials/GET.ts
1825
- const handler$18 = async (c) => {
1826
- const organization = c.get("organization");
1827
- const credentials = await enrichCredentialInstances(await (0, _keystrokehq_database.listAllCredentialInstances)(), organization.organizationId);
1828
- return c.json(require_dist.ListCredentialsResponseSchema.parse(credentials));
1829
- };
1830
- //#endregion
1831
- //#region src/routes/account/credentials/POST.ts
1832
- function withTargetScope(target, fn) {
1833
- if (target.projectScope) return (0, _keystrokehq_database.runWithProjectScope)(target.projectScope, fn);
1834
- return fn();
1835
- }
1836
- const handler$17 = async (c) => {
1837
- const organization = c.get("organization");
1838
- const user = c.get("user");
1839
- const parsed = require_dist.CreateCredentialsRequestSchema.safeParse(await c.req.json().catch(() => null));
1840
- if (!parsed.success) {
1841
- const message = parsed.error.issues[0]?.message ?? "Invalid request body";
1842
- return c.json({ error: message }, 400);
1843
- }
1844
- const input = parsed.data;
1845
- if (input.connectionKind === "manual" && input.value) {
1846
- const app = await (0, _keystrokehq_platform_database.selectAppForOrganization)(organization.organizationId, input.appId);
1847
- if (app && (0, _keystrokehq_platform_database.hasCredentialFieldTemplate)(app)) {
1848
- const validation = require_dist.validateCredentialValueAgainstFields(app.credentialFields, input.value);
1849
- if (!validation.ok) return c.json({ error: validation.message }, 400);
1850
- }
1851
- }
1852
- const resolvedProjects = [];
1853
- for (const slug of input.projects) {
1854
- const project = await (0, _keystrokehq_platform_database.selectProjectForOrganizationBySlug)(organization.organizationId, slug);
1855
- if (!project) return c.json({ error: `Project "${slug}" not found` }, 400);
1856
- resolvedProjects.push({
1857
- id: project.id,
1858
- name: project.name
1859
- });
1860
- }
1861
- const targets = [
1862
- ...resolvedProjects.map((project) => ({
1863
- scopeType: "project",
1864
- scopeId: project.id,
1865
- projectScope: project.id,
1866
- projectName: project.name
1867
- })),
1868
- ...input.createOrganizationCredential ? [{
1869
- scopeType: "organization",
1870
- scopeId: (0, _keystrokehq_database.getServerTenantScopeId)()
1871
- }] : [],
1872
- ...input.createUserProvidedCredential ? [{
1873
- scopeType: "user",
1874
- scopeId: user.id
1875
- }] : []
1876
- ];
1877
- const appName = require_dist.displayCredentialAppName(input.appId);
1878
- const siblingCounts = /* @__PURE__ */ new Map();
1879
- for (const target of targets) {
1880
- const siblings = await withTargetScope(target, () => (0, _keystrokehq_database.selectCredentialInstancesForScope)(input.appId, target.scopeType, target.scopeId));
1881
- siblingCounts.set(target, siblings.length);
1882
- }
1883
- const value = input.value;
1884
- const createdIds = [];
1885
- for (const target of targets) {
1886
- const siblings = await withTargetScope(target, () => (0, _keystrokehq_database.selectCredentialInstancesForScope)(input.appId, target.scopeType, target.scopeId));
1887
- const label = require_dist.resolveUniqueCredentialInstanceLabel({
1888
- baseLabel: input.label?.trim() || require_dist.buildCredentialInstanceLabel({
1889
- scopeType: target.scopeType,
1890
- appName,
1891
- projectName: target.projectName
1892
- }),
1893
- takenLabels: siblings.map((row) => row.label)
1894
- });
1895
- const id = crypto.randomUUID();
1896
- await withTargetScope(target, () => require_dist.setCredentialInstanceSecret({
1897
- id,
1898
- key: input.appId,
1899
- scopeType: target.scopeType,
1900
- scopeId: target.scopeId,
1901
- label,
1902
- isDefault: (siblingCounts.get(target) ?? 0) === 0,
1903
- value
1904
- }));
1905
- createdIds.push(id);
1906
- }
1907
- const rows = [];
1908
- for (const id of createdIds) {
1909
- const row = await (0, _keystrokehq_database.selectCredentialInstanceById)(id);
1910
- if (row) rows.push(row);
1911
- }
1912
- const credentials = await enrichCredentialInstances(rows, organization.organizationId);
1913
- return c.json(require_dist.CreateCredentialsResponseSchema.parse(credentials), 201);
1914
- };
1915
- //#endregion
1916
- //#region src/routes/account/credentials/[credentialId]/GET.ts
1917
- const handler$16 = async (c) => {
1918
- const organization = c.get("organization");
1919
- const credentialId = c.req.param("credentialId") ?? "";
1920
- const row = credentialId ? await (0, _keystrokehq_database.selectCredentialInstanceById)(credentialId) : void 0;
1921
- if (!row || toAppCredentialScope(row.scopeType) === null) return c.json({ error: "Credential not found" }, 404);
1922
- const [credential] = await enrichCredentialInstances([row], organization.organizationId);
1923
- return c.json(require_dist.GetCredentialResponseSchema.parse(credential));
1924
- };
1925
- //#endregion
1926
- //#region src/routes/account/credentials/[credentialId]/PATCH.ts
1927
- const handler$15 = async (c) => {
1928
- const organization = c.get("organization");
1929
- const user = c.get("user");
1930
- const credentialId = c.req.param("credentialId") ?? "";
1931
- const existing = credentialId ? await (0, _keystrokehq_database.selectCredentialInstanceById)(credentialId) : void 0;
1932
- if (!existing || toAppCredentialScope(existing.scopeType) === null) return c.json({ error: "Credential not found" }, 404);
1933
- if (!canManageCredential(existing, user.id)) return c.json({ error: "Forbidden" }, 403);
1934
- const parsed = require_dist.UpdateCredentialRequestSchema.safeParse(await c.req.json().catch(() => null));
1935
- if (!parsed.success) {
1936
- const message = parsed.error.issues[0]?.message ?? "Invalid request body";
1937
- return c.json({ error: message }, 400);
1938
- }
1939
- if (parsed.data.value && existing.authKind !== "api_key") return c.json({ error: "Only api-key credentials support secret rotation" }, 400);
1940
- const label = parsed.data.label !== void 0 ? parsed.data.label : existing.label;
1941
- const isDefault = parsed.data.isDefault !== void 0 ? parsed.data.isDefault : Boolean(existing.isDefault);
1942
- if (label !== existing.label) {
1943
- if ((await withCredentialRowScope(existing, () => (0, _keystrokehq_database.selectCredentialInstancesForScope)(existing.slug, existing.scopeType, existing.scopeId))).some((row) => row.id !== credentialId && (row.label ?? null) === label)) return c.json({ error: "A credential with this label already exists" }, 409);
1944
- }
1945
- await withCredentialRowScope(existing, async () => {
1946
- if (parsed.data.value) {
1947
- await require_dist.setCredentialInstanceSecret({
1948
- id: existing.id,
1949
- key: existing.slug,
1950
- scopeType: existing.scopeType,
1951
- scopeId: existing.scopeId,
1952
- label,
1953
- isDefault,
1954
- value: parsed.data.value
1955
- });
1956
- return;
1957
- }
1958
- if (isDefault) await (0, _keystrokehq_database.clearCredentialInstanceDefaults)({
1959
- slug: existing.slug,
1960
- scopeType: existing.scopeType,
1961
- scopeId: existing.scopeId,
1962
- exceptId: credentialId
1963
- });
1964
- await (0, _keystrokehq_database.upsertCredentialInstance)({
1965
- id: existing.id,
1966
- slug: existing.slug,
1967
- scopeType: existing.scopeType,
1968
- scopeId: existing.scopeId,
1969
- label,
1970
- isDefault,
1971
- authKind: existing.authKind,
1972
- ciphertext: existing.ciphertext,
1973
- connectionId: existing.connectionId,
1974
- createdAt: existing.createdAt,
1975
- updatedAt: /* @__PURE__ */ new Date()
1976
- });
1977
- });
1978
- const updated = await (0, _keystrokehq_database.selectCredentialInstanceById)(credentialId);
1979
- const [credential] = await enrichCredentialInstances(updated ? [updated] : [], organization.organizationId);
1980
- return c.json(require_dist.GetCredentialResponseSchema.parse(credential));
1981
- };
1982
- //#endregion
1983
- //#region src/routes/account/credentials/[credentialId]/DELETE.ts
1984
- function createDeleteCredentialHandler(options = {}) {
1985
- return async (c) => {
1986
- const user = c.get("user");
1987
- const credentialId = c.req.param("credentialId") ?? "";
1988
- const existing = credentialId ? await (0, _keystrokehq_database.selectCredentialInstanceById)(credentialId) : void 0;
1989
- if (!existing || toAppCredentialScope(existing.scopeType) === null) return c.json({ error: "Credential not found" }, 404);
1990
- if (!canManageCredential(existing, user.id)) return c.json({ error: "Forbidden" }, 403);
1991
- if (existing.authKind === "oauth_managed") {
1992
- if (existing.connectionId) {
1993
- if ((await (0, _keystrokehq_database.listCredentialInstancesByConnectionId)(existing.connectionId)).every((row) => row.id === existing.id)) await (0, _keystrokehq_platform_database.deleteOAuthConnectionById)(existing.connectionId);
1994
- }
1995
- } else if (existing.authKind === "keystroke") {
1996
- if (existing.connectionId) {
1997
- if ((await (0, _keystrokehq_database.listCredentialInstancesByConnectionId)(existing.connectionId)).every((row) => row.id === existing.id)) {
1998
- if (!options.mcp) return c.json({ error: "mcp_unconfigured" }, 501);
1999
- await options.mcp.revokeConnection((0, _keystrokehq_http.resolveMcpEntityId)(existing), existing.connectionId);
2000
- }
2001
- }
2002
- } else await require_dist.deleteCredentialInstanceSecret(existing.id);
2003
- await (0, _keystrokehq_database.deleteCredentialInstanceById)(credentialId);
2004
- return c.body(null, 204);
2005
- };
2006
- }
2007
- //#endregion
2008
- //#region src/routes/account/members/GET.ts
2009
- const handler$14 = async (c) => {
2010
- const { organizationId } = c.get("organization");
2011
- const members = await (0, _keystrokehq_platform_database.selectOrganizationMembers)(organizationId);
2012
- return c.json(require_dist.ListOrganizationMembersResponseSchema.parse(members.map(require_dist.mapOrganizationMember)));
2013
- };
2014
- //#endregion
2015
- //#region src/email/organization-invite-email.ts
2016
- function envValue(name) {
2017
- return process.env[name]?.trim() || void 0;
2018
- }
2019
- function resolveOrganizationInviteUrl(invitationId) {
2020
- return `${(envValue("PUBLIC_WEB_URL") ?? "http://localhost:3000").replace(/\/$/, "")}${require_dist.organizationInvitationAcceptPath(invitationId)}`;
2021
- }
2022
- function resolveResendApiKey() {
2023
- return envValue("RESEND_API_KEY");
2024
- }
2025
- function buildOrganizationInviteEmailHtml(payload) {
2026
- const inviteUrl = resolveOrganizationInviteUrl(payload.invitationId);
2027
- const escapedOrg = payload.organizationName.replaceAll("&", "&amp;").replaceAll("<", "&lt;");
2028
- return `<!DOCTYPE html>
2029
- <html>
2030
- <body style="font-family: system-ui, sans-serif; line-height: 1.5; color: #111;">
2031
- ${payload.inviterName ? `<p>${payload.inviterName.replaceAll("&", "&amp;").replaceAll("<", "&lt;")} invited you to join <strong>${escapedOrg}</strong> on Keystroke.</p>` : `<p>You have been invited to join <strong>${escapedOrg}</strong> on Keystroke.</p>`}
2032
- <p><a href="${inviteUrl}" style="display: inline-block; padding: 10px 16px; background: #111; color: #fff; text-decoration: none; border-radius: 8px;">View invitation</a></p>
2033
- <p style="color: #666; font-size: 13px;">Sign in with this email address to accept the invitation.</p>
2034
- </body>
2035
- </html>`;
2036
- }
2037
- async function sendOrganizationInviteEmail(payload, resend$1) {
2038
- const apiKey = resolveResendApiKey();
2039
- if (!apiKey) {
2040
- console.warn("[platform] RESEND_API_KEY not set; organization invite email skipped");
2041
- return false;
2042
- }
2043
- const { error } = await (resend$1 ?? new resend.Resend(apiKey)).emails.send({
2044
- from: (0, _keystrokehq_auth.resolveAuthEmailFrom)(),
2045
- to: payload.email,
2046
- subject: `Invitation to join ${payload.organizationName} on Keystroke`,
2047
- html: buildOrganizationInviteEmailHtml(payload)
2048
- });
2049
- if (error) {
2050
- console.warn(`[platform] Failed to send organization invite email: ${error.message}`);
2051
- return false;
2052
- }
2053
- return true;
2054
- }
2055
- //#endregion
2056
- //#region src/routes/account/members/invitations/POST.ts
2057
- const handler$13 = async (c) => {
2058
- const user = c.get("user");
2059
- const organization = c.get("organization");
2060
- const body = await c.req.json().catch(() => null);
2061
- const parsed = require_dist.InviteOrganizationMembersRequestSchema.safeParse(body);
2062
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid invite request" }), 400);
2063
- const results = await (0, _keystrokehq_platform_database.inviteOrganizationMembers)({
2064
- organizationId: organization.organizationId,
2065
- invitedByUserId: user.id,
2066
- emails: parsed.data.emails,
2067
- role: parsed.data.role
2068
- });
2069
- const inviter = await (0, _keystrokehq_platform_database.selectUserById)(user.id);
2070
- for (const result of results) {
2071
- if (!result.invitationId || result.status !== "sent" && result.status !== "pending") continue;
2072
- await sendOrganizationInviteEmail({
2073
- email: result.email,
2074
- organizationName: organization.organizationName,
2075
- invitationId: result.invitationId,
2076
- inviterName: inviter?.name
2077
- });
2078
- }
2079
- return c.json(require_dist.InviteOrganizationMembersResponseSchema.parse(results));
2080
- };
2081
- //#endregion
2082
- //#region src/routes/account/members/[userId]/PATCH.ts
2083
- const handler$12 = async (c) => {
2084
- const { organizationId } = c.get("organization");
2085
- const userId = c.req.param("userId");
2086
- const body = await c.req.json().catch(() => null);
2087
- const parsed = require_dist.UpdateOrganizationMemberRequestSchema.safeParse(body);
2088
- if (!userId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "User id is required" }), 400);
2089
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid member update request" }), 400);
2090
- try {
2091
- const member = await (0, _keystrokehq_platform_database.updateOrganizationMemberRole)(organizationId, userId, parsed.data.role);
2092
- return c.json(require_dist.UpdateOrganizationMemberResponseSchema.parse(require_dist.mapOrganizationMember(member)));
2093
- } catch (error) {
2094
- if (error instanceof _keystrokehq_platform_database.CannotModifyOwnerError || error instanceof _keystrokehq_platform_database.OrganizationMemberNotFoundError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 400);
2095
- throw error;
2096
- }
2097
- };
2098
- //#endregion
2099
- //#region src/routes/account/members/[userId]/DELETE.ts
2100
- const handler$11 = async (c) => {
2101
- const { organizationId } = c.get("organization");
2102
- const userId = c.req.param("userId");
2103
- if (!userId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "User id is required" }), 400);
2104
- try {
2105
- await (0, _keystrokehq_platform_database.removeOrganizationMember)(organizationId, userId);
2106
- return c.body(null, 204);
2107
- } catch (error) {
2108
- if (error instanceof _keystrokehq_platform_database.CannotModifyOwnerError || error instanceof _keystrokehq_platform_database.OrganizationMemberNotFoundError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 400);
2109
- throw error;
2110
- }
2111
- };
2112
- //#endregion
2113
- //#region src/routes/account/invitations/GET.ts
2114
- const handler$10 = async (c) => {
2115
- const invitations = await (0, _keystrokehq_platform_database.selectPendingInvitationsForUser)(c.get("user").id);
2116
- return c.json(require_dist.ListOrganizationInvitationsResponseSchema.parse(invitations.map(require_dist.mapOrganizationInvitation)));
2117
- };
2118
- //#endregion
2119
- //#region src/routes/account/invitations/[invitationId]/accept/POST.ts
2120
- const handler$9 = async (c) => {
2121
- const user = c.get("user");
2122
- const invitationId = c.req.param("invitationId");
2123
- if (!invitationId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invitation id is required" }), 400);
2124
- try {
2125
- const membership = await (0, _keystrokehq_platform_database.acceptInvitation)(invitationId, user.id);
2126
- return c.json(require_dist.AcceptOrganizationInvitationResponseSchema.parse(require_dist.mapUserOrganization(membership)));
2127
- } catch (error) {
2128
- if (error instanceof _keystrokehq_platform_database.OrganizationInvitationNotFoundError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 404);
2129
- if (error instanceof _keystrokehq_platform_database.OrganizationInvitationForbiddenError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 403);
2130
- if (error instanceof _keystrokehq_platform_database.OrganizationInvitationExpiredError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 410);
2131
- throw error;
2132
- }
2133
- };
2134
- //#endregion
2135
- //#region src/routes/account/invitations/[invitationId]/decline/POST.ts
2136
- const handler$8 = async (c) => {
2137
- const user = c.get("user");
2138
- const invitationId = c.req.param("invitationId");
2139
- if (!invitationId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invitation id is required" }), 400);
2140
- try {
2141
- await (0, _keystrokehq_platform_database.declineInvitation)(invitationId, user.id);
2142
- return c.json(require_dist.DeclineOrganizationInvitationResponseSchema.parse({ success: true }));
2143
- } catch (error) {
2144
- if (error instanceof _keystrokehq_platform_database.OrganizationInvitationNotFoundError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 404);
2145
- if (error instanceof _keystrokehq_platform_database.OrganizationInvitationForbiddenError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 403);
2146
- throw error;
2147
- }
2148
- };
2149
- //#endregion
2150
- //#region src/routes/account/apps/map-catalog.ts
2151
- /** Map a platform `apps` row to the connect-picker wire shape. */
2152
- function appRowToCatalogEntry(row) {
2153
- return {
2154
- id: row.slug,
2155
- name: row.name,
2156
- description: row.description,
2157
- category: row.category,
2158
- integrationDescription: row.description,
2159
- ...row.logo ? { logo: row.logo } : {},
2160
- authKind: row.authKind,
2161
- oauthScopes: row.oauthScopes,
2162
- source: row.source,
2163
- ...(0, _keystrokehq_platform_database.hasCredentialFieldTemplate)(row) ? { credentialFields: row.credentialFields } : {}
2164
- };
2165
- }
2166
- function appRowToCustomAppDetail(row) {
2167
- if (row.source !== "custom" || row.authKind !== "api_key") throw new Error(`App is not a custom api_key app: ${row.slug}`);
2168
- if (!(0, _keystrokehq_platform_database.hasCredentialFieldTemplate)(row)) throw new Error(`Custom app is missing credential fields: ${row.slug}`);
2169
- return {
2170
- id: row.slug,
2171
- slug: row.slug,
2172
- name: row.name,
2173
- description: row.description,
2174
- category: row.category,
2175
- authKind: "api_key",
2176
- source: "custom",
2177
- credentialFields: row.credentialFields,
2178
- createdAt: row.createdAt.toISOString(),
2179
- updatedAt: row.updatedAt.toISOString()
2180
- };
2181
- }
2182
- //#endregion
2183
- //#region src/routes/account/apps/GET.ts
2184
- const handler$7 = async (c) => {
2185
- const apps = (await (0, _keystrokehq_platform_database.listAppsForOrganization)(c.get("organization").organizationId)).map(appRowToCatalogEntry);
2186
- return c.json(require_dist.ListAppsResponseSchema.parse(apps));
2187
- };
2188
- //#endregion
2189
- //#region src/routes/account/apps/POST.ts
2190
- const handler$6 = async (c) => {
2191
- const organization = c.get("organization");
2192
- const parsed = require_dist.CreateCustomAppRequestSchema.safeParse(await c.req.json().catch(() => null));
2193
- if (!parsed.success) {
2194
- const message = parsed.error.issues[0]?.message ?? "Invalid request body";
2195
- return c.json(require_dist.ErrorResponseSchema.parse({ error: message }), 400);
2196
- }
2197
- const org = await (0, _keystrokehq_platform_database.selectOrganizationById)(organization.organizationId);
2198
- if (!org) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Organization not found" }), 404);
2199
- try {
2200
- const row = await (0, _keystrokehq_platform_database.createOrgApp)({
2201
- organizationId: organization.organizationId,
2202
- orgSlug: org.slug,
2203
- name: parsed.data.name,
2204
- slug: parsed.data.slug,
2205
- description: parsed.data.description,
2206
- credentialFields: parsed.data.fields
2207
- });
2208
- return c.json(require_dist.CreateCustomAppResponseSchema.parse(appRowToCustomAppDetail(row)), 201);
2209
- } catch (error) {
2210
- if (error instanceof _keystrokehq_platform_database.OrgAppSlugTakenError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 409);
2211
- throw error;
2212
- }
2213
- };
2214
- //#endregion
2215
- //#region src/routes/account/apps/slug-available/GET.ts
2216
- const handler$5 = async (c) => {
2217
- const organization = c.get("organization");
2218
- const parsed = require_dist.AppSlugAvailabilityQuerySchema.safeParse({ slug: c.req.query("slug") });
2219
- if (!parsed.success) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Invalid slug query" }), 400);
2220
- const org = await (0, _keystrokehq_platform_database.selectOrganizationById)(organization.organizationId);
2221
- if (!org) return c.json(require_dist.ErrorResponseSchema.parse({ error: "Organization not found" }), 404);
2222
- const availability = await (0, _keystrokehq_platform_database.checkOrgAppSlugAvailability)(org.slug, parsed.data.slug);
2223
- return c.json(require_dist.AppSlugAvailabilityResponseSchema.parse(availability));
2224
- };
2225
- //#endregion
2226
- //#region src/routes/account/apps/[slug]/GET.ts
2227
- const handler$4 = async (c) => {
2228
- const organization = c.get("organization");
2229
- const slug = c.req.param("slug") ?? "";
2230
- if (!slug) return c.json(require_dist.ErrorResponseSchema.parse({ error: "App not found" }), 404);
2231
- const row = await (0, _keystrokehq_platform_database.selectAppForOrganization)(organization.organizationId, decodeURIComponent(slug));
2232
- if (!row || row.source !== "custom") return c.json(require_dist.ErrorResponseSchema.parse({ error: "App not found" }), 404);
2233
- try {
2234
- return c.json(require_dist.GetCustomAppResponseSchema.parse(appRowToCustomAppDetail(row)));
2235
- } catch {
2236
- return c.json(require_dist.ErrorResponseSchema.parse({ error: "App not found" }), 404);
2237
- }
2238
- };
2239
- //#endregion
2240
- //#region src/routes/account/api-keys/GET.ts
2241
- const handler$3 = async (c) => {
2242
- const { organizationId } = c.get("organization");
2243
- const user = c.get("user");
2244
- const records = apiKeyListScope(accessContext(c)).kind === "all" ? await (0, _keystrokehq_platform_database.listOrgPlatformApiKeysForOrganization)(organizationId) : await (0, _keystrokehq_platform_database.listOrgPlatformApiKeysForUser)(organizationId, user.id);
2245
- const creators = await (0, _keystrokehq_platform_database.selectUsersByIds)([...new Set(records.map((record) => record.createdByUserId))]);
2246
- const creatorsById = new Map(creators.map((creator) => [creator.id, creator]));
2247
- return c.json(require_dist.ListApiKeysResponseSchema.parse(records.map((record) => ({
2248
- id: record.id,
2249
- name: record.name,
2250
- keyPreview: record.keyPreview,
2251
- createdAt: record.createdAt.toISOString(),
2252
- createdBy: (0, _keystrokehq_platform_database.mapOrgPlatformApiKeyCreatorOrDeleted)(record.createdByUserId, creatorsById.get(record.createdByUserId)),
2253
- isCreatedByCurrentUser: record.createdByUserId === user.id
2254
- }))));
2255
- };
2256
- //#endregion
2257
- //#region src/routes/account/api-keys/POST.ts
2258
- const handler$2 = async (c) => {
2259
- const { organizationId } = c.get("organization");
2260
- const user = c.get("user");
2261
- const body = require_dist.CreateApiKeyRequestSchema.parse(await c.req.json());
2262
- const created = await (0, _keystrokehq_platform_database.createOrgPlatformApiKey)({
2263
- organizationId,
2264
- userId: user.id,
2265
- name: body.name
2266
- });
2267
- const creator = await (0, _keystrokehq_platform_database.loadOrgPlatformApiKeyUser)(user.id);
2268
- if (!creator) return c.json({ error: "User not found" }, 404);
2269
- return c.json(require_dist.CreateApiKeyResponseSchema.parse({
2270
- id: created.id,
2271
- name: created.name,
2272
- keyPreview: created.keyPreview,
2273
- createdAt: created.createdAt.toISOString(),
2274
- createdBy: (0, _keystrokehq_platform_database.mapOrgPlatformApiKeyCreator)(creator),
2275
- isCreatedByCurrentUser: true,
2276
- secret: created.secret
2277
- }), 201);
2278
- };
2279
- //#endregion
2280
- //#region src/routes/account/api-keys/[apiKeyId]/DELETE.ts
2281
- const handler$1 = async (c) => {
2282
- const { organizationId } = c.get("organization");
2283
- const user = c.get("user");
2284
- const apiKeyId = c.req.param("apiKeyId");
2285
- if (!apiKeyId) return c.json(require_dist.ErrorResponseSchema.parse({ error: "API key id is required" }), 400);
2286
- const apiKey = await (0, _keystrokehq_platform_database.selectOrgPlatformApiKeyForOrganization)(apiKeyId, organizationId);
2287
- if (!apiKey) return c.json(require_dist.ErrorResponseSchema.parse({ error: "API key not found" }), 404);
2288
- if (!canReadApiKey(accessContext(c), {
2289
- userId: user.id,
2290
- createdByUserId: apiKey.createdByUserId
2291
- })) return c.json(require_dist.ErrorResponseSchema.parse({ error: "API key not found" }), 404);
2292
- if (!canRevokeApiKey(accessContext(c), {
2293
- userId: user.id,
2294
- createdByUserId: apiKey.createdByUserId
2295
- })) return forbidden(c);
2296
- try {
2297
- await (0, _keystrokehq_platform_database.revokeOrgPlatformApiKey)(apiKeyId, organizationId);
2298
- return c.body(null, 204);
2299
- } catch (error) {
2300
- if (error instanceof _keystrokehq_platform_database.OrgPlatformApiKeyNotFoundError) return c.json(require_dist.ErrorResponseSchema.parse({ error: error.message }), 404);
2301
- throw error;
2302
- }
2303
- };
2304
- //#endregion
2305
- //#region src/lib/team-request-slack.ts
2306
- const TEAM_REQUEST_HEADINGS = {
2307
- "org-deletion": "Org deletion requested",
2308
- contact: "Contact request",
2309
- "enterprise-upgrade": "Enterprise upgrade requested"
2310
- };
2311
- function buildTeamRequestSlackPayload(input) {
2312
- const timestamp = input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString();
2313
- const heading = TEAM_REQUEST_HEADINGS[input.type];
2314
- const summary = `${heading} from ${input.user.name} (${input.org.name})`;
2315
- const fields = [
2316
- {
2317
- type: "mrkdwn",
2318
- text: `*Request type:*\n${input.type}`
2319
- },
2320
- {
2321
- type: "mrkdwn",
2322
- text: `*Timestamp:*\n${timestamp}`
2323
- },
2324
- {
2325
- type: "mrkdwn",
2326
- text: `*User:*\n${input.user.name}\n${input.user.email}\n\`${input.user.id}\``
2327
- },
2328
- {
2329
- type: "mrkdwn",
2330
- text: `*Organization:*\n${input.org.name}\n\`${input.org.slug}\`\n\`${input.org.id}\``
2331
- }
2332
- ];
2333
- const blocks = [{
2334
- type: "header",
2335
- text: {
2336
- type: "plain_text",
2337
- text: heading,
2338
- emoji: true
2339
- }
2340
- }, {
2341
- type: "section",
2342
- fields
2343
- }];
2344
- if (input.type === "contact" && input.message?.trim()) blocks.push({
2345
- type: "section",
2346
- text: {
2347
- type: "mrkdwn",
2348
- text: `*Message:*\n${input.message.trim()}`
2349
- }
2350
- });
2351
- return {
2352
- text: summary,
2353
- blocks
2354
- };
2355
- }
2356
- async function postTeamRequestToSlack(input) {
2357
- const webhookUrl = process.env.TEAM_SLACK_WEBHOOK_URL?.trim();
2358
- if (!webhookUrl) {
2359
- console.warn("TEAM_SLACK_WEBHOOK_URL is not set; skipping team request Slack delivery");
2360
- return;
2361
- }
2362
- const payload = buildTeamRequestSlackPayload(input);
2363
- const response = await fetch(webhookUrl, {
2364
- method: "POST",
2365
- headers: { "Content-Type": "application/json" },
2366
- body: JSON.stringify(payload)
2367
- });
2368
- if (!response.ok) {
2369
- const body = await response.text().catch(() => "");
2370
- throw new Error(`Failed to deliver team request to Slack (${response.status})${body ? `: ${body}` : ""}`);
2371
- }
2372
- }
2373
- //#endregion
2374
- //#region src/routes/account/team-requests/POST.ts
2375
- const handler = async (c) => {
2376
- const user = c.get("user");
2377
- const organizationContext = c.get("organization");
2378
- const parsed = require_dist.SubmitTeamRequestRequestSchema.safeParse(await c.req.json().catch(() => null));
2379
- if (!parsed.success) {
2380
- const message = parsed.error.issues[0]?.message ?? "Invalid request body";
2381
- return c.json({ error: message }, 400);
2382
- }
2383
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(organizationContext.organizationId);
2384
- if (!organization) return c.json({ error: "Organization not found" }, 404);
2385
- try {
2386
- await postTeamRequestToSlack({
2387
- type: parsed.data.type,
2388
- message: parsed.data.message,
2389
- user: {
2390
- id: user.id,
2391
- name: user.name,
2392
- email: user.email
2393
- },
2394
- org: {
2395
- id: organization.id,
2396
- name: organization.name,
2397
- slug: organization.slug
2398
- }
2399
- });
2400
- } catch (error) {
2401
- console.error("Failed to deliver team request to Slack", error);
2402
- return c.json({ error: "Failed to deliver team request" }, 502);
2403
- }
2404
- return c.json(require_dist.SubmitTeamRequestResponseSchema.parse({ ok: true }), 200);
2405
- };
2406
- //#endregion
2407
- //#region src/routes/account/mount.ts
2408
- function mountAccountRoutes(options) {
2409
- const account = new hono.Hono();
2410
- const orgScoped = new hono.Hono();
2411
- const projectScoped = new hono.Hono();
2412
- const protect = requireSession((0, _keystrokehq_auth.createDefaultAuthJwtVerifier)());
2413
- const deleteCredential = createDeleteCredentialHandler({ mcp: options.mcp });
2414
- account.use("/*", protect);
2415
- orgScoped.use("/*", protect);
2416
- orgScoped.use("/*", requireOrganization());
2417
- projectScoped.use("/*", protect);
2418
- projectScoped.use("/*", requireOrganization());
2419
- const requireOrgUpdate = authorize(organizationActions.update);
2420
- const requireUserManage = authorize(userActions.manage);
2421
- const requireUserInvite = authorize(userActions.invite);
2422
- const requireApiKeyCreate = authorize(apiKeysActions.create);
2423
- const requireInvitableRole = authorizePayload(require_dist.InviteOrganizationMembersRequestSchema, ({ ctx, body }) => canInviteRole(ctx.orgRole, body.role));
2424
- const requireProjectMember = requireProjectMembership();
2425
- const requireProjectDeploy = authorize(projectActions.deploy);
2426
- const requireProjectUpdate = authorize(projectActions.update);
2427
- const requireProjectDelete = authorize(projectActions.delete);
2428
- const requireProjectManageMembers = authorize(projectActions.manageMembers);
2429
- const requireInvitableProjectRole = authorizePayload(require_dist.InviteProjectMembersRequestSchema, ({ c, ctx, body }) => canInviteToProject(ctx, { invitePermission: getProjectInvitePermission(c) }, body.role));
2430
- const requireOrgParam = requireOrganizationParam();
2431
- account.get("/organizations", handler$58);
2432
- account.get("/organizations/slug-available", handler$57);
2433
- account.post("/organizations", createOrganizationHandler(options));
2434
- account.get("/organizations/:organizationId", requireOrgParam, handler$56);
2435
- account.patch("/organizations/:organizationId", requireOrgParam, requireOrgUpdate, handler$55);
2436
- account.get("/organizations/:organizationId/branding", requireOrgParam, handler$54);
2437
- account.patch("/organizations/:organizationId/branding", requireOrgParam, requireOrgUpdate, handler$53);
2438
- account.post("/organizations/:organizationId/branding/logo/presign", requireOrgParam, requireOrgUpdate, handler$52);
2439
- account.get("/invitations", handler$10);
2440
- account.post("/invitations/:invitationId/accept", handler$9);
2441
- account.post("/invitations/:invitationId/decline", handler$8);
2442
- account.get("/users/me/avatar", handler$63);
2443
- account.post("/users/me/avatar/presign", handler$62);
2444
- account.patch("/users/me/avatar", handler$61);
2445
- account.get("/users/me/preferences", handler$60);
2446
- account.patch("/users/me/preferences", handler$59);
2447
- orgScoped.get("/apps", handler$7);
2448
- orgScoped.get("/apps/slug-available", handler$5);
2449
- orgScoped.post("/apps", requireOrgUpdate, handler$6);
2450
- orgScoped.get("/apps/:slug", handler$4);
2451
- orgScoped.get("/members", handler$14);
2452
- orgScoped.post("/members/invitations", requireUserInvite, requireInvitableRole, handler$13);
2453
- orgScoped.patch("/members/:userId", requireUserManage, handler$12);
2454
- orgScoped.delete("/members/:userId", requireUserManage, handler$11);
2455
- orgScoped.get("/api-keys", handler$3);
2456
- orgScoped.post("/api-keys", requireApiKeyCreate, handler$2);
2457
- orgScoped.delete("/api-keys/:apiKeyId", handler$1);
2458
- const withOrgDb = withOrganizationProjectDatabase();
2459
- orgScoped.get("/agents", withOrgDb, handler$49);
2460
- orgScoped.get("/agents/:agentId", withOrgDb, handler$48);
2461
- orgScoped.get("/workflows", withOrgDb, handler$46);
2462
- orgScoped.get("/workflows/:workflowId", withOrgDb, handler$45);
2463
- orgScoped.get("/skills", withOrgDb, handler$43);
2464
- orgScoped.get("/skills/:skillId", withOrgDb, handler$42);
2465
- orgScoped.get("/recents", withOrgDb, handler$41);
2466
- orgScoped.get("/history", withOrgDb, handler$51);
2467
- orgScoped.post("/team-requests", handler);
2468
- orgScoped.get("/history/:runId", withOrgDb, handler$50);
2469
- orgScoped.post("/workflows/runs/:runId/cancel", withOrgDb, handler$44);
2470
- orgScoped.post("/agents/sessions/:sessionId/cancel", withOrgDb, handler$47);
2471
- orgScoped.get("/credentials", withOrgDb, handler$18);
2472
- orgScoped.post("/credentials", withOrgDb, handler$17);
2473
- orgScoped.get("/credentials/:credentialId", withOrgDb, (c, next) => c.req.param("credentialId") === "instances" ? next() : handler$16(c, next));
2474
- orgScoped.patch("/credentials/:credentialId", withOrgDb, handler$15);
2475
- orgScoped.delete("/credentials/:credentialId", withOrgDb, deleteCredential);
2476
- orgScoped.get("/projects", handler$40);
2477
- orgScoped.get("/projects/slug-available", handler$37);
2478
- orgScoped.get("/projects/metrics", withOrgDb, handler$39);
2479
- orgScoped.post("/projects", handler$38);
2480
- projectScoped.get("/:projectId", requireProject(), requireProjectMember, handler$36);
2481
- projectScoped.patch("/:projectId", requireProject(), requireProjectMember, requireProjectUpdate, handler$35);
2482
- projectScoped.delete("/:projectId", requireProject(), requireProjectMember, requireProjectDelete, handler$34);
2483
- projectScoped.get("/:projectId/settings", requireProject(), requireProjectMember, handler$20);
2484
- projectScoped.patch("/:projectId/settings", requireProject(), requireProjectMember, requireProjectUpdate, handler$19);
2485
- projectScoped.get("/:projectId/members", requireProject(), requireProjectMember, handler$25);
2486
- projectScoped.post("/:projectId/members", requireProject(), requireProjectMember, requireInvitableProjectRole, handler$24);
2487
- projectScoped.patch("/:projectId/members/:userId", requireProject(), requireProjectMember, requireProjectManageMembers, handler$23);
2488
- projectScoped.delete("/:projectId/members/:userId", requireProject(), requireProjectMember, requireProjectManageMembers, handler$22);
2489
- projectScoped.delete("/:projectId/members/me", requireProject(), requireProjectMember, handler$21);
2490
- projectScoped.get("/:projectId/reachability", requireProject(), requireProjectMember, createProjectReachabilityHandler(options.hosting));
2491
- projectScoped.get("/:projectId/files", requireProject(), requireProjectMember, withOrgDb, handler$27);
2492
- projectScoped.get("/:projectId/artifacts/:artifactId/files/content", requireProject(), requireProjectMember, handler$26);
2493
- projectScoped.get("/:projectId/deployments", requireProject(), requireProjectMember, handler$33);
2494
- projectScoped.get("/:projectId/artifacts/active/download", requireProject(), requireProjectMember, requireProjectDeploy, handler$31);
2495
- projectScoped.post("/:projectId/artifacts", requireProject(), requireProjectMember, requireProjectDeploy, handler$32);
2496
- projectScoped.post("/:projectId/artifacts/:artifactId/complete", requireProject(), requireProjectMember, requireProjectDeploy, handler$30);
2497
- projectScoped.post("/:projectId/artifacts/:artifactId/source/presign", requireProject(), requireProjectMember, requireProjectDeploy, handler$29);
2498
- projectScoped.post("/:projectId/artifacts/:artifactId/source/manifest", requireProject(), requireProjectMember, requireProjectDeploy, handler$28);
2499
- orgScoped.route("/projects", projectScoped);
2500
- account.route("/", orgScoped);
2501
- return account;
2502
- }
2503
- //#endregion
2504
- //#region src/middleware/require-worker-token.ts
2505
- /** Worker auth from Bearer or x-api-key (Anthropic SDK uses the latter). */
2506
- function readWorkerTokenFromRequest(c) {
2507
- const authorization = c.req.header("authorization");
2508
- if (authorization?.startsWith("Bearer ")) return authorization.slice(7).trim();
2509
- const apiKey = c.req.header("x-api-key")?.trim();
2510
- if (apiKey) return apiKey;
2511
- }
2512
- function requireWorkerToken(expectedToken) {
2513
- return async (c, next) => {
2514
- if (!expectedToken) return c.json({
2515
- error: "worker_auth_unconfigured",
2516
- message: "Worker auth is not configured."
2517
- }, 503);
2518
- const token = readWorkerTokenFromRequest(c);
2519
- if (!token || token !== expectedToken) return c.json({
2520
- error: "unauthorized",
2521
- message: "Invalid worker token."
2522
- }, 401);
2523
- await next();
2524
- };
2525
- }
2526
- //#endregion
2527
- //#region src/routes/internal/web-search-proxy.ts
2528
- const EXA_API_ORIGIN = "https://api.exa.ai";
2529
- async function proxyExaWebSearchRequest(options) {
2530
- const apiKey = options.apiKey?.trim();
2531
- if (!apiKey) return Response.json({ error: "web_search_unconfigured" }, { status: 501 });
2532
- const target = new URL(`${EXA_API_ORIGIN}/${options.path.replace(/^\/+/, "")}`);
2533
- target.search = new URL(options.requestUrl).search;
2534
- const response = await (options.fetchImpl ?? fetch)(target, {
2535
- method: options.method,
2536
- headers: {
2537
- "content-type": "application/json",
2538
- "x-api-key": apiKey
2539
- },
2540
- body: options.method === "GET" || options.method === "HEAD" ? void 0 : options.body
2541
- });
2542
- const headers = new Headers(response.headers);
2543
- headers.delete("content-encoding");
2544
- headers.delete("transfer-encoding");
2545
- return new Response(response.body, {
2546
- status: response.status,
2547
- statusText: response.statusText,
2548
- headers
2549
- });
2550
- }
2551
- //#endregion
2552
- //#region src/routes/internal/with-project-scope.ts
2553
- async function withProjectScope(projectId, fn) {
2554
- const project = await (0, _keystrokehq_platform_database.selectProjectById)(projectId);
2555
- if (!project) return;
2556
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(project.organizationId);
2557
- if (!organization) return;
2558
- const url = (0, _keystrokehq_platform_database.resolveOrgDatabaseUrl)(organization);
2559
- let result;
2560
- await (0, _keystrokehq_platform_database.runWithOrganizationScope)(project.organizationId, () => (0, _keystrokehq_database.runWithProjectDatabase)({
2561
- url,
2562
- searchPath: organization.dbSchema
2563
- }, () => (0, _keystrokehq_database.runWithProjectScope)(project.id, () => (0, _keystrokehq_database.runWithTenantScope)(project.organizationId, async () => {
2564
- result = await fn({
2565
- organizationId: project.organizationId,
2566
- projectId: project.id
2567
- });
2568
- }))));
2569
- return result;
2570
- }
2571
- //#endregion
2572
- //#region src/routes/internal/mount.ts
2573
- const EnsureWebhookRouteBodySchema = zod.z.object({
2574
- route: zod.z.string().trim().min(1),
2575
- attachmentKeys: zod.z.array(zod.z.string().trim().min(1)).min(1)
2576
- });
2577
- const SandboxSessionBodySchema = zod.z.object({
2578
- agentId: zod.z.string().trim().min(1),
2579
- sessionId: zod.z.string().trim().min(1)
2580
- });
2581
- const SandboxExecBodySchema = SandboxSessionBodySchema.extend({
2582
- script: zod.z.string(),
2583
- options: zod.z.object({
2584
- cwd: zod.z.string().optional(),
2585
- env: zod.z.record(zod.z.string(), zod.z.string()).optional(),
2586
- stdin: zod.z.string().optional()
2587
- }).optional()
2588
- });
2589
- const SandboxReadBodySchema = SandboxSessionBodySchema.extend({ path: zod.z.string().trim().min(1) });
2590
- const SandboxWriteBodySchema = SandboxSessionBodySchema.extend({
2591
- path: zod.z.string().trim().min(1),
2592
- content: zod.z.string()
2593
- });
2594
- function mountInternalRoutes(workerToken, tokenRefresh, llmProxy, sandboxProxy, mcp) {
2595
- const internal = new hono.Hono();
2596
- const protect = requireWorkerToken(workerToken);
2597
- const materialize = (0, _keystrokehq_runtime.createCredentialMaterializeHandler)(tokenRefresh);
2598
- internal.use("/*", protect);
2599
- mcp?.mountInternalRoutes?.(internal, { withProjectScope });
2600
- internal.post("/projects/:projectId/credentials/materialize", async (c) => {
2601
- const response = await withProjectScope(c.req.param("projectId"), async () => materialize(c));
2602
- if (response === void 0) return c.json({ error: "Project not found" }, 404);
2603
- return response ?? c.json({
2604
- error: "internal_error",
2605
- message: "Failed to materialize credential."
2606
- }, 500);
2607
- });
2608
- internal.all("/projects/:projectId/web-search/:path{.+}", async (c) => {
2609
- const body = c.req.method === "GET" || c.req.method === "HEAD" ? void 0 : await c.req.arrayBuffer();
2610
- return proxyExaWebSearchRequest({
2611
- apiKey: process.env.EXA_API_KEY,
2612
- method: c.req.method,
2613
- path: c.req.param("path"),
2614
- requestUrl: c.req.url,
2615
- body
2616
- });
2617
- });
2618
- if (llmProxy) internal.all("/projects/:projectId/llm/:path{.+}", async (c) => {
2619
- const response = await withProjectScope(c.req.param("projectId"), async (ctx) => llmProxy.handler(c, {
2620
- organizationId: ctx.organizationId,
2621
- projectId: ctx.projectId,
2622
- pathSuffix: `/${c.req.param("path")}`
2623
- }));
2624
- if (response === void 0) return c.json({ error: "Project not found" }, 404);
2625
- return response ?? c.json({
2626
- error: "internal_error",
2627
- message: "Failed to proxy LLM request."
2628
- }, 500);
2629
- });
2630
- if (sandboxProxy) {
2631
- internal.post("/projects/:projectId/sandbox/create", async (c) => {
2632
- const projectId = c.req.param("projectId");
2633
- const parsed = SandboxSessionBodySchema.safeParse(await c.req.json().catch(() => null));
2634
- if (!parsed.success) return c.json({
2635
- error: "Invalid request body",
2636
- details: parsed.error.flatten()
2637
- }, 400);
2638
- const result = await withProjectScope(projectId, async (ctx) => sandboxProxy.create({
2639
- ...ctx,
2640
- ...parsed.data
2641
- }));
2642
- if (result === void 0) return c.json({ error: "Project not found" }, 404);
2643
- return c.json(result);
2644
- });
2645
- internal.post("/projects/:projectId/sandbox/exec", async (c) => {
2646
- const projectId = c.req.param("projectId");
2647
- const parsed = SandboxExecBodySchema.safeParse(await c.req.json().catch(() => null));
2648
- if (!parsed.success) return c.json({
2649
- error: "Invalid request body",
2650
- details: parsed.error.flatten()
2651
- }, 400);
2652
- const { script, options, ...session } = parsed.data;
2653
- const result = await withProjectScope(projectId, async (ctx) => sandboxProxy.exec({
2654
- ...ctx,
2655
- ...session
2656
- }, script, options));
2657
- if (result === void 0) return c.json({ error: "Project not found" }, 404);
2658
- return c.json(result);
2659
- });
2660
- internal.post("/projects/:projectId/sandbox/read", async (c) => {
2661
- const projectId = c.req.param("projectId");
2662
- const parsed = SandboxReadBodySchema.safeParse(await c.req.json().catch(() => null));
2663
- if (!parsed.success) return c.json({
2664
- error: "Invalid request body",
2665
- details: parsed.error.flatten()
2666
- }, 400);
2667
- const { path, ...session } = parsed.data;
2668
- const content = await withProjectScope(projectId, async (ctx) => sandboxProxy.readFile({
2669
- ...ctx,
2670
- ...session
2671
- }, path));
2672
- if (content === void 0) return c.json({ error: "Project not found" }, 404);
2673
- return c.json({ content });
2674
- });
2675
- internal.post("/projects/:projectId/sandbox/write", async (c) => {
2676
- const projectId = c.req.param("projectId");
2677
- const parsed = SandboxWriteBodySchema.safeParse(await c.req.json().catch(() => null));
2678
- if (!parsed.success) return c.json({
2679
- error: "Invalid request body",
2680
- details: parsed.error.flatten()
2681
- }, 400);
2682
- const { path, content, ...session } = parsed.data;
2683
- if (await withProjectScope(projectId, async (ctx) => {
2684
- await sandboxProxy.writeFile({
2685
- ...ctx,
2686
- ...session
2687
- }, path, content);
2688
- return true;
2689
- }) === void 0) return c.json({ error: "Project not found" }, 404);
2690
- return c.json({});
2691
- });
2692
- internal.post("/projects/:projectId/sandbox/dispose", async (c) => {
2693
- const projectId = c.req.param("projectId");
2694
- const parsed = SandboxSessionBodySchema.safeParse(await c.req.json().catch(() => null));
2695
- if (!parsed.success) return c.json({
2696
- error: "Invalid request body",
2697
- details: parsed.error.flatten()
2698
- }, 400);
2699
- if (await withProjectScope(projectId, async (ctx) => {
2700
- await sandboxProxy.dispose({
2701
- ...ctx,
2702
- ...parsed.data
2703
- });
2704
- return true;
2705
- }) === void 0) return c.json({ error: "Project not found" }, 404);
2706
- return c.json({});
2707
- });
2708
- }
2709
- internal.post("/projects/:projectId/webhooks/ensure", async (c) => {
2710
- const projectId = c.req.param("projectId");
2711
- if (!await withProjectScope(projectId, async (ctx) => ctx)) return c.json({ error: "Project not found" }, 404);
2712
- const parsed = EnsureWebhookRouteBodySchema.safeParse(await c.req.json().catch(() => null));
2713
- if (!parsed.success) return c.json({
2714
- error: "Invalid request body",
2715
- details: parsed.error.flatten()
2716
- }, 400);
2717
- const origin = (0, _keystrokehq_http.platformWebhookOrigin)(projectId, (0, _keystrokehq_http.externalPlatformOrigin)());
2718
- if (!origin) return c.json({ error: "PUBLIC_PLATFORM_URL is not configured" }, 500);
2719
- try {
2720
- const token = await (0, _keystrokehq_platform_database.ensureWebhookApiKeyForRoute)(projectId, parsed.data.route, parsed.data.attachmentKeys);
2721
- return c.json({ webhookUrl: (0, _keystrokehq_runtime.buildWebhookUrl)(origin, parsed.data.route, token) });
2722
- } catch (error) {
2723
- const message = error instanceof Error ? error.message : "Failed to ensure webhook API key.";
2724
- return c.json({
2725
- error: "webhook_provisioning_failed",
2726
- message
2727
- }, 500);
2728
- }
2729
- });
2730
- return internal;
2731
- }
2732
- //#endregion
2733
- //#region src/app.ts
2734
- async function createApp(auth, options) {
2735
- return (0, _keystrokehq_http.createApp)({
2736
- mode: "platform",
2737
- webOrigin: options.webOrigin,
2738
- schedulerPlugin: options.scheduler,
2739
- mcp: options.mcp,
2740
- auth,
2741
- mountAuth: (app, authInstance) => {
2742
- mountAuth(app, authInstance);
2743
- },
2744
- mountAccount: async (app) => {
2745
- app.route("/api", mountAccountRoutes({
2746
- hosting: options.hosting,
2747
- storage: options.storage,
2748
- mcp: options.mcp
2749
- }));
2750
- },
2751
- mountInternal: (app, { tokenRefresh }) => {
2752
- app.route("/internal", mountInternalRoutes(options.hosting.workerRuntime.workerToken, tokenRefresh, options.llmProxy, options.sandboxProxy, options.mcp));
2753
- }
2754
- });
2755
- }
2756
- //#endregion
2757
- //#region src/start.ts
2758
- /** Fly `internal_port` — not the public HTTPS URL port. */
2759
- const PRODUCTION_PLATFORM_LISTEN_PORT = 8080;
2760
- const LOCAL_PLATFORM_PORT = 3002;
2761
- function resolvePlatformListenPort() {
2762
- if (process.env.NODE_ENV === "production") return PRODUCTION_PLATFORM_LISTEN_PORT;
2763
- return require_dist.listenPortFromPublicUrl(process.env.PUBLIC_PLATFORM_URL, LOCAL_PLATFORM_PORT);
2764
- }
2765
- function usesPgBossScheduler(platformConfig) {
2766
- return platformConfig.scheduler.name === "pg-boss" || platformConfig.scheduler.name === "default";
2767
- }
2768
- async function startPlatformServer(platformConfig, hooks = {}) {
2769
- const runtime = platformConfig.hosting.createRuntime();
2770
- await (0, _keystrokehq_platform_database.initDatabase)();
2771
- await require_dist.ensureKeystrokeAssetsBucket();
2772
- await (0, _keystrokehq_runtime.seedOAuthAppsFromEnvForAllOrganizations)();
2773
- if (usesPgBossScheduler(platformConfig)) await (0, _keystrokehq_platform_database.ensureProjectPgBossGrants)();
2774
- configureProjectRuntimeScheduler(platformConfig.scheduler);
2775
- await startProjectRuntimeWorker(runtime, { resolveStartInput: async (job) => {
2776
- const organization = await (0, _keystrokehq_platform_database.selectOrganizationById)(job.organizationId);
2777
- if (!organization) throw new Error(`Organization ${job.organizationId} not found`);
2778
- const database = await (0, _keystrokehq_platform_database.resolveOrgRuntimeDatabase)(job.organizationId);
2779
- const workerRuntime = platformConfig.hosting.workerRuntime;
2780
- return {
2781
- organizationId: job.organizationId,
2782
- projects: [],
2783
- database: {
2784
- ...database,
2785
- organizationId: job.organizationId
2786
- },
2787
- env: {
2788
- ...(0, _keystrokehq_platform_database.orgWorkspacesRuntimeEnv)(organization, { containerEnv: process.env }),
2789
- ...platformConfig.llmProxy?.workerEnv({
2790
- platformUrl: workerRuntime.platformUrl,
2791
- workerToken: workerRuntime.workerToken
2792
- }),
2793
- ...platformConfig.sandboxProxy?.workerEnv({
2794
- platformUrl: workerRuntime.platformUrl,
2795
- workerToken: workerRuntime.workerToken
2796
- }),
2797
- ...platformConfig.workerEnv?.({
2798
- platformUrl: workerRuntime.platformUrl,
2799
- workerToken: workerRuntime.workerToken
2800
- })
2801
- },
2802
- hosting: organization.hostingAppName ? { appName: organization.hostingAppName } : void 0,
2803
- previousRuntimeId: organization.runtimeId
2804
- };
2805
- } });
2806
- const webUrl = process.env.PUBLIC_WEB_URL;
2807
- if (!webUrl) throw new Error("PUBLIC_WEB_URL is required for the platform server");
2808
- const platformUrl = process.env.PUBLIC_PLATFORM_URL?.replace(/\/+$/, "");
2809
- if (!platformUrl) throw new Error("PUBLIC_PLATFORM_URL is required for the platform server");
2810
- const auth = (0, _keystrokehq_auth.createAuth)({
2811
- baseURL: platformUrl,
2812
- verificationUri: `${webUrl.replace(/\/+$/, "")}/device`,
2813
- trustedOrigins: [webUrl]
2814
- });
2815
- if (!auth) throw new Error("BETTER_AUTH_SECRET is required for the platform server");
2816
- const app = await createApp(auth, {
2817
- webOrigin: webUrl,
2818
- hosting: platformConfig.hosting,
2819
- storage: platformConfig.storage,
2820
- scheduler: platformConfig.scheduler,
2821
- llmProxy: platformConfig.llmProxy,
2822
- sandboxProxy: platformConfig.sandboxProxy,
2823
- mcp: platformConfig.mcp
2824
- });
2825
- await hooks.afterCreateApp?.(app);
2826
- const port = resolvePlatformListenPort();
2827
- (0, _hono_node_server.serve)({
2828
- fetch: app.fetch,
2829
- port
2830
- }, (info) => {
2831
- console.log(`Platform API listening on http://localhost:${info.port}`);
2832
- });
2833
- }
2834
- //#endregion
2835
- Object.defineProperty(exports, "startPlatformServer", {
2836
- enumerable: true,
2837
- get: function() {
2838
- return startPlatformServer;
2839
- }
2840
- });
2841
-
2842
- //# sourceMappingURL=start-CBrH4KOb.cjs.map