upfynai-code 2.5.1 → 2.6.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 (293) hide show
  1. package/README.md +123 -88
  2. package/bin/cli.js +63 -0
  3. package/package.json +48 -112
  4. package/src/auth.js +115 -0
  5. package/src/config.js +33 -0
  6. package/src/connect.js +314 -0
  7. package/src/launch.js +54 -0
  8. package/src/mcp.js +57 -0
  9. package/src/server.js +54 -0
  10. package/client/dist/api-docs.html +0 -879
  11. package/client/dist/assets/AppContent-C0CyP3g5.js +0 -513
  12. package/client/dist/assets/CanvasPanel-0u9QR7U-.js +0 -34
  13. package/client/dist/assets/CanvasPanel-WhZulBJw.css +0 -1
  14. package/client/dist/assets/DashboardPanel-Dgqw1yZk.js +0 -1
  15. package/client/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  16. package/client/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  17. package/client/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  18. package/client/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  19. package/client/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  20. package/client/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  21. package/client/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  22. package/client/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  23. package/client/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  24. package/client/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  25. package/client/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  26. package/client/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  27. package/client/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  28. package/client/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  29. package/client/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  30. package/client/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  31. package/client/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  32. package/client/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  33. package/client/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  34. package/client/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  35. package/client/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  36. package/client/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  37. package/client/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  38. package/client/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  39. package/client/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  40. package/client/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  41. package/client/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  42. package/client/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  43. package/client/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  44. package/client/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  45. package/client/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  46. package/client/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  47. package/client/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  48. package/client/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  49. package/client/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  50. package/client/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  51. package/client/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  52. package/client/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  53. package/client/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  54. package/client/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  55. package/client/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  56. package/client/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  57. package/client/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  58. package/client/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  59. package/client/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  60. package/client/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  61. package/client/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  62. package/client/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  63. package/client/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  64. package/client/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  65. package/client/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  66. package/client/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  67. package/client/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  68. package/client/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  69. package/client/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  70. package/client/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  71. package/client/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  72. package/client/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  73. package/client/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  74. package/client/dist/assets/LoginModal-CZDEzqjK.js +0 -19
  75. package/client/dist/assets/MarkdownPreview-CYdvwJaV.js +0 -1
  76. package/client/dist/assets/Onboarding-DR6NZ4Vz.js +0 -1
  77. package/client/dist/assets/SetupForm-D49gtWY4.js +0 -1
  78. package/client/dist/assets/Tableau10-B-NsZVaP.js +0 -1
  79. package/client/dist/assets/WorkflowsPanel-CqlbEJA_.js +0 -1
  80. package/client/dist/assets/_commonjs-dynamic-modules-TDtrdbi3.js +0 -1
  81. package/client/dist/assets/ar-SA-G6X2FPQ2-BWqa1yBH.js +0 -10
  82. package/client/dist/assets/arc-BegSKqEW.js +0 -1
  83. package/client/dist/assets/array-BKyUJesY.js +0 -1
  84. package/client/dist/assets/az-AZ-76LH7QW2-DrVlbZDP.js +0 -1
  85. package/client/dist/assets/bg-BG-XCXSNQG7-DdunjBgT.js +0 -5
  86. package/client/dist/assets/blockDiagram-38ab4fdb-BKMbwGHu.js +0 -118
  87. package/client/dist/assets/bn-BD-2XOGV67Q-_7DtmvwO.js +0 -5
  88. package/client/dist/assets/c4Diagram-3d4e48cf-hJuiHhSn.js +0 -10
  89. package/client/dist/assets/ca-ES-6MX7JW3Y-BFIrmojG.js +0 -8
  90. package/client/dist/assets/channel-Bur-rRTp.js +0 -1
  91. package/client/dist/assets/classDiagram-70f12bd4-BjiAf9cM.js +0 -2
  92. package/client/dist/assets/classDiagram-v2-f2320105-pwBewejc.js +0 -2
  93. package/client/dist/assets/clone-BtqXeoBJ.js +0 -1
  94. package/client/dist/assets/createText-2e5e7dd3-Dq_acOWe.js +0 -5
  95. package/client/dist/assets/cs-CZ-2BRQDIVT-B-x4F6TJ.js +0 -11
  96. package/client/dist/assets/da-DK-5WZEPLOC-Btlc8Dgn.js +0 -5
  97. package/client/dist/assets/de-DE-XR44H4JA-BVu3ZIoD.js +0 -8
  98. package/client/dist/assets/directory-open-01563666-DWU9wJ6I.js +0 -1
  99. package/client/dist/assets/directory-open-4ed118d0-CunoC1EB.js +0 -1
  100. package/client/dist/assets/edges-e0da2a9e-DH0wVTXR.js +0 -4
  101. package/client/dist/assets/el-GR-BZB4AONW-h2ll8_ZC.js +0 -10
  102. package/client/dist/assets/erDiagram-9861fffd-BYezLIR7.js +0 -51
  103. package/client/dist/assets/es-ES-U4NZUMDT-Cveiulwt.js +0 -9
  104. package/client/dist/assets/eu-ES-A7QVB2H4-DQluL2PY.js +0 -11
  105. package/client/dist/assets/fa-IR-HGAKTJCU-BJtcMBSv.js +0 -8
  106. package/client/dist/assets/fi-FI-Z5N7JZ37-D8NfbVXV.js +0 -6
  107. package/client/dist/assets/file-open-002ab408-DIuFHtCF.js +0 -1
  108. package/client/dist/assets/file-open-7c801643-684qeFg4.js +0 -1
  109. package/client/dist/assets/file-save-3189631c-C1wFhQhH.js +0 -1
  110. package/client/dist/assets/file-save-745eba88-Bb9F9Kg7.js +0 -1
  111. package/client/dist/assets/flowDb-956e92f1-scnUykhM.js +0 -10
  112. package/client/dist/assets/flowDiagram-66a62f08-jVyWsfyU.js +0 -4
  113. package/client/dist/assets/flowDiagram-v2-96b9c2cf-N6xgi25h.js +0 -1
  114. package/client/dist/assets/flowchart-elk-definition-4a651766-gKGX3HqR.js +0 -139
  115. package/client/dist/assets/fr-FR-RHASNOE6-vdj42kC6.js +0 -9
  116. package/client/dist/assets/ganttDiagram-c361ad54-C2CiWFUP.js +0 -257
  117. package/client/dist/assets/gitGraphDiagram-72cf32ee-C59Yz2LK.js +0 -70
  118. package/client/dist/assets/gl-ES-HMX3MZ6V-DQo0TzoP.js +0 -10
  119. package/client/dist/assets/graph-Dx_H43Kv.js +0 -1
  120. package/client/dist/assets/he-IL-6SHJWFNN-DKXK5e33.js +0 -10
  121. package/client/dist/assets/hi-IN-IWLTKZ5I-C2Qgqc0R.js +0 -4
  122. package/client/dist/assets/hu-HU-A5ZG7DT2-Ss-6vX0m.js +0 -7
  123. package/client/dist/assets/id-ID-SAP4L64H-D7Wsg1S2.js +0 -10
  124. package/client/dist/assets/image-blob-reduce.esm-D6s-rqMO.js +0 -7
  125. package/client/dist/assets/index-3862675e-u8Nv7hHC.js +0 -1
  126. package/client/dist/assets/index-BVowJdZF.js +0 -97
  127. package/client/dist/assets/index-ce18TYkg.js +0 -27
  128. package/client/dist/assets/index-kQoJx-bc.css +0 -1
  129. package/client/dist/assets/infoDiagram-f8f76790-LmoJYsxo.js +0 -7
  130. package/client/dist/assets/init-Gi6I4Gst.js +0 -1
  131. package/client/dist/assets/it-IT-JPQ66NNP-CAPTVl7M.js +0 -11
  132. package/client/dist/assets/ja-JP-DBVTYXUO-eNVPawR2.js +0 -8
  133. package/client/dist/assets/journeyDiagram-49397b02-BaJqehpR.js +0 -139
  134. package/client/dist/assets/kaa-6HZHGXH3-tpuNkKhS.js +0 -1
  135. package/client/dist/assets/kab-KAB-ZGHBKWFO-Dp83kx4x.js +0 -8
  136. package/client/dist/assets/kk-KZ-P5N5QNE5-B9IlC6YN.js +0 -1
  137. package/client/dist/assets/km-KH-HSX4SM5Z-B_KMYaMj.js +0 -11
  138. package/client/dist/assets/ko-KR-MTYHY66A-yebnUNdb.js +0 -9
  139. package/client/dist/assets/ku-TR-6OUDTVRD-BR6fh6-5.js +0 -9
  140. package/client/dist/assets/layout-DLl5Jwcl.js +0 -1
  141. package/client/dist/assets/line-FpB7omSK.js +0 -1
  142. package/client/dist/assets/linear-CkXqUFJ8.js +0 -1
  143. package/client/dist/assets/lt-LT-XHIRWOB4-SutZSWtR.js +0 -3
  144. package/client/dist/assets/lv-LV-5QDEKY6T-DuAxdcZL.js +0 -7
  145. package/client/dist/assets/mindmap-definition-fc14e90a-DyxXOExh.js +0 -425
  146. package/client/dist/assets/mr-IN-CRQNXWMA-DqDUWM_8.js +0 -13
  147. package/client/dist/assets/my-MM-5M5IBNSE-C40kMFMR.js +0 -1
  148. package/client/dist/assets/nb-NO-T6EIAALU-DVij32Ju.js +0 -10
  149. package/client/dist/assets/nl-NL-IS3SIHDZ-rT84mDYq.js +0 -8
  150. package/client/dist/assets/nn-NO-6E72VCQL-BBZXBW8V.js +0 -8
  151. package/client/dist/assets/oc-FR-POXYY2M6-DzjOugOf.js +0 -8
  152. package/client/dist/assets/ordinal-Cboi1Yqb.js +0 -1
  153. package/client/dist/assets/pa-IN-N4M65BXN-DD1iU8_F.js +0 -4
  154. package/client/dist/assets/path-CbwjOpE9.js +0 -1
  155. package/client/dist/assets/pdf-CE_K4jFx.js +0 -12
  156. package/client/dist/assets/pdf.worker-BA9kU3Pw.mjs +0 -61080
  157. package/client/dist/assets/percentages-BXMCSKIN-WVlHS4wx.js +0 -207
  158. package/client/dist/assets/pica-CQIY57Tf.js +0 -7
  159. package/client/dist/assets/pieDiagram-8a3498a8-Dd_85qBH.js +0 -35
  160. package/client/dist/assets/pl-PL-T2D74RX3-ukVXa48G.js +0 -9
  161. package/client/dist/assets/pt-BR-5N22H2LF-BibawarT.js +0 -9
  162. package/client/dist/assets/pt-PT-UZXXM6DQ-So3i9l9w.js +0 -9
  163. package/client/dist/assets/quadrantDiagram-120e2f19-C4dFVDEx.js +0 -7
  164. package/client/dist/assets/requirementDiagram-deff3bca-DrTO7yFl.js +0 -52
  165. package/client/dist/assets/ro-RO-JPDTUUEW-DY0Xq_Hd.js +0 -11
  166. package/client/dist/assets/roundRect-0PYZxl1G.js +0 -1
  167. package/client/dist/assets/ru-RU-B4JR7IUQ-B7u_Zvkd.js +0 -9
  168. package/client/dist/assets/sankeyDiagram-04a897e0-D24gfzuS.js +0 -8
  169. package/client/dist/assets/sequenceDiagram-704730f1-Dgji2XLQ.js +0 -122
  170. package/client/dist/assets/si-LK-N5RQ5JYF-OejsLzQ_.js +0 -1
  171. package/client/dist/assets/sk-SK-C5VTKIMK-_vy2Bt-M.js +0 -6
  172. package/client/dist/assets/sl-SI-NN7IZMDC-DKOl_u2M.js +0 -6
  173. package/client/dist/assets/stateDiagram-587899a1-CJ8eBaiU.js +0 -1
  174. package/client/dist/assets/stateDiagram-v2-d93cdb3a-C5K3l-Nt.js +0 -1
  175. package/client/dist/assets/styles-6aaf32cf-DAKE0jbx.js +0 -207
  176. package/client/dist/assets/styles-9a916d00-LFAJCgEy.js +0 -160
  177. package/client/dist/assets/styles-c10674c1-CllKO8NG.js +0 -116
  178. package/client/dist/assets/subset-shared.chunk-Uy-J87FQ.js +0 -84
  179. package/client/dist/assets/subset-worker.chunk-dvgDvqt9.js +0 -1
  180. package/client/dist/assets/sv-SE-XGPEYMSR-CDCB2ZV5.js +0 -10
  181. package/client/dist/assets/svgDrawCommon-08f97a94-CObOzbFQ.js +0 -1
  182. package/client/dist/assets/ta-IN-2NMHFXQM-DHUNdO69.js +0 -9
  183. package/client/dist/assets/th-TH-HPSO5L25-zI2hnBq3.js +0 -2
  184. package/client/dist/assets/timeline-definition-85554ec2-C2XHRmxK.js +0 -61
  185. package/client/dist/assets/tr-TR-DEFEU3FU-l-6Hu4-D.js +0 -7
  186. package/client/dist/assets/uk-UA-QMV73CPH-CqSOwrl7.js +0 -6
  187. package/client/dist/assets/vendor-codemirror-D_s0aGBu.js +0 -35
  188. package/client/dist/assets/vendor-i18n-DCFGyhQR.js +0 -1
  189. package/client/dist/assets/vendor-icons-Lb69KSFJ.js +0 -646
  190. package/client/dist/assets/vendor-markdown-BXEi_H3G.js +0 -298
  191. package/client/dist/assets/vendor-react-9mUTKBHH.js +0 -67
  192. package/client/dist/assets/vendor-syntax-DnmwQQJF.js +0 -16
  193. package/client/dist/assets/vendor-xterm-CZq1hqo1.js +0 -66
  194. package/client/dist/assets/vendor-xterm-qxJ8_QYu.css +0 -32
  195. package/client/dist/assets/vi-VN-M7AON7JQ-CUL8-mBZ.js +0 -5
  196. package/client/dist/assets/xychartDiagram-e933f94c-1fmf6slj.js +0 -7
  197. package/client/dist/assets/zh-CN-LNUGB5OW-CB5y5VVU.js +0 -10
  198. package/client/dist/assets/zh-HK-E62DVLB3-BHcrrEeJ.js +0 -1
  199. package/client/dist/assets/zh-TW-RAJ6MFWO-DoDUdkaJ.js +0 -9
  200. package/client/dist/clear-cache.html +0 -85
  201. package/client/dist/convert-icons.md +0 -53
  202. package/client/dist/favicon.png +0 -0
  203. package/client/dist/favicon.svg +0 -9
  204. package/client/dist/generate-icons.js +0 -49
  205. package/client/dist/icons/claude-ai-icon.svg +0 -1
  206. package/client/dist/icons/codex-white.svg +0 -3
  207. package/client/dist/icons/codex.svg +0 -3
  208. package/client/dist/icons/cursor-white.svg +0 -12
  209. package/client/dist/icons/cursor.svg +0 -1
  210. package/client/dist/icons/icon-128x128.png +0 -0
  211. package/client/dist/icons/icon-128x128.svg +0 -12
  212. package/client/dist/icons/icon-144x144.png +0 -0
  213. package/client/dist/icons/icon-144x144.svg +0 -12
  214. package/client/dist/icons/icon-152x152.png +0 -0
  215. package/client/dist/icons/icon-152x152.svg +0 -12
  216. package/client/dist/icons/icon-192x192.png +0 -0
  217. package/client/dist/icons/icon-192x192.svg +0 -12
  218. package/client/dist/icons/icon-384x384.png +0 -0
  219. package/client/dist/icons/icon-384x384.svg +0 -12
  220. package/client/dist/icons/icon-512x512.png +0 -0
  221. package/client/dist/icons/icon-512x512.svg +0 -12
  222. package/client/dist/icons/icon-72x72.png +0 -0
  223. package/client/dist/icons/icon-72x72.svg +0 -12
  224. package/client/dist/icons/icon-96x96.png +0 -0
  225. package/client/dist/icons/icon-96x96.svg +0 -12
  226. package/client/dist/icons/icon-template.svg +0 -12
  227. package/client/dist/index.html +0 -128
  228. package/client/dist/logo-128.png +0 -0
  229. package/client/dist/logo-256.png +0 -0
  230. package/client/dist/logo-32.png +0 -0
  231. package/client/dist/logo-512.png +0 -0
  232. package/client/dist/logo-64.png +0 -0
  233. package/client/dist/logo.svg +0 -17
  234. package/client/dist/manifest.json +0 -61
  235. package/client/dist/mcp-docs.html +0 -119
  236. package/client/dist/screenshots/cli-selection.png +0 -0
  237. package/client/dist/screenshots/desktop-main.png +0 -0
  238. package/client/dist/screenshots/mobile-chat.png +0 -0
  239. package/client/dist/screenshots/tools-modal.png +0 -0
  240. package/client/dist/sw.js +0 -19
  241. package/commands/upfynai-connect.md +0 -59
  242. package/commands/upfynai-disconnect.md +0 -31
  243. package/commands/upfynai-doctor.md +0 -99
  244. package/commands/upfynai-export.md +0 -49
  245. package/commands/upfynai-local.md +0 -82
  246. package/commands/upfynai-status.md +0 -75
  247. package/commands/upfynai-stop.md +0 -49
  248. package/commands/upfynai-uninstall.md +0 -58
  249. package/commands/upfynai.md +0 -69
  250. package/scripts/build-client.js +0 -17
  251. package/scripts/fix-node-pty.js +0 -67
  252. package/scripts/install-commands.js +0 -78
  253. package/server/claude-sdk.js +0 -714
  254. package/server/cli-ui.js +0 -785
  255. package/server/cli.js +0 -596
  256. package/server/constants/config.js +0 -31
  257. package/server/cursor-cli.js +0 -270
  258. package/server/database/auth.db +0 -0
  259. package/server/database/db.js +0 -808
  260. package/server/database/init.sql +0 -70
  261. package/server/index.js +0 -2621
  262. package/server/load-env.js +0 -26
  263. package/server/mcp-server.js +0 -621
  264. package/server/middleware/auth.js +0 -173
  265. package/server/openai-codex.js +0 -403
  266. package/server/openrouter.js +0 -137
  267. package/server/projects.js +0 -1742
  268. package/server/relay-client.js +0 -619
  269. package/server/routes/agent.js +0 -1266
  270. package/server/routes/auth.js +0 -263
  271. package/server/routes/cli-auth.js +0 -263
  272. package/server/routes/codex.js +0 -344
  273. package/server/routes/commands.js +0 -601
  274. package/server/routes/cursor.js +0 -808
  275. package/server/routes/dashboard.js +0 -52
  276. package/server/routes/git.js +0 -1165
  277. package/server/routes/mcp-utils.js +0 -48
  278. package/server/routes/mcp.js +0 -552
  279. package/server/routes/payments.js +0 -172
  280. package/server/routes/projects.js +0 -552
  281. package/server/routes/settings.js +0 -269
  282. package/server/routes/taskmaster.js +0 -1964
  283. package/server/routes/user.js +0 -106
  284. package/server/routes/voice.js +0 -198
  285. package/server/routes/webhooks.js +0 -166
  286. package/server/routes/workflows.js +0 -118
  287. package/server/services/whisperService.js +0 -84
  288. package/server/services/workflowScheduler.js +0 -186
  289. package/server/utils/commandParser.js +0 -303
  290. package/server/utils/gitConfig.js +0 -24
  291. package/server/utils/mcp-detector.js +0 -198
  292. package/server/utils/taskmaster-websocket.js +0 -129
  293. package/shared/modelConstants.js +0 -96
