upfynai-code 2.7.1 → 2.7.3
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 +166 -166
- package/bin/cli.js +91 -91
- package/package.json +1 -1
- package/src/auth.js +122 -122
- package/src/config.js +40 -40
- package/src/connect.js +766 -758
- package/src/launch.js +54 -54
- package/src/mcp.js +57 -57
- package/src/server.js +54 -54
package/src/auth.js
CHANGED
|
@@ -1,122 +1,122 @@
|
|
|
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)}!\n`));
|
|
89
|
-
} catch (err) {
|
|
90
|
-
const config = readConfig();
|
|
91
|
-
console.log(chalk.red(`\n Connection error. Could not reach ${displayUrl(config.serverUrl)}.`));
|
|
92
|
-
console.log(chalk.dim(' Check your network and try again.\n'));
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export async function logout() {
|
|
98
|
-
clearConfig();
|
|
99
|
-
console.log(chalk.green('\n Logged out. Credentials cleared.\n'));
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export async function status() {
|
|
103
|
-
const config = readConfig();
|
|
104
|
-
|
|
105
|
-
if (!config.token) {
|
|
106
|
-
console.log(chalk.yellow('\n Not logged in. Run `uc login` to authenticate.\n'));
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
console.log(chalk.dim('\n Checking session...'));
|
|
111
|
-
const user = await validateToken();
|
|
112
|
-
|
|
113
|
-
if (!user) {
|
|
114
|
-
console.log(chalk.yellow(' Session expired. Run `uc login` to re-authenticate.\n'));
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const name = user.first_name || user.username;
|
|
119
|
-
console.log(chalk.bold(` Logged in as: ${chalk.cyan(name)} (${chalk.dim(user.username)})`));
|
|
120
|
-
console.log(chalk.dim(` Server: ${displayUrl(config.serverUrl)}`));
|
|
121
|
-
console.log(chalk.dim(` Local port: ${config.localPort}\n`));
|
|
122
|
-
}
|
|
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)}!\n`));
|
|
89
|
+
} catch (err) {
|
|
90
|
+
const config = readConfig();
|
|
91
|
+
console.log(chalk.red(`\n Connection error. Could not reach ${displayUrl(config.serverUrl)}.`));
|
|
92
|
+
console.log(chalk.dim(' Check your network and try again.\n'));
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export async function logout() {
|
|
98
|
+
clearConfig();
|
|
99
|
+
console.log(chalk.green('\n Logged out. Credentials cleared.\n'));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export async function status() {
|
|
103
|
+
const config = readConfig();
|
|
104
|
+
|
|
105
|
+
if (!config.token) {
|
|
106
|
+
console.log(chalk.yellow('\n Not logged in. Run `uc login` to authenticate.\n'));
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
console.log(chalk.dim('\n Checking session...'));
|
|
111
|
+
const user = await validateToken();
|
|
112
|
+
|
|
113
|
+
if (!user) {
|
|
114
|
+
console.log(chalk.yellow(' Session expired. Run `uc login` to re-authenticate.\n'));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const name = user.first_name || user.username;
|
|
119
|
+
console.log(chalk.bold(` Logged in as: ${chalk.cyan(name)} (${chalk.dim(user.username)})`));
|
|
120
|
+
console.log(chalk.dim(` Server: ${displayUrl(config.serverUrl)}`));
|
|
121
|
+
console.log(chalk.dim(` Local port: ${config.localPort}\n`));
|
|
122
|
+
}
|
package/src/config.js
CHANGED
|
@@ -1,40 +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 };
|
|
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 };
|