upfynai-code 2.3.0 → 2.4.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/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 +194 -21
- package/server/index.js +159 -107
- package/server/middleware/auth.js +9 -5
- package/server/openrouter.js +137 -0
- package/server/relay-client.js +104 -17
- package/server/routes/agent.js +54 -19
- package/server/routes/auth.js +23 -12
- 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.js
CHANGED
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
* Visual AI coding interface with Upfyn-Canvas for AI coding assistants
|
|
7
7
|
*
|
|
8
8
|
* Commands:
|
|
9
|
-
* (no args) -
|
|
9
|
+
* (no args) - Launch Claude Code with Upfyn branding (default)
|
|
10
10
|
* start - Start the server
|
|
11
11
|
* connect - Connect to hosted server (relay bridge)
|
|
12
|
+
* config - View/set configuration (API key, server, etc.)
|
|
12
13
|
* status - Show configuration and data locations
|
|
13
14
|
* help - Show help information
|
|
14
15
|
* version - Show version information
|
|
@@ -19,6 +20,7 @@ import path from 'path';
|
|
|
19
20
|
import os from 'os';
|
|
20
21
|
import { fileURLToPath } from 'url';
|
|
21
22
|
import { dirname } from 'path';
|
|
23
|
+
import { execSync, spawn } from 'child_process';
|
|
22
24
|
import {
|
|
23
25
|
c,
|
|
24
26
|
showStyledHelp,
|
|
@@ -26,8 +28,12 @@ import {
|
|
|
26
28
|
showServerBanner,
|
|
27
29
|
showConnectStartup,
|
|
28
30
|
showConnectionBanner,
|
|
31
|
+
showLaunchScreen,
|
|
32
|
+
showConfig,
|
|
29
33
|
logRelayEvent,
|
|
30
34
|
createSpinner,
|
|
35
|
+
playRocketAnimation,
|
|
36
|
+
clearScreen,
|
|
31
37
|
} from './cli-ui.js';
|
|
32
38
|
|
|
33
39
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -37,6 +43,9 @@ const __dirname = dirname(__filename);
|
|
|
37
43
|
const packageJsonPath = path.join(__dirname, '../package.json');
|
|
38
44
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
39
45
|
|
|
46
|
+
const CONFIG_DIR = path.join(os.homedir(), '.upfynai');
|
|
47
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
48
|
+
|
|
40
49
|
// Load environment variables from .env file if it exists
|
|
41
50
|
function loadEnvFile() {
|
|
42
51
|
try {
|
|
@@ -56,6 +65,26 @@ function loadEnvFile() {
|
|
|
56
65
|
}
|
|
57
66
|
}
|
|
58
67
|
|
|
68
|
+
// Load saved config from ~/.upfynai/config.json
|
|
69
|
+
function loadConfig() {
|
|
70
|
+
try {
|
|
71
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
72
|
+
return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
|
73
|
+
}
|
|
74
|
+
} catch (e) { /* ignore */ }
|
|
75
|
+
return {};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Save config to ~/.upfynai/config.json
|
|
79
|
+
function saveConfig(config) {
|
|
80
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
81
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
82
|
+
}
|
|
83
|
+
// Don't save internal keys
|
|
84
|
+
const { _path, ...rest } = config;
|
|
85
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(rest, null, 2));
|
|
86
|
+
}
|
|
87
|
+
|
|
59
88
|
// Get the database path (same logic as db.js)
|
|
60
89
|
function getDatabasePath() {
|
|
61
90
|
loadEnvFile();
|
|
@@ -67,8 +96,29 @@ function getInstallDir() {
|
|
|
67
96
|
return path.join(__dirname, '..');
|
|
68
97
|
}
|
|
69
98
|
|
|
70
|
-
//
|
|
99
|
+
// --- OS Detection + Claude Binary Discovery ---
|
|
100
|
+
|
|
101
|
+
function findClaudeBinary() {
|
|
102
|
+
const isWindows = process.platform === 'win32';
|
|
103
|
+
const candidates = isWindows
|
|
104
|
+
? ['claude.exe', 'claude.cmd', 'claude']
|
|
105
|
+
: ['claude'];
|
|
106
|
+
|
|
107
|
+
for (const cmd of candidates) {
|
|
108
|
+
try {
|
|
109
|
+
const whichCmd = isWindows ? 'where' : 'which';
|
|
110
|
+
const result = execSync(`${whichCmd} ${cmd}`, { stdio: 'pipe', encoding: 'utf8' }).trim();
|
|
111
|
+
if (result) return cmd;
|
|
112
|
+
} catch {
|
|
113
|
+
// not found, try next
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// --- Show status command ---
|
|
71
120
|
function showStatus() {
|
|
121
|
+
const config = loadConfig();
|
|
72
122
|
const installDir = getInstallDir();
|
|
73
123
|
const dbPath = getDatabasePath();
|
|
74
124
|
const dbExists = fs.existsSync(dbPath);
|
|
@@ -86,11 +136,12 @@ function showStatus() {
|
|
|
86
136
|
dbSize,
|
|
87
137
|
port: process.env.PORT || '3001',
|
|
88
138
|
portDefault: !process.env.PORT,
|
|
89
|
-
claudeCli:
|
|
139
|
+
claudeCli: findClaudeBinary() || null,
|
|
140
|
+
apiKey: config.anthropicApiKey || null,
|
|
90
141
|
});
|
|
91
142
|
}
|
|
92
143
|
|
|
93
|
-
// Show help
|
|
144
|
+
// Show help
|
|
94
145
|
function showHelp() {
|
|
95
146
|
showStyledHelp(packageJson.version);
|
|
96
147
|
}
|
|
@@ -114,18 +165,17 @@ function isNewerVersion(v1, v2) {
|
|
|
114
165
|
// Check for updates
|
|
115
166
|
async function checkForUpdates(silent = false) {
|
|
116
167
|
try {
|
|
117
|
-
const { execSync } = await import('child_process');
|
|
118
168
|
const latestVersion = execSync('npm show upfynai-code version', { encoding: 'utf8' }).trim();
|
|
119
169
|
const currentVersion = packageJson.version;
|
|
120
170
|
|
|
121
171
|
if (isNewerVersion(latestVersion, currentVersion)) {
|
|
122
172
|
if (!silent) {
|
|
123
|
-
console.log(`\n ${c.yellow('
|
|
173
|
+
console.log(`\n ${c.yellow('!')} New version available: ${c.bBright(latestVersion)} ${c.dim(`(current: ${currentVersion})`)}`);
|
|
124
174
|
console.log(` Run ${c.bright('uc update')} to update\n`);
|
|
125
175
|
}
|
|
126
176
|
return { hasUpdate: true, latestVersion, currentVersion };
|
|
127
177
|
} else if (!silent) {
|
|
128
|
-
console.log(` ${c.green('
|
|
178
|
+
console.log(` ${c.green('OK')} You are on the latest version (${currentVersion})`);
|
|
129
179
|
}
|
|
130
180
|
return { hasUpdate: false, latestVersion, currentVersion };
|
|
131
181
|
} catch (e) {
|
|
@@ -139,7 +189,6 @@ async function checkForUpdates(silent = false) {
|
|
|
139
189
|
// Update the package
|
|
140
190
|
async function updatePackage() {
|
|
141
191
|
try {
|
|
142
|
-
const { execSync } = await import('child_process');
|
|
143
192
|
const spinner = createSpinner('Checking for updates...');
|
|
144
193
|
spinner.start();
|
|
145
194
|
|
|
@@ -148,20 +197,20 @@ async function updatePackage() {
|
|
|
148
197
|
spinner.stop(`Already on the latest version (${currentVersion})`);
|
|
149
198
|
return;
|
|
150
199
|
}
|
|
151
|
-
spinner.stop(`Update available: ${currentVersion}
|
|
200
|
+
spinner.stop(`Update available: ${currentVersion} -> ${latestVersion}`);
|
|
152
201
|
|
|
153
202
|
const installSpinner = createSpinner(`Updating to v${latestVersion}...`);
|
|
154
203
|
installSpinner.start();
|
|
155
204
|
execSync('npm update -g upfynai-code', { stdio: 'pipe' });
|
|
156
205
|
installSpinner.stop(`Updated to v${latestVersion}! Restart uc to use the new version.`);
|
|
157
206
|
} catch (e) {
|
|
158
|
-
console.log(` ${c.red('
|
|
207
|
+
console.log(` ${c.red('FAIL')} Update failed: ${e.message}`);
|
|
159
208
|
console.log(` ${c.dim('Try running manually:')} ${c.bright('npm update -g upfynai-code')}`);
|
|
160
209
|
}
|
|
161
210
|
}
|
|
162
211
|
|
|
163
212
|
// Install slash commands to ~/.claude/commands/
|
|
164
|
-
async function installCommands() {
|
|
213
|
+
async function installCommands(silent = false) {
|
|
165
214
|
const commandsSource = path.join(__dirname, '..', 'commands');
|
|
166
215
|
const commandsDest = path.join(os.homedir(), '.claude', 'commands');
|
|
167
216
|
|
|
@@ -170,8 +219,8 @@ async function installCommands() {
|
|
|
170
219
|
}
|
|
171
220
|
|
|
172
221
|
if (!fs.existsSync(commandsSource)) {
|
|
173
|
-
console.log(` ${c.red('
|
|
174
|
-
|
|
222
|
+
if (!silent) console.log(` ${c.red('FAIL')} Commands directory not found`);
|
|
223
|
+
return 0;
|
|
175
224
|
}
|
|
176
225
|
|
|
177
226
|
const files = fs.readdirSync(commandsSource).filter(f => f.endsWith('.md'));
|
|
@@ -182,12 +231,17 @@ async function installCommands() {
|
|
|
182
231
|
path.join(commandsSource, file),
|
|
183
232
|
path.join(commandsDest, file)
|
|
184
233
|
);
|
|
185
|
-
|
|
234
|
+
if (!silent) {
|
|
235
|
+
console.log(` ${c.green('OK')} Installed ${c.violet('/' + file.replace('.md', ''))}`);
|
|
236
|
+
}
|
|
186
237
|
count++;
|
|
187
238
|
}
|
|
188
239
|
|
|
189
|
-
|
|
190
|
-
|
|
240
|
+
if (!silent) {
|
|
241
|
+
console.log(`\n ${c.bBright(`${count} slash commands installed!`)}`);
|
|
242
|
+
console.log(` ${c.dim('Available in your AI CLI as /upfynai-*')}\n`);
|
|
243
|
+
}
|
|
244
|
+
return count;
|
|
191
245
|
}
|
|
192
246
|
|
|
193
247
|
// Remove slash commands from ~/.claude/commands/
|
|
@@ -204,12 +258,114 @@ async function uninstallCommands() {
|
|
|
204
258
|
|
|
205
259
|
for (const file of files) {
|
|
206
260
|
fs.unlinkSync(path.join(commandsDest, file));
|
|
207
|
-
console.log(` ${c.green('
|
|
261
|
+
console.log(` ${c.green('OK')} Removed ${c.violet('/' + file.replace('.md', ''))}`);
|
|
208
262
|
}
|
|
209
263
|
|
|
210
264
|
console.log(`\n ${c.bBright(`${files.length} slash commands removed.`)}\n`);
|
|
211
265
|
}
|
|
212
266
|
|
|
267
|
+
// --- Config command ---
|
|
268
|
+
function handleConfig(options) {
|
|
269
|
+
const config = loadConfig();
|
|
270
|
+
|
|
271
|
+
if (options.apiKey) {
|
|
272
|
+
// Set API key
|
|
273
|
+
config.anthropicApiKey = options.apiKey;
|
|
274
|
+
saveConfig(config);
|
|
275
|
+
console.log(`\n ${c.green('OK')} ${c.white('Anthropic API key saved')}`);
|
|
276
|
+
console.log(` ${c.dim('Key:')} sk-ant-...${options.apiKey.slice(-4)}`);
|
|
277
|
+
console.log(` ${c.dim('Stored in:')} ${CONFIG_FILE}\n`);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (options.clearApiKey) {
|
|
282
|
+
delete config.anthropicApiKey;
|
|
283
|
+
saveConfig(config);
|
|
284
|
+
console.log(`\n ${c.green('OK')} ${c.white('Anthropic API key removed')}\n`);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Show current config
|
|
289
|
+
showConfig({ ...config, _path: CONFIG_FILE });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// --- Launch Interactive (default command) ---
|
|
293
|
+
async function launchInteractive() {
|
|
294
|
+
// 1. Play rocket animation
|
|
295
|
+
await playRocketAnimation();
|
|
296
|
+
clearScreen();
|
|
297
|
+
|
|
298
|
+
// 2. Ensure slash commands are installed (silent)
|
|
299
|
+
await installCommands(true);
|
|
300
|
+
|
|
301
|
+
// 3. Find Claude Code binary
|
|
302
|
+
const claudeBin = findClaudeBinary();
|
|
303
|
+
|
|
304
|
+
// 4. Load config for relay + API key
|
|
305
|
+
const config = loadConfig();
|
|
306
|
+
|
|
307
|
+
// 5. Show launch screen
|
|
308
|
+
showLaunchScreen(packageJson.version, claudeBin, {
|
|
309
|
+
relayStatus: config.relayKey && config.server
|
|
310
|
+
? `Auto-connecting to ${config.server}`
|
|
311
|
+
: null,
|
|
312
|
+
apiKey: config.anthropicApiKey || null,
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// 6. If Claude Code not found, fall back to server mode
|
|
316
|
+
if (!claudeBin) {
|
|
317
|
+
console.log(` ${c.dim('Falling back to server mode...')}\n`);
|
|
318
|
+
await startServer();
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// 7. Build environment for Claude Code
|
|
323
|
+
const childEnv = { ...process.env };
|
|
324
|
+
if (config.anthropicApiKey) {
|
|
325
|
+
childEnv.ANTHROPIC_API_KEY = config.anthropicApiKey;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// 8. Start background relay if config exists
|
|
329
|
+
if (config.relayKey && config.server) {
|
|
330
|
+
startBackgroundRelay(config);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// 9. Spawn Claude Code interactively
|
|
334
|
+
const child = spawn(claudeBin, [], {
|
|
335
|
+
stdio: 'inherit',
|
|
336
|
+
cwd: process.cwd(),
|
|
337
|
+
shell: true,
|
|
338
|
+
env: childEnv,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
child.on('exit', (code) => {
|
|
342
|
+
process.exit(code || 0);
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
child.on('error', (err) => {
|
|
346
|
+
console.log(`\n ${c.red('FAIL')} Failed to launch Claude Code: ${err.message}`);
|
|
347
|
+
console.log(` ${c.dim('Make sure Claude Code is installed:')}`);
|
|
348
|
+
console.log(` ${c.bright('npm install -g @anthropic-ai/claude-code')}\n`);
|
|
349
|
+
process.exit(1);
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// --- Background relay connection ---
|
|
354
|
+
function startBackgroundRelay(config) {
|
|
355
|
+
// Import and start relay in background (non-blocking)
|
|
356
|
+
import('./relay-client.js').then(({ connectToServerBackground }) => {
|
|
357
|
+
if (typeof connectToServerBackground === 'function') {
|
|
358
|
+
connectToServerBackground({
|
|
359
|
+
server: config.server,
|
|
360
|
+
key: config.relayKey,
|
|
361
|
+
silent: true,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}).catch(() => {
|
|
365
|
+
// Relay module not available or no background connect — that's ok
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
213
369
|
// Start the server
|
|
214
370
|
async function startServer() {
|
|
215
371
|
// Check for updates silently on startup
|
|
@@ -225,7 +381,7 @@ async function startServer() {
|
|
|
225
381
|
|
|
226
382
|
// Parse CLI arguments
|
|
227
383
|
function parseArgs(args) {
|
|
228
|
-
const parsed = { command:
|
|
384
|
+
const parsed = { command: null, options: {} };
|
|
229
385
|
|
|
230
386
|
for (let i = 0; i < args.length; i++) {
|
|
231
387
|
const arg = args[i];
|
|
@@ -246,15 +402,26 @@ function parseArgs(args) {
|
|
|
246
402
|
parsed.options.key = args[++i];
|
|
247
403
|
} else if (arg.startsWith('--key=')) {
|
|
248
404
|
parsed.options.key = arg.split('=')[1];
|
|
405
|
+
} else if (arg === '--api-key') {
|
|
406
|
+
parsed.options.apiKey = args[++i];
|
|
407
|
+
} else if (arg.startsWith('--api-key=')) {
|
|
408
|
+
parsed.options.apiKey = arg.split('=')[1];
|
|
409
|
+
} else if (arg === '--clear-api-key') {
|
|
410
|
+
parsed.options.clearApiKey = true;
|
|
249
411
|
} else if (arg === '--help' || arg === '-h') {
|
|
250
412
|
parsed.command = 'help';
|
|
251
413
|
} else if (arg === '--version' || arg === '-v') {
|
|
252
414
|
parsed.command = 'version';
|
|
253
|
-
} else if (!arg.startsWith('-')) {
|
|
415
|
+
} else if (!arg.startsWith('-') && !parsed.command) {
|
|
254
416
|
parsed.command = arg;
|
|
255
417
|
}
|
|
256
418
|
}
|
|
257
419
|
|
|
420
|
+
// Default command: launch interactive
|
|
421
|
+
if (!parsed.command) {
|
|
422
|
+
parsed.command = 'launch';
|
|
423
|
+
}
|
|
424
|
+
|
|
258
425
|
return parsed;
|
|
259
426
|
}
|
|
260
427
|
|
|
@@ -272,6 +439,9 @@ async function main() {
|
|
|
272
439
|
}
|
|
273
440
|
|
|
274
441
|
switch (command) {
|
|
442
|
+
case 'launch':
|
|
443
|
+
await launchInteractive();
|
|
444
|
+
break;
|
|
275
445
|
case 'start':
|
|
276
446
|
await startServer();
|
|
277
447
|
break;
|
|
@@ -292,6 +462,9 @@ async function main() {
|
|
|
292
462
|
case 'update':
|
|
293
463
|
await updatePackage();
|
|
294
464
|
break;
|
|
465
|
+
case 'config':
|
|
466
|
+
handleConfig(options);
|
|
467
|
+
break;
|
|
295
468
|
case 'install-commands':
|
|
296
469
|
await installCommands();
|
|
297
470
|
break;
|
|
@@ -307,7 +480,7 @@ async function main() {
|
|
|
307
480
|
break;
|
|
308
481
|
}
|
|
309
482
|
default:
|
|
310
|
-
console.error(`\n ${c.red('
|
|
483
|
+
console.error(`\n ${c.red('FAIL')} Unknown command: ${command}`);
|
|
311
484
|
console.log(` Run ${c.bright('"uc help"')} for usage information.\n`);
|
|
312
485
|
process.exit(1);
|
|
313
486
|
}
|
|
@@ -315,6 +488,6 @@ async function main() {
|
|
|
315
488
|
|
|
316
489
|
// Run the CLI
|
|
317
490
|
main().catch(error => {
|
|
318
|
-
console.error(`\n ${c.red('
|
|
491
|
+
console.error(`\n ${c.red('FAIL')} Error: ${error.message}`);
|
|
319
492
|
process.exit(1);
|
|
320
493
|
});
|