upfynai-code 2.3.0 → 2.4.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/client/dist/assets/AppContent-DTZ2FbvM.js +513 -0
- package/client/dist/assets/CanvasPanel-DlTW6Jh6.js +6 -0
- package/client/dist/assets/LoginModal-CWoFm0au.js +19 -0
- package/client/dist/assets/MarkdownPreview-CYdvwJaV.js +1 -0
- package/client/dist/assets/{Onboarding-Coxo6mFA.js → Onboarding-CtIoXiTp.js} +1 -1
- package/client/dist/assets/{SetupForm-BzYOsbji.js → SetupForm-B4p8im5O.js} +1 -1
- package/client/dist/assets/{ar-SA-G6X2FPQ2-Bmw2-hDt.js → ar-SA-G6X2FPQ2-2gfmdvHk.js} +1 -1
- package/client/dist/assets/{arc-BMqY7_Ci.js → arc-DCZSHhoJ.js} +1 -1
- package/client/dist/assets/{az-AZ-76LH7QW2-Dh1le_qs.js → az-AZ-76LH7QW2-CDdeucRZ.js} +1 -1
- package/client/dist/assets/{bg-BG-XCXSNQG7-Cbav8Z9z.js → bg-BG-XCXSNQG7-D6__XtOK.js} +1 -1
- package/client/dist/assets/{blockDiagram-38ab4fdb-ChHJxsXw.js → blockDiagram-38ab4fdb-Cfbaeyp6.js} +3 -3
- package/client/dist/assets/{bn-BD-2XOGV67Q-DCNjOaWz.js → bn-BD-2XOGV67Q-DHNJw3OG.js} +1 -1
- package/client/dist/assets/{c4Diagram-3d4e48cf-b8Xue4Z6.js → c4Diagram-3d4e48cf-BBCnjOTy.js} +1 -1
- package/client/dist/assets/{ca-ES-6MX7JW3Y-Dl_vM7NS.js → ca-ES-6MX7JW3Y-r5g4o3zQ.js} +1 -1
- package/client/dist/assets/channel-O3ovC0x9.js +1 -0
- package/client/dist/assets/{classDiagram-70f12bd4-BheP7Ggo.js → classDiagram-70f12bd4-D0lhAcxU.js} +1 -1
- package/client/dist/assets/classDiagram-v2-f2320105-BuwUsF3F.js +2 -0
- package/client/dist/assets/clone-BG9u7vLi.js +1 -0
- package/client/dist/assets/{createText-2e5e7dd3-_n4jI_fO.js → createText-2e5e7dd3-B8jCDmF_.js} +1 -1
- package/client/dist/assets/{cs-CZ-2BRQDIVT-ftsKDdz4.js → cs-CZ-2BRQDIVT-p08jRLRC.js} +1 -1
- package/client/dist/assets/{da-DK-5WZEPLOC-DAjdwGRO.js → da-DK-5WZEPLOC-CnhOImFf.js} +1 -1
- package/client/dist/assets/{de-DE-XR44H4JA-BJXczHGT.js → de-DE-XR44H4JA-BunSXZ-Y.js} +1 -1
- package/client/dist/assets/{edges-e0da2a9e-CfPZr4YM.js → edges-e0da2a9e-CGBBhG8k.js} +2 -2
- package/client/dist/assets/{el-GR-BZB4AONW-DW2p_uy7.js → el-GR-BZB4AONW-D4wv1oIz.js} +1 -1
- package/client/dist/assets/{erDiagram-9861fffd-CF33V-Of.js → erDiagram-9861fffd-CYaF3q1I.js} +1 -1
- package/client/dist/assets/{es-ES-U4NZUMDT-DLOIGnrl.js → es-ES-U4NZUMDT-CGeTKXgd.js} +1 -1
- package/client/dist/assets/{eu-ES-A7QVB2H4-LJXbf89m.js → eu-ES-A7QVB2H4-Cayx1TxR.js} +1 -1
- package/client/dist/assets/{fa-IR-HGAKTJCU-Dvx65fgW.js → fa-IR-HGAKTJCU-CmUg8pmw.js} +1 -1
- package/client/dist/assets/{fi-FI-Z5N7JZ37-EoL65BQh.js → fi-FI-Z5N7JZ37-xvHcPhsU.js} +1 -1
- package/client/dist/assets/{flowDb-956e92f1-HgoXVy2H.js → flowDb-956e92f1-C-_LFz70.js} +3 -3
- package/client/dist/assets/flowDiagram-66a62f08-C1sHdSjn.js +4 -0
- package/client/dist/assets/flowDiagram-v2-96b9c2cf-Cd0Iascd.js +1 -0
- package/client/dist/assets/{flowchart-elk-definition-4a651766-DJbI2dpv.js → flowchart-elk-definition-4a651766-CNGfpudb.js} +7 -7
- package/client/dist/assets/{fr-FR-RHASNOE6-DNk_jdDs.js → fr-FR-RHASNOE6-DBoHEcNj.js} +1 -1
- package/client/dist/assets/{ganttDiagram-c361ad54-2XX670FU.js → ganttDiagram-c361ad54-B8HJQqjt.js} +1 -1
- package/client/dist/assets/{gitGraphDiagram-72cf32ee-CcUfruAo.js → gitGraphDiagram-72cf32ee-DojCDvlS.js} +1 -1
- package/client/dist/assets/{gl-ES-HMX3MZ6V-dxzFjZlG.js → gl-ES-HMX3MZ6V-p6hrn2cN.js} +1 -1
- package/client/dist/assets/{graph-BSbiMSBC.js → graph-DXM7lcy1.js} +1 -1
- package/client/dist/assets/{he-IL-6SHJWFNN-Cogsfdt1.js → he-IL-6SHJWFNN-y2jEX6-0.js} +1 -1
- package/client/dist/assets/{hi-IN-IWLTKZ5I-L6wbgi4F.js → hi-IN-IWLTKZ5I-99pNfyWr.js} +1 -1
- package/client/dist/assets/{hu-HU-A5ZG7DT2-DSA6ZDsH.js → hu-HU-A5ZG7DT2-hygceGMS.js} +1 -1
- package/client/dist/assets/{id-ID-SAP4L64H-BK_vGGS6.js → id-ID-SAP4L64H-CyIqi1hv.js} +1 -1
- package/client/dist/assets/{image-blob-reduce.esm-BLtmMM_J.js → image-blob-reduce.esm-D6s-rqMO.js} +6 -1
- package/client/dist/assets/{index-3862675e-Bv32HUgT.js → index-3862675e-4idOQN2N.js} +1 -1
- package/client/dist/assets/{index-BPwf8Fw3.js → index-BGmwbRlb.js} +6 -6
- package/client/dist/assets/index-BHZfFT_V.js +97 -0
- package/client/dist/assets/{infoDiagram-f8f76790-w4mR4pxn.js → infoDiagram-f8f76790-CFLrHqtc.js} +1 -1
- package/client/dist/assets/{it-IT-JPQ66NNP-BLdHYMhn.js → it-IT-JPQ66NNP-DzVvVdQI.js} +1 -1
- package/client/dist/assets/{ja-JP-DBVTYXUO-B_vmexl_.js → ja-JP-DBVTYXUO-BI4fPexV.js} +1 -1
- package/client/dist/assets/{journeyDiagram-49397b02-D9nmO17e.js → journeyDiagram-49397b02-C3CFDo8z.js} +1 -1
- package/client/dist/assets/{kaa-6HZHGXH3-5s-3jl6F.js → kaa-6HZHGXH3-fwOleoQB.js} +1 -1
- package/client/dist/assets/{kab-KAB-ZGHBKWFO-2QaVDuSf.js → kab-KAB-ZGHBKWFO-DBI_ri48.js} +1 -1
- package/client/dist/assets/{kk-KZ-P5N5QNE5-CTC52Vbi.js → kk-KZ-P5N5QNE5-zpl7uvyF.js} +1 -1
- package/client/dist/assets/{km-KH-HSX4SM5Z-DxawH8UZ.js → km-KH-HSX4SM5Z-DOMFSres.js} +1 -1
- package/client/dist/assets/{ko-KR-MTYHY66A-CmosEM8_.js → ko-KR-MTYHY66A-tb08hXzd.js} +1 -1
- package/client/dist/assets/{ku-TR-6OUDTVRD-DbiLen4y.js → ku-TR-6OUDTVRD-DlIQCCY4.js} +1 -1
- package/client/dist/assets/{layout-jmt3H9tA.js → layout-B_11mCXA.js} +1 -1
- package/client/dist/assets/{line-JTlRayUJ.js → line-B-qmK_vI.js} +1 -1
- package/client/dist/assets/{linear-DJeB5p7x.js → linear-Ph6uuYcX.js} +1 -1
- package/client/dist/assets/{lt-LT-XHIRWOB4-CH15wrjA.js → lt-LT-XHIRWOB4--qWy24_Z.js} +1 -1
- package/client/dist/assets/{lv-LV-5QDEKY6T-dhgfPuCQ.js → lv-LV-5QDEKY6T-Bnd_1GDb.js} +1 -1
- package/client/dist/assets/mindmap-definition-fc14e90a-Do79tIc0.js +425 -0
- package/client/dist/assets/{mr-IN-CRQNXWMA-3Gi6iq7A.js → mr-IN-CRQNXWMA-BsV6HaD9.js} +1 -1
- package/client/dist/assets/{my-MM-5M5IBNSE-CpH4rdJj.js → my-MM-5M5IBNSE-kZQURVIi.js} +1 -1
- package/client/dist/assets/{nb-NO-T6EIAALU-Du6iiGql.js → nb-NO-T6EIAALU-Cvf9FdSF.js} +1 -1
- package/client/dist/assets/{nl-NL-IS3SIHDZ-BGvsd1MT.js → nl-NL-IS3SIHDZ-DA1yqpXw.js} +1 -1
- package/client/dist/assets/{nn-NO-6E72VCQL-B-odvJZW.js → nn-NO-6E72VCQL-89lm3vku.js} +1 -1
- package/client/dist/assets/{oc-FR-POXYY2M6-COC8xNjo.js → oc-FR-POXYY2M6-BsrjTJQh.js} +1 -1
- package/client/dist/assets/{pa-IN-N4M65BXN-CE21PUQH.js → pa-IN-N4M65BXN-CczefYaj.js} +1 -1
- package/client/dist/assets/pdf-CE_K4jFx.js +12 -0
- package/client/dist/assets/percentages-BXMCSKIN-Be6p9phi.js +207 -0
- package/client/dist/assets/pica-CQIY57Tf.js +7 -0
- package/client/dist/assets/{pieDiagram-8a3498a8-Cvfh7Qr5.js → pieDiagram-8a3498a8-CfblQHdm.js} +2 -2
- package/client/dist/assets/{pl-PL-T2D74RX3-D4xFVSoT.js → pl-PL-T2D74RX3-DdhH-zcK.js} +1 -1
- package/client/dist/assets/{pt-BR-5N22H2LF-CCq257gA.js → pt-BR-5N22H2LF-gpwlheL6.js} +1 -1
- package/client/dist/assets/{pt-PT-UZXXM6DQ-1l8gt5vA.js → pt-PT-UZXXM6DQ-Cs87vICi.js} +1 -1
- package/client/dist/assets/{quadrantDiagram-120e2f19-BA0js1aD.js → quadrantDiagram-120e2f19-CRMSamSP.js} +1 -1
- package/client/dist/assets/{requirementDiagram-deff3bca-B0QNFfIn.js → requirementDiagram-deff3bca-D3LBN016.js} +1 -1
- package/client/dist/assets/{ro-RO-JPDTUUEW-yosBW01E.js → ro-RO-JPDTUUEW-CWTSJ1Dt.js} +1 -1
- package/client/dist/assets/roundRect-0PYZxl1G.js +1 -0
- package/client/dist/assets/{ru-RU-B4JR7IUQ-8LkEJUix.js → ru-RU-B4JR7IUQ-Bq7aN2ep.js} +1 -1
- package/client/dist/assets/{sankeyDiagram-04a897e0-D4T9eCXn.js → sankeyDiagram-04a897e0-CsFqOQZN.js} +3 -3
- package/client/dist/assets/{sequenceDiagram-704730f1-CfBUTCrO.js → sequenceDiagram-704730f1-BRYXVDGX.js} +1 -1
- package/client/dist/assets/{si-LK-N5RQ5JYF-D8rjbqtd.js → si-LK-N5RQ5JYF-BBjcNYQh.js} +1 -1
- package/client/dist/assets/{sk-SK-C5VTKIMK-Bg14sAzN.js → sk-SK-C5VTKIMK-ByjKQzUb.js} +1 -1
- package/client/dist/assets/{sl-SI-NN7IZMDC-CMTib6Zs.js → sl-SI-NN7IZMDC-B8WCyMBU.js} +1 -1
- package/client/dist/assets/{stateDiagram-587899a1-BGgvmVSZ.js → stateDiagram-587899a1-BHoy9LtD.js} +1 -1
- package/client/dist/assets/{stateDiagram-v2-d93cdb3a-Qn3DpYuO.js → stateDiagram-v2-d93cdb3a-BvMUA6bS.js} +1 -1
- package/client/dist/assets/{styles-6aaf32cf-IdVZLPrD.js → styles-6aaf32cf-Dr-lfIOW.js} +2 -2
- package/client/dist/assets/{styles-9a916d00-BAC3L45X.js → styles-9a916d00-DS4wRpL7.js} +1 -1
- package/client/dist/assets/{styles-c10674c1-COhXxX8c.js → styles-c10674c1-nKRF6NrH.js} +1 -1
- package/client/dist/assets/{subset-shared.chunk-BWHnFai4.js → subset-shared.chunk-KT79s7KG.js} +64 -2
- package/client/dist/assets/subset-worker.chunk-BMx1eyv3.js +1 -0
- package/client/dist/assets/{sv-SE-XGPEYMSR-C1425rOF.js → sv-SE-XGPEYMSR-BiIPUVbv.js} +1 -1
- package/client/dist/assets/{svgDrawCommon-08f97a94-Cfk-fgnN.js → svgDrawCommon-08f97a94-C3uP9PYr.js} +1 -1
- package/client/dist/assets/{ta-IN-2NMHFXQM-BHHo1zpF.js → ta-IN-2NMHFXQM-Cidadso2.js} +1 -1
- package/client/dist/assets/{th-TH-HPSO5L25-CZVzm_WT.js → th-TH-HPSO5L25-CFNnJwSv.js} +1 -1
- package/client/dist/assets/{timeline-definition-85554ec2-VAvuJith.js → timeline-definition-85554ec2-BSsLsIgF.js} +1 -1
- package/client/dist/assets/{tr-TR-DEFEU3FU-DE1lclCq.js → tr-TR-DEFEU3FU-DaFcI-KL.js} +1 -1
- package/client/dist/assets/{uk-UA-QMV73CPH-D4lJZ85O.js → uk-UA-QMV73CPH-DkBW36St.js} +1 -1
- package/client/dist/assets/vendor-codemirror-langs-BH1ZcKHY.js +20 -0
- package/client/dist/assets/vendor-codemirror-rix45NST.js +16 -0
- package/client/dist/assets/vendor-i18n-DCFGyhQR.js +1 -0
- package/client/dist/assets/vendor-icons-Dh9m_Ydt.js +596 -0
- package/client/dist/assets/{vendor-markdown-CIVH08vJ.js → vendor-markdown-BXEi_H3G.js} +3 -3
- package/client/dist/assets/vendor-react-9mUTKBHH.js +67 -0
- package/client/dist/assets/{vendor-syntax-Djb62v3a.js → vendor-syntax-DnmwQQJF.js} +14 -7
- package/client/dist/assets/vendor-xterm-CZq1hqo1.js +66 -0
- package/client/dist/assets/vendor-xterm-qxJ8_QYu.css +32 -0
- package/client/dist/assets/{vi-VN-M7AON7JQ-Dgc_SShk.js → vi-VN-M7AON7JQ-KrtfxOzl.js} +1 -1
- package/client/dist/assets/{xychartDiagram-e933f94c-BeyVBJhb.js → xychartDiagram-e933f94c-CgNgZ4pp.js} +1 -1
- package/client/dist/assets/{zh-CN-LNUGB5OW-MH4Yh8in.js → zh-CN-LNUGB5OW-BQu12RoD.js} +1 -1
- package/client/dist/assets/{zh-HK-E62DVLB3-D4XHehjx.js → zh-HK-E62DVLB3-zx9CvERq.js} +1 -1
- package/client/dist/assets/{zh-TW-RAJ6MFWO--efj3evj.js → zh-TW-RAJ6MFWO-ffJWgVxn.js} +1 -1
- package/client/dist/index.html +128 -66
- package/client/dist/manifest.json +61 -15
- package/client/dist/sw.js +19 -55
- package/commands/upfynai-connect.md +31 -18
- package/commands/upfynai.md +45 -26
- package/package.json +1 -1
- package/server/cli-ui.js +320 -169
- package/server/cli.js +255 -23
- package/server/constants/config.js +29 -3
- package/server/database/auth.db +0 -0
- package/server/index.js +380 -121
- package/server/mcp-server.js +2 -1
- package/server/middleware/auth.js +18 -8
- package/server/openrouter.js +137 -0
- package/server/relay-client.js +262 -18
- package/server/routes/agent.js +54 -19
- package/server/routes/auth.js +23 -12
- package/server/routes/commands.js +1 -1
- package/server/routes/settings.js +91 -0
- package/shared/modelConstants.js +29 -0
- package/client/dist/assets/AppContent-CTSHQdyq.js +0 -513
- package/client/dist/assets/CanvasPanel-Cig0Mo9s.js +0 -6
- package/client/dist/assets/LoginModal-silya-zP.js +0 -11
- package/client/dist/assets/MarkdownPreview-B3c7OEj6.js +0 -1
- package/client/dist/assets/channel-CSnvHe_M.js +0 -1
- package/client/dist/assets/classDiagram-v2-f2320105-xtym7GEZ.js +0 -2
- package/client/dist/assets/clone-B75abXxS.js +0 -1
- package/client/dist/assets/flowDiagram-66a62f08-tffoET0H.js +0 -4
- package/client/dist/assets/flowDiagram-v2-96b9c2cf-Byc3JCHh.js +0 -1
- package/client/dist/assets/index-BnXuHrpJ.js +0 -523
- package/client/dist/assets/index-BwxNox94.css +0 -1
- package/client/dist/assets/index-D1urGMYu.js +0 -95
- package/client/dist/assets/mindmap-definition-fc14e90a-BOOrexmz.js +0 -415
- package/client/dist/assets/pdf-TYrZqVzP.js +0 -12
- package/client/dist/assets/percentages-BXMCSKIN-C9GT0OD3.js +0 -199
- package/client/dist/assets/pica-VkdyTzi8.js +0 -2
- package/client/dist/assets/roundRect-mAH3dD0p.js +0 -1
- package/client/dist/assets/subset-worker.chunk-C8QUSruZ.js +0 -1
- package/client/dist/assets/vendor-codemirror-BARtJV1V.js +0 -16
- package/client/dist/assets/vendor-codemirror-langs-52_y1wip.js +0 -20
- package/client/dist/assets/vendor-i18n-ByAl-gdx.js +0 -1
- package/client/dist/assets/vendor-icons-D33IkSIf.js +0 -1
- package/client/dist/assets/vendor-react-CHoMc7ka.js +0 -8
- package/client/dist/assets/vendor-xterm-DBb3RXlu.js +0 -66
- package/client/dist/assets/vendor-xterm-DrlLKa8f.css +0 -1
- package/client/dist/llms.txt +0 -40
- package/client/dist/robots.txt +0 -11
- package/client/dist/sitemap.xml +0 -45
package/server/cli-ui.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Upfyn-Code CLI — Terminal UI & Animations
|
|
3
3
|
*
|
|
4
|
-
* Beautiful blue-themed terminal experience inspired by Claude Code
|
|
5
|
-
*
|
|
4
|
+
* Beautiful blue-themed terminal experience inspired by Claude Code.
|
|
5
|
+
* Uses terminal-safe characters that render correctly on Windows CMD,
|
|
6
|
+
* PowerShell, Windows Terminal, Git Bash, macOS Terminal, and Linux.
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
|
-
//
|
|
9
|
+
// --- ANSI escape codes ---
|
|
9
10
|
const ESC = '\x1b';
|
|
10
11
|
const CSI = `${ESC}[`;
|
|
11
12
|
|
|
12
|
-
// Blue theme palette
|
|
13
|
+
// Blue theme palette (24-bit RGB — works in all modern terminals)
|
|
13
14
|
const theme = {
|
|
14
15
|
// Core blues
|
|
15
16
|
blue: `${CSI}38;2;59;130;246m`, // #3B82F6
|
|
@@ -47,6 +48,62 @@ const theme = {
|
|
|
47
48
|
const t = theme;
|
|
48
49
|
const r = t.reset;
|
|
49
50
|
|
|
51
|
+
// --- Terminal capability detection ---
|
|
52
|
+
function detectTerminalSupport() {
|
|
53
|
+
// Windows Terminal, VS Code, modern terminals support full Unicode
|
|
54
|
+
if (process.env.WT_SESSION) return 'unicode';
|
|
55
|
+
if (process.env.TERM_PROGRAM === 'vscode') return 'unicode';
|
|
56
|
+
if (process.env.TERM_PROGRAM === 'iTerm.app') return 'unicode';
|
|
57
|
+
if (process.env.TERM_PROGRAM === 'Hyper') return 'unicode';
|
|
58
|
+
if (process.env.TERM === 'xterm-256color') return 'unicode';
|
|
59
|
+
if (process.env.TERM === 'xterm-kitty') return 'unicode';
|
|
60
|
+
if (process.env.COLORTERM === 'truecolor') return 'unicode';
|
|
61
|
+
|
|
62
|
+
// Windows without WT_SESSION — use ASCII
|
|
63
|
+
if (process.platform === 'win32') return 'ascii';
|
|
64
|
+
|
|
65
|
+
// Most modern Linux/Mac terminals support basic box-drawing
|
|
66
|
+
return 'unicode';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Box-drawing character sets
|
|
70
|
+
const CHARS_UNICODE = {
|
|
71
|
+
h: '\u2500', // ─
|
|
72
|
+
v: '\u2502', // │
|
|
73
|
+
tl: '\u250C', // ┌
|
|
74
|
+
tr: '\u2510', // ┐
|
|
75
|
+
bl: '\u2514', // └
|
|
76
|
+
br: '\u2518', // ┘
|
|
77
|
+
cross: '\u253C', // ┼
|
|
78
|
+
ltee: '\u251C', // ├
|
|
79
|
+
rtee: '\u2524', // ┤
|
|
80
|
+
ttee: '\u252C', // ┬
|
|
81
|
+
btee: '\u2534', // ┴
|
|
82
|
+
dot: '\u00B7', // ·
|
|
83
|
+
bullet: '\u2022', // •
|
|
84
|
+
star: '*',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const CHARS_ASCII = {
|
|
88
|
+
h: '-',
|
|
89
|
+
v: '|',
|
|
90
|
+
tl: '+',
|
|
91
|
+
tr: '+',
|
|
92
|
+
bl: '+',
|
|
93
|
+
br: '+',
|
|
94
|
+
cross: '+',
|
|
95
|
+
ltee: '+',
|
|
96
|
+
rtee: '+',
|
|
97
|
+
ttee: '+',
|
|
98
|
+
btee: '+',
|
|
99
|
+
dot: '.',
|
|
100
|
+
bullet: '*',
|
|
101
|
+
star: '*',
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const termLevel = detectTerminalSupport();
|
|
105
|
+
const ch = termLevel === 'unicode' ? CHARS_UNICODE : CHARS_ASCII;
|
|
106
|
+
|
|
50
107
|
// Helper — colorize
|
|
51
108
|
const c = {
|
|
52
109
|
blue: (s) => `${t.blue}${s}${r}`,
|
|
@@ -71,7 +128,7 @@ const c = {
|
|
|
71
128
|
bCyan: (s) => `${t.bold}${t.cyan}${s}${r}`,
|
|
72
129
|
};
|
|
73
130
|
|
|
74
|
-
//
|
|
131
|
+
// --- ASCII Art Logo ---
|
|
75
132
|
const LOGO = [
|
|
76
133
|
`${t.brightBlue} __ __ ____ ${t.skyBlue} ______ __ ${r}`,
|
|
77
134
|
`${t.brightBlue} / / / /___ / __/_ ______ ${t.skyBlue}/ ____/___ ____/ /__ ${r}`,
|
|
@@ -81,127 +138,150 @@ const LOGO = [
|
|
|
81
138
|
`${t.brightBlue} /_/ /____/ ${r}`,
|
|
82
139
|
];
|
|
83
140
|
|
|
84
|
-
//
|
|
141
|
+
// --- Rocket ASCII Art (safe characters only) ---
|
|
85
142
|
const ROCKET_FRAMES = [
|
|
86
|
-
// Frame 0: Pre-launch
|
|
143
|
+
// Frame 0: Pre-launch
|
|
87
144
|
[
|
|
88
|
-
` ${t.dimGray}
|
|
89
|
-
` ${t.white}
|
|
90
|
-
` ${t.white}
|
|
91
|
-
` ${t.white}
|
|
92
|
-
` ${t.white}
|
|
93
|
-
` ${t.white}
|
|
94
|
-
` ${t.white}
|
|
95
|
-
` ${t.dimGray}
|
|
145
|
+
` ${t.dimGray}|${r}`,
|
|
146
|
+
` ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
|
|
147
|
+
` ${t.white}|${t.blue}||${t.white}|${r}`,
|
|
148
|
+
` ${t.white}|${t.blue}||${t.white}|${r}`,
|
|
149
|
+
` ${t.white}|${t.brightBlue}||${t.white}|${r}`,
|
|
150
|
+
` ${t.white}/${t.blue}|||${t.white}\\${r}`,
|
|
151
|
+
` ${t.white}/${t.blue}=====${t.white}\\${r}`,
|
|
152
|
+
` ${t.dimGray}==========${r}`,
|
|
96
153
|
],
|
|
97
154
|
// Frame 1: Ignition
|
|
98
155
|
[
|
|
99
|
-
` ${t.dimGray}
|
|
100
|
-
` ${t.white}
|
|
101
|
-
` ${t.white}
|
|
102
|
-
` ${t.white}
|
|
103
|
-
` ${t.white}
|
|
104
|
-
` ${t.white}
|
|
105
|
-
` ${t.white}
|
|
106
|
-
` ${t.orange}
|
|
156
|
+
` ${t.dimGray}|${r}`,
|
|
157
|
+
` ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
|
|
158
|
+
` ${t.white}|${t.blue}||${t.white}|${r}`,
|
|
159
|
+
` ${t.white}|${t.blue}||${t.white}|${r}`,
|
|
160
|
+
` ${t.white}|${t.brightBlue}||${t.white}|${r}`,
|
|
161
|
+
` ${t.white}/${t.blue}|||${t.white}\\${r}`,
|
|
162
|
+
` ${t.white}/${t.blue}=====${t.white}\\${r}`,
|
|
163
|
+
` ${t.orange}#${t.yellow}*${t.orange}#${t.yellow}*${t.orange}#${r}`,
|
|
107
164
|
],
|
|
108
165
|
// Frame 2: Lift-off
|
|
109
166
|
[
|
|
110
|
-
` ${t.white}
|
|
111
|
-
` ${t.white}
|
|
112
|
-
` ${t.white}
|
|
113
|
-
` ${t.white}
|
|
114
|
-
` ${t.white}
|
|
115
|
-
` ${t.white}
|
|
116
|
-
` ${t.yellow}
|
|
117
|
-
` ${t.orange}
|
|
167
|
+
` ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
|
|
168
|
+
` ${t.white}|${t.blue}||${t.white}|${r}`,
|
|
169
|
+
` ${t.white}|${t.blue}||${t.white}|${r}`,
|
|
170
|
+
` ${t.white}|${t.brightBlue}||${t.white}|${r}`,
|
|
171
|
+
` ${t.white}/${t.blue}|||${t.white}\\${r}`,
|
|
172
|
+
` ${t.white}/${t.blue}=====${t.white}\\${r}`,
|
|
173
|
+
` ${t.yellow}#${t.orange}@${t.yellow}#${t.orange}@${t.yellow}#${r}`,
|
|
174
|
+
` ${t.orange}*${t.yellow}o${t.orange}*${r}`,
|
|
118
175
|
],
|
|
119
176
|
// Frame 3: Ascending
|
|
120
177
|
[
|
|
121
|
-
` ${t.white}
|
|
122
|
-
` ${t.white}
|
|
123
|
-
` ${t.white}
|
|
124
|
-
` ${t.white}
|
|
125
|
-
` ${t.white}
|
|
126
|
-
` ${t.yellow}
|
|
127
|
-
` ${t.orange}
|
|
128
|
-
` ${t.yellow}
|
|
178
|
+
` ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
|
|
179
|
+
` ${t.white}|${t.blue}||${t.white}|${r}`,
|
|
180
|
+
` ${t.white}|${t.brightBlue}||${t.white}|${r}`,
|
|
181
|
+
` ${t.white}/${t.blue}|||${t.white}\\${r}`,
|
|
182
|
+
` ${t.white}/${t.blue}=====${t.white}\\${r}`,
|
|
183
|
+
` ${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${t.yellow}@${r}`,
|
|
184
|
+
` ${t.orange}#${t.yellow}@${t.orange}#${r}`,
|
|
185
|
+
` ${t.yellow}*${t.orange}*${r}`,
|
|
129
186
|
],
|
|
130
187
|
// Frame 4: Full thrust
|
|
131
188
|
[
|
|
132
|
-
` ${t.white}
|
|
133
|
-
` ${t.white}
|
|
134
|
-
` ${t.white}
|
|
135
|
-
` ${t.white}
|
|
136
|
-
` ${t.white}
|
|
137
|
-
` ${t.yellow}
|
|
138
|
-
` ${t.orange}
|
|
139
|
-
` ${t.yellow}
|
|
140
|
-
` ${t.orange}
|
|
189
|
+
` ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
|
|
190
|
+
` ${t.white}|${t.blue}||${t.white}|${r}`,
|
|
191
|
+
` ${t.white}|${t.brightBlue}||${t.white}|${r}`,
|
|
192
|
+
` ${t.white}/${t.blue}|||${t.white}\\${r}`,
|
|
193
|
+
` ${t.white}/${t.blue}=====${t.white}\\${r}`,
|
|
194
|
+
` ${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${r}`,
|
|
195
|
+
` ${t.orange}#${t.yellow}@${t.orange}#${t.yellow}@${r}`,
|
|
196
|
+
` ${t.yellow}o${t.orange}*${t.yellow}o${r}`,
|
|
197
|
+
` ${t.orange}*${t.yellow}*${r}`,
|
|
141
198
|
],
|
|
142
|
-
// Frame 5: Going up
|
|
199
|
+
// Frame 5: Going up
|
|
143
200
|
[
|
|
144
201
|
``,
|
|
145
|
-
` ${t.white}
|
|
146
|
-
` ${t.white}
|
|
147
|
-
` ${t.white}
|
|
148
|
-
` ${t.white}
|
|
149
|
-
` ${t.yellow}
|
|
150
|
-
` ${t.orange}
|
|
151
|
-
` ${t.yellow}
|
|
152
|
-
` ${t.orange}
|
|
202
|
+
` ${t.white}/${t.brightBlue}^${t.white}\\${r}`,
|
|
203
|
+
` ${t.white}|${t.blue}||${t.white}|${r}`,
|
|
204
|
+
` ${t.white}/${t.blue}|||${t.white}\\${r}`,
|
|
205
|
+
` ${t.white}/${t.blue}=====${t.white}\\${r}`,
|
|
206
|
+
` ${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${t.yellow}@${t.orange}#${r}`,
|
|
207
|
+
` ${t.orange}@${t.yellow}#${t.orange}@${t.yellow}#${r}`,
|
|
208
|
+
` ${t.yellow}o${t.orange}o${t.yellow}o${r}`,
|
|
209
|
+
` ${t.orange}*${r} ${t.dimGray}.${r}`,
|
|
153
210
|
],
|
|
154
211
|
// Frame 6: Higher
|
|
155
212
|
[
|
|
156
213
|
``,
|
|
157
214
|
``,
|
|
158
|
-
` ${t.skyBlue}
|
|
159
|
-
` ${t.skyBlue}
|
|
160
|
-
` ${t.skyBlue}
|
|
161
|
-
` ${t.yellow}
|
|
162
|
-
` ${t.orange}
|
|
163
|
-
` ${t.yellow}
|
|
164
|
-
` ${t.dimGray}
|
|
215
|
+
` ${t.skyBlue}/${t.brightBlue}^${t.skyBlue}\\${r}`,
|
|
216
|
+
` ${t.skyBlue}|${t.blue}||${t.skyBlue}|${r}`,
|
|
217
|
+
` ${t.skyBlue}/${t.blue}==${t.skyBlue}\\${r}`,
|
|
218
|
+
` ${t.yellow}#${t.orange}@${t.yellow}#${t.orange}#${r}`,
|
|
219
|
+
` ${t.orange}o${t.yellow}o${r}`,
|
|
220
|
+
` ${t.yellow}*${r}`,
|
|
221
|
+
` ${t.dimGray}.${r} ${t.dimGray}.${r}`,
|
|
165
222
|
],
|
|
166
|
-
// Frame 7: Almost gone
|
|
223
|
+
// Frame 7: Almost gone
|
|
167
224
|
[
|
|
168
225
|
``,
|
|
169
226
|
``,
|
|
170
227
|
``,
|
|
171
|
-
` ${t.skyBlue}
|
|
172
|
-
` ${t.blue}
|
|
173
|
-
` ${t.orange}
|
|
174
|
-
` ${t.yellow}
|
|
228
|
+
` ${t.skyBlue}/${t.brightBlue}^${t.skyBlue}\\${r}`,
|
|
229
|
+
` ${t.blue}==${r}`,
|
|
230
|
+
` ${t.orange}o${t.yellow}o${r}`,
|
|
231
|
+
` ${t.yellow}*${r}`,
|
|
175
232
|
``,
|
|
176
|
-
` ${t.dimGray}
|
|
233
|
+
` ${t.dimGray}.${r} ${t.dimGray}.${r} ${t.dimGray}.${r}`,
|
|
177
234
|
],
|
|
178
235
|
// Frame 8: Gone — just stars
|
|
179
236
|
[
|
|
180
237
|
``,
|
|
181
238
|
``,
|
|
182
239
|
``,
|
|
183
|
-
` ${t.brightBlue}
|
|
240
|
+
` ${t.brightBlue}*${r}`,
|
|
184
241
|
``,
|
|
185
|
-
` ${t.dimGray}
|
|
242
|
+
` ${t.dimGray}.${r}`,
|
|
186
243
|
``,
|
|
187
|
-
` ${t.dimGray}
|
|
188
|
-
` ${t.dimGray}
|
|
244
|
+
` ${t.dimGray}.${r} ${t.dimGray}.${r}`,
|
|
245
|
+
` ${t.dimGray}.${r} ${t.dimGray}.${r} ${t.dimGray}.${r}`,
|
|
189
246
|
],
|
|
190
247
|
];
|
|
191
248
|
|
|
192
|
-
//
|
|
249
|
+
// --- Sleep utility ---
|
|
193
250
|
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
194
251
|
|
|
195
|
-
//
|
|
252
|
+
// --- Clear screen ---
|
|
196
253
|
const clearScreen = () => process.stdout.write(`${CSI}2J${CSI}H`);
|
|
197
254
|
|
|
198
|
-
//
|
|
255
|
+
// --- Move cursor ---
|
|
199
256
|
const moveTo = (row, col) => process.stdout.write(`${CSI}${row};${col}H`);
|
|
200
257
|
|
|
201
|
-
//
|
|
258
|
+
// --- Hide/show cursor ---
|
|
202
259
|
const hideCursor = () => process.stdout.write(`${CSI}?25l`);
|
|
203
260
|
const showCursor = () => process.stdout.write(`${CSI}?25h`);
|
|
204
261
|
|
|
262
|
+
/**
|
|
263
|
+
* Strip ANSI codes for length calculation
|
|
264
|
+
*/
|
|
265
|
+
function stripAnsi(str) {
|
|
266
|
+
return str.replace(/\x1b\[[0-9;]*m/g, '');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Pad a string (with ANSI codes) to a visual width
|
|
271
|
+
*/
|
|
272
|
+
function padAnsi(str, width) {
|
|
273
|
+
const visible = stripAnsi(str).length;
|
|
274
|
+
const pad = Math.max(0, width - visible);
|
|
275
|
+
return str + ' '.repeat(pad);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Draw a horizontal line
|
|
280
|
+
*/
|
|
281
|
+
function hLine(width = 60) {
|
|
282
|
+
return c.dark(ch.h.repeat(width));
|
|
283
|
+
}
|
|
284
|
+
|
|
205
285
|
/**
|
|
206
286
|
* Play the rocket launch animation
|
|
207
287
|
*/
|
|
@@ -242,7 +322,7 @@ async function playRocketAnimation() {
|
|
|
242
322
|
else if (f <= 4) process.stdout.write(c.bright('Ascending...'));
|
|
243
323
|
else if (f <= 6) process.stdout.write(c.sky('Reaching orbit...'));
|
|
244
324
|
else if (f === 7) process.stdout.write(c.cyan('Entering space...'));
|
|
245
|
-
else process.stdout.write(c.bBright('Ready to code!
|
|
325
|
+
else process.stdout.write(c.bBright('Ready to code! *'));
|
|
246
326
|
|
|
247
327
|
await sleep(delays[f] || 200);
|
|
248
328
|
}
|
|
@@ -252,82 +332,72 @@ async function playRocketAnimation() {
|
|
|
252
332
|
}
|
|
253
333
|
|
|
254
334
|
/**
|
|
255
|
-
* Draw a
|
|
256
|
-
*/
|
|
257
|
-
function hLine(char = '─', width = 60) {
|
|
258
|
-
return c.dark(char.repeat(width));
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Draw a box with title
|
|
335
|
+
* Draw a box with title (terminal-safe characters)
|
|
263
336
|
*/
|
|
264
337
|
function box(title, content, width = 58) {
|
|
265
338
|
const lines = [];
|
|
266
339
|
const inner = width - 4;
|
|
267
340
|
|
|
268
|
-
lines.push(` ${t.dimGray}
|
|
341
|
+
lines.push(` ${t.dimGray}${ch.tl}${ch.h}${r} ${c.bBright(title)} ${t.dimGray}${ch.h.repeat(Math.max(0, inner - title.length - 1))}${ch.tr}${r}`);
|
|
269
342
|
|
|
270
343
|
for (const line of content) {
|
|
271
|
-
|
|
272
|
-
lines.push(` ${t.dimGray}│${r} ${line}`);
|
|
344
|
+
lines.push(` ${t.dimGray}${ch.v}${r} ${line}`);
|
|
273
345
|
}
|
|
274
346
|
|
|
275
|
-
lines.push(` ${t.dimGray}
|
|
347
|
+
lines.push(` ${t.dimGray}${ch.bl}${ch.h.repeat(width - 2)}${ch.br}${r}`);
|
|
276
348
|
return lines;
|
|
277
349
|
}
|
|
278
350
|
|
|
279
351
|
/**
|
|
280
|
-
* Show the main welcome screen (
|
|
352
|
+
* Show the main welcome screen (Claude Code-style layout)
|
|
281
353
|
*/
|
|
282
354
|
function showWelcomeScreen(version, options = {}) {
|
|
283
355
|
const cols = process.stdout.columns || 80;
|
|
284
356
|
const { serverUrl, username, cwd, isConnected } = options;
|
|
357
|
+
const W = Math.min(cols - 4, 72); // content width
|
|
358
|
+
const leftW = 32;
|
|
359
|
+
const rightW = W - leftW - 3; // 3 for separator + padding
|
|
285
360
|
|
|
286
361
|
clearScreen();
|
|
287
362
|
|
|
288
363
|
const lines = [];
|
|
289
364
|
|
|
290
|
-
//
|
|
365
|
+
// --- Top border with version ---
|
|
291
366
|
const verStr = `Upfyn-Code v${version}`;
|
|
292
|
-
const
|
|
367
|
+
const topPad = Math.max(0, W - verStr.length - 4);
|
|
293
368
|
lines.push('');
|
|
294
|
-
lines.push(` ${
|
|
369
|
+
lines.push(` ${t.dimGray}${ch.h}${ch.h} ${r}${c.bBright(verStr)}${t.dimGray} ${ch.h.repeat(topPad)}${r}`);
|
|
295
370
|
lines.push('');
|
|
296
371
|
|
|
297
|
-
//
|
|
298
|
-
// We use a side-by-side layout like Claude Code
|
|
372
|
+
// --- Build left and right panels ---
|
|
299
373
|
const leftPanel = [];
|
|
300
374
|
const rightPanel = [];
|
|
301
375
|
|
|
302
|
-
// Welcome
|
|
376
|
+
// Left: Welcome + Rocket mascot
|
|
303
377
|
leftPanel.push(c.bWhite(' Welcome back!'));
|
|
304
378
|
leftPanel.push('');
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
leftPanel.push(`
|
|
308
|
-
leftPanel.push(`
|
|
309
|
-
leftPanel.push(`
|
|
310
|
-
leftPanel.push(`
|
|
311
|
-
leftPanel.push(` ${t.white}╱${t.blue}═══${t.white}╲${r}`);
|
|
312
|
-
leftPanel.push(` ${t.cyan}▔▔▔▔▔${r}`);
|
|
379
|
+
leftPanel.push(` ${t.dimGray}|${r}`);
|
|
380
|
+
leftPanel.push(` ${t.white}/${t.brightBlue}^${t.white}\\${r}`);
|
|
381
|
+
leftPanel.push(` ${t.white}|${t.blue}|${t.brightBlue}o${t.blue}|${t.white}|${r}`);
|
|
382
|
+
leftPanel.push(` ${t.white}|${t.blue}||${t.white}|${r}`);
|
|
383
|
+
leftPanel.push(` ${t.white}/${t.blue}===${t.white}\\${r}`);
|
|
384
|
+
leftPanel.push(` ${t.cyan}~~~~~${r}`);
|
|
313
385
|
leftPanel.push('');
|
|
314
|
-
|
|
315
|
-
// Info
|
|
316
386
|
if (username) {
|
|
317
387
|
leftPanel.push(` ${c.gray('User:')} ${c.bright(username)}`);
|
|
318
388
|
}
|
|
319
389
|
leftPanel.push(` ${c.gray('Path:')} ${c.dim(cwd || process.cwd())}`);
|
|
320
390
|
|
|
321
|
-
// Right
|
|
391
|
+
// Right: Tips + Recent Activity
|
|
322
392
|
rightPanel.push(` ${c.bCyan('Tips for getting started')}`);
|
|
323
|
-
rightPanel.push(` ${c.gray('Run')} ${c.bright('uc connect')} ${c.gray('to bridge to
|
|
324
|
-
rightPanel.push(` ${c.gray('Run')} ${c.bright('uc start')} ${c.gray('to launch
|
|
393
|
+
rightPanel.push(` ${c.gray('Run')} ${c.bright('uc connect')} ${c.gray('to bridge to web UI')}`);
|
|
394
|
+
rightPanel.push(` ${c.gray('Run')} ${c.bright('uc start')} ${c.gray('to launch local server')}`);
|
|
325
395
|
rightPanel.push(` ${c.gray('Run')} ${c.bright('uc status')} ${c.gray('to see configuration')}`);
|
|
326
396
|
rightPanel.push(` ${c.gray('Run')} ${c.bright('uc help')} ${c.gray('for all commands')}`);
|
|
327
397
|
rightPanel.push('');
|
|
328
398
|
rightPanel.push(` ${c.bCyan('Recent activity')}`);
|
|
329
399
|
if (isConnected) {
|
|
330
|
-
rightPanel.push(` ${c.green('
|
|
400
|
+
rightPanel.push(` ${c.green('*')} Connected to ${c.bright(serverUrl || 'server')}`);
|
|
331
401
|
} else {
|
|
332
402
|
rightPanel.push(` ${c.dim('No active connection')}`);
|
|
333
403
|
}
|
|
@@ -337,40 +407,38 @@ function showWelcomeScreen(version, options = {}) {
|
|
|
337
407
|
}
|
|
338
408
|
|
|
339
409
|
// Merge panels side by side
|
|
340
|
-
const leftWidth = 30;
|
|
341
410
|
const maxRows = Math.max(leftPanel.length, rightPanel.length);
|
|
342
411
|
|
|
343
412
|
for (let i = 0; i < maxRows; i++) {
|
|
344
|
-
const left = leftPanel[i] || '';
|
|
413
|
+
const left = padAnsi(leftPanel[i] || '', leftW);
|
|
345
414
|
const right = rightPanel[i] || '';
|
|
346
|
-
|
|
347
|
-
// Separator between panels
|
|
348
|
-
if (i === 0) {
|
|
349
|
-
lines.push(`${left}${''.padEnd(Math.max(0, leftWidth - stripAnsi(left).length))}${t.dimGray}│${r} ${right}`);
|
|
350
|
-
} else {
|
|
351
|
-
lines.push(`${left}${''.padEnd(Math.max(0, leftWidth - stripAnsi(left).length))}${t.dimGray}│${r} ${right}`);
|
|
352
|
-
}
|
|
415
|
+
lines.push(`${left}${t.dimGray}${ch.v}${r} ${right}`);
|
|
353
416
|
}
|
|
354
417
|
|
|
355
418
|
lines.push('');
|
|
356
419
|
|
|
357
|
-
//
|
|
358
|
-
lines.push(` ${t.dimGray}${
|
|
420
|
+
// --- Bottom border ---
|
|
421
|
+
lines.push(` ${t.dimGray}${ch.h.repeat(W)}${r}`);
|
|
359
422
|
lines.push('');
|
|
360
423
|
|
|
361
|
-
//
|
|
424
|
+
// --- Status bar ---
|
|
362
425
|
const statusItems = [];
|
|
363
426
|
if (isConnected) {
|
|
364
|
-
statusItems.push(`${t.green}
|
|
427
|
+
statusItems.push(`${t.green}* Connected${r}`);
|
|
365
428
|
} else {
|
|
366
|
-
statusItems.push(`${t.dimGray}
|
|
429
|
+
statusItems.push(`${t.dimGray}o Not connected${r}`);
|
|
367
430
|
}
|
|
368
431
|
statusItems.push(`${t.gray}v${version}${r}`);
|
|
369
432
|
|
|
370
|
-
lines.push(` ${statusItems.join(` ${t.dimGray}
|
|
433
|
+
lines.push(` ${statusItems.join(` ${t.dimGray}${ch.dot}${r} `)}`);
|
|
434
|
+
lines.push('');
|
|
435
|
+
|
|
436
|
+
// --- Input prompt area (between two lines like Claude Code) ---
|
|
437
|
+
lines.push(` ${t.dimGray}${ch.h.repeat(W)}${r}`);
|
|
438
|
+
lines.push(` ${t.brightBlue}>${r} ${c.dim('Type a command or use /upfynai-connect ...')}`);
|
|
439
|
+
lines.push(` ${t.dimGray}${ch.h.repeat(W)}${r}`);
|
|
371
440
|
lines.push('');
|
|
372
441
|
|
|
373
|
-
// Print all at once
|
|
374
442
|
process.stdout.write(lines.join('\n') + '\n');
|
|
375
443
|
}
|
|
376
444
|
|
|
@@ -378,17 +446,19 @@ function showWelcomeScreen(version, options = {}) {
|
|
|
378
446
|
* Show connection success banner
|
|
379
447
|
*/
|
|
380
448
|
function showConnectionBanner(username, serverUrl) {
|
|
449
|
+
const W = 50;
|
|
381
450
|
const lines = [];
|
|
451
|
+
const bLine = (content) => ` ${t.green}${ch.v}${r}${padAnsi(content, W)}${t.green}${ch.v}${r}`;
|
|
382
452
|
lines.push('');
|
|
383
|
-
lines.push(` ${t.green}
|
|
384
|
-
lines.push(` ${
|
|
385
|
-
lines.push(
|
|
386
|
-
lines.push(` ${
|
|
387
|
-
lines.push(` ${
|
|
388
|
-
lines.push(
|
|
389
|
-
lines.push(` ${
|
|
390
|
-
lines.push(` ${
|
|
391
|
-
lines.push(` ${t.green}
|
|
453
|
+
lines.push(` ${t.green}${ch.tl}${ch.h.repeat(W)}${ch.tr}${r}`);
|
|
454
|
+
lines.push(bLine(` ${c.green('OK')} ${c.bWhite('Connected successfully!')}`));
|
|
455
|
+
lines.push(bLine(''));
|
|
456
|
+
lines.push(bLine(` ${c.gray('User:')} ${c.bright(username || 'Unknown')}`));
|
|
457
|
+
lines.push(bLine(` ${c.gray('Server:')} ${c.cyan(serverUrl || 'Unknown')}`));
|
|
458
|
+
lines.push(bLine(''));
|
|
459
|
+
lines.push(bLine(` ${c.dim('Your machine is bridged to the web UI.')}`));
|
|
460
|
+
lines.push(bLine(` ${c.dim('Press Ctrl+C to disconnect.')}`));
|
|
461
|
+
lines.push(` ${t.green}${ch.bl}${ch.h.repeat(W)}${ch.br}${r}`);
|
|
392
462
|
lines.push('');
|
|
393
463
|
|
|
394
464
|
process.stdout.write(lines.join('\n') + '\n');
|
|
@@ -398,7 +468,7 @@ function showConnectionBanner(username, serverUrl) {
|
|
|
398
468
|
* Show a spinner with message
|
|
399
469
|
*/
|
|
400
470
|
function createSpinner(message) {
|
|
401
|
-
const frames = ['
|
|
471
|
+
const frames = ['/', '-', '\\', '|'];
|
|
402
472
|
let i = 0;
|
|
403
473
|
let interval;
|
|
404
474
|
|
|
@@ -409,16 +479,16 @@ function createSpinner(message) {
|
|
|
409
479
|
const frame = frames[i % frames.length];
|
|
410
480
|
process.stdout.write(`\r ${t.brightBlue}${frame}${r} ${c.gray(message)}`);
|
|
411
481
|
i++;
|
|
412
|
-
},
|
|
482
|
+
}, 100);
|
|
413
483
|
},
|
|
414
484
|
stop(finalMessage) {
|
|
415
485
|
clearInterval(interval);
|
|
416
|
-
process.stdout.write(`\r ${c.green('
|
|
486
|
+
process.stdout.write(`\r ${c.green('OK')} ${c.white(finalMessage || message)}${''.padEnd(20)}\n`);
|
|
417
487
|
showCursor();
|
|
418
488
|
},
|
|
419
489
|
fail(finalMessage) {
|
|
420
490
|
clearInterval(interval);
|
|
421
|
-
process.stdout.write(`\r ${c.red('
|
|
491
|
+
process.stdout.write(`\r ${c.red('FAIL')} ${c.red(finalMessage || message)}${''.padEnd(20)}\n`);
|
|
422
492
|
showCursor();
|
|
423
493
|
}
|
|
424
494
|
};
|
|
@@ -428,14 +498,17 @@ function createSpinner(message) {
|
|
|
428
498
|
* Show styled help
|
|
429
499
|
*/
|
|
430
500
|
function showStyledHelp(version) {
|
|
501
|
+
const W = 60;
|
|
431
502
|
const lines = [];
|
|
432
503
|
|
|
433
504
|
lines.push('');
|
|
434
|
-
// Header
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
lines.push(` ${t.brightBlue}
|
|
438
|
-
lines.push(` ${t.brightBlue}
|
|
505
|
+
// Header box — build each line to exactly W visible chars inside the borders
|
|
506
|
+
const hdrLine1 = ` ${c.bBright('Upfyn-Code')} ${c.dim('--')} ${c.gray('by Thinqmesh Technologies')}`;
|
|
507
|
+
const hdrLine2 = ` ${c.dim('Visual AI Coding Interface with Upfyn-Canvas')}`;
|
|
508
|
+
lines.push(` ${t.brightBlue}${ch.tl}${ch.h.repeat(W)}${ch.tr}${r}`);
|
|
509
|
+
lines.push(` ${t.brightBlue}${ch.v}${r}${padAnsi(hdrLine1, W)}${t.brightBlue}${ch.v}${r}`);
|
|
510
|
+
lines.push(` ${t.brightBlue}${ch.v}${r}${padAnsi(hdrLine2, W)}${t.brightBlue}${ch.v}${r}`);
|
|
511
|
+
lines.push(` ${t.brightBlue}${ch.bl}${ch.h.repeat(W)}${ch.br}${r}`);
|
|
439
512
|
lines.push('');
|
|
440
513
|
|
|
441
514
|
// Usage
|
|
@@ -446,8 +519,10 @@ function showStyledHelp(version) {
|
|
|
446
519
|
// Commands
|
|
447
520
|
lines.push(` ${c.bBright('Commands:')}`);
|
|
448
521
|
const cmds = [
|
|
449
|
-
['
|
|
522
|
+
['(default)', 'Launch Claude Code with Upfyn branding'],
|
|
523
|
+
['start', 'Start the local server only'],
|
|
450
524
|
['connect', 'Connect local machine to hosted server'],
|
|
525
|
+
['config', 'View/set configuration (API key, etc.)'],
|
|
451
526
|
['status', 'Show configuration and data locations'],
|
|
452
527
|
['install-commands', 'Install /upfynai-* slash commands'],
|
|
453
528
|
['uninstall-commands', 'Remove /upfynai-* slash commands'],
|
|
@@ -461,7 +536,7 @@ function showStyledHelp(version) {
|
|
|
461
536
|
lines.push('');
|
|
462
537
|
|
|
463
538
|
// Slash Commands
|
|
464
|
-
lines.push(` ${c.bBright('Slash Commands')} ${c.dim('(inside
|
|
539
|
+
lines.push(` ${c.bBright('Slash Commands')} ${c.dim('(inside Claude Code CLI):')}`);
|
|
465
540
|
const slashCmds = [
|
|
466
541
|
['/upfynai', 'Start the web UI server'],
|
|
467
542
|
['/upfynai-connect', 'Connect CLI session to web UI'],
|
|
@@ -480,6 +555,7 @@ function showStyledHelp(version) {
|
|
|
480
555
|
['-p, --port <port>', 'Set server port (default: 3001)'],
|
|
481
556
|
['--server <url>', 'Server URL for connect'],
|
|
482
557
|
['--key <token>', 'Relay token for connect'],
|
|
558
|
+
['--api-key <key>', 'Set Anthropic API key'],
|
|
483
559
|
['--database-path <path>', 'Custom database location'],
|
|
484
560
|
['-h, --help', 'Show help'],
|
|
485
561
|
['-v, --version', 'Show version'],
|
|
@@ -491,9 +567,10 @@ function showStyledHelp(version) {
|
|
|
491
567
|
|
|
492
568
|
// Examples
|
|
493
569
|
lines.push(` ${c.bBright('Examples:')}`);
|
|
494
|
-
lines.push(` ${c.dim('$')} ${c.bright('uc')} ${c.dim('#
|
|
495
|
-
lines.push(` ${c.dim('$')} ${c.bright('uc --port 8080')} ${c.dim('# Start on port 8080')}`);
|
|
570
|
+
lines.push(` ${c.dim('$')} ${c.bright('uc')} ${c.dim('# Launch Claude Code')}`);
|
|
496
571
|
lines.push(` ${c.dim('$')} ${c.bright('uc connect --key upfyn_xxx')} ${c.dim('# Bridge to hosted server')}`);
|
|
572
|
+
lines.push(` ${c.dim('$')} ${c.bright('uc config --api-key sk-ant-xxx')} ${c.dim('# Save Anthropic API key')}`);
|
|
573
|
+
lines.push(` ${c.dim('$')} ${c.bright('uc start --port 8080')} ${c.dim('# Start on port 8080')}`);
|
|
497
574
|
lines.push(` ${c.dim('$')} ${c.bright('uc status')} ${c.dim('# Show configuration')}`);
|
|
498
575
|
lines.push('');
|
|
499
576
|
|
|
@@ -512,8 +589,8 @@ function showStyledStatus(info) {
|
|
|
512
589
|
const lines = [];
|
|
513
590
|
|
|
514
591
|
lines.push('');
|
|
515
|
-
lines.push(` ${c.bBright('Upfyn-Code')} ${c.dim('
|
|
516
|
-
lines.push(` ${c.dark('
|
|
592
|
+
lines.push(` ${c.bBright('Upfyn-Code')} ${c.dim('-- Status')}`);
|
|
593
|
+
lines.push(` ${c.dark('='.repeat(50))}`);
|
|
517
594
|
lines.push('');
|
|
518
595
|
|
|
519
596
|
// Version
|
|
@@ -524,9 +601,9 @@ function showStyledStatus(info) {
|
|
|
524
601
|
lines.push(` ${c.bright('Install')} ${c.dim(info.installDir)}`);
|
|
525
602
|
lines.push(` ${c.bright('Database')} ${c.dim(info.dbPath)}`);
|
|
526
603
|
if (info.dbExists) {
|
|
527
|
-
lines.push(` ${c.green('
|
|
604
|
+
lines.push(` ${c.green('OK')} ${c.gray(`Exists (${info.dbSize})`)}`);
|
|
528
605
|
} else {
|
|
529
|
-
lines.push(` ${c.yellow('
|
|
606
|
+
lines.push(` ${c.yellow('--')} ${c.gray('Not created yet')}`);
|
|
530
607
|
}
|
|
531
608
|
lines.push('');
|
|
532
609
|
|
|
@@ -535,15 +612,18 @@ function showStyledStatus(info) {
|
|
|
535
612
|
lines.push(` ${c.gray('PORT')} ${c.cyan(info.port)} ${info.portDefault ? c.dim('(default)') : ''}`);
|
|
536
613
|
lines.push(` ${c.gray('DATABASE')} ${c.dim(info.dbPath)}`);
|
|
537
614
|
lines.push(` ${c.gray('CLI')} ${c.dim(info.claudeCli || 'claude (default)')}`);
|
|
615
|
+
if (info.apiKey) {
|
|
616
|
+
lines.push(` ${c.gray('API KEY')} ${c.green('Set')} ${c.dim('(sk-ant-...' + info.apiKey.slice(-4) + ')')}`);
|
|
617
|
+
}
|
|
538
618
|
lines.push('');
|
|
539
619
|
|
|
540
620
|
// Bottom
|
|
541
|
-
lines.push(` ${c.dark('
|
|
621
|
+
lines.push(` ${c.dark('='.repeat(50))}`);
|
|
542
622
|
lines.push('');
|
|
543
623
|
lines.push(` ${c.bCyan('Tips:')}`);
|
|
544
|
-
lines.push(` ${c.dim('>')} Use ${c.bright('uc
|
|
624
|
+
lines.push(` ${c.dim('>')} Use ${c.bright('uc')} to launch Claude Code with Upfyn branding`);
|
|
545
625
|
lines.push(` ${c.dim('>')} Use ${c.bright('uc connect --key upfyn_xxx')} to bridge to web UI`);
|
|
546
|
-
lines.push(` ${c.dim('>')}
|
|
626
|
+
lines.push(` ${c.dim('>')} Use ${c.bright('uc config --api-key sk-ant-xxx')} to save your API key`);
|
|
547
627
|
lines.push('');
|
|
548
628
|
|
|
549
629
|
process.stdout.write(lines.join('\n') + '\n');
|
|
@@ -558,11 +638,11 @@ function showServerBanner(port, version) {
|
|
|
558
638
|
lines.push('');
|
|
559
639
|
for (const line of LOGO) lines.push(` ${line}`);
|
|
560
640
|
lines.push('');
|
|
561
|
-
lines.push(` ${c.dim('v' + version)} ${c.dim('
|
|
641
|
+
lines.push(` ${c.dim('v' + version)} ${c.dim('--')} ${c.gray('by Thinqmesh Technologies')}`);
|
|
562
642
|
lines.push('');
|
|
563
|
-
lines.push(` ${c.dark(
|
|
643
|
+
lines.push(` ${c.dark(ch.h.repeat(52))}`);
|
|
564
644
|
lines.push('');
|
|
565
|
-
lines.push(` ${c.green('
|
|
645
|
+
lines.push(` ${c.green('*')} ${c.bWhite('Server running')} ${c.gray('on')} ${c.bCyan(`http://localhost:${port}`)}`);
|
|
566
646
|
lines.push('');
|
|
567
647
|
lines.push(` ${c.dim('Press Ctrl+C to stop.')}`);
|
|
568
648
|
lines.push('');
|
|
@@ -583,9 +663,9 @@ async function showConnectStartup(serverUrl, machine, user, version) {
|
|
|
583
663
|
lines.push('');
|
|
584
664
|
for (const line of LOGO) lines.push(` ${line}`);
|
|
585
665
|
lines.push('');
|
|
586
|
-
lines.push(` ${c.dim('v' + version)} ${c.dim('
|
|
666
|
+
lines.push(` ${c.dim('v' + version)} ${c.dim('--')} ${c.gray('Relay Client')}`);
|
|
587
667
|
lines.push('');
|
|
588
|
-
lines.push(` ${c.dark(
|
|
668
|
+
lines.push(` ${c.dark(ch.h.repeat(52))}`);
|
|
589
669
|
lines.push('');
|
|
590
670
|
lines.push(` ${c.gray('Server:')} ${c.cyan(serverUrl)}`);
|
|
591
671
|
lines.push(` ${c.gray('Machine:')} ${c.dim(machine)}`);
|
|
@@ -595,6 +675,79 @@ async function showConnectStartup(serverUrl, machine, user, version) {
|
|
|
595
675
|
process.stdout.write(lines.join('\n') + '\n');
|
|
596
676
|
}
|
|
597
677
|
|
|
678
|
+
/**
|
|
679
|
+
* Show interactive launch screen (before spawning Claude Code)
|
|
680
|
+
*/
|
|
681
|
+
function showLaunchScreen(version, claudeBin, options = {}) {
|
|
682
|
+
const cols = process.stdout.columns || 80;
|
|
683
|
+
const W = Math.min(cols - 4, 72);
|
|
684
|
+
|
|
685
|
+
const lines = [];
|
|
686
|
+
|
|
687
|
+
lines.push('');
|
|
688
|
+
for (const line of LOGO) lines.push(` ${line}`);
|
|
689
|
+
lines.push('');
|
|
690
|
+
lines.push(` ${c.dim('v' + version)} ${c.dim('--')} ${c.gray('by Thinqmesh Technologies')}`);
|
|
691
|
+
lines.push('');
|
|
692
|
+
lines.push(` ${c.dark(ch.h.repeat(W))}`);
|
|
693
|
+
lines.push('');
|
|
694
|
+
|
|
695
|
+
if (claudeBin) {
|
|
696
|
+
lines.push(` ${c.green('*')} ${c.bWhite('Claude Code detected:')} ${c.dim(claudeBin)}`);
|
|
697
|
+
}
|
|
698
|
+
if (options.relayStatus) {
|
|
699
|
+
lines.push(` ${c.green('*')} ${c.bWhite('Relay:')} ${c.dim(options.relayStatus)}`);
|
|
700
|
+
}
|
|
701
|
+
if (options.apiKey) {
|
|
702
|
+
lines.push(` ${c.green('*')} ${c.bWhite('API Key:')} ${c.dim('Configured')}`);
|
|
703
|
+
}
|
|
704
|
+
lines.push('');
|
|
705
|
+
|
|
706
|
+
if (claudeBin) {
|
|
707
|
+
lines.push(` ${c.dim('Launching Claude Code...')}`);
|
|
708
|
+
lines.push(` ${c.dim('Slash commands available: /upfynai-connect, /upfynai-status')}`);
|
|
709
|
+
} else {
|
|
710
|
+
lines.push(` ${c.yellow('!')} ${c.white('Claude Code CLI not found on PATH')}`);
|
|
711
|
+
lines.push('');
|
|
712
|
+
lines.push(` ${c.gray('Install Claude Code:')}`);
|
|
713
|
+
lines.push(` ${c.bright('npm install -g @anthropic-ai/claude-code')}`);
|
|
714
|
+
lines.push('');
|
|
715
|
+
lines.push(` ${c.gray('Or start the server instead:')}`);
|
|
716
|
+
lines.push(` ${c.bright('uc start')}`);
|
|
717
|
+
}
|
|
718
|
+
lines.push('');
|
|
719
|
+
lines.push(` ${c.dark(ch.h.repeat(W))}`);
|
|
720
|
+
lines.push('');
|
|
721
|
+
|
|
722
|
+
process.stdout.write(lines.join('\n') + '\n');
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Show config display
|
|
727
|
+
*/
|
|
728
|
+
function showConfig(config) {
|
|
729
|
+
const lines = [];
|
|
730
|
+
lines.push('');
|
|
731
|
+
lines.push(` ${c.bBright('Upfyn-Code')} ${c.dim('-- Configuration')}`);
|
|
732
|
+
lines.push(` ${c.dark('='.repeat(50))}`);
|
|
733
|
+
lines.push('');
|
|
734
|
+
|
|
735
|
+
lines.push(` ${c.gray('Server')} ${config.server ? c.cyan(config.server) : c.dim('(not set)')}`);
|
|
736
|
+
lines.push(` ${c.gray('Relay Key')} ${config.relayKey ? c.green('Set') + ' ' + c.dim('(' + config.relayKey.slice(0, 10) + '...)') : c.dim('(not set)')}`);
|
|
737
|
+
lines.push(` ${c.gray('API Key')} ${config.anthropicApiKey ? c.green('Set') + ' ' + c.dim('(sk-ant-...' + config.anthropicApiKey.slice(-4) + ')') : c.dim('(not set)')}`);
|
|
738
|
+
lines.push('');
|
|
739
|
+
lines.push(` ${c.gray('Config file:')} ${c.dim(config._path || '~/.upfynai/config.json')}`);
|
|
740
|
+
lines.push('');
|
|
741
|
+
|
|
742
|
+
lines.push(` ${c.bCyan('Set values:')}`);
|
|
743
|
+
lines.push(` ${c.dim('$')} ${c.bright('uc config --api-key sk-ant-xxx')} ${c.dim('# Save Anthropic API key')}`);
|
|
744
|
+
lines.push(` ${c.dim('$')} ${c.bright('uc config --clear-api-key')} ${c.dim('# Remove API key')}`);
|
|
745
|
+
lines.push(` ${c.dim('$')} ${c.bright('uc connect --server <url> --key <token>')}`);
|
|
746
|
+
lines.push('');
|
|
747
|
+
|
|
748
|
+
process.stdout.write(lines.join('\n') + '\n');
|
|
749
|
+
}
|
|
750
|
+
|
|
598
751
|
/**
|
|
599
752
|
* Log a relay event with icon
|
|
600
753
|
*/
|
|
@@ -604,17 +757,12 @@ function logRelayEvent(icon, message, color = 'gray') {
|
|
|
604
757
|
console.log(` ${c.dim(timestamp)} ${icon} ${colorFn(message)}`);
|
|
605
758
|
}
|
|
606
759
|
|
|
607
|
-
/**
|
|
608
|
-
* Strip ANSI codes for length calculation
|
|
609
|
-
*/
|
|
610
|
-
function stripAnsi(str) {
|
|
611
|
-
return str.replace(/\x1b\[[0-9;]*m/g, '');
|
|
612
|
-
}
|
|
613
|
-
|
|
614
760
|
export {
|
|
615
761
|
theme,
|
|
616
762
|
c,
|
|
763
|
+
ch,
|
|
617
764
|
LOGO,
|
|
765
|
+
detectTerminalSupport,
|
|
618
766
|
playRocketAnimation,
|
|
619
767
|
showWelcomeScreen,
|
|
620
768
|
showConnectionBanner,
|
|
@@ -622,6 +770,8 @@ export {
|
|
|
622
770
|
showStyledStatus,
|
|
623
771
|
showServerBanner,
|
|
624
772
|
showConnectStartup,
|
|
773
|
+
showLaunchScreen,
|
|
774
|
+
showConfig,
|
|
625
775
|
logRelayEvent,
|
|
626
776
|
createSpinner,
|
|
627
777
|
hideCursor,
|
|
@@ -631,4 +781,5 @@ export {
|
|
|
631
781
|
hLine,
|
|
632
782
|
box,
|
|
633
783
|
stripAnsi,
|
|
784
|
+
padAnsi,
|
|
634
785
|
};
|