upfynai-code 3.0.4 → 3.2.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 +69 -92
- package/bin/cli.js +191 -0
- package/dist/client/assets/AppContent-M14Au3SB.js +542 -0
- package/{client/dist/assets/BrowserPanel-0TLEl-IC.js → dist/client/assets/BrowserPanel-TFKm2NDJ.js} +2 -2
- package/dist/client/assets/DashboardPanel-C88HjsCh.js +1 -0
- package/dist/client/assets/FileTree-DvO1xnDE.js +1 -0
- package/{client/dist/assets/GitPanel-C_xFM-N2.js → dist/client/assets/GitPanel-D-slVlyy.js} +2 -2
- package/dist/client/assets/LoginModal-Chi4SYcr.js +21 -0
- package/{client/dist/assets/MarkdownPreview-CESjI261.js → dist/client/assets/MarkdownPreview-CuIix2u9.js} +1 -1
- package/dist/client/assets/MermaidBlock-Dq9uFv82.js +2 -0
- package/dist/client/assets/Onboarding-QYXx24dX.js +1 -0
- package/{client/dist/assets/PreviewPanel-CqCa92Tf.js → dist/client/assets/PreviewPanel-Dd8q-jo0.js} +1 -1
- package/dist/client/assets/SetupForm-CrspaUva.js +1 -0
- package/dist/client/assets/WorkflowsPanel-DIlYAdhB.js +1 -0
- package/dist/client/assets/index-CnNNzw9A.css +1 -0
- package/{client/dist/assets/index-HaY-3pK1.js → dist/client/assets/index-rUkK9FDP.js} +26 -26
- package/{client/dist/assets/vendor-codemirror-D2ALgpaX.js → dist/client/assets/vendor-codemirror-jc6nyJQg.js} +1 -1
- package/{client/dist/assets/vendor-diff-DNQpbhrT.js → dist/client/assets/vendor-diff-THJmAcEI.js} +1 -1
- package/{client/dist/assets/vendor-icons-GyYE35HP.js → dist/client/assets/vendor-icons-CfjIpdrD.js} +145 -155
- package/{client/dist/assets/vendor-markdown-CimbIo6Y.js → dist/client/assets/vendor-markdown-Cdm6NEGf.js} +1 -1
- package/dist/client/assets/vendor-mermaid-DTPaBx-U.js +2559 -0
- package/{client/dist/assets/vendor-react-96lCPsRK.js → dist/client/assets/vendor-react-wFkb6mSf.js} +1 -1
- package/{client/dist/assets/vendor-syntax-LS_Nt30I.js → dist/client/assets/vendor-syntax-C_UZR7tc.js} +1 -1
- package/dist/client/favicon.png +0 -0
- package/dist/client/icons/icon-128x128.png +0 -0
- package/dist/client/icons/icon-144x144.png +0 -0
- package/dist/client/icons/icon-152x152.png +0 -0
- package/dist/client/icons/icon-192x192.png +0 -0
- package/dist/client/icons/icon-384x384.png +0 -0
- package/dist/client/icons/icon-512x512.png +0 -0
- package/dist/client/icons/icon-72x72.png +0 -0
- package/dist/client/icons/icon-96x96.png +0 -0
- package/{client/dist → dist/client}/index.html +37 -36
- package/dist/client/logo-128.png +0 -0
- package/dist/client/logo-256.png +0 -0
- package/dist/client/logo-32.png +0 -0
- package/dist/client/logo-512.png +0 -0
- package/dist/client/logo-64.png +0 -0
- package/dist/client/logo.png +0 -0
- package/{client/dist → dist/client}/manifest.json +12 -12
- package/{client/dist → dist/client}/mcp-docs.html +1 -1
- package/{client/dist → dist/client}/sw.js +2 -2
- package/package.json +56 -105
- 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/AppContent-CwrTP6TW.js +0 -545
- 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/LoginModal-CImJHRjX.js +0 -13
- 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/pdf-CE_K4jFx.js +0 -12
- package/client/dist/assets/vendor-canvas-BZV40eAE.css +0 -1
- package/client/dist/assets/vendor-canvas-DvHJ_Pn2.js +0 -49
- package/client/dist/assets/vendor-mermaid-DucWyDEe.js +0 -2556
- package/client/dist/favicon.png +0 -0
- package/client/dist/icons/icon-128x128.png +0 -0
- package/client/dist/icons/icon-144x144.png +0 -0
- package/client/dist/icons/icon-152x152.png +0 -0
- package/client/dist/icons/icon-192x192.png +0 -0
- package/client/dist/icons/icon-384x384.png +0 -0
- package/client/dist/icons/icon-512x512.png +0 -0
- package/client/dist/icons/icon-72x72.png +0 -0
- package/client/dist/icons/icon-96x96.png +0 -0
- 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/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/vendor-i18n-DCFGyhQR.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}/favicon.svg +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.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-144x144.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-152x152.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-192x192.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-384x384.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-512x512.svg +0 -0
- /package/{client/dist → dist/client}/icons/icon-72x72.svg +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.svg +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/{shared → dist}/gitagent/index.js +0 -0
- /package/{shared → dist}/gitagent/parser.js +0 -0
- /package/{shared → dist}/gitagent/prompt-builder.js +0 -0
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
|
+
}
|
package/src/auth.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { readConfig, writeConfig, clearConfig, displayUrl } 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(options = {}) {
|
|
40
|
+
// Allow --server flag to override the server URL
|
|
41
|
+
if (options.server) {
|
|
42
|
+
writeConfig({ serverUrl: options.server.replace(/\/+$/, '') });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
console.log(chalk.bold('\n Upfyn Code — Login\n'));
|
|
46
|
+
|
|
47
|
+
const response = await prompts([
|
|
48
|
+
{
|
|
49
|
+
type: 'text',
|
|
50
|
+
name: 'username',
|
|
51
|
+
message: 'Username',
|
|
52
|
+
validate: v => (v.trim() ? true : 'Username is required'),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: 'password',
|
|
56
|
+
name: 'password',
|
|
57
|
+
message: 'Password',
|
|
58
|
+
validate: v => (v ? true : 'Password is required'),
|
|
59
|
+
},
|
|
60
|
+
], {
|
|
61
|
+
onCancel: () => {
|
|
62
|
+
console.log(chalk.dim('\n Login cancelled.\n'));
|
|
63
|
+
process.exit(0);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const { username, password } = response;
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const res = await apiCall('/api/auth/login', {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
body: JSON.stringify({ username: username.trim(), password }),
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const data = await res.json();
|
|
76
|
+
|
|
77
|
+
if (!res.ok) {
|
|
78
|
+
console.log(chalk.red(`\n Login failed: ${data.error || 'Unknown error'}\n`));
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
writeConfig({
|
|
83
|
+
token: data.token,
|
|
84
|
+
user: data.user,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const name = data.user.first_name || data.user.username;
|
|
88
|
+
console.log(chalk.green(`\n Logged in as ${chalk.bold(name)}!`));
|
|
89
|
+
|
|
90
|
+
// Auto-fetch and save relay token for one-command connect
|
|
91
|
+
try {
|
|
92
|
+
const config = readConfig();
|
|
93
|
+
const tokenRes = await fetch(`${config.serverUrl}/api/auth/connect-token`, {
|
|
94
|
+
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${data.token}` },
|
|
95
|
+
});
|
|
96
|
+
if (tokenRes.ok) {
|
|
97
|
+
const tokenData = await tokenRes.json();
|
|
98
|
+
if (tokenData.token) {
|
|
99
|
+
writeConfig({ relayKey: tokenData.token });
|
|
100
|
+
console.log(chalk.dim(' Relay token saved.'));
|
|
101
|
+
console.log(chalk.cyan(`\n Run ${chalk.bold('uc web connect')} to bridge your machine to the web UI.\n`));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
} catch { /* best-effort — relay token fetch is optional */ }
|
|
105
|
+
|
|
106
|
+
if (!readConfig().relayKey) {
|
|
107
|
+
console.log('');
|
|
108
|
+
}
|
|
109
|
+
} catch (err) {
|
|
110
|
+
const config = readConfig();
|
|
111
|
+
console.log(chalk.red(`\n Connection error. Could not reach ${displayUrl(config.serverUrl)}.`));
|
|
112
|
+
console.log(chalk.dim(' Check your network and try again.\n'));
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function logout() {
|
|
118
|
+
clearConfig();
|
|
119
|
+
console.log(chalk.green('\n Logged out. Credentials cleared.\n'));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export async function status() {
|
|
123
|
+
const config = readConfig();
|
|
124
|
+
|
|
125
|
+
if (!config.token) {
|
|
126
|
+
console.log(chalk.yellow('\n Not logged in. Run `uc login` to authenticate.\n'));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
console.log(chalk.dim('\n Checking session...'));
|
|
131
|
+
const user = await validateToken();
|
|
132
|
+
|
|
133
|
+
if (!user) {
|
|
134
|
+
console.log(chalk.yellow(' Session expired. Run `uc login` to re-authenticate.\n'));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const name = user.first_name || user.username;
|
|
139
|
+
console.log(chalk.bold(` Logged in as: ${chalk.cyan(name)} (${chalk.dim(user.username)})`));
|
|
140
|
+
console.log(chalk.dim(` Server: ${displayUrl(config.serverUrl)}`));
|
|
141
|
+
console.log(chalk.dim(` Local port: ${config.localPort}\n`));
|
|
142
|
+
}
|
package/src/config.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
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
|
+
/** Display-friendly server label — masks the internal URL */
|
|
34
|
+
export function displayUrl(url) {
|
|
35
|
+
if (!url || url === DEFAULTS.serverUrl) return 'Upfyn Cloud';
|
|
36
|
+
// Custom server — show the hostname only
|
|
37
|
+
try { return new URL(url).host; } catch { return url; }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { CONFIG_PATH, DEFAULTS };
|