@runeya/runeya 2.0.9 → 2.0.11

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 (318) hide show
  1. package/agent/index.js +513 -52
  2. package/agent/index.js.map +1 -1
  3. package/agent-manager-V47DLMYP-26VYXTSG.js +8 -0
  4. package/{chunk-BSPKMRKW.js → chunk-6547GLUJ.js} +49 -16
  5. package/chunk-6547GLUJ.js.map +1 -0
  6. package/{dist-PSPHMTZN.js → dist-2H7XZQCV.js} +1255 -378
  7. package/dist-2H7XZQCV.js.map +1 -0
  8. package/index.js +6 -1
  9. package/index.js.map +1 -1
  10. package/package.json +1 -1
  11. package/web/assets/AddressBar.vue-BxQkuTJ-.js +1 -0
  12. package/web/assets/AgentScalarChatInterface.vue-BZyh4z8j.js +13 -0
  13. package/web/assets/AgentTerminalPage-SWnqcTm-.js +1 -0
  14. package/web/assets/AgentTerminalPage-anYDkj7H.css +1 -0
  15. package/web/assets/AiChatPage-PJvieNVr.js +1 -0
  16. package/web/assets/AppLayout-CDtyYNWp.css +1 -0
  17. package/web/assets/AppLayout-qD2ReaTx.js +1 -0
  18. package/web/assets/AuditPage-DCvW5-HA.js +1 -0
  19. package/web/assets/CodeInput.vue-DDs5Eel7.js +1 -0
  20. package/web/assets/Collection.vue-HH2Z976J.js +1 -0
  21. package/web/assets/CollectionAuthentication.vue-BbsKOTJ9.js +1 -0
  22. package/web/assets/CollectionCookies.vue-Dzlq0l8S.js +1 -0
  23. package/web/assets/CollectionEnvironment.vue-BS9B1OU-.js +1 -0
  24. package/web/assets/CollectionOverview.vue-DXXQHn9J.js +1 -0
  25. package/web/assets/CollectionScripts.vue-TVNOxHuu.js +1 -0
  26. package/web/assets/CollectionServers.vue-DDyH4n80.js +1 -0
  27. package/web/assets/CollectionSettings.vue-BD5QvG5c.js +1 -0
  28. package/web/assets/CollectionSync.vue-g_NhkdXC.js +1 -0
  29. package/web/assets/CommandActionInput.vue-Cot3fJDd.js +1 -0
  30. package/web/assets/Cookies.vue-X8bc_7ud.js +1 -0
  31. package/web/assets/DashboardPage-BuP2oOo3.js +1 -0
  32. package/web/assets/DataTable.vue-DmcNIRcD.js +1 -0
  33. package/web/assets/DataTableCheckbox.vue-B7bvOQ_f.js +1 -0
  34. package/web/assets/{DataTableHeader.vue-ByesjY2f.js → DataTableHeader.vue-D5k0UCfl.js} +1 -1
  35. package/web/assets/DataTableInput.vue-DVUCY60y.js +1 -0
  36. package/web/assets/DeleteSidebarListElement.vue-CAri6AWj.js +1 -0
  37. package/web/assets/EditSidebarListElement.vue-DFY1ZZNE.js +1 -0
  38. package/web/assets/{EditorIcon-B70ii4EM.js → EditorIcon-DOV6wP8X.js} +2 -2
  39. package/web/assets/{EmptyState.vue-CcnWPtfW.js → EmptyState.vue-watFzTsD.js} +2 -2
  40. package/web/assets/Environment.vue-BbpisYLs.js +1 -0
  41. package/web/assets/EnvironmentForm-CyJtNH2k.js +108 -0
  42. package/web/assets/EnvironmentFormPage-Du4EXZlm.js +1 -0
  43. package/web/assets/EnvironmentListPage-1Jdh0AWO.js +1 -0
  44. package/web/assets/EnvironmentModal.vue-DaI310h8.js +1 -0
  45. package/web/assets/EnvironmentSelector-BPhBcKYj.js +1 -0
  46. package/web/assets/Form.vue-CMWUiD6f.js +1 -0
  47. package/web/assets/IconSelector.vue-90PWhHNq.js +1 -0
  48. package/web/assets/KanbanBoardPage-DzFRgXlJ.js +141 -0
  49. package/web/assets/KanbanListPage-O3T-L6z3.js +1 -0
  50. package/web/assets/LaunchProjectPage-B2m_PflY.js +1 -0
  51. package/web/assets/LaunchServicesPage-DgfE9971.js +1 -0
  52. package/web/assets/LogViewer-CXVXsymr.js +3 -0
  53. package/web/assets/ProcessControls-DVQwL-qx.js +1 -0
  54. package/web/assets/ProcessDetailPage-8GtSwfXG.js +1 -0
  55. package/web/assets/ProcessDetailPage-CzGUsQM9.css +1 -0
  56. package/web/assets/ProcessMetrics-9RjmvDOk.js +51 -0
  57. package/web/assets/ProjectDetailPage-B3s8bbmw.js +1 -0
  58. package/web/assets/ProjectListPage-HQ9gZWHw.js +1 -0
  59. package/web/assets/RandomJobTestPage-DAM5nNLf.js +2 -0
  60. package/web/assets/Request.vue-DiF4lAAD.js +1 -0
  61. package/web/assets/RequestAuth.vue-DHU9RNUf.js +1 -0
  62. package/web/assets/RequestRoot.vue-BiM2Tr20.js +19 -0
  63. package/web/assets/ScalarAsciiArt.vue-2vz_9aEa.js +2 -0
  64. package/web/assets/{ScalarIconEyeSlash.vue-DWKhR_BX.js → ScalarIconEyeSlash.vue-CwJnZ-zD.js} +1 -1
  65. package/web/assets/{ScalarIconTrash.vue-CtSwrO5S.js → ScalarIconTrash.vue-DAEOI9Kk.js} +1 -1
  66. package/web/assets/ScenarioEditorPage-BzPL_7Up.js +14 -0
  67. package/web/assets/ServerVariablesForm.vue-Dj2R8IEV.js +1 -0
  68. package/web/assets/ServiceControlsBar-CsHZTuPK.js +1 -0
  69. package/web/assets/ServiceDetailPage-Csf55wQD.js +2 -0
  70. package/web/assets/ServiceDetailPage-znbWajpt.css +1 -0
  71. package/web/assets/ServiceFormPage-DDJYv2z3.js +1 -0
  72. package/web/assets/Settings.vue-Dyzw_xwE.js +1 -0
  73. package/web/assets/SettingsPage-CYQGpGyw.js +225 -0
  74. package/web/assets/SettingsPage-CgJN_IL7.css +1 -0
  75. package/web/assets/SetupKeyPage-CnaFhUR6.js +1 -0
  76. package/web/assets/SetupPage-sqBZmTQ9.js +1 -0
  77. package/web/assets/Sidebar.vue-DqiliUT_.js +1 -0
  78. package/web/assets/SidebarButton.vue-MCBoC3jO.js +1 -0
  79. package/web/assets/SidebarListElement.vue-DswWWg_S.js +1 -0
  80. package/web/assets/UnlockPage-rDy89SdE.js +1 -0
  81. package/web/assets/VariablesTable-CEaksHyg.js +1 -0
  82. package/web/assets/{VariablesTable-BtdK5olT.css → VariablesTable-W4rxlL35.css} +1 -1
  83. package/web/assets/ViewLayout.vue-CgpeQh3K.js +1 -0
  84. package/web/assets/ViewLayoutContent.vue-DP_GK_Ip.js +1 -0
  85. package/web/assets/ViewLayoutSection.vue-YQYzkcAB.js +1 -0
  86. package/web/assets/active-entities-CWFFm964.js +1 -0
  87. package/web/assets/api-reference-UJl6P2J4.js +1 -0
  88. package/web/assets/autocomplete-CK9Z1-Wz.js +422 -0
  89. package/web/assets/card-DadsU5ZI.js +32 -0
  90. package/web/assets/{checkbox-C0sXsL9e.js → checkbox-4z5ftHhs.js} +3 -3
  91. package/web/assets/{chip-rnk9_cKV.js → chip-KJbF4Jjk.js} +2 -2
  92. package/web/assets/column-Cp1kVQOt.js +763 -0
  93. package/web/assets/core-7y546zlP.js +1 -0
  94. package/web/assets/{cssMode-DdlczEni.js → cssMode-CIUATcSv.js} +1 -1
  95. package/web/assets/dist-BLSATgV0.js +1 -0
  96. package/web/assets/{dist-DBBhfLmf.js → dist-Cp1hgSqY.js} +3 -3
  97. package/web/assets/{dist-DeOvPbza.js → dist-CpE_ZYIQ.js} +1 -1
  98. package/web/assets/dist-DR4LqG1l.js +192 -0
  99. package/web/assets/{divider-D6L7p-FU.js → divider-D-vBLTer.js} +2 -2
  100. package/web/assets/editor.store-COpS72tz.js +1 -0
  101. package/web/assets/{fieldset-CiwzR0un.js → fieldset-CSlJxjpZ.js} +2 -2
  102. package/web/assets/{freemarker2-_wLEdPSz.js → freemarker2-Dsxb69Av.js} +1 -1
  103. package/web/assets/{handlebars-66zKrSAk.js → handlebars-ChbvHuc-.js} +1 -1
  104. package/web/assets/{html-oM24gnvF.js → html-DOIF2Zpc.js} +1 -1
  105. package/web/assets/{htmlMode-D65_fKu-.js → htmlMode-DKICvQwb.js} +1 -1
  106. package/web/assets/index-A6eiSk8H.css +1 -0
  107. package/web/assets/{index-D5xJxOo2.js → index-C0UzL9Y-.js} +269 -234
  108. package/web/assets/{javascript-D-njx6Yh.js → javascript-Bmt68E8X.js} +1 -1
  109. package/web/assets/{jsonMode-bqHogKpM.js → jsonMode-CYcvn9c0.js} +1 -1
  110. package/web/assets/{keyboard-BzTLpobK.js → keyboard-DZklF_AY.js} +2 -2
  111. package/web/assets/{lib-CPo2W-Kx.js → lib-B5TdN_ca.js} +4 -4
  112. package/web/assets/{library-DmdL5Pgv.js → library-DtrGq8p8.js} +1 -1
  113. package/web/assets/{liquid-BDL70fhI.js → liquid-3ot_oRqd.js} +1 -1
  114. package/web/assets/{mdx-Bo_N_Jd-.js → mdx-Cm1rlDNM.js} +1 -1
  115. package/web/assets/{mediaTypes-Cnm-r_sv.js → mediaTypes-Bz4C7Sle.js} +2 -2
  116. package/web/assets/{message-gtjFpAbc.js → message-DFReN7Fq.js} +2 -2
  117. package/web/assets/{minus-C5Lsl7Wp.js → minus-t_EQEzUj.js} +2 -2
  118. package/web/assets/{multiselect-BlmCsiSW.js → multiselect-BZbgA1pl.js} +3 -3
  119. package/web/assets/{password-RYOg4soC.js → password-D82un95s.js} +4 -4
  120. package/web/assets/{plus-C52I3-BN.js → plus-B-AhHpHU.js} +6 -6
  121. package/web/assets/pretty-ms-XBeIOdhN.js +202 -0
  122. package/web/assets/process.store-jv0SI_6q.js +1 -0
  123. package/web/assets/project.store-DHXLE6Lv.js +1 -0
  124. package/web/assets/{python-D1UXSNgK.js → python-BuQCsdKw.js} +1 -1
  125. package/web/assets/{radiobutton-B0t-WlKP.js → radiobutton-Btattklk.js} +2 -2
  126. package/web/assets/{razor-Bd4GOtMe.js → razor-DgnEPQLs.js} +1 -1
  127. package/web/assets/router-w5lyb-nn.js +1 -0
  128. package/web/assets/settings.store-bNnLJ43c.js +1 -0
  129. package/web/assets/store-DWOu5TTl.js +1840 -0
  130. package/web/assets/{tabpanel-geoVG-sX.js → tabpanel-CIyzJ44J.js} +3 -3
  131. package/web/assets/{tag-Dv5CaUPa.js → tag-DV-szbCr.js} +2 -2
  132. package/web/assets/trpc-wp_QsEqG.js +1 -0
  133. package/web/assets/{tsMode-BkM4CkKr.js → tsMode-ChD0IpIg.js} +1 -1
  134. package/web/assets/{typescript-CUKl0qxN.js → typescript-BRYpIqKe.js} +1 -1
  135. package/web/assets/urls-CoBMqtDH.js +12 -0
  136. package/web/assets/{use-tree-walker-E64HILpa.js → use-tree-walker-M4-Gn01v.js} +1 -1
  137. package/web/assets/useAiChatDrawer-BhlTNoXz.js +1 -0
  138. package/web/assets/{useClipboard-Bep2crMO.js → useClipboard-Cro2wlg3.js} +1 -1
  139. package/web/assets/{useLayout-F9XKAPPL.js → useLayout-BciG4r-1.js} +1 -1
  140. package/web/assets/{usePluginManager-yL67GqCi.js → usePluginManager-BonTfGSN.js} +1 -1
  141. package/web/assets/useSidebar-77_u4hef.js +1 -0
  142. package/web/assets/{vue-router-uE6ClrN-.js → vue-router-DdBypSuY.js} +1 -1
  143. package/web/assets/{xml-DMOW2yTg.js → xml-Cz29Bxul.js} +1 -1
  144. package/web/assets/{yaml-D2q3K0ZL.js → yaml-CiZl2tNW.js} +1 -1
  145. package/web/index.html +2 -2
  146. package/agent-manager-UP3PJ35X-LO6B3XKF.js +0 -8
  147. package/chunk-BSPKMRKW.js.map +0 -1
  148. package/dist-PSPHMTZN.js.map +0 -1
  149. package/web/assets/AddressBar.vue-BOHUxRhN.js +0 -1
  150. package/web/assets/AgentPage-BTWkJvqr.css +0 -1
  151. package/web/assets/AgentPage-DFHxsu-9.js +0 -2
  152. package/web/assets/AgentScalarChatInterface.vue-Cxxiyyj8.js +0 -13
  153. package/web/assets/AgentTerminalPage-D-T5emEl.js +0 -36
  154. package/web/assets/AgentTerminalPage-EX_n6P3x.css +0 -1
  155. package/web/assets/AiChatPage-C81mFvv5.js +0 -1
  156. package/web/assets/ApiDocsPage-CMGvcGEJ.js +0 -5
  157. package/web/assets/ApiDocsPage-D2Z0wqGZ.css +0 -1
  158. package/web/assets/AppLayout-D10vX1fo.js +0 -1
  159. package/web/assets/AppLayout-sngalCCj.css +0 -1
  160. package/web/assets/AuditPage-DZiwogoY.js +0 -1
  161. package/web/assets/CodeInput.vue-8aNMYCYM.js +0 -1
  162. package/web/assets/Collection.vue-N8zZa4pa.js +0 -1
  163. package/web/assets/CollectionAuthentication.vue-cJOxjafo.js +0 -1
  164. package/web/assets/CollectionCookies.vue-DrFQqbwv.js +0 -1
  165. package/web/assets/CollectionEnvironment.vue-DWPTZ8qx.js +0 -1
  166. package/web/assets/CollectionOverview.vue-1Qf130d5.js +0 -1
  167. package/web/assets/CollectionScripts.vue-DhcFFz80.js +0 -1
  168. package/web/assets/CollectionServers.vue-h7E03W0v.js +0 -1
  169. package/web/assets/CollectionSettings.vue-CFrOwl7U.js +0 -1
  170. package/web/assets/CollectionSync.vue-PV_tIrJS.js +0 -1
  171. package/web/assets/CommandActionInput.vue-L7AcEf6T.js +0 -1
  172. package/web/assets/Cookies.vue-_P19OjMm.js +0 -1
  173. package/web/assets/DashboardPage-BUDWnuJT.js +0 -1
  174. package/web/assets/DataTable.vue-DYVeGQPP.js +0 -1
  175. package/web/assets/DataTableCheckbox.vue-n2xCTJj1.js +0 -1
  176. package/web/assets/DataTableInput.vue-uPpuKzrX.js +0 -1
  177. package/web/assets/DeleteSidebarListElement.vue-CBIb58rU.js +0 -1
  178. package/web/assets/EditSidebarListElement.vue-DqTVSZtI.js +0 -1
  179. package/web/assets/Environment.vue-Cgx06nkH.js +0 -1
  180. package/web/assets/EnvironmentForm-iBZzqZKd.js +0 -108
  181. package/web/assets/EnvironmentFormPage-YVxAAreT.js +0 -1
  182. package/web/assets/EnvironmentListPage-CHYDJ_c-.js +0 -1
  183. package/web/assets/EnvironmentModal.vue-BJNYZuPC.js +0 -1
  184. package/web/assets/EnvironmentSelector-BZn_taec.js +0 -1
  185. package/web/assets/Form.vue-NLXFw40d.js +0 -1
  186. package/web/assets/IconSelector.vue-Ykh6DAln.js +0 -1
  187. package/web/assets/KanbanBoardPage-gtXv0ZhK.js +0 -141
  188. package/web/assets/KanbanListPage-DMNSYO_o.js +0 -1
  189. package/web/assets/LaunchProjectPage-DSyBuhky.js +0 -1
  190. package/web/assets/LaunchServicesPage-CiGkiqwE.js +0 -1
  191. package/web/assets/LogViewer-DBVkaZnm.js +0 -3
  192. package/web/assets/ProcessControls-Cya4eb3d.js +0 -1
  193. package/web/assets/ProcessDetailPage-8ypC6zkc.js +0 -1
  194. package/web/assets/ProcessDetailPage-B0qGKtvQ.css +0 -1
  195. package/web/assets/ProcessMetrics-CxRgbaUS.js +0 -1
  196. package/web/assets/ProjectDetailPage-a1lTAjKP.js +0 -1
  197. package/web/assets/ProjectListPage-Dewqu8Dm.js +0 -1
  198. package/web/assets/RandomJobTestPage-E6mevkqw.js +0 -2
  199. package/web/assets/Request.vue-DQPTi6ur.js +0 -1
  200. package/web/assets/RequestAuth.vue-DV5nNO3f.js +0 -1
  201. package/web/assets/RequestRoot.vue-DKlASKU5.js +0 -19
  202. package/web/assets/ScalarAsciiArt.vue-mk9jZSKh.js +0 -2
  203. package/web/assets/ScenarioEditorPage-DogHTbNU.js +0 -14
  204. package/web/assets/ServerVariablesForm.vue-DYmWiAuz.js +0 -1
  205. package/web/assets/ServiceControlsBar-B8Sm6p9E.js +0 -1
  206. package/web/assets/ServiceDetailPage-BriHTCpT.css +0 -1
  207. package/web/assets/ServiceDetailPage-DpWLccOg.js +0 -2
  208. package/web/assets/ServiceFormPage-DQbOgtB3.js +0 -1
  209. package/web/assets/Settings.vue-buoYkM3l.js +0 -1
  210. package/web/assets/SettingsPage-CCjZq5jP.js +0 -508
  211. package/web/assets/SettingsPage-vGhb_tlY.css +0 -1
  212. package/web/assets/SetupKeyPage-BdSpJPDR.js +0 -1
  213. package/web/assets/SetupPage-BsWaVllB.js +0 -1
  214. package/web/assets/Sidebar.vue-DntMEn5m.js +0 -1
  215. package/web/assets/SidebarButton.vue-DTin2zI2.js +0 -1
  216. package/web/assets/SidebarListElement.vue-zlfRLuE5.js +0 -1
  217. package/web/assets/UnlockPage-CmwRV1XA.js +0 -1
  218. package/web/assets/VariablesTable-C8lxLV1V.js +0 -1
  219. package/web/assets/ViewLayout.vue-C7w_U_o6.js +0 -1
  220. package/web/assets/ViewLayoutContent.vue-CAXM5eIo.js +0 -1
  221. package/web/assets/ViewLayoutSection.vue-BzJIsja7.js +0 -1
  222. package/web/assets/active-entities-C2TbBQeI.js +0 -1
  223. package/web/assets/api-reference-BJkGMKQj.js +0 -1
  224. package/web/assets/autocomplete-CxPmwkcZ.js +0 -308
  225. package/web/assets/card-D5_gGGD-.js +0 -32
  226. package/web/assets/column-ChvIrUdH.js +0 -763
  227. package/web/assets/core-wYvkV3-A.js +0 -1
  228. package/web/assets/dist-BHh6fQzR.js +0 -1
  229. package/web/assets/dist-ZJ37S89a.js +0 -192
  230. package/web/assets/editor.store-CWtgIxvE.js +0 -1
  231. package/web/assets/index-Pqvy10Qz.css +0 -1
  232. package/web/assets/pretty-ms-BBvjfSt1.js +0 -202
  233. package/web/assets/process.store-3BOses3z.js +0 -1
  234. package/web/assets/project.store-emr8mjg8.js +0 -1
  235. package/web/assets/router-DHhyM3YQ.js +0 -1
  236. package/web/assets/settings.store-CDr0Mia7.js +0 -1
  237. package/web/assets/store-CZKREOuj.js +0 -1840
  238. package/web/assets/toggleswitch-DNzwv4Lc.js +0 -115
  239. package/web/assets/trpc-B-vyi6vd.js +0 -1
  240. package/web/assets/urls-BqL-MrG5.js +0 -12
  241. package/web/assets/useAiChatDrawer-uS6dsG6x.js +0 -1
  242. package/web/assets/useSidebar-DVRRagIa.js +0 -1
  243. /package/{agent-manager-UP3PJ35X-LO6B3XKF.js.map → agent-manager-V47DLMYP-26VYXTSG.js.map} +0 -0
  244. /package/web/assets/{_plugin-vue_export-helper-C7ztIXtE.js → _plugin-vue_export-helper-BVSTY9ge.js} +0 -0
  245. /package/web/assets/{abap-C4tHUUCU.js → abap-BF8nUS5p.js} +0 -0
  246. /package/web/assets/{apex-6cG6aG-w.js → apex-Bbj_Fak2.js} +0 -0
  247. /package/web/assets/{azcli-51BngrSU.js → azcli-B8w3JS7J.js} +0 -0
  248. /package/web/assets/{base64-uZi92-DX.js → base64-CG47Jc3Y.js} +0 -0
  249. /package/web/assets/{bat-BDcdVSIt.js → bat-CaNuqacB.js} +0 -0
  250. /package/web/assets/{bicep-Cg0BCcky.js → bicep-DAvnLugW.js} +0 -0
  251. /package/web/assets/{cameligo-C3ekVui9.js → cameligo-BlI8LCmP.js} +0 -0
  252. /package/web/assets/{clojure-Ci5xNgh_.js → clojure-CxxhrBQl.js} +0 -0
  253. /package/web/assets/{coffee-xsRz4GKy.js → coffee-SkbnTBhO.js} +0 -0
  254. /package/web/assets/{cpp-B2gW4e23.js → cpp-Dm2HJxj0.js} +0 -0
  255. /package/web/assets/{csharp-SRujvHqy.js → csharp-BOGHPGcq.js} +0 -0
  256. /package/web/assets/{csp-Cr-ll6gP.js → csp-CMA_7tOs.js} +0 -0
  257. /package/web/assets/{css-BYTJZCno.js → css-DU8LSGcn.js} +0 -0
  258. /package/web/assets/{cypher-AmQ0R_D3.js → cypher-BZPsEDmT.js} +0 -0
  259. /package/web/assets/{dart-Du01a0J5.js → dart-C1tIJhFk.js} +0 -0
  260. /package/web/assets/{dist-DkaYBczY.js → dist-BPIMeATj.js} +0 -0
  261. /package/web/assets/{dockerfile-Dtlk9wqf.js → dockerfile-z4dmGi5q.js} +0 -0
  262. /package/web/assets/{ecl-CpmVnLkK.js → ecl-Rv9JwhOI.js} +0 -0
  263. /package/web/assets/{elixir-B3MVAC8k.js → elixir-DL6xFSed.js} +0 -0
  264. /package/web/assets/{flow9-Chkly0RN.js → flow9-DFZ52-2d.js} +0 -0
  265. /package/web/assets/{fsharp-CZvMkppk.js → fsharp-RvVOB9Dm.js} +0 -0
  266. /package/web/assets/{go-dT2iT7lt.js → go-B2USMDMv.js} +0 -0
  267. /package/web/assets/{graphql-DmObWyBD.js → graphql-CsHpCYeJ.js} +0 -0
  268. /package/web/assets/{hcl-D1x5Oyp4.js → hcl-CK021J-J.js} +0 -0
  269. /package/web/assets/{ini-Bg2o1S3s.js → ini-v1EoSUxR.js} +0 -0
  270. /package/web/assets/{java-XviKSSn5.js → java-CUXpSPxY.js} +0 -0
  271. /package/web/assets/{julia-DfTIwUGh.js → julia-DwKveiZg.js} +0 -0
  272. /package/web/assets/{kotlin-CNaIBh9d.js → kotlin-SsG_4ZBt.js} +0 -0
  273. /package/web/assets/{less-D7o76tXd.js → less-BviquM8A.js} +0 -0
  274. /package/web/assets/{lexon-Dd374QjV.js → lexon-C8G_qWst.js} +0 -0
  275. /package/web/assets/{lua-DZKuiFbY.js → lua-xqYje_o5.js} +0 -0
  276. /package/web/assets/{m3-CbwRx9Bb.js → m3-B5PetinG.js} +0 -0
  277. /package/web/assets/{markdown-DwLB5Rib.js → markdown-BksexNux.js} +0 -0
  278. /package/web/assets/{mips-DLbIq1yM.js → mips-DKSTezUQ.js} +0 -0
  279. /package/web/assets/{msdax-D4IjoZ6m.js → msdax-SeFNE86e.js} +0 -0
  280. /package/web/assets/{mysql-DQL_jy6H.js → mysql-5TQWJDdB.js} +0 -0
  281. /package/web/assets/{objective-c-D74wM5bv.js → objective-c-DeaYl08g.js} +0 -0
  282. /package/web/assets/{pascal-5tRlZk4O.js → pascal-CGBtIfZg.js} +0 -0
  283. /package/web/assets/{pascaligo-CAE4rAEt.js → pascaligo-B85wuk0w.js} +0 -0
  284. /package/web/assets/{perl-DREAbuQT.js → perl-Bl61zsEQ.js} +0 -0
  285. /package/web/assets/{pgsql-DASKdyAW.js → pgsql-KgXv5Cq7.js} +0 -0
  286. /package/web/assets/{php-C37ZWqoO.js → php-KRRf0kxu.js} +0 -0
  287. /package/web/assets/{pla-v5u9R8i1.js → pla-CFpO6lSz.js} +0 -0
  288. /package/web/assets/{postiats-Szt5m-7G.js → postiats-B0jQ-DXO.js} +0 -0
  289. /package/web/assets/{powerquery-BzVrUSu3.js → powerquery-T9Ge5xUx.js} +0 -0
  290. /package/web/assets/{powershell-BdbPbX_X.js → powershell-rmYjKoE4.js} +0 -0
  291. /package/web/assets/{protobuf-qqDa50tu.js → protobuf-B--9ME3E.js} +0 -0
  292. /package/web/assets/{pug-Cu20UQ5w.js → pug-y0-ppnAV.js} +0 -0
  293. /package/web/assets/{qsharp-DcbHL5X7.js → qsharp-DobgOAC8.js} +0 -0
  294. /package/web/assets/{r-Bvig6Flk.js → r-BHQZIThn.js} +0 -0
  295. /package/web/assets/{redis-BxHDcW3-.js → redis-DMHMVIni.js} +0 -0
  296. /package/web/assets/{redshift-B8dvlzjH.js → redshift-ilRjY5HF.js} +0 -0
  297. /package/web/assets/{restructuredtext-npodtAFM.js → restructuredtext-jr4YYJbv.js} +0 -0
  298. /package/web/assets/{ruby-DiofbcJD.js → ruby-D-h_0NIs.js} +0 -0
  299. /package/web/assets/{rust-BjYid3-m.js → rust-VxeTSQU2.js} +0 -0
  300. /package/web/assets/{sb-CzcPAP71.js → sb-BlhKufrP.js} +0 -0
  301. /package/web/assets/{scala-Ci4wFrYi.js → scala-IAk6nSCU.js} +0 -0
  302. /package/web/assets/{scheme-D3iWhvP7.js → scheme-Dggdm5LS.js} +0 -0
  303. /package/web/assets/{scss-DdlqDgmu.js → scss-Bzj9Cp1q.js} +0 -0
  304. /package/web/assets/{shell-Bawb9gbH.js → shell-CSwYJdGJ.js} +0 -0
  305. /package/web/assets/{solidity-Z2Sq8PBC.js → solidity-DnWqIXnk.js} +0 -0
  306. /package/web/assets/{sophia--yD-H1Ow.js → sophia-ClaYC_5N.js} +0 -0
  307. /package/web/assets/{sparql-0vv3-wLi.js → sparql-CfjIZAcz.js} +0 -0
  308. /package/web/assets/{sql-0gdWKhmJ.js → sql-DxdJ7snd.js} +0 -0
  309. /package/web/assets/{st-rE-x-DTZ.js → st-DJgQE1uj.js} +0 -0
  310. /package/web/assets/{swift-CSKeG8Ne.js → swift-5cz3wIvv.js} +0 -0
  311. /package/web/assets/{systemverilog-CblNM3Im.js → systemverilog-C8-7QuIt.js} +0 -0
  312. /package/web/assets/{tcl-BYnzj-GZ.js → tcl-C99u42o5.js} +0 -0
  313. /package/web/assets/{twig-DiGWiEtp.js → twig-Cv9kOcBK.js} +0 -0
  314. /package/web/assets/{typespec-a6xMcpXw.js → typespec-DF1s-ehc.js} +0 -0
  315. /package/web/assets/{uuid-B9GFVXPm.js → uuid-6HQMUkhT.js} +0 -0
  316. /package/web/assets/{vb---51HVMC.js → vb-4mpz9ITX.js} +0 -0
  317. /package/web/assets/{w3c-keyname-DDCGDLuI.js → w3c-keyname-emj7Fjc1.js} +0 -0
  318. /package/web/assets/{wgsl-2A8z4pT5.js → wgsl-xExw6Z08.js} +0 -0