@@ -1,619 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Upfyn-Code Relay Client
4
- *
5
- * Connects your local machine to the hosted Upfyn-Code server.
6
- * Bridges Claude CLI, terminal, filesystem, and git to the web UI.
7
- *
8
- * Usage:
9
- * upfynai-code connect --server https://upfynai.thinqmesh.com --key upfyn_xxx
10
- * upfynai-code connect (uses saved config from ~/.upfynai/config.json)
11
- */
12
-
13
- import WebSocket from 'ws';
14
- import os from 'os';
15
- import fs from 'fs';
16
- import path from 'path';
17
- import { spawn, execSync } from 'child_process';
18
- import { promises as fsPromises } from 'fs';
19
- import crypto from 'crypto';
20
- import {
21
- c,
22
- showConnectStartup,
23
- showConnectionBanner,
24
- logRelayEvent,
25
- createSpinner,
26
- } from './cli-ui.js';
27
-
28
- // Load package.json for version
29
- import { fileURLToPath } from 'url';
30
- const __filename_rc = fileURLToPath(import.meta.url);
31
- const __dirname_rc = path.dirname(__filename_rc);
32
- let VERSION = '0.0.0';
33
- try {
34
- const pkg = JSON.parse(fs.readFileSync(path.join(__dirname_rc, '../package.json'), 'utf8'));
35
- VERSION = pkg.version;
36
- } catch { /* ignore */ }
37
-
38
- const CONFIG_DIR = path.join(os.homedir(), '.upfynai');
39
- const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
40
-
41
- function loadConfig() {
42
- try {
43
- if (fs.existsSync(CONFIG_FILE)) {
44
- return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
45
- }
46
- } catch (e) { /* ignore */ }
47
- return {};
48
- }
49
-
50
- function saveConfig(config) {
51
- if (!fs.existsSync(CONFIG_DIR)) {
52
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
53
- }
54
- fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
55
- }
56
-
57
- /**
58
- * Execute a shell command and return stdout
59
- */
60
- function execCommand(cmd, args, options = {}) {
61
- return new Promise((resolve, reject) => {
62
- const proc = spawn(cmd, args, {
63
- shell: true,
64
- cwd: options.cwd || os.homedir(),
65
- env: { ...process.env, ...options.env },
66
- stdio: ['pipe', 'pipe', 'pipe'],
67
- });
68
-
69
- let stdout = '';
70
- let stderr = '';
71
- proc.stdout.on('data', (d) => { stdout += d; });
72
- proc.stderr.on('data', (d) => { stderr += d; });
73
-
74
- const timeout = setTimeout(() => {
75
- proc.kill();
76
- reject(new Error('Command timed out'));
77
- }, options.timeout || 30000);
78
-
79
- proc.on('close', (code) => {
80
- clearTimeout(timeout);
81
- if (code === 0) resolve(stdout);
82
- else reject(new Error(stderr || `Exit code ${code}`));
83
- });
84
-
85
- proc.on('error', (err) => {
86
- clearTimeout(timeout);
87
- reject(err);
88
- });
89
- });
90
- }
91
-
92
- /**
93
- * Handle incoming relay commands from the server
94
- */
95
- async function handleRelayCommand(data, ws) {
96
- const { requestId, action } = data;
97
-
98
- try {
99
- switch (action) {
100
- case 'claude-query': {
101
- const { command, options } = data;
102
- logRelayEvent('>', `Claude query: ${command?.slice(0, 60)}...`, 'cyan');
103
-
104
- const args = ['--print'];
105
- if (options?.projectPath) args.push('--cwd', options.projectPath);
106
- if (options?.sessionId) args.push('--continue', options.sessionId);
107
-
108
- const proc = spawn('claude', [...args, command || ''], {
109
- shell: true,
110
- cwd: options?.projectPath || os.homedir(),
111
- env: process.env,
112
- });
113
-
114
- proc.stdout.on('data', (chunk) => {
115
- ws.send(JSON.stringify({
116
- type: 'relay-stream',
117
- requestId,
118
- data: { type: 'claude-response', content: chunk.toString() }
119
- }));
120
- });
121
-
122
- proc.stderr.on('data', (chunk) => {
123
- ws.send(JSON.stringify({
124
- type: 'relay-stream',
125
- requestId,
126
- data: { type: 'claude-error', content: chunk.toString() }
127
- }));
128
- });
129
-
130
- proc.on('close', (code) => {
131
- ws.send(JSON.stringify({
132
- type: 'relay-complete',
133
- requestId,
134
- exitCode: code
135
- }));
136
- });
137
- break;
138
- }
139
-
140
- case 'codex-query': {
141
- const { command, options } = data;
142
- logRelayEvent('>', `Codex query: ${command?.slice(0, 60)}...`, 'cyan');
143
-
144
- const codexArgs = ['--quiet'];
145
- if (options?.projectPath || options?.cwd) {
146
- codexArgs.push('--cwd', options.projectPath || options.cwd);
147
- }
148
- if (options?.model) codexArgs.push('--model', options.model);
149
-
150
- const codexProc = spawn('codex', [...codexArgs, command || ''], {
151
- shell: true,
152
- cwd: options?.projectPath || options?.cwd || os.homedir(),
153
- env: process.env,
154
- });
155
-
156
- codexProc.stdout.on('data', (chunk) => {
157
- ws.send(JSON.stringify({
158
- type: 'relay-stream',
159
- requestId,
160
- data: { type: 'codex-response', content: chunk.toString() }
161
- }));
162
- });
163
-
164
- codexProc.stderr.on('data', (chunk) => {
165
- ws.send(JSON.stringify({
166
- type: 'relay-stream',
167
- requestId,
168
- data: { type: 'codex-error', content: chunk.toString() }
169
- }));
170
- });
171
-
172
- codexProc.on('close', (code) => {
173
- ws.send(JSON.stringify({
174
- type: 'relay-complete',
175
- requestId,
176
- exitCode: code
177
- }));
178
- });
179
- break;
180
- }
181
-
182
- case 'cursor-query': {
183
- const { command, options } = data;
184
- logRelayEvent('>', `Cursor query: ${command?.slice(0, 60)}...`, 'cyan');
185
-
186
- const cursorArgs = [];
187
- if (options?.projectPath || options?.cwd) {
188
- cursorArgs.push('--cwd', options.projectPath || options.cwd);
189
- }
190
- if (options?.model) cursorArgs.push('--model', options.model);
191
-
192
- const cursorProc = spawn('cursor-agent', [...cursorArgs, command || ''], {
193
- shell: true,
194
- cwd: options?.projectPath || options?.cwd || os.homedir(),
195
- env: process.env,
196
- });
197
-
198
- cursorProc.stdout.on('data', (chunk) => {
199
- ws.send(JSON.stringify({
200
- type: 'relay-stream',
201
- requestId,
202
- data: { type: 'cursor-response', content: chunk.toString() }
203
- }));
204
- });
205
-
206
- cursorProc.stderr.on('data', (chunk) => {
207
- ws.send(JSON.stringify({
208
- type: 'relay-stream',
209
- requestId,
210
- data: { type: 'cursor-error', content: chunk.toString() }
211
- }));
212
- });
213
-
214
- cursorProc.on('close', (code) => {
215
- ws.send(JSON.stringify({
216
- type: 'relay-complete',
217
- requestId,
218
- exitCode: code
219
- }));
220
- });
221
- break;
222
- }
223
-
224
- case 'detect-agents': {
225
- const agents = detectInstalledAgents();
226
- ws.send(JSON.stringify({
227
- type: 'relay-response',
228
- requestId,
229
- data: { agents }
230
- }));
231
- break;
232
- }
233
-
234
- case 'shell-command': {
235
- const { command: cmd, cwd } = data;
236
- // Block dangerous shell patterns
237
- if (!cmd || typeof cmd !== 'string') throw new Error('Invalid command');
238
- const dangerous = ['rm -rf /', 'mkfs', 'dd if=', ':(){', 'fork bomb', '> /dev/sd'];
239
- if (dangerous.some(d => cmd.includes(d))) throw new Error('Command blocked for safety');
240
- logRelayEvent('$', `Shell: ${cmd?.slice(0, 50)}`, 'dim');
241
- const result = await execCommand(cmd, [], { cwd: cwd || os.homedir(), timeout: 60000 });
242
- ws.send(JSON.stringify({ type: 'relay-response', requestId, data: { stdout: result } }));
243
- break;
244
- }
245
-
246
- case 'file-read': {
247
- const { filePath } = data;
248
- if (!filePath || typeof filePath !== 'string') throw new Error('Invalid file path');
249
- // Block reading sensitive system files
250
- const normalizedPath = path.resolve(filePath);
251
- const blocked = ['/etc/shadow', '/etc/passwd', '.ssh/id_rsa', '.env'];
252
- if (blocked.some(b => normalizedPath.includes(b))) throw new Error('Access denied');
253
- logRelayEvent('R', `Read: ${filePath}`, 'dim');
254
- const content = await fsPromises.readFile(normalizedPath, 'utf8');
255
- ws.send(JSON.stringify({ type: 'relay-response', requestId, data: { content } }));
256
- break;
257
- }
258
-
259
- case 'file-write': {
260
- const { filePath: fp, content: fileContent } = data;
261
- if (!fp || typeof fp !== 'string') throw new Error('Invalid file path');
262
- // Block writing to sensitive locations
263
- const normalizedFp = path.resolve(fp);
264
- const blockedDirs = ['/etc/', '/usr/bin/', '/usr/sbin/', 'System32', '.ssh/'];
265
- if (blockedDirs.some(d => normalizedFp.includes(d))) throw new Error('Access denied');
266
- logRelayEvent('W', `Write: ${fp}`, 'dim');
267
- await fsPromises.writeFile(normalizedFp, fileContent, 'utf8');
268
- ws.send(JSON.stringify({ type: 'relay-response', requestId, data: { success: true } }));
269
- break;
270
- }
271
-
272
- case 'file-tree': {
273
- const { dirPath, depth = 3 } = data;
274
- const tree = await buildFileTree(dirPath || os.homedir(), depth);
275
- ws.send(JSON.stringify({ type: 'relay-response', requestId, data: { tree } }));
276
- break;
277
- }
278
-
279
- case 'git-operation': {
280
- const { gitCommand, cwd: gitCwd } = data;
281
- logRelayEvent('G', `Git: ${gitCommand}`, 'dim');
282
- const result = await execCommand('git', [gitCommand], { cwd: gitCwd });
283
- ws.send(JSON.stringify({ type: 'relay-response', requestId, data: { stdout: result } }));
284
- break;
285
- }
286
-
287
- default:
288
- ws.send(JSON.stringify({
289
- type: 'relay-response',
290
- requestId,
291
- error: `Unknown action: ${action}`
292
- }));
293
- }
294
- } catch (err) {
295
- ws.send(JSON.stringify({
296
- type: 'relay-response',
297
- requestId,
298
- error: err.message
299
- }));
300
- }
301
- }
302
-
303
- /**
304
- * Build a file tree for a directory
305
- */
306
- async function buildFileTree(dirPath, maxDepth, currentDepth = 0) {
307
- if (currentDepth >= maxDepth) return [];
308
- try {
309
- const entries = await fsPromises.readdir(dirPath, { withFileTypes: true });
310
- const items = [];
311
- for (const entry of entries.slice(0, 100)) {
312
- if (entry.name.startsWith('.') || entry.name === 'node_modules') continue;
313
- const item = { name: entry.name, type: entry.isDirectory() ? 'directory' : 'file' };
314
- if (entry.isDirectory() && currentDepth < maxDepth - 1) {
315
- item.children = await buildFileTree(path.join(dirPath, entry.name), maxDepth, currentDepth + 1);
316
- }
317
- items.push(item);
318
- }
319
- return items;
320
- } catch (e) {
321
- return [];
322
- }
323
- }
324
-
325
- /**
326
- * Detect which AI CLI agents are installed on this machine
327
- * Returns an object with agent names and their availability
328
- */
329
- function detectInstalledAgents() {
330
- const isWindows = process.platform === 'win32';
331
- const whichCmd = isWindows ? 'where' : 'which';
332
-
333
- const agents = [
334
- { name: 'claude', binary: 'claude', label: 'Claude Code' },
335
- { name: 'codex', binary: 'codex', label: 'OpenAI Codex' },
336
- { name: 'cursor', binary: 'cursor-agent', label: 'Cursor Agent' },
337
- ];
338
-
339
- const detected = {};
340
- for (const agent of agents) {
341
- try {
342
- const result = execSync(`${whichCmd} ${agent.binary}`, { stdio: 'pipe', timeout: 5000 }).toString().trim();
343
- detected[agent.name] = {
344
- installed: true,
345
- path: result.split('\n')[0].trim(),
346
- label: agent.label,
347
- };
348
- } catch {
349
- detected[agent.name] = {
350
- installed: false,
351
- label: agent.label,
352
- };
353
- }
354
- }
355
- return detected;
356
- }
357
-
358
- /**
359
- * Create WebSocket connection with optional API key in handshake
360
- */
361
- function createRelayConnection(wsUrl, config = {}) {
362
- const headers = {};
363
- // Send API key in WebSocket headers if available
364
- if (config.anthropicApiKey) {
365
- headers['x-anthropic-api-key'] = config.anthropicApiKey;
366
- }
367
- headers['x-upfyn-version'] = VERSION;
368
- headers['x-upfyn-machine'] = os.hostname();
369
- headers['x-upfyn-platform'] = process.platform;
370
- headers['x-upfyn-cwd'] = process.cwd();
371
-
372
- return new WebSocket(wsUrl, { headers });
373
- }
374
-
375
- /**
376
- * Main connect function (interactive — with animation and logging)
377
- */
378
- export async function connectToServer(options = {}) {
379
- const config = loadConfig();
380
- const serverUrl = options.server || config.server || 'https://upfynai.thinqmesh.com';
381
- const relayKey = options.key || config.relayKey;
382
-
383
- if (!relayKey) {
384
- console.log('');
385
- console.log(` ${c.red('FAIL')} No relay key provided.`);
386
- console.log('');
387
- console.log(` ${c.gray('Get your relay token from the web UI:')}`);
388
- console.log(` ${c.dim('1.')} Sign in at ${c.cyan('https://cli.upfyn.com')}`);
389
- console.log(` ${c.dim('2.')} Click ${c.bright('Connect')} button`);
390
- console.log(` ${c.dim('3.')} Copy the command and run it here`);
391
- console.log('');
392
- console.log(` ${c.gray('Or run:')} ${c.bright('uc connect --server <url> --key upfyn_your_token')}`);
393
- console.log('');
394
- process.exit(1);
395
- }
396
-
397
- // Save config for future use
398
- saveConfig({ ...config, server: serverUrl, relayKey });
399
-
400
- // Show beautiful startup with rocket animation
401
- await showConnectStartup(
402
- serverUrl,
403
- os.hostname(),
404
- os.userInfo().username,
405
- VERSION
406
- );
407
-
408
- const wsUrl = serverUrl.replace(/^http/, 'ws') + '/relay?token=' + encodeURIComponent(relayKey);
409
-
410
- const spinner = createSpinner('Connecting to server...');
411
- spinner.start();
412
-
413
- let reconnectAttempts = 0;
414
- const MAX_RECONNECT = 10;
415
-
416
- let lastPongTime = Date.now();
417
-
418
- function connect() {
419
- const ws = createRelayConnection(wsUrl, config);
420
- lastPongTime = Date.now();
421
-
422
- ws.on('open', () => {
423
- reconnectAttempts = 0;
424
- lastPongTime = Date.now();
425
- // Don't stop spinner yet — wait for relay-connected message
426
- });
427
-
428
- ws.on('message', (rawMessage) => {
429
- try {
430
- const data = JSON.parse(rawMessage);
431
-
432
- if (data.type === 'relay-connected') {
433
- spinner.stop('Connected!');
434
- // Extract username from message if possible
435
- const nameMatch = data.message?.match(/Connected as (.+?)\./);
436
- const username = nameMatch ? nameMatch[1] : 'Unknown';
437
- showConnectionBanner(username, serverUrl);
438
-
439
- // Detect and report installed agents
440
- const agents = detectInstalledAgents();
441
- const installed = Object.entries(agents)
442
- .filter(([, info]) => info.installed)
443
- .map(([name, info]) => info.label);
444
- const missing = Object.entries(agents)
445
- .filter(([, info]) => !info.installed)
446
- .map(([name, info]) => info.label);
447
-
448
- if (installed.length > 0) {
449
- logRelayEvent('+', `Agents found: ${installed.join(', ')}`, 'green');
450
- }
451
- if (missing.length > 0) {
452
- logRelayEvent('~', `Not found: ${missing.join(', ')} (install to enable)`, 'yellow');
453
- }
454
-
455
- // Send agent capabilities to server
456
- ws.send(JSON.stringify({
457
- type: 'agent-capabilities',
458
- agents,
459
- machine: {
460
- hostname: os.hostname(),
461
- platform: process.platform,
462
- cwd: process.cwd(),
463
- }
464
- }));
465
-
466
- logRelayEvent('*', 'Relay active -- waiting for commands...', 'green');
467
- return;
468
- }
469
-
470
- if (data.type === 'relay-command') {
471
- handleRelayCommand(data, ws);
472
- return;
473
- }
474
-
475
- if (data.type === 'pong' || data.type === 'server-ping') {
476
- lastPongTime = Date.now();
477
- // Reply to server-ping so server knows we're alive
478
- if (data.type === 'server-ping') {
479
- ws.send(JSON.stringify({ type: 'ping' }));
480
- }
481
- return;
482
- }
483
-
484
- if (data.type === 'error') {
485
- spinner.fail(`Server error: ${data.error}`);
486
- return;
487
- }
488
- } catch (e) {
489
- logRelayEvent('!', `Parse error: ${e.message}`, 'red');
490
- }
491
- });
492
-
493
- ws.on('close', (code) => {
494
- if (code === 1000) {
495
- logRelayEvent('-', 'Disconnected gracefully.', 'dim');
496
- process.exit(0);
497
- }
498
-
499
- reconnectAttempts++;
500
- if (reconnectAttempts <= MAX_RECONNECT) {
501
- const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000);
502
- logRelayEvent('~', `Connection lost. Reconnecting in ${delay / 1000}s... (${reconnectAttempts}/${MAX_RECONNECT})`, 'yellow');
503
- setTimeout(connect, delay);
504
- } else {
505
- logRelayEvent('X', 'Max reconnection attempts reached. Exiting.', 'red');
506
- process.exit(1);
507
- }
508
- });
509
-
510
- ws.on('error', (err) => {
511
- if (err.code === 'ECONNREFUSED') {
512
- spinner.fail(`Cannot reach ${serverUrl}. Is the server running?`);
513
- }
514
- // close handler will trigger reconnect
515
- });
516
-
517
- // Heartbeat every 30 seconds with pong timeout detection
518
- const heartbeat = setInterval(() => {
519
- if (ws.readyState !== 1) {
520
- clearInterval(heartbeat);
521
- return;
522
- }
523
- // If no pong received in 75s, consider connection dead
524
- if (Date.now() - lastPongTime > 75000) {
525
- clearInterval(heartbeat);
526
- logRelayEvent('!', 'No heartbeat response — connection stale, reconnecting...', 'yellow');
527
- ws.terminate();
528
- return;
529
- }
530
- ws.send(JSON.stringify({ type: 'ping' }));
531
- }, 30000);
532
-
533
- ws.on('close', () => clearInterval(heartbeat));
534
- ws.on('error', () => clearInterval(heartbeat));
535
- }
536
-
537
- connect();
538
-
539
- // Graceful shutdown
540
- process.on('SIGINT', () => {
541
- console.log('');
542
- logRelayEvent('-', 'Disconnecting...', 'dim');
543
- process.exit(0);
544
- });
545
- }
546
-
547
- /**
548
- * Background connect function (silent — used when uc launches Claude Code)
549
- * Runs relay in the background without animation or user-facing output.
550
- */
551
- export function connectToServerBackground(options = {}) {
552
- const config = loadConfig();
553
- const serverUrl = options.server || config.server;
554
- const relayKey = options.key || config.relayKey;
555
-
556
- if (!serverUrl || !relayKey) return;
557
-
558
- const wsUrl = serverUrl.replace(/^http/, 'ws') + '/relay?token=' + encodeURIComponent(relayKey);
559
-
560
- let reconnectAttempts = 0;
561
- const MAX_RECONNECT = 5;
562
- let lastPongTime = Date.now();
563
-
564
- function connect() {
565
- const ws = createRelayConnection(wsUrl, config);
566
- lastPongTime = Date.now();
567
-
568
- ws.on('message', (rawMessage) => {
569
- try {
570
- const data = JSON.parse(rawMessage);
571
- if (data.type === 'pong' || data.type === 'server-ping') {
572
- lastPongTime = Date.now();
573
- if (data.type === 'server-ping') {
574
- ws.send(JSON.stringify({ type: 'ping' }));
575
- }
576
- return;
577
- }
578
- if (data.type === 'relay-command') {
579
- handleRelayCommand(data, ws);
580
- }
581
- } catch { /* ignore */ }
582
- });
583
-
584
- ws.on('open', () => {
585
- reconnectAttempts = 0;
586
- lastPongTime = Date.now();
587
- });
588
-
589
- ws.on('close', (code) => {
590
- clearInterval(heartbeat);
591
- if (code === 1000) return;
592
- reconnectAttempts++;
593
- if (reconnectAttempts <= MAX_RECONNECT) {
594
- const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000);
595
- setTimeout(connect, delay);
596
- }
597
- });
598
-
599
- ws.on('error', () => {
600
- clearInterval(heartbeat);
601
- });
602
-
603
- // Heartbeat with pong timeout
604
- const heartbeat = setInterval(() => {
605
- if (ws.readyState !== 1) {
606
- clearInterval(heartbeat);
607
- return;
608
- }
609
- if (Date.now() - lastPongTime > 75000) {
610
- clearInterval(heartbeat);
611
- ws.terminate();
612
- return;
613
- }
614
- ws.send(JSON.stringify({ type: 'ping' }));
615
- }, 30000);
616
- }
617
-
618
- connect();
619
- }