upfynai-code 3.0.4 → 3.1.0
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 +66 -91
- package/bin/cli.js +191 -0
- package/{client/dist/assets/AppContent-CwrTP6TW.js → dist/client/assets/AppContent-BofJquUs.js} +4 -4
- package/{client/dist/assets/BrowserPanel-0TLEl-IC.js → dist/client/assets/BrowserPanel-CSvD4jOX.js} +2 -2
- package/dist/client/assets/CanvasFullScreen-onRfarpc.js +1 -0
- package/dist/client/assets/CanvasWorkspace-DvGKdL-k.js +259 -0
- package/dist/client/assets/DashboardPanel-DqAHbXDO.js +1 -0
- package/dist/client/assets/FileTree-BE0h-9M9.js +1 -0
- package/{client/dist/assets/GitPanel-C_xFM-N2.js → dist/client/assets/GitPanel-DdeJ0bp5.js} +2 -2
- package/{client/dist/assets/LoginModal-CImJHRjX.js → dist/client/assets/LoginModal-BP0pCTrH.js} +3 -3
- package/dist/client/assets/MermaidBlock-D0rfEhrT.js +2 -0
- package/dist/client/assets/Onboarding-B2zQy-_6.js +1 -0
- package/dist/client/assets/SetupForm-Be7-WBe-.js +1 -0
- package/dist/client/assets/WorkflowsPanel-CusLbVJ6.js +1 -0
- package/{client/dist/assets/index-HaY-3pK1.js → dist/client/assets/index-BQy15irW.js} +24 -24
- package/dist/client/assets/index-CS0fDqEC.js +1 -0
- package/dist/client/assets/index-DYLSCCCp.css +1 -0
- package/dist/client/assets/vendor-canvas-QWTduIvM.js +23 -0
- package/{client/dist/assets/vendor-icons-GyYE35HP.js → dist/client/assets/vendor-icons-kix3Gb31.js} +1 -1
- package/{client/dist/assets/vendor-mermaid-DucWyDEe.js → dist/client/assets/vendor-mermaid-CS3J4_Bz.js} +329 -326
- package/dist/client/favicon.png +0 -0
- package/dist/client/favicon.svg +15 -0
- package/{client/dist → dist/client}/index.html +3 -3
- package/{client/dist → dist/client}/manifest.json +12 -12
- package/package.json +55 -104
- package/scripts/postinstall.js +9 -0
- package/scripts/prepublish.js +77 -0
- package/src/animation.js +228 -0
- package/src/auth.js +142 -0
- package/src/config.js +40 -0
- package/src/connect.js +416 -0
- package/src/launch.js +81 -0
- package/src/mcp.js +57 -0
- package/src/permissions.js +140 -0
- package/src/persistent-shell.js +261 -0
- package/src/server.js +54 -0
- package/client/dist/assets/CanvasFullScreen-D1GWQsGL.js +0 -1
- package/client/dist/assets/CanvasWorkspace-D7ORj358.js +0 -163
- package/client/dist/assets/DashboardPanel-BV7ybUDe.js +0 -1
- package/client/dist/assets/FileTree-5qfhBqdE.js +0 -1
- package/client/dist/assets/MermaidBlock-BFM21cwe.js +0 -2
- package/client/dist/assets/Onboarding-B3cteLu2.js +0 -1
- package/client/dist/assets/SetupForm-P6dsYgHO.js +0 -1
- package/client/dist/assets/WorkflowsPanel-CBoN80kc.js +0 -1
- package/client/dist/assets/index-46kkVu2i.css +0 -1
- package/client/dist/assets/vendor-canvas-DvHJ_Pn2.js +0 -49
- package/client/dist/favicon.png +0 -0
- package/client/dist/favicon.svg +0 -5
- 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/agent-loop.js +0 -242
- package/server/auto-compact.js +0 -99
- package/server/browser.js +0 -131
- package/server/claude-sdk.js +0 -797
- package/server/cli-ui.js +0 -798
- package/server/cli.js +0 -751
- 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 -1547
- package/server/database/init.sql +0 -70
- package/server/index.js +0 -3813
- package/server/load-env.js +0 -26
- package/server/mcp-server.js +0 -621
- package/server/middleware/auth.js +0 -184
- package/server/middleware/relayHelpers.js +0 -44
- package/server/middleware/sandboxRouter.js +0 -174
- package/server/openai-codex.js +0 -403
- package/server/openrouter.js +0 -137
- package/server/projects.js +0 -1807
- package/server/provider-factory.js +0 -174
- package/server/relay-client.js +0 -390
- package/server/routes/agent.js +0 -1234
- package/server/routes/auth.js +0 -559
- package/server/routes/browser.js +0 -419
- package/server/routes/canvas.js +0 -53
- package/server/routes/cli-auth.js +0 -263
- package/server/routes/codex.js +0 -396
- package/server/routes/commands.js +0 -707
- package/server/routes/composio.js +0 -176
- package/server/routes/cursor.js +0 -770
- package/server/routes/dashboard.js +0 -295
- package/server/routes/git.js +0 -1208
- package/server/routes/keys.js +0 -34
- package/server/routes/mcp-utils.js +0 -48
- package/server/routes/mcp.js +0 -661
- package/server/routes/payments.js +0 -227
- package/server/routes/projects.js +0 -754
- package/server/routes/sessions.js +0 -146
- 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 -624
- package/server/routes/voice.js +0 -235
- package/server/routes/webhooks.js +0 -166
- package/server/routes/workflows.js +0 -312
- package/server/sandbox.js +0 -120
- package/server/services/browser-ai.js +0 -154
- package/server/services/composio.js +0 -204
- package/server/services/sessionRegistry.js +0 -139
- package/server/services/whisperService.js +0 -84
- package/server/services/workflowScheduler.js +0 -211
- package/server/tests/relay-flow.test.js +0 -570
- package/server/tests/sessions.test.js +0 -259
- package/server/utils/commandParser.js +0 -303
- package/server/utils/email.js +0 -66
- 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/integrationCatalog.d.ts +0 -12
- package/shared/integrationCatalog.js +0 -172
- package/shared/modelConstants.js +0 -96
- /package/{shared → dist}/agents/claude.js +0 -0
- /package/{shared → dist}/agents/codex.js +0 -0
- /package/{shared → dist}/agents/cursor.js +0 -0
- /package/{shared → dist}/agents/detect.js +0 -0
- /package/{shared → dist}/agents/exec.js +0 -0
- /package/{shared → dist}/agents/files.js +0 -0
- /package/{shared → dist}/agents/git.js +0 -0
- /package/{shared → dist}/agents/gitagent.js +0 -0
- /package/{shared → dist}/agents/index.js +0 -0
- /package/{shared → dist}/agents/shell.js +0 -0
- /package/{shared → dist}/agents/utils.js +0 -0
- /package/{client/dist → dist/client}/api-docs.html +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- /package/{client/dist → dist/client}/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- /package/{client/dist → dist/client}/assets/MarkdownPreview-CESjI261.js +0 -0
- /package/{client/dist → dist/client}/assets/PreviewPanel-CqCa92Tf.js +0 -0
- /package/{client/dist → dist/client}/assets/pdf-CE_K4jFx.js +0 -0
- /package/{client/dist → dist/client}/assets/vendor-canvas-BZV40eAE.css +0 -0
- /package/{client/dist → dist/client}/assets/vendor-codemirror-D2ALgpaX.js +0 -0
- /package/{client/dist → dist/client}/assets/vendor-diff-DNQpbhrT.js +0 -0
- /package/{client/dist → dist/client}/assets/vendor-i18n-DCFGyhQR.js +0 -0
- /package/{client/dist → dist/client}/assets/vendor-markdown-CimbIo6Y.js +0 -0
- /package/{client/dist → dist/client}/assets/vendor-react-96lCPsRK.js +0 -0
- /package/{client/dist → dist/client}/assets/vendor-syntax-LS_Nt30I.js +0 -0
- /package/{client/dist → dist/client}/assets/vendor-xterm-CZq1hqo1.js +0 -0
- /package/{client/dist → dist/client}/assets/vendor-xterm-qxJ8_QYu.css +0 -0
- /package/{client/dist → dist/client}/clear-cache.html +0 -0
- /package/{client/dist → dist/client}/convert-icons.md +0 -0
- /package/{client/dist → dist/client}/generate-icons.js +0 -0
- /package/{client/dist → dist/client}/icons/claude-ai-icon.svg +0 -0
- /package/{client/dist → dist/client}/icons/codex-white.svg +0 -0
- /package/{client/dist → dist/client}/icons/codex.svg +0 -0
- /package/{client/dist → dist/client}/icons/cursor-white.svg +0 -0
- /package/{client/dist → dist/client}/icons/cursor.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-128x128.png +0 -0
- /package/{client/dist → dist/client}/icons/icon-128x128.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-144x144.png +0 -0
- /package/{client/dist → dist/client}/icons/icon-144x144.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-152x152.png +0 -0
- /package/{client/dist → dist/client}/icons/icon-152x152.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-192x192.png +0 -0
- /package/{client/dist → dist/client}/icons/icon-192x192.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-384x384.png +0 -0
- /package/{client/dist → dist/client}/icons/icon-384x384.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-512x512.png +0 -0
- /package/{client/dist → dist/client}/icons/icon-512x512.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-72x72.png +0 -0
- /package/{client/dist → dist/client}/icons/icon-72x72.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-96x96.png +0 -0
- /package/{client/dist → dist/client}/icons/icon-96x96.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-template.svg +0 -0
- /package/{client/dist → dist/client}/logo-128.png +0 -0
- /package/{client/dist → dist/client}/logo-256.png +0 -0
- /package/{client/dist → dist/client}/logo-32.png +0 -0
- /package/{client/dist → dist/client}/logo-512.png +0 -0
- /package/{client/dist → dist/client}/logo-64.png +0 -0
- /package/{client/dist → dist/client}/logo.svg +0 -0
- /package/{client/dist → dist/client}/mcp-docs.html +0 -0
- /package/{client/dist → dist/client}/offline.html +0 -0
- /package/{client/dist → dist/client}/screenshots/cli-selection.png +0 -0
- /package/{client/dist → dist/client}/screenshots/desktop-main.png +0 -0
- /package/{client/dist → dist/client}/screenshots/mobile-chat.png +0 -0
- /package/{client/dist → dist/client}/screenshots/tools-modal.png +0 -0
- /package/{client/dist → dist/client}/sw.js +0 -0
- /package/{shared → dist}/gitagent/index.js +0 -0
- /package/{shared → dist}/gitagent/parser.js +0 -0
- /package/{shared → dist}/gitagent/prompt-builder.js +0 -0
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="arrow-grad" x1="0" y1="1" x2="1" y2="0">
|
|
4
|
+
<stop offset="0%" stop-color="#00b8d4"/>
|
|
5
|
+
<stop offset="100%" stop-color="#26c6da"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect width="64" height="64" rx="12" fill="#0a0f1e"/>
|
|
9
|
+
<!-- Outer arrow (dark border) -->
|
|
10
|
+
<path d="M12 52 L27 37 L23 37 L42 12 L52 22 L33 47 L37 47 Z" fill="#1a1a2e" stroke="#1a1a2e" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/>
|
|
11
|
+
<!-- Inner arrow (cyan) -->
|
|
12
|
+
<path d="M15 49 L28 36 L24 36 L42 15 L49 22 L31 44 L35 44 Z" fill="url(#arrow-grad)" stroke="none"/>
|
|
13
|
+
<!-- Highlight stripe -->
|
|
14
|
+
<path d="M18 47 L29 36 L26 36 L43 17 L45 19 L28 38 L31 38 Z" fill="#00e5ff" opacity="0.4"/>
|
|
15
|
+
</svg>
|
|
@@ -62,13 +62,13 @@
|
|
|
62
62
|
40% { transform: translateY(-8px); }
|
|
63
63
|
}
|
|
64
64
|
</style>
|
|
65
|
-
<script type="module" crossorigin src="/app/assets/index-
|
|
65
|
+
<script type="module" crossorigin src="/app/assets/index-BQy15irW.js"></script>
|
|
66
66
|
<link rel="modulepreload" crossorigin href="/app/assets/vendor-react-96lCPsRK.js">
|
|
67
67
|
<link rel="modulepreload" crossorigin href="/app/assets/vendor-markdown-CimbIo6Y.js">
|
|
68
68
|
<link rel="modulepreload" crossorigin href="/app/assets/vendor-syntax-LS_Nt30I.js">
|
|
69
|
-
<link rel="modulepreload" crossorigin href="/app/assets/vendor-icons-
|
|
69
|
+
<link rel="modulepreload" crossorigin href="/app/assets/vendor-icons-kix3Gb31.js">
|
|
70
70
|
<link rel="modulepreload" crossorigin href="/app/assets/vendor-i18n-DCFGyhQR.js">
|
|
71
|
-
<link rel="stylesheet" crossorigin href="/app/assets/index-
|
|
71
|
+
<link rel="stylesheet" crossorigin href="/app/assets/index-DYLSCCCp.css">
|
|
72
72
|
</head>
|
|
73
73
|
<body>
|
|
74
74
|
<!-- Static splash screen: visible INSTANTLY (pure HTML, no JS needed) -->
|
|
@@ -2,57 +2,57 @@
|
|
|
2
2
|
"name": "UpfynAI",
|
|
3
3
|
"short_name": "UpfynAI",
|
|
4
4
|
"description": "UpfynAI — Visual AI Coding Interface",
|
|
5
|
-
"start_url": "/",
|
|
5
|
+
"start_url": "/app/",
|
|
6
6
|
"display": "standalone",
|
|
7
|
-
"background_color": "#
|
|
8
|
-
"theme_color": "#
|
|
7
|
+
"background_color": "#0a0f1e",
|
|
8
|
+
"theme_color": "#0a0f1e",
|
|
9
9
|
"orientation": "portrait-primary",
|
|
10
|
-
"scope": "/",
|
|
10
|
+
"scope": "/app/",
|
|
11
11
|
"icons": [
|
|
12
12
|
{
|
|
13
|
-
"src": "
|
|
13
|
+
"src": "icons/icon-72x72.png",
|
|
14
14
|
"sizes": "72x72",
|
|
15
15
|
"type": "image/png",
|
|
16
16
|
"purpose": "maskable any"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
|
-
"src": "
|
|
19
|
+
"src": "icons/icon-96x96.png",
|
|
20
20
|
"sizes": "96x96",
|
|
21
21
|
"type": "image/png",
|
|
22
22
|
"purpose": "maskable any"
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
|
-
"src": "
|
|
25
|
+
"src": "icons/icon-128x128.png",
|
|
26
26
|
"sizes": "128x128",
|
|
27
27
|
"type": "image/png",
|
|
28
28
|
"purpose": "maskable any"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
|
-
"src": "
|
|
31
|
+
"src": "icons/icon-144x144.png",
|
|
32
32
|
"sizes": "144x144",
|
|
33
33
|
"type": "image/png",
|
|
34
34
|
"purpose": "maskable any"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
|
-
"src": "
|
|
37
|
+
"src": "icons/icon-152x152.png",
|
|
38
38
|
"sizes": "152x152",
|
|
39
39
|
"type": "image/png",
|
|
40
40
|
"purpose": "maskable any"
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
|
-
"src": "
|
|
43
|
+
"src": "icons/icon-192x192.png",
|
|
44
44
|
"sizes": "192x192",
|
|
45
45
|
"type": "image/png",
|
|
46
46
|
"purpose": "maskable any"
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
|
-
"src": "
|
|
49
|
+
"src": "icons/icon-384x384.png",
|
|
50
50
|
"sizes": "384x384",
|
|
51
51
|
"type": "image/png",
|
|
52
52
|
"purpose": "maskable any"
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
|
-
"src": "
|
|
55
|
+
"src": "icons/icon-512x512.png",
|
|
56
56
|
"sizes": "512x512",
|
|
57
57
|
"type": "image/png",
|
|
58
58
|
"purpose": "maskable any"
|
package/package.json
CHANGED
|
@@ -1,136 +1,87 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "upfynai-code",
|
|
3
|
-
"version": "3.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.1.0",
|
|
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
|
-
"
|
|
11
|
+
"bin/",
|
|
12
|
+
"src/",
|
|
13
|
+
"dist/",
|
|
15
14
|
"scripts/",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE"
|
|
18
17
|
],
|
|
19
18
|
"scripts": {
|
|
20
|
-
"start": "node
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"typecheck": "npx tsc --noEmit -p client/tsconfig.json",
|
|
24
|
-
"postinstall": "node scripts/fix-node-pty.js || true && node scripts/install-commands.js"
|
|
19
|
+
"start": "node bin/cli.js",
|
|
20
|
+
"postinstall": "node scripts/postinstall.js",
|
|
21
|
+
"prepublishOnly": "node scripts/prepublish.js"
|
|
25
22
|
},
|
|
26
23
|
"keywords": [
|
|
24
|
+
"upfyn",
|
|
25
|
+
"upfynai-code",
|
|
27
26
|
"ai",
|
|
27
|
+
"coding",
|
|
28
|
+
"cli",
|
|
29
|
+
"terminal",
|
|
30
|
+
"remote-development",
|
|
31
|
+
"code-editor",
|
|
32
|
+
"ai-assistant",
|
|
28
33
|
"ai-coding",
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
34
|
+
"developer-tools",
|
|
35
|
+
"devtools",
|
|
36
|
+
"browser-ide",
|
|
37
|
+
"remote-access",
|
|
38
|
+
"websocket",
|
|
39
|
+
"git",
|
|
40
|
+
"file-explorer",
|
|
33
41
|
"canvas",
|
|
34
42
|
"whiteboard",
|
|
35
|
-
"visual-coding",
|
|
36
|
-
"terminal",
|
|
37
|
-
"git",
|
|
38
43
|
"mcp",
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
+
"model-context-protocol",
|
|
45
|
+
"desktop",
|
|
46
|
+
"tauri",
|
|
47
|
+
"swarm",
|
|
48
|
+
"ai-canvas",
|
|
49
|
+
"visual-programming"
|
|
44
50
|
],
|
|
45
|
-
"author":
|
|
51
|
+
"author": {
|
|
52
|
+
"name": "Thinqmesh Technologies",
|
|
53
|
+
"url": "https://cli.upfyn.com"
|
|
54
|
+
},
|
|
46
55
|
"license": "GPL-3.0",
|
|
47
|
-
"homepage": "https://
|
|
56
|
+
"homepage": "https://cli.upfyn.com",
|
|
48
57
|
"repository": {
|
|
49
58
|
"type": "git",
|
|
50
|
-
"url": "git+https://github.com/AnitChaudhry/UpfynAI-Code.git"
|
|
59
|
+
"url": "git+https://github.com/AnitChaudhry/UpfynAI-Code.git",
|
|
60
|
+
"directory": "packages/cli"
|
|
51
61
|
},
|
|
52
62
|
"bugs": {
|
|
53
63
|
"url": "https://github.com/AnitChaudhry/UpfynAI-Code/issues"
|
|
54
64
|
},
|
|
55
65
|
"dependencies": {
|
|
56
66
|
"@anthropic-ai/claude-agent-sdk": "^0.1.71",
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"bcryptjs": "^3.0.3",
|
|
62
|
-
"chokidar": "^4.0.3",
|
|
63
|
-
"cookie-parser": "^1.4.7",
|
|
64
|
-
"cors": "^2.8.5",
|
|
65
|
-
"cross-spawn": "^7.0.3",
|
|
66
|
-
"edge-tts-universal": "^1.3.3",
|
|
67
|
-
"express": "^4.18.2",
|
|
68
|
-
"form-data": "^4.0.5",
|
|
69
|
-
"gray-matter": "^4.0.3",
|
|
67
|
+
"chalk": "^5.3.0",
|
|
68
|
+
"commander": "^12.1.0",
|
|
69
|
+
"express": "^4.21.0",
|
|
70
|
+
"http-proxy-middleware": "^3.0.0",
|
|
70
71
|
"js-yaml": "^4.1.0",
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"ws": "^8.14.2",
|
|
75
|
-
"zod": "^3.25.76"
|
|
72
|
+
"open": "^10.1.0",
|
|
73
|
+
"prompts": "^2.4.2",
|
|
74
|
+
"ws": "^8.18.0"
|
|
76
75
|
},
|
|
77
76
|
"optionalDependencies": {
|
|
78
|
-
"libsql": "^0.5.22",
|
|
79
77
|
"node-pty": "^1.1.0-beta34"
|
|
80
78
|
},
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
"@codemirror/theme-one-dark": "^6.1.2",
|
|
90
|
-
"@replit/codemirror-minimap": "^0.5.2",
|
|
91
|
-
"@tailwindcss/typography": "^0.5.16",
|
|
92
|
-
"@types/node": "^22.19.7",
|
|
93
|
-
"@types/react": "^18.2.43",
|
|
94
|
-
"@types/react-dom": "^18.2.17",
|
|
95
|
-
"@uiw/react-codemirror": "^4.23.13",
|
|
96
|
-
"@vapi-ai/web": "^2.5.2",
|
|
97
|
-
"@vitejs/plugin-react": "^4.5.2",
|
|
98
|
-
"@xterm/addon-clipboard": "^0.1.0",
|
|
99
|
-
"@xterm/addon-fit": "^0.10.0",
|
|
100
|
-
"@xterm/addon-web-links": "^0.11.0",
|
|
101
|
-
"@xterm/addon-webgl": "^0.18.0",
|
|
102
|
-
"@xterm/xterm": "^5.5.0",
|
|
103
|
-
"@xyflow/react": "^12.10.1",
|
|
104
|
-
"autoprefixer": "^10.4.16",
|
|
105
|
-
"class-variance-authority": "^0.7.1",
|
|
106
|
-
"clsx": "^2.1.1",
|
|
107
|
-
"dagre": "^0.8.5",
|
|
108
|
-
"elkjs": "^0.11.0",
|
|
109
|
-
"fuse.js": "^7.0.0",
|
|
110
|
-
"i18next": "^25.7.4",
|
|
111
|
-
"i18next-browser-languagedetector": "^8.2.0",
|
|
112
|
-
"katex": "^0.16.25",
|
|
113
|
-
"lightningcss": "^1.31.1",
|
|
114
|
-
"lucide-react": "^0.515.0",
|
|
115
|
-
"mermaid": "^11.12.3",
|
|
116
|
-
"pdfjs-dist": "^5.4.624",
|
|
117
|
-
"postcss": "^8.4.32",
|
|
118
|
-
"react": "^18.2.0",
|
|
119
|
-
"react-diff-viewer-continued": "^4.1.2",
|
|
120
|
-
"react-dom": "^18.2.0",
|
|
121
|
-
"react-dropzone": "^14.2.3",
|
|
122
|
-
"react-i18next": "^16.5.3",
|
|
123
|
-
"react-markdown": "^10.1.0",
|
|
124
|
-
"react-router-dom": "^6.8.1",
|
|
125
|
-
"react-syntax-highlighter": "^15.6.1",
|
|
126
|
-
"rehype-katex": "^7.0.1",
|
|
127
|
-
"rehype-raw": "^7.0.0",
|
|
128
|
-
"remark-gfm": "^4.0.0",
|
|
129
|
-
"remark-math": "^6.0.0",
|
|
130
|
-
"tailwind-merge": "^3.3.1",
|
|
131
|
-
"tailwindcss": "^3.4.0",
|
|
132
|
-
"typescript": "^5.9.3",
|
|
133
|
-
"vite": "~6.3.5",
|
|
134
|
-
"zustand": "^5.0.11"
|
|
135
|
-
}
|
|
79
|
+
"engines": {
|
|
80
|
+
"node": ">=18.0.0"
|
|
81
|
+
},
|
|
82
|
+
"os": [
|
|
83
|
+
"darwin",
|
|
84
|
+
"linux",
|
|
85
|
+
"win32"
|
|
86
|
+
]
|
|
136
87
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { playInstallAnimation } from '../src/animation.js';
|
|
3
|
+
|
|
4
|
+
try {
|
|
5
|
+
await playInstallAnimation();
|
|
6
|
+
} catch {
|
|
7
|
+
// Silently fail — animation is cosmetic, don't break installs
|
|
8
|
+
console.log('\n ✓ upfynai-code installed. Run `uc --help` to get started.\n');
|
|
9
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Prepublish script — copies shared agents into dist/ for npm distribution.
|
|
4
|
+
*
|
|
5
|
+
* In the monorepo, connect.js imports from ../../shared/agents/.
|
|
6
|
+
* For npm, we copy those files into dist/agents/ and connect.js
|
|
7
|
+
* resolves them at runtime.
|
|
8
|
+
*/
|
|
9
|
+
import { cpSync, mkdirSync, rmSync, existsSync } from 'fs';
|
|
10
|
+
import { join, dirname } from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
|
|
13
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
const cliRoot = join(__dirname, '..');
|
|
15
|
+
const distAgents = join(cliRoot, 'dist', 'agents');
|
|
16
|
+
const sharedAgents = join(cliRoot, '..', 'shared', 'agents');
|
|
17
|
+
|
|
18
|
+
// Clean
|
|
19
|
+
if (existsSync(distAgents)) rmSync(distAgents, { recursive: true });
|
|
20
|
+
mkdirSync(distAgents, { recursive: true });
|
|
21
|
+
|
|
22
|
+
// Copy all agent files
|
|
23
|
+
const files = [
|
|
24
|
+
'index.js', 'utils.js',
|
|
25
|
+
'claude.js', 'codex.js', 'cursor.js',
|
|
26
|
+
'shell.js', 'files.js', 'git.js', 'exec.js', 'detect.js',
|
|
27
|
+
'gitagent.js',
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
let copied = 0;
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
const src = join(sharedAgents, file);
|
|
33
|
+
const dest = join(distAgents, file);
|
|
34
|
+
if (existsSync(src)) {
|
|
35
|
+
cpSync(src, dest);
|
|
36
|
+
copied++;
|
|
37
|
+
} else {
|
|
38
|
+
console.warn(` [WARN] Missing: ${file}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Copy gitagent module (parser + prompt-builder) — needed by gitagent agent
|
|
43
|
+
const sharedGitagent = join(cliRoot, '..', 'shared', 'gitagent');
|
|
44
|
+
const distGitagent = join(cliRoot, 'dist', 'gitagent');
|
|
45
|
+
if (existsSync(distGitagent)) rmSync(distGitagent, { recursive: true });
|
|
46
|
+
mkdirSync(distGitagent, { recursive: true });
|
|
47
|
+
|
|
48
|
+
const gitagentFiles = ['index.js', 'parser.js', 'prompt-builder.js'];
|
|
49
|
+
for (const file of gitagentFiles) {
|
|
50
|
+
const src = join(sharedGitagent, file);
|
|
51
|
+
const dest = join(distGitagent, file);
|
|
52
|
+
if (existsSync(src)) {
|
|
53
|
+
cpSync(src, dest);
|
|
54
|
+
copied++;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log(` [prepublish] Copied ${copied} agent files to dist/`);
|
|
59
|
+
|
|
60
|
+
// ─── Copy built client dist for local-server static serving ──────────────
|
|
61
|
+
const clientSrc = join(cliRoot, '..', '..', 'backend', 'client', 'dist');
|
|
62
|
+
const clientDest = join(cliRoot, 'dist', 'client');
|
|
63
|
+
|
|
64
|
+
if (existsSync(clientSrc)) {
|
|
65
|
+
if (existsSync(clientDest)) rmSync(clientDest, { recursive: true });
|
|
66
|
+
cpSync(clientSrc, clientDest, { recursive: true });
|
|
67
|
+
console.log(` [prepublish] Copied client dist to dist/client/`);
|
|
68
|
+
} else {
|
|
69
|
+
console.warn(` [WARN] Client dist not found at ${clientSrc} — run 'npm run build' in backend/client first`);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ─── Note: local-server bundling ─────────────────────────────────────────
|
|
73
|
+
// For npm global installs, local-server needs to be bundled with esbuild
|
|
74
|
+
// into dist/local-server.js (with node-pty as external).
|
|
75
|
+
// Run: npx esbuild packages/local-server/index.js --bundle --platform=node --outfile=packages/cli/dist/local-server.js --external:node-pty
|
|
76
|
+
// This is handled by the CI/CD pipeline before npm publish.
|
|
77
|
+
console.log(` [prepublish] Done.`);
|
package/src/animation.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI spaceship-to-star animation for Upfyn-Code.
|
|
3
|
+
* Plays after install (postinstall) and before `uc connect` starts.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const STAR_FRAMES = ['✦', '✧', '✦', '★'];
|
|
7
|
+
|
|
8
|
+
// Spaceship frames (4 animation states)
|
|
9
|
+
const SHIP = [
|
|
10
|
+
' ╱▏▔▔╲ ',
|
|
11
|
+
' ╱ ▏══ ╲ ',
|
|
12
|
+
'╱ ▏▁▁ ╲ ',
|
|
13
|
+
' ╱▏▔▔╲ ',
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
// Simpler inline ship for the travel animation
|
|
17
|
+
const SHIP_R = [
|
|
18
|
+
' ▄▄ ',
|
|
19
|
+
' ◁━━██━━▷ ',
|
|
20
|
+
' ▀▀ ',
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const SHIP_SMALL = '◁━━▶';
|
|
24
|
+
const SHIP_TRAVEL = '⟫⟫';
|
|
25
|
+
const EXHAUST_CHARS = ['░', '▒', '▓', '═', '~', '·'];
|
|
26
|
+
|
|
27
|
+
function sleep(ms) {
|
|
28
|
+
return new Promise(r => setTimeout(r, ms));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function clearLines(n) {
|
|
32
|
+
for (let i = 0; i < n; i++) {
|
|
33
|
+
process.stdout.write('\x1b[1A\x1b[2K');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function dim(s) { return `\x1b[2m${s}\x1b[0m`; }
|
|
38
|
+
function cyan(s) { return `\x1b[36m${s}\x1b[0m`; }
|
|
39
|
+
function yellow(s) { return `\x1b[33m${s}\x1b[0m`; }
|
|
40
|
+
function bold(s) { return `\x1b[1m${s}\x1b[0m`; }
|
|
41
|
+
function magenta(s) { return `\x1b[35m${s}\x1b[0m`; }
|
|
42
|
+
function white(s) { return `\x1b[97m${s}\x1b[0m`; }
|
|
43
|
+
function green(s) { return `\x1b[32m${s}\x1b[0m`; }
|
|
44
|
+
function blue(s) { return `\x1b[34m${s}\x1b[0m`; }
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Generate a star field background line
|
|
48
|
+
*/
|
|
49
|
+
function starFieldLine(width, density = 0.08, frame = 0) {
|
|
50
|
+
let line = '';
|
|
51
|
+
for (let i = 0; i < width; i++) {
|
|
52
|
+
if (Math.random() < density) {
|
|
53
|
+
const stars = ['.', '·', '∘', '°', '✧'];
|
|
54
|
+
const s = stars[Math.floor(Math.random() * stars.length)];
|
|
55
|
+
line += dim(s);
|
|
56
|
+
} else {
|
|
57
|
+
line += ' ';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return line;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Main spaceship-to-star animation
|
|
65
|
+
* @param {'install'|'connect'} mode
|
|
66
|
+
*/
|
|
67
|
+
export async function playSpaceshipAnimation(mode = 'connect') {
|
|
68
|
+
const cols = Math.min(process.stdout.columns || 70, 80);
|
|
69
|
+
const totalFrames = 28;
|
|
70
|
+
const LINES = 11; // total lines we'll use
|
|
71
|
+
|
|
72
|
+
const starX = cols - 6;
|
|
73
|
+
|
|
74
|
+
// Phase 1: Launch sequence text
|
|
75
|
+
const tagline = mode === 'install'
|
|
76
|
+
? 'Installation complete!'
|
|
77
|
+
: 'Launching relay bridge...';
|
|
78
|
+
|
|
79
|
+
console.log('');
|
|
80
|
+
console.log(dim(' ─'.repeat(Math.floor(cols / 3))));
|
|
81
|
+
console.log('');
|
|
82
|
+
|
|
83
|
+
// Phase 2: Spaceship travels across the screen toward a star
|
|
84
|
+
for (let frame = 0; frame < totalFrames; frame++) {
|
|
85
|
+
const progress = frame / (totalFrames - 1); // 0 → 1
|
|
86
|
+
const shipX = Math.floor(progress * (cols - 16)) + 2;
|
|
87
|
+
|
|
88
|
+
// Build exhaust trail
|
|
89
|
+
const exhaustLen = Math.min(shipX, Math.floor(progress * 20));
|
|
90
|
+
let exhaust = '';
|
|
91
|
+
for (let e = 0; e < exhaustLen; e++) {
|
|
92
|
+
const intensity = 1 - (e / exhaustLen);
|
|
93
|
+
if (intensity > 0.7) exhaust = '▓' + exhaust;
|
|
94
|
+
else if (intensity > 0.4) exhaust = '▒' + exhaust;
|
|
95
|
+
else if (intensity > 0.2) exhaust = '░' + exhaust;
|
|
96
|
+
else exhaust = '·' + exhaust;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Star pulse
|
|
100
|
+
const starChar = STAR_FRAMES[frame % STAR_FRAMES.length];
|
|
101
|
+
const starGlow = progress > 0.7 ? yellow('✦ ') : '';
|
|
102
|
+
|
|
103
|
+
// Build the 5 display lines
|
|
104
|
+
const lines = [];
|
|
105
|
+
|
|
106
|
+
// Line 1: starfield
|
|
107
|
+
lines.push(' ' + starFieldLine(cols - 4, 0.05, frame));
|
|
108
|
+
|
|
109
|
+
// Line 2: top space
|
|
110
|
+
lines.push(' ' + starFieldLine(cols - 4, 0.03, frame));
|
|
111
|
+
|
|
112
|
+
// Line 3: ship row (main action)
|
|
113
|
+
let shipRow = '';
|
|
114
|
+
const beforeShip = Math.max(0, shipX - exhaustLen);
|
|
115
|
+
shipRow += ' '.repeat(beforeShip);
|
|
116
|
+
shipRow += dim(exhaust);
|
|
117
|
+
shipRow += cyan(' ◁━━▶');
|
|
118
|
+
// Fill to star position
|
|
119
|
+
const afterShip = Math.max(0, starX - shipX - 7);
|
|
120
|
+
// Dots between ship and star
|
|
121
|
+
let midSpace = '';
|
|
122
|
+
for (let d = 0; d < afterShip; d++) {
|
|
123
|
+
midSpace += Math.random() < 0.06 ? dim('·') : ' ';
|
|
124
|
+
}
|
|
125
|
+
shipRow += midSpace;
|
|
126
|
+
if (progress < 0.92) {
|
|
127
|
+
shipRow += starGlow + yellow(starChar);
|
|
128
|
+
} else {
|
|
129
|
+
shipRow += yellow('✦★✦');
|
|
130
|
+
}
|
|
131
|
+
lines.push(shipRow);
|
|
132
|
+
|
|
133
|
+
// Line 4: thrust glow
|
|
134
|
+
let thrustRow = ' '.repeat(Math.max(0, shipX + 1));
|
|
135
|
+
if (frame % 2 === 0) {
|
|
136
|
+
thrustRow += dim(magenta('~≈~'));
|
|
137
|
+
} else {
|
|
138
|
+
thrustRow += dim(magenta('≈~≈'));
|
|
139
|
+
}
|
|
140
|
+
lines.push(thrustRow);
|
|
141
|
+
|
|
142
|
+
// Line 5: starfield
|
|
143
|
+
lines.push(' ' + starFieldLine(cols - 4, 0.04, frame));
|
|
144
|
+
|
|
145
|
+
// Line 6: message (centered)
|
|
146
|
+
const msg = progress < 0.3
|
|
147
|
+
? dim(` ${tagline}`)
|
|
148
|
+
: progress < 0.6
|
|
149
|
+
? cyan(` ⟫ Navigating to the stars...`)
|
|
150
|
+
: progress < 0.9
|
|
151
|
+
? magenta(` ⟫⟫ Almost there...`)
|
|
152
|
+
: green(` ★ ${mode === 'install' ? 'Ready for launch!' : 'Connection established!'}`);
|
|
153
|
+
lines.push(msg);
|
|
154
|
+
|
|
155
|
+
// Line 7: progress bar
|
|
156
|
+
const barWidth = cols - 10;
|
|
157
|
+
const filled = Math.floor(progress * barWidth);
|
|
158
|
+
const bar = ' ' + dim('[')
|
|
159
|
+
+ cyan('█'.repeat(filled))
|
|
160
|
+
+ dim('░'.repeat(barWidth - filled))
|
|
161
|
+
+ dim(']')
|
|
162
|
+
+ dim(` ${Math.floor(progress * 100)}%`);
|
|
163
|
+
lines.push(bar);
|
|
164
|
+
|
|
165
|
+
// Print
|
|
166
|
+
if (frame > 0) clearLines(lines.length);
|
|
167
|
+
for (const l of lines) console.log(l);
|
|
168
|
+
|
|
169
|
+
// Speed: start slow, middle fast, end slow
|
|
170
|
+
const delay = progress < 0.2 ? 120
|
|
171
|
+
: progress > 0.85 ? 150
|
|
172
|
+
: 60;
|
|
173
|
+
await sleep(delay);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Phase 3: Final flash
|
|
177
|
+
await sleep(200);
|
|
178
|
+
clearLines(7);
|
|
179
|
+
|
|
180
|
+
// Arrival burst
|
|
181
|
+
const burstLines = [];
|
|
182
|
+
burstLines.push(' ' + starFieldLine(cols - 4, 0.06));
|
|
183
|
+
burstLines.push('');
|
|
184
|
+
burstLines.push(
|
|
185
|
+
' '.repeat(Math.floor(cols / 2 - 12))
|
|
186
|
+
+ yellow('· ✧ · ★ ')
|
|
187
|
+
+ bold(white('UPFYN'))
|
|
188
|
+
+ yellow(' ★ · ✧ ·')
|
|
189
|
+
);
|
|
190
|
+
burstLines.push('');
|
|
191
|
+
|
|
192
|
+
if (mode === 'install') {
|
|
193
|
+
burstLines.push(
|
|
194
|
+
' '.repeat(Math.floor(cols / 2 - 20))
|
|
195
|
+
+ green('✓ ') + bold('upfynai-code') + dim(' installed successfully')
|
|
196
|
+
);
|
|
197
|
+
burstLines.push('');
|
|
198
|
+
burstLines.push(dim(' Quick start:'));
|
|
199
|
+
burstLines.push(cyan(' uc login ') + dim('— authenticate'));
|
|
200
|
+
burstLines.push(cyan(' uc connect ') + dim('— bridge to cloud'));
|
|
201
|
+
burstLines.push(cyan(' uc --local ') + dim('— start local server'));
|
|
202
|
+
} else {
|
|
203
|
+
burstLines.push(
|
|
204
|
+
' '.repeat(Math.floor(cols / 2 - 16))
|
|
205
|
+
+ green('✓ ') + bold('Relay bridge activated')
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
burstLines.push('');
|
|
210
|
+
burstLines.push(dim(' ─'.repeat(Math.floor(cols / 3))));
|
|
211
|
+
burstLines.push('');
|
|
212
|
+
|
|
213
|
+
for (const l of burstLines) console.log(l);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Postinstall animation (shorter variant)
|
|
218
|
+
*/
|
|
219
|
+
export async function playInstallAnimation() {
|
|
220
|
+
return playSpaceshipAnimation('install');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Connect animation
|
|
225
|
+
*/
|
|
226
|
+
export async function playConnectAnimation() {
|
|
227
|
+
return playSpaceshipAnimation('connect');
|
|
228
|
+
}
|