upfynai-code 2.6.0 → 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.
- package/README.md +123 -88
- package/bin/cli.js +63 -0
- package/package.json +48 -106
- package/src/auth.js +115 -0
- package/src/config.js +33 -0
- package/src/connect.js +314 -0
- package/src/launch.js +54 -0
- package/src/mcp.js +57 -0
- package/src/server.js +54 -0
- package/client/dist/api-docs.html +0 -879
- package/client/dist/assets/AppContent-C0CyP3g5.js +0 -513
- package/client/dist/assets/CanvasPanel-0u9QR7U-.js +0 -34
- package/client/dist/assets/CanvasPanel-WhZulBJw.css +0 -1
- package/client/dist/assets/DashboardPanel-Dgqw1yZk.js +0 -1
- package/client/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/client/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/client/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/client/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/client/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/client/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/client/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/client/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/client/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/client/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/client/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/client/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/client/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/client/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/client/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/client/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/client/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/client/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/client/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/client/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/client/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/client/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/client/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/client/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/client/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/client/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/client/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/client/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/client/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/client/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/client/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/client/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/client/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/client/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/client/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/client/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/client/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/client/dist/assets/LoginModal-CZDEzqjK.js +0 -19
- package/client/dist/assets/MarkdownPreview-CYdvwJaV.js +0 -1
- package/client/dist/assets/Onboarding-DR6NZ4Vz.js +0 -1
- package/client/dist/assets/SetupForm-D49gtWY4.js +0 -1
- package/client/dist/assets/Tableau10-B-NsZVaP.js +0 -1
- package/client/dist/assets/WorkflowsPanel-CqlbEJA_.js +0 -1
- package/client/dist/assets/_commonjs-dynamic-modules-TDtrdbi3.js +0 -1
- package/client/dist/assets/ar-SA-G6X2FPQ2-BWqa1yBH.js +0 -10
- package/client/dist/assets/arc-BegSKqEW.js +0 -1
- package/client/dist/assets/array-BKyUJesY.js +0 -1
- package/client/dist/assets/az-AZ-76LH7QW2-DrVlbZDP.js +0 -1
- package/client/dist/assets/bg-BG-XCXSNQG7-DdunjBgT.js +0 -5
- package/client/dist/assets/blockDiagram-38ab4fdb-BKMbwGHu.js +0 -118
- package/client/dist/assets/bn-BD-2XOGV67Q-_7DtmvwO.js +0 -5
- package/client/dist/assets/c4Diagram-3d4e48cf-hJuiHhSn.js +0 -10
- package/client/dist/assets/ca-ES-6MX7JW3Y-BFIrmojG.js +0 -8
- package/client/dist/assets/channel-Bur-rRTp.js +0 -1
- package/client/dist/assets/classDiagram-70f12bd4-BjiAf9cM.js +0 -2
- package/client/dist/assets/classDiagram-v2-f2320105-pwBewejc.js +0 -2
- package/client/dist/assets/clone-BtqXeoBJ.js +0 -1
- package/client/dist/assets/createText-2e5e7dd3-Dq_acOWe.js +0 -5
- package/client/dist/assets/cs-CZ-2BRQDIVT-B-x4F6TJ.js +0 -11
- package/client/dist/assets/da-DK-5WZEPLOC-Btlc8Dgn.js +0 -5
- package/client/dist/assets/de-DE-XR44H4JA-BVu3ZIoD.js +0 -8
- package/client/dist/assets/directory-open-01563666-DWU9wJ6I.js +0 -1
- package/client/dist/assets/directory-open-4ed118d0-CunoC1EB.js +0 -1
- package/client/dist/assets/edges-e0da2a9e-DH0wVTXR.js +0 -4
- package/client/dist/assets/el-GR-BZB4AONW-h2ll8_ZC.js +0 -10
- package/client/dist/assets/erDiagram-9861fffd-BYezLIR7.js +0 -51
- package/client/dist/assets/es-ES-U4NZUMDT-Cveiulwt.js +0 -9
- package/client/dist/assets/eu-ES-A7QVB2H4-DQluL2PY.js +0 -11
- package/client/dist/assets/fa-IR-HGAKTJCU-BJtcMBSv.js +0 -8
- package/client/dist/assets/fi-FI-Z5N7JZ37-D8NfbVXV.js +0 -6
- package/client/dist/assets/file-open-002ab408-DIuFHtCF.js +0 -1
- package/client/dist/assets/file-open-7c801643-684qeFg4.js +0 -1
- package/client/dist/assets/file-save-3189631c-C1wFhQhH.js +0 -1
- package/client/dist/assets/file-save-745eba88-Bb9F9Kg7.js +0 -1
- package/client/dist/assets/flowDb-956e92f1-scnUykhM.js +0 -10
- package/client/dist/assets/flowDiagram-66a62f08-jVyWsfyU.js +0 -4
- package/client/dist/assets/flowDiagram-v2-96b9c2cf-N6xgi25h.js +0 -1
- package/client/dist/assets/flowchart-elk-definition-4a651766-gKGX3HqR.js +0 -139
- package/client/dist/assets/fr-FR-RHASNOE6-vdj42kC6.js +0 -9
- package/client/dist/assets/ganttDiagram-c361ad54-C2CiWFUP.js +0 -257
- package/client/dist/assets/gitGraphDiagram-72cf32ee-C59Yz2LK.js +0 -70
- package/client/dist/assets/gl-ES-HMX3MZ6V-DQo0TzoP.js +0 -10
- package/client/dist/assets/graph-Dx_H43Kv.js +0 -1
- package/client/dist/assets/he-IL-6SHJWFNN-DKXK5e33.js +0 -10
- package/client/dist/assets/hi-IN-IWLTKZ5I-C2Qgqc0R.js +0 -4
- package/client/dist/assets/hu-HU-A5ZG7DT2-Ss-6vX0m.js +0 -7
- package/client/dist/assets/id-ID-SAP4L64H-D7Wsg1S2.js +0 -10
- package/client/dist/assets/image-blob-reduce.esm-D6s-rqMO.js +0 -7
- package/client/dist/assets/index-3862675e-u8Nv7hHC.js +0 -1
- package/client/dist/assets/index-BVowJdZF.js +0 -97
- package/client/dist/assets/index-ce18TYkg.js +0 -27
- package/client/dist/assets/index-kQoJx-bc.css +0 -1
- package/client/dist/assets/infoDiagram-f8f76790-LmoJYsxo.js +0 -7
- package/client/dist/assets/init-Gi6I4Gst.js +0 -1
- package/client/dist/assets/it-IT-JPQ66NNP-CAPTVl7M.js +0 -11
- package/client/dist/assets/ja-JP-DBVTYXUO-eNVPawR2.js +0 -8
- package/client/dist/assets/journeyDiagram-49397b02-BaJqehpR.js +0 -139
- package/client/dist/assets/kaa-6HZHGXH3-tpuNkKhS.js +0 -1
- package/client/dist/assets/kab-KAB-ZGHBKWFO-Dp83kx4x.js +0 -8
- package/client/dist/assets/kk-KZ-P5N5QNE5-B9IlC6YN.js +0 -1
- package/client/dist/assets/km-KH-HSX4SM5Z-B_KMYaMj.js +0 -11
- package/client/dist/assets/ko-KR-MTYHY66A-yebnUNdb.js +0 -9
- package/client/dist/assets/ku-TR-6OUDTVRD-BR6fh6-5.js +0 -9
- package/client/dist/assets/layout-DLl5Jwcl.js +0 -1
- package/client/dist/assets/line-FpB7omSK.js +0 -1
- package/client/dist/assets/linear-CkXqUFJ8.js +0 -1
- package/client/dist/assets/lt-LT-XHIRWOB4-SutZSWtR.js +0 -3
- package/client/dist/assets/lv-LV-5QDEKY6T-DuAxdcZL.js +0 -7
- package/client/dist/assets/mindmap-definition-fc14e90a-DyxXOExh.js +0 -425
- package/client/dist/assets/mr-IN-CRQNXWMA-DqDUWM_8.js +0 -13
- package/client/dist/assets/my-MM-5M5IBNSE-C40kMFMR.js +0 -1
- package/client/dist/assets/nb-NO-T6EIAALU-DVij32Ju.js +0 -10
- package/client/dist/assets/nl-NL-IS3SIHDZ-rT84mDYq.js +0 -8
- package/client/dist/assets/nn-NO-6E72VCQL-BBZXBW8V.js +0 -8
- package/client/dist/assets/oc-FR-POXYY2M6-DzjOugOf.js +0 -8
- package/client/dist/assets/ordinal-Cboi1Yqb.js +0 -1
- package/client/dist/assets/pa-IN-N4M65BXN-DD1iU8_F.js +0 -4
- package/client/dist/assets/path-CbwjOpE9.js +0 -1
- package/client/dist/assets/pdf-CE_K4jFx.js +0 -12
- package/client/dist/assets/pdf.worker-BA9kU3Pw.mjs +0 -61080
- package/client/dist/assets/percentages-BXMCSKIN-WVlHS4wx.js +0 -207
- package/client/dist/assets/pica-CQIY57Tf.js +0 -7
- package/client/dist/assets/pieDiagram-8a3498a8-Dd_85qBH.js +0 -35
- package/client/dist/assets/pl-PL-T2D74RX3-ukVXa48G.js +0 -9
- package/client/dist/assets/pt-BR-5N22H2LF-BibawarT.js +0 -9
- package/client/dist/assets/pt-PT-UZXXM6DQ-So3i9l9w.js +0 -9
- package/client/dist/assets/quadrantDiagram-120e2f19-C4dFVDEx.js +0 -7
- package/client/dist/assets/requirementDiagram-deff3bca-DrTO7yFl.js +0 -52
- package/client/dist/assets/ro-RO-JPDTUUEW-DY0Xq_Hd.js +0 -11
- package/client/dist/assets/roundRect-0PYZxl1G.js +0 -1
- package/client/dist/assets/ru-RU-B4JR7IUQ-B7u_Zvkd.js +0 -9
- package/client/dist/assets/sankeyDiagram-04a897e0-D24gfzuS.js +0 -8
- package/client/dist/assets/sequenceDiagram-704730f1-Dgji2XLQ.js +0 -122
- package/client/dist/assets/si-LK-N5RQ5JYF-OejsLzQ_.js +0 -1
- package/client/dist/assets/sk-SK-C5VTKIMK-_vy2Bt-M.js +0 -6
- package/client/dist/assets/sl-SI-NN7IZMDC-DKOl_u2M.js +0 -6
- package/client/dist/assets/stateDiagram-587899a1-CJ8eBaiU.js +0 -1
- package/client/dist/assets/stateDiagram-v2-d93cdb3a-C5K3l-Nt.js +0 -1
- package/client/dist/assets/styles-6aaf32cf-DAKE0jbx.js +0 -207
- package/client/dist/assets/styles-9a916d00-LFAJCgEy.js +0 -160
- package/client/dist/assets/styles-c10674c1-CllKO8NG.js +0 -116
- package/client/dist/assets/subset-shared.chunk-Uy-J87FQ.js +0 -84
- package/client/dist/assets/subset-worker.chunk-dvgDvqt9.js +0 -1
- package/client/dist/assets/sv-SE-XGPEYMSR-CDCB2ZV5.js +0 -10
- package/client/dist/assets/svgDrawCommon-08f97a94-CObOzbFQ.js +0 -1
- package/client/dist/assets/ta-IN-2NMHFXQM-DHUNdO69.js +0 -9
- package/client/dist/assets/th-TH-HPSO5L25-zI2hnBq3.js +0 -2
- package/client/dist/assets/timeline-definition-85554ec2-C2XHRmxK.js +0 -61
- package/client/dist/assets/tr-TR-DEFEU3FU-l-6Hu4-D.js +0 -7
- package/client/dist/assets/uk-UA-QMV73CPH-CqSOwrl7.js +0 -6
- package/client/dist/assets/vendor-codemirror-D_s0aGBu.js +0 -35
- package/client/dist/assets/vendor-i18n-DCFGyhQR.js +0 -1
- package/client/dist/assets/vendor-icons-Lb69KSFJ.js +0 -646
- package/client/dist/assets/vendor-markdown-BXEi_H3G.js +0 -298
- package/client/dist/assets/vendor-react-9mUTKBHH.js +0 -67
- package/client/dist/assets/vendor-syntax-DnmwQQJF.js +0 -16
- package/client/dist/assets/vendor-xterm-CZq1hqo1.js +0 -66
- package/client/dist/assets/vendor-xterm-qxJ8_QYu.css +0 -32
- package/client/dist/assets/vi-VN-M7AON7JQ-CUL8-mBZ.js +0 -5
- package/client/dist/assets/xychartDiagram-e933f94c-1fmf6slj.js +0 -7
- package/client/dist/assets/zh-CN-LNUGB5OW-CB5y5VVU.js +0 -10
- package/client/dist/assets/zh-HK-E62DVLB3-BHcrrEeJ.js +0 -1
- package/client/dist/assets/zh-TW-RAJ6MFWO-DoDUdkaJ.js +0 -9
- package/client/dist/clear-cache.html +0 -85
- package/client/dist/convert-icons.md +0 -53
- package/client/dist/favicon.png +0 -0
- package/client/dist/favicon.svg +0 -9
- package/client/dist/generate-icons.js +0 -49
- package/client/dist/icons/claude-ai-icon.svg +0 -1
- package/client/dist/icons/codex-white.svg +0 -3
- package/client/dist/icons/codex.svg +0 -3
- package/client/dist/icons/cursor-white.svg +0 -12
- package/client/dist/icons/cursor.svg +0 -1
- package/client/dist/icons/icon-128x128.png +0 -0
- package/client/dist/icons/icon-128x128.svg +0 -12
- package/client/dist/icons/icon-144x144.png +0 -0
- package/client/dist/icons/icon-144x144.svg +0 -12
- package/client/dist/icons/icon-152x152.png +0 -0
- package/client/dist/icons/icon-152x152.svg +0 -12
- package/client/dist/icons/icon-192x192.png +0 -0
- package/client/dist/icons/icon-192x192.svg +0 -12
- package/client/dist/icons/icon-384x384.png +0 -0
- package/client/dist/icons/icon-384x384.svg +0 -12
- package/client/dist/icons/icon-512x512.png +0 -0
- package/client/dist/icons/icon-512x512.svg +0 -12
- package/client/dist/icons/icon-72x72.png +0 -0
- package/client/dist/icons/icon-72x72.svg +0 -12
- package/client/dist/icons/icon-96x96.png +0 -0
- package/client/dist/icons/icon-96x96.svg +0 -12
- package/client/dist/icons/icon-template.svg +0 -12
- package/client/dist/index.html +0 -128
- package/client/dist/logo-128.png +0 -0
- package/client/dist/logo-256.png +0 -0
- package/client/dist/logo-32.png +0 -0
- package/client/dist/logo-512.png +0 -0
- package/client/dist/logo-64.png +0 -0
- package/client/dist/logo.svg +0 -17
- package/client/dist/manifest.json +0 -61
- package/client/dist/mcp-docs.html +0 -119
- package/client/dist/screenshots/cli-selection.png +0 -0
- package/client/dist/screenshots/desktop-main.png +0 -0
- package/client/dist/screenshots/mobile-chat.png +0 -0
- package/client/dist/screenshots/tools-modal.png +0 -0
- package/client/dist/sw.js +0 -19
- package/commands/upfynai-connect.md +0 -59
- package/commands/upfynai-disconnect.md +0 -31
- package/commands/upfynai-doctor.md +0 -99
- package/commands/upfynai-export.md +0 -49
- package/commands/upfynai-local.md +0 -82
- package/commands/upfynai-status.md +0 -75
- package/commands/upfynai-stop.md +0 -49
- package/commands/upfynai-uninstall.md +0 -58
- package/commands/upfynai.md +0 -69
- package/scripts/build-client.js +0 -17
- package/scripts/fix-node-pty.js +0 -67
- package/scripts/install-commands.js +0 -78
- package/server/claude-sdk.js +0 -714
- package/server/cli-ui.js +0 -785
- package/server/cli.js +0 -596
- package/server/constants/config.js +0 -31
- package/server/cursor-cli.js +0 -270
- package/server/database/auth.db +0 -0
- package/server/database/db.js +0 -822
- package/server/database/init.sql +0 -70
- package/server/index.js +0 -2738
- package/server/load-env.js +0 -26
- package/server/mcp-server.js +0 -621
- package/server/middleware/auth.js +0 -181
- package/server/openai-codex.js +0 -403
- package/server/openrouter.js +0 -137
- package/server/projects.js +0 -1742
- package/server/relay-client.js +0 -672
- package/server/routes/agent.js +0 -1226
- package/server/routes/auth.js +0 -266
- package/server/routes/cli-auth.js +0 -263
- package/server/routes/codex.js +0 -344
- package/server/routes/commands.js +0 -598
- package/server/routes/cursor.js +0 -807
- package/server/routes/dashboard.js +0 -205
- package/server/routes/git.js +0 -1151
- package/server/routes/mcp-utils.js +0 -48
- package/server/routes/mcp.js +0 -535
- package/server/routes/payments.js +0 -172
- package/server/routes/projects.js +0 -552
- package/server/routes/settings.js +0 -261
- package/server/routes/taskmaster.js +0 -1928
- package/server/routes/user.js +0 -106
- package/server/routes/vapi-chat.js +0 -94
- package/server/routes/voice.js +0 -194
- package/server/routes/webhooks.js +0 -166
- package/server/routes/workflows.js +0 -118
- package/server/sandbox.js +0 -120
- package/server/services/whisperService.js +0 -84
- package/server/services/workflowScheduler.js +0 -186
- package/server/utils/commandParser.js +0 -303
- package/server/utils/gitConfig.js +0 -24
- package/server/utils/mcp-detector.js +0 -198
- package/server/utils/taskmaster-websocket.js +0 -129
- package/shared/modelConstants.js +0 -96
package/README.md
CHANGED
|
@@ -1,131 +1,166 @@
|
|
|
1
|
-
#
|
|
1
|
+
# upfyn-code
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Unified AI coding interface — access AI chat, terminal, file explorer, git, and visual canvas from any browser.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Upfyn-Code** connects your local development machine to a browser-based UI through a secure WebSocket relay. Write code with AI assistance, run shell commands, manage files, handle git operations, and plan on a visual canvas — all from any device, anywhere.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Your source code **never leaves your machine**. All file operations, terminal commands, and git actions execute locally through the relay connection.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Install
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- **Multi-Agent Chat** — Claude Code, Cursor, Codex, and 200+ models via OpenRouter
|
|
16
|
-
- **Visual Canvas** — Infinite whiteboard with AI-powered blocks (Chat, Research, Code, Notes, PDF, Dashboard)
|
|
17
|
-
- **Integrated Terminal** — Multi-tab shell with full ANSI color support
|
|
18
|
-
- **File Explorer** — Browse, edit, and manage project files
|
|
19
|
-
- **Git Panel** — Stage, commit, push, view diffs, switch branches
|
|
20
|
-
- **Voice Assistant** — Talk to Upfyn hands-free
|
|
21
|
-
- **Task Tracker** — AI-powered task breakdown from PRDs
|
|
22
|
-
- **MCP Protocol** — Connect to Claude Code, Cursor, or any MCP-compatible tool
|
|
23
|
-
- **Dashboard** — Session analytics, usage stats, and getting-started guide
|
|
24
|
-
- **BYOK** — Bring Your Own API Key (Anthropic, OpenAI, Google, OpenRouter)
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g upfyn-code
|
|
13
|
+
```
|
|
25
14
|
|
|
26
|
-
|
|
15
|
+
Or run directly with npx:
|
|
27
16
|
|
|
28
|
-
|
|
17
|
+
```bash
|
|
18
|
+
npx upfyn-code
|
|
19
|
+
```
|
|
29
20
|
|
|
30
|
-
|
|
21
|
+
**Requirements:** Node.js 18 or later. Works on Windows, macOS, and Linux.
|
|
31
22
|
|
|
32
|
-
|
|
23
|
+
## Quick Start
|
|
33
24
|
|
|
34
25
|
```bash
|
|
35
|
-
|
|
26
|
+
# 1. Authenticate with your Upfyn account
|
|
27
|
+
upfyn-code login
|
|
36
28
|
|
|
37
|
-
#
|
|
38
|
-
|
|
29
|
+
# 2. Connect your machine to the web interface
|
|
30
|
+
upfyn-code connect
|
|
39
31
|
|
|
40
|
-
#
|
|
41
|
-
|
|
32
|
+
# 3. Open the web UI (opens automatically)
|
|
33
|
+
upfyn-code
|
|
42
34
|
```
|
|
43
35
|
|
|
44
|
-
|
|
36
|
+
Once connected, open [cli.upfyn.com](https://cli.upfyn.com) on any device to access your full development environment.
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
- Full web UI with all features (chat, canvas, terminal, git, files, tasks)
|
|
48
|
-
- Direct SDK calls to your local Claude Code / Codex / Cursor
|
|
49
|
-
- No network round-trip — everything runs on your machine
|
|
50
|
-
- Works offline (except AI queries which need API access)
|
|
38
|
+
## Commands
|
|
51
39
|
|
|
52
|
-
|
|
40
|
+
| Command | Description |
|
|
41
|
+
|---------|-------------|
|
|
42
|
+
| `upfyn-code` | Open the hosted web interface (default) |
|
|
43
|
+
| `upfyn-code --local` | Start a local server instead of the hosted app |
|
|
44
|
+
| `upfyn-code login` | Authenticate with your Upfyn account |
|
|
45
|
+
| `upfyn-code logout` | Clear saved credentials |
|
|
46
|
+
| `upfyn-code status` | Show current auth status and configuration |
|
|
47
|
+
| `upfyn-code connect` | Connect your local machine to the remote server |
|
|
48
|
+
| `upfyn-code mcp` | Show MCP integration config for Claude / Cursor |
|
|
53
49
|
|
|
54
|
-
|
|
50
|
+
### Connect Options
|
|
55
51
|
|
|
56
52
|
```bash
|
|
57
|
-
|
|
58
|
-
# 2. Connect your machine
|
|
59
|
-
uc connect --server https://cli.upfyn.com --key upfyn_your_token
|
|
53
|
+
upfyn-code connect --server <url> --key <token>
|
|
60
54
|
```
|
|
61
55
|
|
|
62
|
-
|
|
56
|
+
- `--server <url>` — Server URL to connect to
|
|
57
|
+
- `--key <token>` — Relay token (get from the web UI after signing in)
|
|
63
58
|
|
|
64
|
-
|
|
65
|
-
- An active subscription at [cli.upfyn.com/pricing](https://cli.upfyn.com/pricing)
|
|
66
|
-
- Your relay token (provided after signup)
|
|
67
|
-
- The CLI installed on your machine
|
|
59
|
+
### MCP Integration
|
|
68
60
|
|
|
69
|
-
|
|
70
|
-
-
|
|
71
|
-
|
|
72
|
-
- Voice assistant with daily call allowance
|
|
73
|
-
- Priority support
|
|
61
|
+
```bash
|
|
62
|
+
upfyn-code mcp --server <url> --key <token>
|
|
63
|
+
```
|
|
74
64
|
|
|
75
|
-
|
|
65
|
+
Outputs the MCP (Model Context Protocol) configuration JSON for use with Claude Desktop, Cursor, or other MCP-compatible tools.
|
|
66
|
+
|
|
67
|
+
**Example output:**
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"mcpServers": {
|
|
72
|
+
"upfyn-code": {
|
|
73
|
+
"url": "https://your-server.com/mcp",
|
|
74
|
+
"headers": {
|
|
75
|
+
"Authorization": "Bearer rt_xxxxx"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
76
81
|
|
|
77
|
-
##
|
|
82
|
+
## Features
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
| `uc` | Launch Claude Code with Upfyn web UI |
|
|
82
|
-
| `uc start` | Start the local web server only |
|
|
83
|
-
| `uc connect --key <token>` | Connect to cli.upfyn.com (subscription required) |
|
|
84
|
-
| `uc config --api-key <key>` | Save your Anthropic API key |
|
|
85
|
-
| `uc status` | Show configuration and data locations |
|
|
86
|
-
| `uc install-commands` | Install `/upfynai-*` slash commands for Claude Code |
|
|
87
|
-
| `uc update` | Update to latest version |
|
|
88
|
-
| `uc help` | Show all commands |
|
|
84
|
+
### AI Chat
|
|
85
|
+
Converse with AI coding assistants to write, debug, and refactor code across any language. Supports multiple AI models.
|
|
89
86
|
|
|
90
|
-
|
|
87
|
+
### Integrated Terminal
|
|
88
|
+
Run shell commands on your connected machine directly from the browser. Full terminal emulation with command history.
|
|
91
89
|
|
|
92
|
-
|
|
90
|
+
### File Explorer
|
|
91
|
+
Browse, create, edit, and manage your entire project tree remotely. Supports drag-and-drop, file search, and bulk operations.
|
|
93
92
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
| `/upfynai-connect` | Connect CLI session to web UI |
|
|
97
|
-
| `/upfynai-disconnect` | Disconnect from web UI |
|
|
98
|
-
| `/upfynai-status` | Show connection status |
|
|
99
|
-
| `/upfynai-doctor` | Run diagnostics |
|
|
93
|
+
### Git Management
|
|
94
|
+
Visual git interface for commits, branches, diffs, and merges. Stage changes, resolve conflicts, and manage branches without leaving the browser.
|
|
100
95
|
|
|
101
|
-
|
|
96
|
+
### Upfyn Canvas
|
|
97
|
+
Visual whiteboard with AI-powered blocks for planning and collaboration. Connect chat, research, code, and documentation blocks into context flows.
|
|
102
98
|
|
|
103
|
-
|
|
99
|
+
### MCP Protocol
|
|
100
|
+
Connect external tools and services via the Model Context Protocol. Use Upfyn-Code as an MCP server with Claude Desktop, Cursor, and other compatible tools.
|
|
104
101
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
## How It Works
|
|
103
|
+
|
|
104
|
+
1. **Install** the CLI on your development machine
|
|
105
|
+
2. **Authenticate** with `upfyn-code login`
|
|
106
|
+
3. **Connect** with `upfyn-code connect` — this creates a secure WebSocket tunnel
|
|
107
|
+
4. **Open** [cli.upfyn.com](https://cli.upfyn.com) on any browser (desktop, tablet, or mobile)
|
|
108
|
+
|
|
109
|
+
The CLI bridges your local filesystem, terminal, and git to the web interface. No ports are exposed and no firewall configuration is needed — the connection works through a secure relay.
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
┌─────────────┐ WebSocket ┌──────────────┐ Browser ┌──────────────┐
|
|
113
|
+
│ Your Local │ ──────────────▶ │ Upfyn Relay │ ◀────────────── │ Web UI at │
|
|
114
|
+
│ Machine │ (encrypted) │ Server │ │ cli.upfyn.com│
|
|
115
|
+
└─────────────┘ └──────────────┘ └──────────────┘
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Security
|
|
119
|
+
|
|
120
|
+
- All communication is encrypted with TLS
|
|
121
|
+
- Source code is relayed in real-time and **never stored** on servers
|
|
122
|
+
- Authentication uses JWT tokens with httpOnly cookies
|
|
123
|
+
- The relay connection requires both a valid session and a connection token
|
|
124
|
+
- Self-hosting is supported for full data sovereignty
|
|
125
|
+
|
|
126
|
+
## Self-Hosting
|
|
127
|
+
|
|
128
|
+
Upfyn-Code is open source under the GPL-3.0 license. You can deploy the entire stack on your own infrastructure:
|
|
109
129
|
|
|
110
|
-
Configure via the web UI (Settings > AI Providers) or CLI:
|
|
111
130
|
```bash
|
|
112
|
-
|
|
131
|
+
git clone https://github.com/AnitChaudhry/UpfynAI-Code.git
|
|
132
|
+
cd UpfynAI-Code
|
|
133
|
+
|
|
134
|
+
# Install dependencies
|
|
135
|
+
npm install
|
|
136
|
+
|
|
137
|
+
# Start the backend
|
|
138
|
+
cd backend && npm start
|
|
139
|
+
|
|
140
|
+
# Start the frontend
|
|
141
|
+
cd frontend && npm run dev
|
|
113
142
|
```
|
|
114
143
|
|
|
115
|
-
|
|
144
|
+
See the [repository](https://github.com/AnitChaudhry/UpfynAI-Code) for full deployment instructions.
|
|
116
145
|
|
|
117
|
-
|
|
118
|
-
- At least one AI agent installed:
|
|
119
|
-
```bash
|
|
120
|
-
npm install -g @anthropic-ai/claude-code # Claude Code
|
|
121
|
-
npm install -g @openai/codex # OpenAI Codex
|
|
122
|
-
# Cursor — install from cursor.com
|
|
123
|
-
```
|
|
146
|
+
## Configuration
|
|
124
147
|
|
|
125
|
-
|
|
148
|
+
Credentials and config are stored locally at:
|
|
126
149
|
|
|
127
|
-
|
|
150
|
+
| Platform | Path |
|
|
151
|
+
|----------|------|
|
|
152
|
+
| macOS / Linux | `~/.config/upfyn-code/` |
|
|
153
|
+
| Windows | `%APPDATA%\upfyn-code\` |
|
|
154
|
+
|
|
155
|
+
## Links
|
|
156
|
+
|
|
157
|
+
- **Website:** [cli.upfyn.com](https://cli.upfyn.com)
|
|
158
|
+
- **Documentation:** [cli.upfyn.com/docs](https://cli.upfyn.com/docs)
|
|
159
|
+
- **GitHub:** [github.com/AnitChaudhry/UpfynAI-Code](https://github.com/AnitChaudhry/UpfynAI-Code)
|
|
160
|
+
- **Issues:** [github.com/AnitChaudhry/UpfynAI-Code/issues](https://github.com/AnitChaudhry/UpfynAI-Code/issues)
|
|
128
161
|
|
|
129
162
|
## License
|
|
130
163
|
|
|
131
|
-
GPL-3.0 —
|
|
164
|
+
GPL-3.0 — see [LICENSE](https://github.com/AnitChaudhry/UpfynAI-Code/blob/main/LICENSE) for details.
|
|
165
|
+
|
|
166
|
+
Built by [Thinqmesh Technologies](https://cli.upfyn.com).
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { login, logout, status } from '../src/auth.js';
|
|
5
|
+
import { openHosted, startLocal } from '../src/launch.js';
|
|
6
|
+
import { connect } from '../src/connect.js';
|
|
7
|
+
import { mcp } from '../src/mcp.js';
|
|
8
|
+
|
|
9
|
+
const program = new Command();
|
|
10
|
+
|
|
11
|
+
program
|
|
12
|
+
.name('upfyn-code')
|
|
13
|
+
.description('Launch Upfyn AI coding environment from your terminal')
|
|
14
|
+
.version('1.0.4')
|
|
15
|
+
.option('--local', 'Start a local server instead of opening the hosted app')
|
|
16
|
+
.action(async (options) => {
|
|
17
|
+
if (options.local) {
|
|
18
|
+
await startLocal();
|
|
19
|
+
} else {
|
|
20
|
+
await openHosted();
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
program
|
|
25
|
+
.command('login')
|
|
26
|
+
.description('Authenticate with your Upfyn account')
|
|
27
|
+
.action(async () => {
|
|
28
|
+
await login();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
program
|
|
32
|
+
.command('logout')
|
|
33
|
+
.description('Clear saved credentials')
|
|
34
|
+
.action(async () => {
|
|
35
|
+
await logout();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
program
|
|
39
|
+
.command('status')
|
|
40
|
+
.description('Show current auth status and config')
|
|
41
|
+
.action(async () => {
|
|
42
|
+
await status();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
program
|
|
46
|
+
.command('connect')
|
|
47
|
+
.description('Connect local machine to the remote server (bridges Claude Code, shell, files, git)')
|
|
48
|
+
.option('--server <url>', 'Server URL to connect to')
|
|
49
|
+
.option('--key <token>', 'Relay token (rt_xxx) — get from the web UI')
|
|
50
|
+
.action(async (options) => {
|
|
51
|
+
await connect(options);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
program
|
|
55
|
+
.command('mcp')
|
|
56
|
+
.description('Show MCP integration config for Claude / Cursor')
|
|
57
|
+
.option('--server <url>', 'Server URL')
|
|
58
|
+
.option('--key <token>', 'Relay token')
|
|
59
|
+
.action(async (options) => {
|
|
60
|
+
await mcp(options);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
program.parse();
|
package/package.json
CHANGED
|
@@ -1,132 +1,74 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "upfynai-code",
|
|
3
|
-
"version": "2.6.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.6.1",
|
|
4
|
+
"description": "Unified AI coding interface — access AI chat, terminal, file explorer, git, and visual canvas from any browser. Connect your local machine and code from anywhere.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "server/index.js",
|
|
7
6
|
"bin": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
7
|
+
"uc": "./bin/cli.js",
|
|
8
|
+
"upfynai-code": "./bin/cli.js"
|
|
10
9
|
},
|
|
11
10
|
"files": [
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"README.md"
|
|
11
|
+
"bin/",
|
|
12
|
+
"src/",
|
|
13
|
+
"dist/",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
18
16
|
],
|
|
19
17
|
"scripts": {
|
|
20
|
-
"start": "node
|
|
21
|
-
"build": "node scripts/build-client.js",
|
|
22
|
-
"postinstall": "node scripts/fix-node-pty.js || true && node scripts/install-commands.js"
|
|
18
|
+
"start": "node bin/cli.js"
|
|
23
19
|
},
|
|
24
20
|
"keywords": [
|
|
21
|
+
"upfyn",
|
|
22
|
+
"upfyn-code",
|
|
25
23
|
"ai",
|
|
24
|
+
"coding",
|
|
25
|
+
"cli",
|
|
26
|
+
"terminal",
|
|
27
|
+
"remote-development",
|
|
28
|
+
"code-editor",
|
|
29
|
+
"ai-assistant",
|
|
26
30
|
"ai-coding",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
+
"developer-tools",
|
|
32
|
+
"devtools",
|
|
33
|
+
"browser-ide",
|
|
34
|
+
"remote-access",
|
|
35
|
+
"websocket",
|
|
36
|
+
"git",
|
|
37
|
+
"file-explorer",
|
|
31
38
|
"canvas",
|
|
32
39
|
"whiteboard",
|
|
33
|
-
"visual-coding",
|
|
34
|
-
"terminal",
|
|
35
|
-
"git",
|
|
36
40
|
"mcp",
|
|
37
|
-
"
|
|
38
|
-
"byok",
|
|
39
|
-
"voice-assistant",
|
|
40
|
-
"upfynai",
|
|
41
|
-
"thinqmesh"
|
|
41
|
+
"model-context-protocol"
|
|
42
42
|
],
|
|
43
|
-
"author":
|
|
43
|
+
"author": {
|
|
44
|
+
"name": "Thinqmesh Technologies",
|
|
45
|
+
"url": "https://cli.upfyn.com"
|
|
46
|
+
},
|
|
44
47
|
"license": "GPL-3.0",
|
|
45
|
-
"homepage": "https://
|
|
48
|
+
"homepage": "https://cli.upfyn.com",
|
|
46
49
|
"repository": {
|
|
47
50
|
"type": "git",
|
|
48
|
-
"url": "git+https://github.com/
|
|
51
|
+
"url": "git+https://github.com/AnitChaudhry/UpfynAI-Code.git",
|
|
52
|
+
"directory": "packages/cli"
|
|
49
53
|
},
|
|
50
54
|
"bugs": {
|
|
51
|
-
"url": "https://github.com/
|
|
55
|
+
"url": "https://github.com/AnitChaudhry/UpfynAI-Code/issues"
|
|
52
56
|
},
|
|
53
57
|
"dependencies": {
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"@codemirror/lang-python": "^6.2.1",
|
|
62
|
-
"@codemirror/merge": "^6.11.1",
|
|
63
|
-
"@codemirror/theme-one-dark": "^6.1.2",
|
|
64
|
-
"@excalidraw/excalidraw": "^0.18.0",
|
|
65
|
-
"@iarna/toml": "^2.2.5",
|
|
66
|
-
"@libsql/client": "^0.14.0",
|
|
67
|
-
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
68
|
-
"@neondatabase/serverless": "^1.0.2",
|
|
69
|
-
"@octokit/rest": "^22.0.0",
|
|
70
|
-
"@openai/codex-sdk": "^0.101.0",
|
|
71
|
-
"@replit/codemirror-minimap": "^0.5.2",
|
|
72
|
-
"@tailwindcss/typography": "^0.5.16",
|
|
73
|
-
"@uiw/react-codemirror": "^4.23.13",
|
|
74
|
-
"@vitejs/plugin-react": "^4.5.2",
|
|
75
|
-
"@xterm/addon-clipboard": "^0.1.0",
|
|
76
|
-
"@xterm/addon-fit": "^0.10.0",
|
|
77
|
-
"@xterm/addon-web-links": "^0.11.0",
|
|
78
|
-
"@xterm/addon-webgl": "^0.18.0",
|
|
79
|
-
"@xterm/xterm": "^5.5.0",
|
|
80
|
-
"autoprefixer": "^10.4.16",
|
|
81
|
-
"bcryptjs": "^3.0.3",
|
|
82
|
-
"chokidar": "^4.0.3",
|
|
83
|
-
"class-variance-authority": "^0.7.1",
|
|
84
|
-
"clsx": "^2.1.1",
|
|
85
|
-
"cookie-parser": "^1.4.7",
|
|
86
|
-
"cors": "^2.8.5",
|
|
87
|
-
"cross-spawn": "^7.0.3",
|
|
88
|
-
"edge-tts-universal": "^1.3.3",
|
|
89
|
-
"express": "^4.18.2",
|
|
90
|
-
"form-data": "^4.0.5",
|
|
91
|
-
"fuse.js": "^7.0.0",
|
|
92
|
-
"gray-matter": "^4.0.3",
|
|
93
|
-
"i18next": "^25.7.4",
|
|
94
|
-
"i18next-browser-languagedetector": "^8.2.0",
|
|
95
|
-
"jsonwebtoken": "^9.0.2",
|
|
96
|
-
"katex": "^0.16.25",
|
|
97
|
-
"lucide-react": "^0.515.0",
|
|
98
|
-
"mime-types": "^3.0.1",
|
|
99
|
-
"multer": "^2.0.2",
|
|
100
|
-
"node-cron": "^4.2.1",
|
|
101
|
-
"pdfjs-dist": "^5.4.624",
|
|
102
|
-
"postcss": "^8.4.32",
|
|
103
|
-
"razorpay": "^2.9.6",
|
|
104
|
-
"react": "^18.2.0",
|
|
105
|
-
"react-dom": "^18.2.0",
|
|
106
|
-
"react-dropzone": "^14.2.3",
|
|
107
|
-
"react-i18next": "^16.5.3",
|
|
108
|
-
"react-markdown": "^10.1.0",
|
|
109
|
-
"react-router-dom": "^6.8.1",
|
|
110
|
-
"react-syntax-highlighter": "^15.6.1",
|
|
111
|
-
"rehype-katex": "^7.0.1",
|
|
112
|
-
"rehype-raw": "^7.0.0",
|
|
113
|
-
"remark-gfm": "^4.0.0",
|
|
114
|
-
"remark-math": "^6.0.0",
|
|
115
|
-
"tailwind-merge": "^3.3.1",
|
|
116
|
-
"tailwindcss": "^3.4.0",
|
|
117
|
-
"vite": "~6.3.5",
|
|
118
|
-
"ws": "^8.14.2",
|
|
119
|
-
"zod": "^3.25.76",
|
|
120
|
-
"zustand": "^5.0.11"
|
|
58
|
+
"chalk": "^5.3.0",
|
|
59
|
+
"commander": "^12.1.0",
|
|
60
|
+
"express": "^4.21.0",
|
|
61
|
+
"http-proxy-middleware": "^3.0.0",
|
|
62
|
+
"open": "^10.1.0",
|
|
63
|
+
"prompts": "^2.4.2",
|
|
64
|
+
"ws": "^8.18.0"
|
|
121
65
|
},
|
|
122
|
-
"
|
|
123
|
-
"node
|
|
66
|
+
"engines": {
|
|
67
|
+
"node": ">=18.0.0"
|
|
124
68
|
},
|
|
125
|
-
"
|
|
126
|
-
"
|
|
127
|
-
"
|
|
128
|
-
"
|
|
129
|
-
|
|
130
|
-
"typescript": "^5.9.3"
|
|
131
|
-
}
|
|
69
|
+
"os": [
|
|
70
|
+
"darwin",
|
|
71
|
+
"linux",
|
|
72
|
+
"win32"
|
|
73
|
+
]
|
|
132
74
|
}
|
package/src/auth.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { readConfig, writeConfig, clearConfig } from './config.js';
|
|
4
|
+
|
|
5
|
+
async function apiCall(path, options = {}) {
|
|
6
|
+
const config = readConfig();
|
|
7
|
+
const url = `${config.serverUrl}${path}`;
|
|
8
|
+
const res = await fetch(url, {
|
|
9
|
+
...options,
|
|
10
|
+
headers: {
|
|
11
|
+
'Content-Type': 'application/json',
|
|
12
|
+
...(options.headers || {}),
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
return res;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getToken() {
|
|
19
|
+
const config = readConfig();
|
|
20
|
+
return config.token || null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function validateToken() {
|
|
24
|
+
const token = getToken();
|
|
25
|
+
if (!token) return null;
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const res = await apiCall('/api/auth/user', {
|
|
29
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
30
|
+
});
|
|
31
|
+
if (!res.ok) return null;
|
|
32
|
+
const data = await res.json();
|
|
33
|
+
return data.user || null;
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export async function login() {
|
|
40
|
+
console.log(chalk.bold('\n Upfyn Code — Login\n'));
|
|
41
|
+
|
|
42
|
+
const response = await prompts([
|
|
43
|
+
{
|
|
44
|
+
type: 'text',
|
|
45
|
+
name: 'username',
|
|
46
|
+
message: 'Username',
|
|
47
|
+
validate: v => (v.trim() ? true : 'Username is required'),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
type: 'password',
|
|
51
|
+
name: 'password',
|
|
52
|
+
message: 'Password',
|
|
53
|
+
validate: v => (v ? true : 'Password is required'),
|
|
54
|
+
},
|
|
55
|
+
], {
|
|
56
|
+
onCancel: () => {
|
|
57
|
+
console.log(chalk.dim('\n Login cancelled.\n'));
|
|
58
|
+
process.exit(0);
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const { username, password } = response;
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const res = await apiCall('/api/auth/login', {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
body: JSON.stringify({ username: username.trim(), password }),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const data = await res.json();
|
|
71
|
+
|
|
72
|
+
if (!res.ok) {
|
|
73
|
+
console.log(chalk.red(`\n Login failed: ${data.error || 'Unknown error'}\n`));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
writeConfig({
|
|
78
|
+
token: data.token,
|
|
79
|
+
user: data.user,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const name = data.user.first_name || data.user.username;
|
|
83
|
+
console.log(chalk.green(`\n Logged in as ${chalk.bold(name)}!\n`));
|
|
84
|
+
} catch (err) {
|
|
85
|
+
console.log(chalk.red('\n Connection error. Check your network and try again.\n'));
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export async function logout() {
|
|
91
|
+
clearConfig();
|
|
92
|
+
console.log(chalk.green('\n Logged out. Credentials cleared.\n'));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export async function status() {
|
|
96
|
+
const config = readConfig();
|
|
97
|
+
|
|
98
|
+
if (!config.token) {
|
|
99
|
+
console.log(chalk.yellow('\n Not logged in. Run `upfyn-code login` to authenticate.\n'));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.log(chalk.dim('\n Checking session...'));
|
|
104
|
+
const user = await validateToken();
|
|
105
|
+
|
|
106
|
+
if (!user) {
|
|
107
|
+
console.log(chalk.yellow(' Session expired. Run `upfyn-code login` to re-authenticate.\n'));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const name = user.first_name || user.username;
|
|
112
|
+
console.log(chalk.bold(` Logged in as: ${chalk.cyan(name)} (${chalk.dim(user.username)})`));
|
|
113
|
+
console.log(chalk.dim(` Server: ${config.serverUrl}`));
|
|
114
|
+
console.log(chalk.dim(` Local port: ${config.localPort}\n`));
|
|
115
|
+
}
|
package/src/config.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { join, dirname } from 'path';
|
|
4
|
+
|
|
5
|
+
const CONFIG_PATH = join(homedir(), '.upfynrc');
|
|
6
|
+
|
|
7
|
+
const DEFAULTS = {
|
|
8
|
+
serverUrl: 'https://upfynai-code-production.up.railway.app',
|
|
9
|
+
localPort: 4200,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function readConfig() {
|
|
13
|
+
try {
|
|
14
|
+
const raw = readFileSync(CONFIG_PATH, 'utf-8');
|
|
15
|
+
return { ...DEFAULTS, ...JSON.parse(raw) };
|
|
16
|
+
} catch {
|
|
17
|
+
return { ...DEFAULTS };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function writeConfig(data) {
|
|
22
|
+
const existing = readConfig();
|
|
23
|
+
const merged = { ...existing, ...data };
|
|
24
|
+
mkdirSync(dirname(CONFIG_PATH), { recursive: true });
|
|
25
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
|
|
26
|
+
return merged;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function clearConfig() {
|
|
30
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(DEFAULTS, null, 2) + '\n', 'utf-8');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { CONFIG_PATH, DEFAULTS };
|