package/agent/index.js CHANGED
@@ -397,6 +397,7 @@ var DockerRunner = class {
397
397
  );
398
398
  return {
399
399
  pid: void 0,
400
+ containerName,
400
401
  stdout,
401
402
  stderr,
402
403
  exitPromise,
@@ -526,6 +527,7 @@ var DockerRunner = class {
526
527
  })();
527
528
  return {
528
529
  pid: void 0,
530
+ containerName,
529
531
  stdout,
530
532
  stderr,
531
533
  exitPromise,
@@ -572,6 +574,7 @@ var DockerRunner = class {
572
574
  );
573
575
  return {
574
576
  pid: void 0,
577
+ containerName,
575
578
  stdout,
576
579
  stderr,
577
580
  exitPromise,
@@ -902,7 +905,13 @@ var NotificationPreferencesSchema = z5.object({
902
905
  ai_conversation_error: z5.boolean().default(true),
903
906
  service_error_log: z5.boolean().default(true),
904
907
  service_status_changed: z5.boolean().default(true),
905
- service_health_changed: z5.boolean().default(true)
908
+ service_health_changed: z5.boolean().default(true),
909
+ /** Service IDs excluded from error-log notifications */
910
+ service_error_log_excluded: z5.array(z5.string().max(100)).max(500).default([]),
911
+ /** Service IDs excluded from status-change notifications */
912
+ service_status_changed_excluded: z5.array(z5.string().max(100)).max(500).default([]),
913
+ /** Service IDs excluded from health-change notifications */
914
+ service_health_changed_excluded: z5.array(z5.string().max(100)).max(500).default([])
906
915
  });
907
916
  var SettingsSchema = z5.object({
908
917
  mode: z5.enum(["local-simple", "cloud"]),
@@ -931,7 +940,10 @@ var SettingsPrivateSchema = z5.object({
931
940
  ai_conversation_error: true,
932
941
  service_error_log: true,
933
942
  service_status_changed: true,
934
- service_health_changed: true
943
+ service_health_changed: true,
944
+ service_error_log_excluded: [],
945
+ service_status_changed_excluded: [],
946
+ service_health_changed_excluded: []
935
947
  })),
936
948
  traefikConfig: TraefikConfigSchema.optional()
937
949
  });
@@ -948,9 +960,6 @@ var safePath = z6.string().min(1).max(4096).refine(
948
960
  ).refine(
949
961
  (p) => !/(^|[/\\])\.\.([/\\]|$)/.test(p),
950
962
  { message: "path must not contain path-traversal sequences (..)" }
951
- ).refine(
952
- (p) => p.startsWith("/") || /^[A-Za-z]:[/\\]/.test(p),
953
- { message: "path must be absolute" }
954
963
  );
955
964
  var ConsoleLogSourceSchema = z6.object({
956
965
  type: z6.literal("console")
@@ -959,7 +968,8 @@ var FileLogSourceSchema = z6.object({
959
968
  type: z6.literal("file"),
960
969
  path: safePath,
961
970
  encoding: z6.string().max(32).default("utf-8"),
962
- startFromEnd: z6.boolean().default(true)
971
+ startFromEnd: z6.boolean().default(true),
972
+ createIfNotExists: z6.boolean().default(false)
963
973
  });
964
974
  var MongoLogSourceSchema = z6.object({
965
975
  type: z6.literal("mongo"),
@@ -2010,6 +2020,21 @@ var FileLogSource = class extends EventEmitter2 {
2010
2020
  this.emitSystemLog(processId, `[FileLogSource] Permission denied: ${this.config.path}`, "error");
2011
2021
  return;
2012
2022
  }
2023
+ if (nodeErr.code === "ENOENT" && this.config.createIfNotExists) {
2024
+ try {
2025
+ await fsPromises.mkdir(
2026
+ (await import("path")).dirname(this.config.path),
2027
+ { recursive: true }
2028
+ );
2029
+ await fsPromises.writeFile(this.config.path, "", { flag: "a" });
2030
+ this.emitSystemLog(processId, `[FileLogSource] File created: ${this.config.path}`, "info");
2031
+ break;
2032
+ } catch (createErr) {
2033
+ const ce = createErr;
2034
+ this.emitSystemLog(processId, `[FileLogSource] Failed to create file: ${ce.message}`, "error");
2035
+ return;
2036
+ }
2037
+ }
2013
2038
  attempts++;
2014
2039
  if (attempts >= RETRY_ATTEMPTS) {
2015
2040
  this.emitSystemLog(processId, `[FileLogSource] File not found after ${RETRY_ATTEMPTS} retries: ${this.config.path}`, "error");
@@ -2475,7 +2500,47 @@ function createLogSource(config, logBuffer, logParser) {
2475
2500
 
2476
2501
  // src/services/metrics-collector.ts
2477
2502
  import pidusage from "pidusage";
2503
+ import { execFile } from "child_process";
2478
2504
  import { EventEmitter as EventEmitter5 } from "events";
2505
+ async function getDockerStats(containerName) {
2506
+ return new Promise((resolve) => {
2507
+ execFile(
2508
+ "docker",
2509
+ ["stats", "--no-stream", "--format", "{{json .}}", containerName],
2510
+ { timeout: 5e3 },
2511
+ (err, stdout) => {
2512
+ if (err || !stdout.trim()) {
2513
+ resolve(null);
2514
+ return;
2515
+ }
2516
+ try {
2517
+ const data = JSON.parse(stdout.trim());
2518
+ const cpu = parseFloat(data.CPUPerc.replace("%", ""));
2519
+ const memStr = data.MemUsage.split("/")[0].trim();
2520
+ const memory = parseMemBytes(memStr);
2521
+ resolve({ cpu: isNaN(cpu) ? 0 : cpu, memory });
2522
+ } catch {
2523
+ resolve(null);
2524
+ }
2525
+ }
2526
+ );
2527
+ });
2528
+ }
2529
+ function parseMemBytes(str) {
2530
+ const m = str.match(/^([\d.]+)\s*(B|kB|MB|MiB|GiB|GB)$/i);
2531
+ if (!m) return 0;
2532
+ const val = parseFloat(m[1]);
2533
+ const unit = m[2].toLowerCase();
2534
+ const multipliers = {
2535
+ b: 1,
2536
+ kb: 1e3,
2537
+ mb: 1e6,
2538
+ mib: 1024 * 1024,
2539
+ gib: 1024 ** 3,
2540
+ gb: 1e9
2541
+ };
2542
+ return Math.round(val * (multipliers[unit] ?? 1));
2543
+ }
2479
2544
  var MetricsCollector = class extends EventEmitter5 {
2480
2545
  intervals = /* @__PURE__ */ new Map();
2481
2546
  intervalMs;
@@ -2483,7 +2548,7 @@ var MetricsCollector = class extends EventEmitter5 {
2483
2548
  super();
2484
2549
  this.intervalMs = intervalMs;
2485
2550
  }
2486
- /** Start collecting metrics for a process */
2551
+ /** Start collecting metrics for a native process (by PID). */
2487
2552
  startCollecting(processId, pid) {
2488
2553
  this.stopCollecting(processId);
2489
2554
  const interval = setInterval(async () => {
@@ -2502,6 +2567,25 @@ var MetricsCollector = class extends EventEmitter5 {
2502
2567
  }, this.intervalMs);
2503
2568
  this.intervals.set(processId, interval);
2504
2569
  }
2570
+ /** Start collecting metrics for a Docker container (by container name). */
2571
+ startCollectingDocker(processId, containerName) {
2572
+ this.stopCollecting(processId);
2573
+ const interval = setInterval(async () => {
2574
+ const stats = await getDockerStats(containerName);
2575
+ if (!stats) {
2576
+ this.stopCollecting(processId);
2577
+ return;
2578
+ }
2579
+ const metrics = {
2580
+ processId,
2581
+ cpu: stats.cpu,
2582
+ memory: stats.memory,
2583
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
2584
+ };
2585
+ this.emit("metrics", metrics);
2586
+ }, this.intervalMs);
2587
+ this.intervals.set(processId, interval);
2588
+ }
2505
2589
  /** Stop collecting metrics for a process */
2506
2590
  stopCollecting(processId) {
2507
2591
  const interval = this.intervals.get(processId);
@@ -2510,23 +2594,31 @@ var MetricsCollector = class extends EventEmitter5 {
2510
2594
  this.intervals.delete(processId);
2511
2595
  }
2512
2596
  }
2513
- /** Get current metrics for a process (one-shot, uses first active PID) */
2597
+ /** Get current metrics for a process (one-shot, uses first active PID or container name). */
2514
2598
  async getMetrics(processId) {
2515
2599
  const proc = processStore.get(processId);
2516
2600
  if (!proc) return null;
2517
2601
  const activePid = proc.commandProcesses.find((cp) => cp.pid !== null)?.pid;
2518
- if (!activePid) return null;
2519
- try {
2520
- const stats = await pidusage(activePid);
2521
- return {
2522
- processId,
2523
- cpu: stats.cpu,
2524
- memory: stats.memory,
2525
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
2526
- };
2527
- } catch {
2528
- return null;
2602
+ if (activePid) {
2603
+ try {
2604
+ const stats = await pidusage(activePid);
2605
+ return {
2606
+ processId,
2607
+ cpu: stats.cpu,
2608
+ memory: stats.memory,
2609
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
2610
+ };
2611
+ } catch {
2612
+ }
2613
+ }
2614
+ const containerName = proc.commandProcesses.find((cp) => cp.containerName)?.containerName;
2615
+ if (containerName) {
2616
+ const stats = await getDockerStats(containerName);
2617
+ if (stats) {
2618
+ return { processId, ...stats, timestamp: (/* @__PURE__ */ new Date()).toISOString() };
2619
+ }
2529
2620
  }
2621
+ return null;
2530
2622
  }
2531
2623
  /** Stop all collection intervals */
2532
2624
  stopAll() {
@@ -2548,8 +2640,8 @@ import { homedir as homedir4 } from "os";
2548
2640
  import { z as z20 } from "zod";
2549
2641
 
2550
2642
  // src/services/traefik-manager.ts
2551
- import { spawn, execFile } from "child_process";
2552
- import { mkdir as mkdir2, writeFile as writeFile2, rename, chmod, access as access2, readFile } from "fs/promises";
2643
+ import { spawn, execFile as execFile2 } from "child_process";
2644
+ import { mkdir as mkdir3, writeFile as writeFile3, rename, chmod, access as access2, readFile } from "fs/promises";
2553
2645
  import { X509Certificate } from "crypto";
2554
2646
  import { join as join2 } from "path";
2555
2647
  import { homedir as homedir3, platform } from "os";
@@ -2575,7 +2667,7 @@ var TraefikManager = class {
2575
2667
  }
2576
2668
  async atomicWrite(filePath, content) {
2577
2669
  const tmpPath = filePath + ".tmp";
2578
- await writeFile2(tmpPath, content, "utf-8");
2670
+ await writeFile3(tmpPath, content, "utf-8");
2579
2671
  await rename(tmpPath, filePath);
2580
2672
  }
2581
2673
  async applyConfig(config) {
@@ -2584,7 +2676,7 @@ var TraefikManager = class {
2584
2676
  await this.stop();
2585
2677
  return;
2586
2678
  }
2587
- await mkdir2(this.dynamicDir, { recursive: true });
2679
+ await mkdir3(this.dynamicDir, { recursive: true });
2588
2680
  await this.writeStaticConfig(config);
2589
2681
  await this.regenerateDynamic();
2590
2682
  await this.stop();
@@ -2629,7 +2721,7 @@ var TraefikManager = class {
2629
2721
  await this.atomicWrite(this.staticConfigPath, yaml);
2630
2722
  }
2631
2723
  async regenerateDynamic() {
2632
- await mkdir2(this.dynamicDir, { recursive: true });
2724
+ await mkdir3(this.dynamicDir, { recursive: true });
2633
2725
  const processes = processStore.getAll();
2634
2726
  const entries = processes.flatMap(
2635
2727
  (p) => (p.serviceConfig.localUrls ?? []).map((lu) => ({ url: lu.url, port: lu.port }))
@@ -2714,7 +2806,7 @@ var TraefikManager = class {
2714
2806
  }
2715
2807
  async ensureAcmeJson() {
2716
2808
  try {
2717
- await writeFile2(this.acmeStorePath, "{}", { flag: "wx" });
2809
+ await writeFile3(this.acmeStorePath, "{}", { flag: "wx" });
2718
2810
  } catch (err) {
2719
2811
  if (err.code !== "EEXIST") throw err;
2720
2812
  }
@@ -2779,7 +2871,7 @@ var TraefikManager = class {
2779
2871
  this.debounceTimer = null;
2780
2872
  }
2781
2873
  await new Promise((resolve) => {
2782
- execFile("docker", ["rm", "-f", "runeya-traefik"], { timeout: 1e4 }, () => resolve());
2874
+ execFile2("docker", ["rm", "-f", "runeya-traefik"], { timeout: 1e4 }, () => resolve());
2783
2875
  });
2784
2876
  await new Promise((resolve) => setTimeout(resolve, 500));
2785
2877
  }
@@ -2821,7 +2913,7 @@ var TraefikManager = class {
2821
2913
  }
2822
2914
  async getLogs(lines = 100) {
2823
2915
  return new Promise((resolve) => {
2824
- execFile("docker", ["logs", "--tail", String(lines), "runeya-traefik"], { timeout: 1e4 }, (err, stdout, stderr) => {
2916
+ execFile2("docker", ["logs", "--tail", String(lines), "runeya-traefik"], { timeout: 1e4 }, (err, stdout, stderr) => {
2825
2917
  if (err) {
2826
2918
  resolve("");
2827
2919
  return;
@@ -2840,7 +2932,7 @@ var TraefikManager = class {
2840
2932
  }
2841
2933
  async forceRenewCert() {
2842
2934
  if (!this.config?.enabled) throw new Error("Traefik non activ\xE9");
2843
- await writeFile2(this.acmeStorePath, "{}", "utf-8");
2935
+ await writeFile3(this.acmeStorePath, "{}", "utf-8");
2844
2936
  await chmod(this.acmeStorePath, 384);
2845
2937
  await this.stop();
2846
2938
  await this.spawnTraefik(this.config);
@@ -2872,7 +2964,7 @@ var TraefikManager = class {
2872
2964
  let dockerAvailable = false;
2873
2965
  try {
2874
2966
  await new Promise((resolve, reject) => {
2875
- execFile("docker", ["info", "--format", "{{.ServerVersion}}"], { timeout: 5e3 }, (err) => {
2967
+ execFile2("docker", ["info", "--format", "{{.ServerVersion}}"], { timeout: 5e3 }, (err) => {
2876
2968
  if (err) reject(err);
2877
2969
  else resolve();
2878
2970
  });
@@ -2892,7 +2984,7 @@ var TraefikManager = class {
2892
2984
  if (dockerAvailable) {
2893
2985
  try {
2894
2986
  const output = await new Promise((resolve, reject) => {
2895
- execFile("docker", ["inspect", "--format", "{{.State.Running}}", "runeya-traefik"], { timeout: 5e3 }, (err, stdout) => {
2987
+ execFile2("docker", ["inspect", "--format", "{{.State.Running}}", "runeya-traefik"], { timeout: 5e3 }, (err, stdout) => {
2896
2988
  if (err) reject(err);
2897
2989
  else resolve(stdout.trim());
2898
2990
  });
@@ -3061,7 +3153,7 @@ var HealthChecker = class extends EventEmitter6 {
3061
3153
  this.stopChecking(id);
3062
3154
  }
3063
3155
  }
3064
- async checkHttp(processId, path, timeout, maxRetries, method = "GET", expectedStatus = 200) {
3156
+ async checkHttp(processId, path3, timeout, maxRetries, method = "GET", expectedStatus = 200) {
3065
3157
  const proc = processStore.get(processId);
3066
3158
  if (!proc || proc.state !== "running") {
3067
3159
  this.updateResult(processId, "unknown", 0);
@@ -3072,7 +3164,7 @@ var HealthChecker = class extends EventEmitter6 {
3072
3164
  this.updateResult(processId, "unknown", 0);
3073
3165
  return;
3074
3166
  }
3075
- const url = `http://localhost:${port}${path}`;
3167
+ const url = `http://localhost:${port}${path3}`;
3076
3168
  let failures = this.failureCounts.get(processId) ?? 0;
3077
3169
  try {
3078
3170
  const response = await fetch(url, {
@@ -3390,6 +3482,7 @@ var ProcessManager = class extends EventEmitter7 {
3390
3482
  commandId: cmd.id,
3391
3483
  runnerProcess,
3392
3484
  pid: null,
3485
+ containerName: runnerProcess.containerName ?? null,
3393
3486
  exitCode: null
3394
3487
  };
3395
3488
  proc.commandProcesses = [...proc.commandProcesses, cmdProcess];
@@ -3475,6 +3568,7 @@ var ProcessManager = class extends EventEmitter7 {
3475
3568
  commandId: cmd.id,
3476
3569
  runnerProcess,
3477
3570
  pid: runnerProcess.pid ?? null,
3571
+ containerName: runnerProcess.containerName ?? null,
3478
3572
  exitCode: null
3479
3573
  };
3480
3574
  proc.commandProcesses = [...proc.commandProcesses, cmdProcess];
@@ -3489,6 +3583,8 @@ var ProcessManager = class extends EventEmitter7 {
3489
3583
  this.consoleLogSource.attach(processId, runnerProcess.stdout, runnerProcess.stderr, runnerProcess.pid ?? null);
3490
3584
  if (runnerProcess.pid) {
3491
3585
  this.metricsCollector.startCollecting(processId, runnerProcess.pid);
3586
+ } else if (runnerProcess.containerName) {
3587
+ this.metricsCollector.startCollectingDocker(processId, runnerProcess.containerName);
3492
3588
  }
3493
3589
  runnerProcess.exitPromise.then(({ exitCode, signal, error }) => {
3494
3590
  const current = processStore.get(processId);
@@ -3650,9 +3746,26 @@ var ProcessManager = class extends EventEmitter7 {
3650
3746
  const proc = this.activeShortcuts.get(key);
3651
3747
  if (proc) proc.kill("SIGTERM");
3652
3748
  }
3653
- cancelAdHocCommand(processId) {
3654
- const proc = this.activeAdHocCommands.get(processId);
3655
- if (proc) proc.kill("SIGTERM");
3749
+ cancelAdHocCommand(processId, commandId) {
3750
+ const targets = [];
3751
+ if (commandId) {
3752
+ const key = `${processId}:${commandId}`;
3753
+ const proc = this.activeAdHocCommands.get(key);
3754
+ if (proc) targets.push(proc);
3755
+ } else {
3756
+ for (const [key, proc] of this.activeAdHocCommands) {
3757
+ if (key.startsWith(`${processId}:`)) targets.push(proc);
3758
+ }
3759
+ }
3760
+ for (const proc of targets) {
3761
+ proc.kill("SIGTERM");
3762
+ void Promise.race([
3763
+ proc.exitPromise,
3764
+ new Promise((resolve) => setTimeout(resolve, 3e3))
3765
+ ]).then((result) => {
3766
+ if (result === void 0) proc.kill("SIGKILL");
3767
+ });
3768
+ }
3656
3769
  }
3657
3770
  /** Execute a shortcut command and stream its output as logs for the given process */
3658
3771
  async executeShortcut(processId, shortcut) {
@@ -3692,7 +3805,7 @@ var ProcessManager = class extends EventEmitter7 {
3692
3805
  return { exitCode };
3693
3806
  }
3694
3807
  /** Execute an ad-hoc command and stream its output as logs for the given process */
3695
- async executeAdHocCommand(processId, command, cwd) {
3808
+ async executeAdHocCommand(processId, command, cwd, commandId) {
3696
3809
  const proc = processStore.get(processId);
3697
3810
  if (!proc) throw new Error(`Process ${processId} not found`);
3698
3811
  const jsParsers = proc.serviceConfig.resolvedLogParsers ?? [];
@@ -3712,10 +3825,11 @@ var ProcessManager = class extends EventEmitter7 {
3712
3825
  this.consoleLogSource.addSystemLog(processId, `Failed to start: ${err instanceof Error ? err.message : String(err)}`, "error", { id: randomUUID3(), type: "command-fail", header: command, state: "self" });
3713
3826
  return { exitCode: 1 };
3714
3827
  }
3715
- this.activeAdHocCommands.set(processId, runnerProcess);
3828
+ const cmdKey = `${processId}:${commandId ?? randomUUID3()}`;
3829
+ this.activeAdHocCommands.set(cmdKey, runnerProcess);
3716
3830
  this.consoleLogSource.attach(processId, runnerProcess.stdout, runnerProcess.stderr, runnerProcess.pid ?? null);
3717
3831
  const { exitCode, signal, error } = await runnerProcess.exitPromise;
3718
- this.activeAdHocCommands.delete(processId);
3832
+ this.activeAdHocCommands.delete(cmdKey);
3719
3833
  if (signal) {
3720
3834
  this.consoleLogSource.addSystemLog(processId, `command cancelled`, "info");
3721
3835
  } else if (exitCode !== 0) {
@@ -3967,17 +4081,18 @@ var processRouter = router({
3967
4081
  return { success: true };
3968
4082
  }),
3969
4083
  /** Cancel a running ad-hoc command */
3970
- cancelAdHocCommand: protectedProcedure.input(z22.object({ id: z22.string().max(128) })).mutation(({ input }) => {
3971
- processManager.cancelAdHocCommand(input.id);
4084
+ cancelAdHocCommand: protectedProcedure.input(z22.object({ id: z22.string().max(128), commandId: z22.string().max(128).optional() })).mutation(({ input }) => {
4085
+ processManager.cancelAdHocCommand(input.id, input.commandId);
3972
4086
  return { success: true };
3973
4087
  }),
3974
4088
  /** Execute an ad-hoc command and stream output into the process log */
3975
4089
  executeAdHocCommand: protectedProcedure.input(z22.object({
3976
4090
  id: z22.string().max(128),
3977
4091
  command: z22.string().min(1).max(4096),
3978
- cwd: z22.string().max(4096).optional()
4092
+ cwd: z22.string().max(4096).optional(),
4093
+ commandId: z22.string().max(128).optional()
3979
4094
  })).mutation(async ({ input }) => {
3980
- const result = await processManager.executeAdHocCommand(input.id, input.command, input.cwd);
4095
+ const result = await processManager.executeAdHocCommand(input.id, input.command, input.cwd, input.commandId);
3981
4096
  return result;
3982
4097
  }),
3983
4098
  /** List active log source types for a process */
@@ -4113,9 +4228,9 @@ var processRouter = router({
4113
4228
 
4114
4229
  // src/trpc/routers/health.ts
4115
4230
  import { networkInterfaces as networkInterfaces2 } from "os";
4116
- import { execFile as execFile2 } from "child_process";
4231
+ import { execFile as execFile3 } from "child_process";
4117
4232
  import { promisify } from "util";
4118
- var execFileAsync = promisify(execFile2);
4233
+ var execFileAsync = promisify(execFile3);
4119
4234
  var startedAt = Date.now();
4120
4235
  function getLanIp2() {
4121
4236
  const nets = networkInterfaces2();
@@ -4280,12 +4395,12 @@ var terminalRouter = router({
4280
4395
  // src/trpc/routers/git.ts
4281
4396
  import { z as z24 } from "zod";
4282
4397
  import { TRPCError as TRPCError4 } from "@trpc/server";
4283
- import { execFile as execFile3, spawn as spawn3 } from "child_process";
4398
+ import { execFile as execFile4, spawn as spawn3 } from "child_process";
4284
4399
  import { promisify as promisify2 } from "util";
4285
4400
  import { existsSync, watch as fsWatch } from "fs";
4286
4401
  import { promises as fsPromises2 } from "fs";
4287
4402
  import { join as join4, resolve as resolvePath } from "path";
4288
- var execFileAsync2 = promisify2(execFile3);
4403
+ var execFileAsync2 = promisify2(execFile4);
4289
4404
  var GIT_TIMEOUT = 15e3;
4290
4405
  var DIFF_MAX_BYTES = 512 * 1024;
4291
4406
  var CWD_SCHEMA = z24.string().min(1).max(4096);
@@ -4716,6 +4831,26 @@ import { spawn as spawn4 } from "child_process";
4716
4831
  import { EventEmitter as EventEmitter9 } from "events";
4717
4832
  import { randomUUID as randomUUID5 } from "crypto";
4718
4833
  import { fileURLToPath } from "url";
4834
+ import { createRequire } from "module";
4835
+ import { existsSync as existsSync2 } from "fs";
4836
+ import * as pty2 from "node-pty";
4837
+ function resolveMcpServerPath() {
4838
+ try {
4839
+ const req = createRequire(import.meta.url);
4840
+ return req.resolve("@runeya/packages-mcp-server");
4841
+ } catch {
4842
+ }
4843
+ const candidates = [
4844
+ new URL("../../../packages/mcp-server/dist/index.js", import.meta.url),
4845
+ new URL("../../../../packages/mcp-server/dist/index.js", import.meta.url),
4846
+ new URL("../mcp-server/index.js", import.meta.url)
4847
+ ];
4848
+ for (const c of candidates) {
4849
+ const p = fileURLToPath(c);
4850
+ if (existsSync2(p)) return p;
4851
+ }
4852
+ throw new Error("Could not locate @runeya/packages-mcp-server (built dist not found)");
4853
+ }
4719
4854
  var MAX_BUFFER_LINES = 1e5;
4720
4855
  var MAX_CONCURRENT_SPAWNS = 10;
4721
4856
  var CLEANUP_INTERVAL_MS = 6e4;
@@ -4737,13 +4872,16 @@ var AiSpawnManager = class {
4737
4872
  const args = [...opts.args];
4738
4873
  if (opts.enableMcp && opts.cli === "claude") {
4739
4874
  try {
4740
- const mcpServerPath = fileURLToPath(new URL("../mcp-server/index.js", import.meta.url));
4875
+ const mcpServerPath = resolveMcpServerPath();
4741
4876
  const mcpConfig = JSON.stringify({
4742
4877
  mcpServers: {
4743
4878
  runeya: {
4744
4879
  command: "node",
4745
4880
  args: [mcpServerPath],
4746
- env: opts.mcpApiBaseUrl ? { RUNEYA_BASE_URL: opts.mcpApiBaseUrl } : {}
4881
+ env: {
4882
+ ...opts.mcpApiBaseUrl ? { RUNEYA_BASE_URL: opts.mcpApiBaseUrl } : {},
4883
+ ...opts.mcpApiToken ? { RUNEYA_API_TOKEN: opts.mcpApiToken } : {}
4884
+ }
4747
4885
  }
4748
4886
  }
4749
4887
  });
@@ -4765,10 +4903,12 @@ var AiSpawnManager = class {
4765
4903
  exitCode: null,
4766
4904
  buffer: [],
4767
4905
  proc,
4906
+ ptyProc: null,
4768
4907
  emitter,
4769
4908
  createdAt: Date.now(),
4770
4909
  doneAt: null,
4771
- acked: false
4910
+ acked: false,
4911
+ lastChunkAt: null
4772
4912
  };
4773
4913
  this.spawns.set(spawnId, entry);
4774
4914
  if (opts.stdinData) {
@@ -4853,8 +4993,119 @@ var AiSpawnManager = class {
4853
4993
  }
4854
4994
  return true;
4855
4995
  }
4996
+ if (entry.ptyProc) {
4997
+ try {
4998
+ entry.ptyProc.kill();
4999
+ } catch {
5000
+ }
5001
+ return true;
5002
+ }
4856
5003
  return false;
4857
5004
  }
5005
+ // ── PTY mode ────────────────────────────────────────────────────────────
5006
+ spawnPty(opts) {
5007
+ const running = [...this.spawns.values()].filter((s) => s.status === "running").length;
5008
+ if (running >= MAX_CONCURRENT_SPAWNS) {
5009
+ throw new Error(`Max concurrent AI spawns reached (${MAX_CONCURRENT_SPAWNS})`);
5010
+ }
5011
+ const spawnId = randomUUID5();
5012
+ const emitter = new EventEmitter9();
5013
+ const args = [...opts.args];
5014
+ if (opts.enableMcp && opts.cli === "claude") {
5015
+ try {
5016
+ const mcpServerPath = resolveMcpServerPath();
5017
+ const mcpConfig = JSON.stringify({
5018
+ mcpServers: {
5019
+ runeya: {
5020
+ command: "node",
5021
+ args: [mcpServerPath],
5022
+ env: {
5023
+ ...opts.mcpApiBaseUrl ? { RUNEYA_BASE_URL: opts.mcpApiBaseUrl } : {},
5024
+ ...opts.mcpApiToken ? { RUNEYA_API_TOKEN: opts.mcpApiToken } : {}
5025
+ }
5026
+ }
5027
+ }
5028
+ });
5029
+ args.push("--mcp-config", mcpConfig);
5030
+ } catch (err) {
5031
+ console.warn("[ai-spawn-manager] Failed to resolve MCP server path:", err.message);
5032
+ }
5033
+ }
5034
+ const env2 = opts.env ? { ...process.env, ...opts.env } : process.env;
5035
+ const ptyProc = pty2.spawn(opts.cli, args, {
5036
+ name: "xterm-256color",
5037
+ cols: opts.cols ?? 120,
5038
+ rows: opts.rows ?? 30,
5039
+ cwd: opts.cwd || process.cwd(),
5040
+ env: env2
5041
+ });
5042
+ const entry = {
5043
+ spawnId,
5044
+ sessionId: opts.sessionId,
5045
+ cli: opts.cli,
5046
+ status: "running",
5047
+ exitCode: null,
5048
+ buffer: [],
5049
+ proc: null,
5050
+ ptyProc,
5051
+ emitter,
5052
+ createdAt: Date.now(),
5053
+ doneAt: null,
5054
+ acked: false,
5055
+ lastChunkAt: null
5056
+ };
5057
+ this.spawns.set(spawnId, entry);
5058
+ ptyProc.onData((data) => {
5059
+ this.pushChunk(entry, { type: "pty-data", data });
5060
+ });
5061
+ ptyProc.onExit(({ exitCode }) => {
5062
+ entry.status = exitCode === 0 ? "done" : "error";
5063
+ entry.exitCode = exitCode;
5064
+ entry.doneAt = Date.now();
5065
+ entry.ptyProc = null;
5066
+ this.pushChunk(entry, { type: "exit", data: "", code: exitCode });
5067
+ });
5068
+ console.log(`[ai-spawn-manager] Spawned PTY ${opts.cli} (${spawnId}), args: ${opts.args.length}, cwd: ${opts.cwd ?? "(default)"}, ${opts.cols ?? 120}x${opts.rows ?? 30}`);
5069
+ return spawnId;
5070
+ }
5071
+ writePty(spawnId, data) {
5072
+ const entry = this.spawns.get(spawnId);
5073
+ if (!entry || !entry.ptyProc) return false;
5074
+ try {
5075
+ entry.ptyProc.write(data);
5076
+ return true;
5077
+ } catch {
5078
+ return false;
5079
+ }
5080
+ }
5081
+ /** Return a running PTY spawn matching the given logical sessionId, if any. */
5082
+ findPtyBySessionId(sessionId) {
5083
+ for (const entry of this.spawns.values()) {
5084
+ if (entry.sessionId === sessionId && entry.status === "running" && entry.ptyProc !== null) {
5085
+ return {
5086
+ spawnId: entry.spawnId,
5087
+ cli: entry.cli,
5088
+ status: entry.status,
5089
+ exitCode: entry.exitCode,
5090
+ bufferLength: entry.buffer.length,
5091
+ createdAt: entry.createdAt,
5092
+ doneAt: entry.doneAt,
5093
+ lastChunkAt: entry.lastChunkAt
5094
+ };
5095
+ }
5096
+ }
5097
+ return null;
5098
+ }
5099
+ resizePty(spawnId, cols, rows) {
5100
+ const entry = this.spawns.get(spawnId);
5101
+ if (!entry || !entry.ptyProc) return false;
5102
+ try {
5103
+ entry.ptyProc.resize(cols, rows);
5104
+ return true;
5105
+ } catch {
5106
+ return false;
5107
+ }
5108
+ }
4858
5109
  list() {
4859
5110
  return [...this.spawns.values()].map((e) => ({
4860
5111
  spawnId: e.spawnId,
@@ -4863,7 +5114,8 @@ var AiSpawnManager = class {
4863
5114
  exitCode: e.exitCode,
4864
5115
  bufferLength: e.buffer.length,
4865
5116
  createdAt: e.createdAt,
4866
- doneAt: e.doneAt
5117
+ doneAt: e.doneAt,
5118
+ lastChunkAt: e.lastChunkAt
4867
5119
  }));
4868
5120
  }
4869
5121
  ack(spawnId) {
@@ -4878,6 +5130,9 @@ var AiSpawnManager = class {
4878
5130
  entry.buffer.shift();
4879
5131
  }
4880
5132
  entry.buffer.push(chunk);
5133
+ if (chunk.type === "stdout" || chunk.type === "stderr" || chunk.type === "pty-data") {
5134
+ entry.lastChunkAt = Date.now();
5135
+ }
4881
5136
  entry.emitter.emit("chunk");
4882
5137
  if (chunk.type === "exit") {
4883
5138
  entry.emitter.emit("done");
@@ -4910,13 +5165,19 @@ var AiSpawnManager = class {
4910
5165
  } catch {
4911
5166
  }
4912
5167
  }
5168
+ if (entry.ptyProc) {
5169
+ try {
5170
+ entry.ptyProc.kill();
5171
+ } catch {
5172
+ }
5173
+ }
4913
5174
  }
4914
5175
  }
4915
5176
  };
4916
5177
  var aiSpawnManager = new AiSpawnManager();
4917
5178
 
4918
5179
  // src/services/codex-app-server-manager.ts
4919
- import { spawn as spawn5 } from "child_process";
5180
+ import { spawn as spawn6 } from "child_process";
4920
5181
  import { createInterface as createInterface2 } from "readline";
4921
5182
  import { EventEmitter as EventEmitter10 } from "events";
4922
5183
  var REQUEST_TIMEOUT_MS = 3e5;
@@ -4944,7 +5205,7 @@ var CodexAppServerManager = class extends EventEmitter10 {
4944
5205
  }
4945
5206
  }
4946
5207
  async doConnect() {
4947
- this.proc = spawn5("codex", ["app-server"], {
5208
+ this.proc = spawn6("codex", ["app-server"], {
4948
5209
  stdio: ["pipe", "pipe", "pipe"],
4949
5210
  env: { ...process.env, ...this.extraEnv }
4950
5211
  });
@@ -5055,7 +5316,142 @@ var CodexAppServerManager = class extends EventEmitter10 {
5055
5316
  };
5056
5317
  var codexAppServerManager = new CodexAppServerManager();
5057
5318
 
5319
+ // src/services/ai-context-files.ts
5320
+ import { mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
5321
+ import path from "path";
5322
+ import os2 from "os";
5323
+ var ROOT_DIR_NAME = "runeya-ai-context";
5324
+ function sanitizeName(name) {
5325
+ let safe = name.replace(/[^A-Za-z0-9._-]/g, "_");
5326
+ if (!safe || safe === "." || safe === "..") safe = "context";
5327
+ if (!/\.[A-Za-z0-9]+$/.test(safe)) safe += ".md";
5328
+ return safe;
5329
+ }
5330
+ function sanitizeSessionId(sessionId) {
5331
+ const safe = sessionId.replace(/[^A-Za-z0-9._-]/g, "_");
5332
+ return safe || "session";
5333
+ }
5334
+ async function writeContextFiles(sessionId, files) {
5335
+ const baseDir = path.join(os2.tmpdir(), ROOT_DIR_NAME, sanitizeSessionId(sessionId));
5336
+ await mkdir4(baseDir, { recursive: true });
5337
+ const paths = [];
5338
+ const usedNames = /* @__PURE__ */ new Set();
5339
+ for (let i = 0; i < files.length; i++) {
5340
+ const file = files[i];
5341
+ let name = sanitizeName(file.name);
5342
+ if (usedNames.has(name)) {
5343
+ const ext = path.extname(name);
5344
+ const base = name.slice(0, name.length - ext.length);
5345
+ name = `${base}-${i}${ext}`;
5346
+ }
5347
+ usedNames.add(name);
5348
+ const fullPath = path.join(baseDir, name);
5349
+ await writeFile4(fullPath, file.content, "utf8");
5350
+ paths.push(fullPath);
5351
+ }
5352
+ return paths;
5353
+ }
5354
+
5355
+ // src/services/ai-paste-image.ts
5356
+ import { mkdir as mkdir5, writeFile as writeFile5, unlink as unlink2 } from "fs/promises";
5357
+ import path2 from "path";
5358
+ import os3 from "os";
5359
+ import { randomUUID as randomUUID6 } from "crypto";
5360
+ import { spawn as spawn7 } from "child_process";
5361
+ var TMP_DIR_NAME = "runeya-ai-paste";
5362
+ var MIME_TO_EXT = {
5363
+ "image/png": "png",
5364
+ "image/jpeg": "jpg",
5365
+ "image/jpg": "jpg",
5366
+ "image/gif": "gif",
5367
+ "image/webp": "webp",
5368
+ "image/bmp": "bmp"
5369
+ };
5370
+ function extForMime(mime) {
5371
+ return MIME_TO_EXT[mime.toLowerCase()] ?? "png";
5372
+ }
5373
+ function runCmd(cmd, args, stdin, timeoutMs = 5e3) {
5374
+ return new Promise((resolve) => {
5375
+ let settled = false;
5376
+ const settle = (code, stderr) => {
5377
+ if (settled) return;
5378
+ settled = true;
5379
+ resolve({ code, stderr });
5380
+ };
5381
+ try {
5382
+ const child = spawn7(cmd, args, { stdio: ["pipe", "ignore", "pipe"] });
5383
+ let stderr = "";
5384
+ child.stderr.on("data", (c) => {
5385
+ stderr += c.toString();
5386
+ });
5387
+ child.on("error", (err) => settle(127, err.message));
5388
+ child.on("exit", (code) => settle(code ?? 1, stderr));
5389
+ const t2 = setTimeout(() => {
5390
+ try {
5391
+ child.kill("SIGKILL");
5392
+ } catch {
5393
+ }
5394
+ settle(124, "timeout");
5395
+ }, timeoutMs);
5396
+ child.on("exit", () => clearTimeout(t2));
5397
+ if (stdin) {
5398
+ child.stdin.on("error", () => {
5399
+ });
5400
+ child.stdin.end(stdin);
5401
+ } else {
5402
+ child.stdin.end();
5403
+ }
5404
+ } catch (err) {
5405
+ settle(127, err.message);
5406
+ }
5407
+ });
5408
+ }
5409
+ async function savePastedImage(base64, mimeType, sessionId) {
5410
+ const buf = Buffer.from(base64, "base64");
5411
+ if (buf.length === 0) throw new Error("Empty image payload");
5412
+ const ext = extForMime(mimeType);
5413
+ const baseDir = path2.join(
5414
+ os3.tmpdir(),
5415
+ TMP_DIR_NAME,
5416
+ sessionId ? sessionId.replace(/[^A-Za-z0-9._-]/g, "_") : "default"
5417
+ );
5418
+ await mkdir5(baseDir, { recursive: true });
5419
+ const tmpPath = path2.join(baseDir, `paste-${Date.now()}-${randomUUID6().slice(0, 8)}.${ext}`);
5420
+ await writeFile5(tmpPath, buf);
5421
+ const { method, error } = await tryWriteClipboard(buf, mimeType, tmpPath);
5422
+ return { tmpPath, clipboardMethod: method, clipboardError: error };
5423
+ }
5424
+ async function tryWriteClipboard(buf, mimeType, tmpPath) {
5425
+ const normalizedMime = mimeType.toLowerCase();
5426
+ const errors = [];
5427
+ if (process.platform === "darwin") {
5428
+ const klass = normalizedMime === "image/jpeg" || normalizedMime === "image/jpg" ? "JPEG picture" : "PNGf";
5429
+ const script = `set the clipboard to (read (POSIX file "${tmpPath.replace(/"/g, '\\"')}") as \xABclass ${klass}\xBB)`;
5430
+ const r = await runCmd("osascript", ["-e", script]);
5431
+ if (r.code === 0) return { method: "pbcopy" };
5432
+ errors.push(`osascript: ${r.stderr.trim()}`);
5433
+ }
5434
+ if (process.platform === "linux") {
5435
+ const r = await runCmd("xclip", ["-selection", "clipboard", "-t", normalizedMime, "-i"], buf);
5436
+ if (r.code === 0) return { method: "xclip" };
5437
+ errors.push(`xclip: ${r.stderr.trim() || `exit ${r.code}`}`);
5438
+ const r2 = await runCmd("wl-copy", ["--type", normalizedMime], buf);
5439
+ if (r2.code === 0) return { method: "wl-copy" };
5440
+ errors.push(`wl-copy: ${r2.stderr.trim() || `exit ${r2.code}`}`);
5441
+ }
5442
+ if (process.platform === "win32") {
5443
+ const ps = `Add-Type -AssemblyName System.Windows.Forms; Add-Type -AssemblyName System.Drawing; $img = [System.Drawing.Image]::FromFile("${tmpPath.replace(/\\/g, "\\\\")}"); [System.Windows.Forms.Clipboard]::SetImage($img); $img.Dispose()`;
5444
+ const r = await runCmd("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", ps]);
5445
+ if (r.code === 0) return { method: "powershell" };
5446
+ errors.push(`powershell: ${r.stderr.trim() || `exit ${r.code}`}`);
5447
+ }
5448
+ return { method: null, error: errors.join(" | ") || "no clipboard tool available" };
5449
+ }
5450
+
5058
5451
  // src/trpc/routers/ai.ts
5452
+ var MAX_CONTEXT_FILES = 20;
5453
+ var MAX_CONTEXT_FILE_BYTES = 1e6;
5454
+ var MAX_CONTEXT_TOTAL_BYTES = 5e6;
5059
5455
  var aiRouter = router({
5060
5456
  /** Spawn an AI CLI process. Returns a spawnId for streaming. */
5061
5457
  spawn: protectedProcedure.input(z25.object({
@@ -5086,6 +5482,71 @@ var aiRouter = router({
5086
5482
  });
5087
5483
  }
5088
5484
  }),
5485
+ /** Spawn an AI CLI process in a PTY (interactive mode). Returns spawnId. */
5486
+ spawnPty: protectedProcedure.input(z25.object({
5487
+ cli: z25.string().max(64),
5488
+ args: z25.array(z25.string().max(5e5)),
5489
+ env: z25.record(z25.string().max(256), z25.string().max(5e5)).optional(),
5490
+ cwd: z25.string().max(4096).optional(),
5491
+ cols: z25.number().int().min(1).max(1e3).optional(),
5492
+ rows: z25.number().int().min(1).max(1e3).optional(),
5493
+ sessionId: z25.string().max(128).optional(),
5494
+ enableMcp: z25.boolean().optional(),
5495
+ mcpApiBaseUrl: z25.string().max(512).optional(),
5496
+ mcpApiToken: z25.string().max(8192).optional()
5497
+ })).mutation(({ input }) => {
5498
+ const spawnId = aiSpawnManager.spawnPty(input);
5499
+ return { spawnId };
5500
+ }),
5501
+ /** Find a running PTY spawn by its logical sessionId (for re-attach). */
5502
+ findPtyBySession: protectedProcedure.input(z25.object({ sessionId: z25.string().max(128) })).query(({ input }) => {
5503
+ return aiSpawnManager.findPtyBySessionId(input.sessionId);
5504
+ }),
5505
+ /** Write input to a PTY spawn (user keystrokes). */
5506
+ writePty: protectedProcedure.input(z25.object({
5507
+ spawnId: z25.string().max(128),
5508
+ data: z25.string().max(1e6)
5509
+ })).mutation(({ input }) => {
5510
+ const ok = aiSpawnManager.writePty(input.spawnId, input.data);
5511
+ return { ok };
5512
+ }),
5513
+ /** Write attached-context files for an AI session to a temp dir. Returns absolute paths. */
5514
+ writeContextFiles: protectedProcedure.input(z25.object({
5515
+ sessionId: z25.string().min(1).max(128),
5516
+ files: z25.array(z25.object({
5517
+ name: z25.string().min(1).max(256),
5518
+ content: z25.string().max(MAX_CONTEXT_FILE_BYTES)
5519
+ })).min(1).max(MAX_CONTEXT_FILES)
5520
+ }).refine(
5521
+ (val) => val.files.reduce((sum, f) => sum + f.content.length, 0) <= MAX_CONTEXT_TOTAL_BYTES,
5522
+ { message: `Total context size exceeds ${MAX_CONTEXT_TOTAL_BYTES} bytes` }
5523
+ )).mutation(async ({ input }) => {
5524
+ const paths = await writeContextFiles(input.sessionId, input.files);
5525
+ return { paths };
5526
+ }),
5527
+ /**
5528
+ * Save a pasted image to disk and try to populate the agent's system clipboard
5529
+ * so Claude's native paste detection picks it up. Returns the tmp path and
5530
+ * which clipboard method (if any) succeeded — caller decides whether to send
5531
+ * Ctrl+V (\x16) or inject `@<path>` into the PTY.
5532
+ */
5533
+ pasteImage: protectedProcedure.input(z25.object({
5534
+ sessionId: z25.string().max(128).optional(),
5535
+ mimeType: z25.string().max(64),
5536
+ base64: z25.string().max(15e6)
5537
+ })).mutation(async ({ input }) => {
5538
+ const res = await savePastedImage(input.base64, input.mimeType, input.sessionId);
5539
+ return res;
5540
+ }),
5541
+ /** Resize a PTY spawn. */
5542
+ resizePty: protectedProcedure.input(z25.object({
5543
+ spawnId: z25.string().max(128),
5544
+ cols: z25.number().int().min(1).max(1e3),
5545
+ rows: z25.number().int().min(1).max(1e3)
5546
+ })).mutation(({ input }) => {
5547
+ const ok = aiSpawnManager.resizePty(input.spawnId, input.cols, input.rows);
5548
+ return { ok };
5549
+ }),
5089
5550
  /** Kill a running AI spawn. */
5090
5551
  kill: protectedProcedure.input(z25.object({ spawnId: z25.string().max(128) })).mutation(({ input }) => {
5091
5552
  const killed = aiSpawnManager.kill(input.spawnId);