upfynai-code 2.7.0 → 2.7.2
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 +768 -695
- package/src/launch.js +54 -54
- package/src/mcp.js +57 -57
- package/src/server.js +54 -54
package/src/launch.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import open from 'open';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { readConfig } from './config.js';
|
|
4
|
-
import { getToken, validateToken } from './auth.js';
|
|
5
|
-
import { startServer } from './server.js';
|
|
6
|
-
|
|
7
|
-
export async function openHosted() {
|
|
8
|
-
const token = getToken();
|
|
9
|
-
|
|
10
|
-
if (!token) {
|
|
11
|
-
console.log(chalk.yellow('\n No account found. Run `uc login` first.\n'));
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
console.log(chalk.dim('\n Validating session...'));
|
|
16
|
-
const user = await validateToken();
|
|
17
|
-
|
|
18
|
-
if (!user) {
|
|
19
|
-
console.log(chalk.yellow(' Session expired. Run `uc login` to re-authenticate.\n'));
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const config = readConfig();
|
|
24
|
-
const url = `${config.serverUrl}?token=${encodeURIComponent(token)}`;
|
|
25
|
-
|
|
26
|
-
const name = user.first_name || user.username;
|
|
27
|
-
console.log(chalk.green(` Welcome back, ${chalk.bold(name)}!`));
|
|
28
|
-
console.log(chalk.dim(' Opening Upfyn-Code in your browser...\n'));
|
|
29
|
-
|
|
30
|
-
await open(url);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export async function startLocal() {
|
|
34
|
-
const token = getToken();
|
|
35
|
-
|
|
36
|
-
if (!token) {
|
|
37
|
-
console.log(chalk.yellow('\n No account found. Run `uc login` first.\n'));
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
console.log(chalk.dim('\n Validating session...'));
|
|
42
|
-
const user = await validateToken();
|
|
43
|
-
|
|
44
|
-
if (!user) {
|
|
45
|
-
console.log(chalk.yellow(' Session expired. Run `uc login` to re-authenticate.\n'));
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const config = readConfig();
|
|
50
|
-
const name = user.first_name || user.username;
|
|
51
|
-
console.log(chalk.green(` Welcome back, ${chalk.bold(name)}!`));
|
|
52
|
-
|
|
53
|
-
await startServer(config.localPort, config.serverUrl, token);
|
|
54
|
-
}
|
|
1
|
+
import open from 'open';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { readConfig } from './config.js';
|
|
4
|
+
import { getToken, validateToken } from './auth.js';
|
|
5
|
+
import { startServer } from './server.js';
|
|
6
|
+
|
|
7
|
+
export async function openHosted() {
|
|
8
|
+
const token = getToken();
|
|
9
|
+
|
|
10
|
+
if (!token) {
|
|
11
|
+
console.log(chalk.yellow('\n No account found. Run `uc login` first.\n'));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log(chalk.dim('\n Validating session...'));
|
|
16
|
+
const user = await validateToken();
|
|
17
|
+
|
|
18
|
+
if (!user) {
|
|
19
|
+
console.log(chalk.yellow(' Session expired. Run `uc login` to re-authenticate.\n'));
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const config = readConfig();
|
|
24
|
+
const url = `${config.serverUrl}?token=${encodeURIComponent(token)}`;
|
|
25
|
+
|
|
26
|
+
const name = user.first_name || user.username;
|
|
27
|
+
console.log(chalk.green(` Welcome back, ${chalk.bold(name)}!`));
|
|
28
|
+
console.log(chalk.dim(' Opening Upfyn-Code in your browser...\n'));
|
|
29
|
+
|
|
30
|
+
await open(url);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function startLocal() {
|
|
34
|
+
const token = getToken();
|
|
35
|
+
|
|
36
|
+
if (!token) {
|
|
37
|
+
console.log(chalk.yellow('\n No account found. Run `uc login` first.\n'));
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log(chalk.dim('\n Validating session...'));
|
|
42
|
+
const user = await validateToken();
|
|
43
|
+
|
|
44
|
+
if (!user) {
|
|
45
|
+
console.log(chalk.yellow(' Session expired. Run `uc login` to re-authenticate.\n'));
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const config = readConfig();
|
|
50
|
+
const name = user.first_name || user.username;
|
|
51
|
+
console.log(chalk.green(` Welcome back, ${chalk.bold(name)}!`));
|
|
52
|
+
|
|
53
|
+
await startServer(config.localPort, config.serverUrl, token);
|
|
54
|
+
}
|
package/src/mcp.js
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { readConfig } from './config.js';
|
|
3
|
-
import { getToken, validateToken } from './auth.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Print MCP configuration for Claude / Cursor / other AI tools.
|
|
7
|
-
* Optionally accepts --server and --key overrides.
|
|
8
|
-
*/
|
|
9
|
-
export async function mcp(options = {}) {
|
|
10
|
-
const config = readConfig();
|
|
11
|
-
const serverUrl = options.server || config.serverUrl;
|
|
12
|
-
let relayKey = options.key;
|
|
13
|
-
|
|
14
|
-
// If no key provided, fetch one using auth token
|
|
15
|
-
if (!relayKey) {
|
|
16
|
-
const token = getToken();
|
|
17
|
-
if (!token) {
|
|
18
|
-
console.log(chalk.yellow('\n No account found. Run `uc login` first.\n'));
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const user = await validateToken();
|
|
23
|
-
if (!user) {
|
|
24
|
-
console.log(chalk.yellow('\n Session expired. Run `uc login` to re-authenticate.\n'));
|
|
25
|
-
process.exit(1);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
const res = await fetch(`${serverUrl}/api/auth/connect-token`, {
|
|
30
|
-
headers: { Authorization: `Bearer ${token}` },
|
|
31
|
-
});
|
|
32
|
-
if (!res.ok) throw new Error('Failed to get connect token');
|
|
33
|
-
const data = await res.json();
|
|
34
|
-
relayKey = data.token;
|
|
35
|
-
} catch (err) {
|
|
36
|
-
console.log(chalk.red('\n Could not get connection token. Check your network and try again.\n'));
|
|
37
|
-
process.exit(1);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const mcpConfig = {
|
|
42
|
-
mcpServers: {
|
|
43
|
-
'upfynai-code': {
|
|
44
|
-
url: `${serverUrl}/mcp`,
|
|
45
|
-
headers: {
|
|
46
|
-
Authorization: `Bearer ${relayKey}`,
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
console.log(chalk.bold('\n Upfyn-Code — MCP Integration\n'));
|
|
53
|
-
console.log(chalk.dim(' Add this to your Claude / Cursor MCP settings:\n'));
|
|
54
|
-
console.log(chalk.white(JSON.stringify(mcpConfig, null, 2)));
|
|
55
|
-
console.log('');
|
|
56
|
-
console.log(chalk.dim(' The JSON above contains your MCP URL and authorization header.\n'));
|
|
57
|
-
}
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { readConfig } from './config.js';
|
|
3
|
+
import { getToken, validateToken } from './auth.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Print MCP configuration for Claude / Cursor / other AI tools.
|
|
7
|
+
* Optionally accepts --server and --key overrides.
|
|
8
|
+
*/
|
|
9
|
+
export async function mcp(options = {}) {
|
|
10
|
+
const config = readConfig();
|
|
11
|
+
const serverUrl = options.server || config.serverUrl;
|
|
12
|
+
let relayKey = options.key;
|
|
13
|
+
|
|
14
|
+
// If no key provided, fetch one using auth token
|
|
15
|
+
if (!relayKey) {
|
|
16
|
+
const token = getToken();
|
|
17
|
+
if (!token) {
|
|
18
|
+
console.log(chalk.yellow('\n No account found. Run `uc login` first.\n'));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const user = await validateToken();
|
|
23
|
+
if (!user) {
|
|
24
|
+
console.log(chalk.yellow('\n Session expired. Run `uc login` to re-authenticate.\n'));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const res = await fetch(`${serverUrl}/api/auth/connect-token`, {
|
|
30
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
31
|
+
});
|
|
32
|
+
if (!res.ok) throw new Error('Failed to get connect token');
|
|
33
|
+
const data = await res.json();
|
|
34
|
+
relayKey = data.token;
|
|
35
|
+
} catch (err) {
|
|
36
|
+
console.log(chalk.red('\n Could not get connection token. Check your network and try again.\n'));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const mcpConfig = {
|
|
42
|
+
mcpServers: {
|
|
43
|
+
'upfynai-code': {
|
|
44
|
+
url: `${serverUrl}/mcp`,
|
|
45
|
+
headers: {
|
|
46
|
+
Authorization: `Bearer ${relayKey}`,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
console.log(chalk.bold('\n Upfyn-Code — MCP Integration\n'));
|
|
53
|
+
console.log(chalk.dim(' Add this to your Claude / Cursor MCP settings:\n'));
|
|
54
|
+
console.log(chalk.white(JSON.stringify(mcpConfig, null, 2)));
|
|
55
|
+
console.log('');
|
|
56
|
+
console.log(chalk.dim(' The JSON above contains your MCP URL and authorization header.\n'));
|
|
57
|
+
}
|
package/src/server.js
CHANGED
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import { fileURLToPath } from 'url';
|
|
2
|
-
import { dirname, join } from 'path';
|
|
3
|
-
import { existsSync } from 'fs';
|
|
4
|
-
import express from 'express';
|
|
5
|
-
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
6
|
-
import open from 'open';
|
|
7
|
-
import chalk from 'chalk';
|
|
8
|
-
|
|
9
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
-
const DIST_DIR = join(__dirname, '..', 'dist');
|
|
11
|
-
|
|
12
|
-
export async function startServer(port, serverUrl, token) {
|
|
13
|
-
if (!existsSync(DIST_DIR)) {
|
|
14
|
-
console.log(chalk.red('\n Error: No built frontend found at dist/.'));
|
|
15
|
-
console.log(chalk.dim(' Run the build-frontend script first, or use the default mode (no --local flag).\n'));
|
|
16
|
-
process.exit(1);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const app = express();
|
|
20
|
-
|
|
21
|
-
// Proxy API calls to the remote Vercel backend
|
|
22
|
-
app.use('/api', createProxyMiddleware({
|
|
23
|
-
target: serverUrl,
|
|
24
|
-
changeOrigin: true,
|
|
25
|
-
headers: {
|
|
26
|
-
Authorization: `Bearer ${token}`,
|
|
27
|
-
},
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
|
-
// Serve the built React frontend
|
|
31
|
-
app.use(express.static(DIST_DIR));
|
|
32
|
-
|
|
33
|
-
// SPA fallback — serve index.html for all non-API, non-static routes
|
|
34
|
-
app.get('*', (req, res) => {
|
|
35
|
-
res.sendFile(join(DIST_DIR, 'index.html'));
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
return new Promise((resolve) => {
|
|
39
|
-
const server = app.listen(port, async () => {
|
|
40
|
-
const url = `http://localhost:${port}?token=${encodeURIComponent(token)}`;
|
|
41
|
-
console.log(chalk.green(`\n Local server running at ${chalk.bold(`http://localhost:${port}`)}`));
|
|
42
|
-
console.log(chalk.dim(' API proxy active. Press Ctrl+C to stop.\n'));
|
|
43
|
-
await open(url);
|
|
44
|
-
resolve(server);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const shutdown = () => {
|
|
48
|
-
console.log(chalk.dim('\n Shutting down...'));
|
|
49
|
-
server.close(() => process.exit(0));
|
|
50
|
-
};
|
|
51
|
-
process.on('SIGINT', shutdown);
|
|
52
|
-
process.on('SIGTERM', shutdown);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
1
|
+
import { fileURLToPath } from 'url';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import express from 'express';
|
|
5
|
+
import { createProxyMiddleware } from 'http-proxy-middleware';
|
|
6
|
+
import open from 'open';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
|
|
9
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const DIST_DIR = join(__dirname, '..', 'dist');
|
|
11
|
+
|
|
12
|
+
export async function startServer(port, serverUrl, token) {
|
|
13
|
+
if (!existsSync(DIST_DIR)) {
|
|
14
|
+
console.log(chalk.red('\n Error: No built frontend found at dist/.'));
|
|
15
|
+
console.log(chalk.dim(' Run the build-frontend script first, or use the default mode (no --local flag).\n'));
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const app = express();
|
|
20
|
+
|
|
21
|
+
// Proxy API calls to the remote Vercel backend
|
|
22
|
+
app.use('/api', createProxyMiddleware({
|
|
23
|
+
target: serverUrl,
|
|
24
|
+
changeOrigin: true,
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: `Bearer ${token}`,
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
// Serve the built React frontend
|
|
31
|
+
app.use(express.static(DIST_DIR));
|
|
32
|
+
|
|
33
|
+
// SPA fallback — serve index.html for all non-API, non-static routes
|
|
34
|
+
app.get('*', (req, res) => {
|
|
35
|
+
res.sendFile(join(DIST_DIR, 'index.html'));
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
const server = app.listen(port, async () => {
|
|
40
|
+
const url = `http://localhost:${port}?token=${encodeURIComponent(token)}`;
|
|
41
|
+
console.log(chalk.green(`\n Local server running at ${chalk.bold(`http://localhost:${port}`)}`));
|
|
42
|
+
console.log(chalk.dim(' API proxy active. Press Ctrl+C to stop.\n'));
|
|
43
|
+
await open(url);
|
|
44
|
+
resolve(server);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const shutdown = () => {
|
|
48
|
+
console.log(chalk.dim('\n Shutting down...'));
|
|
49
|
+
server.close(() => process.exit(0));
|
|
50
|
+
};
|
|
51
|
+
process.on('SIGINT', shutdown);
|
|
52
|
+
process.on('SIGTERM', shutdown);
|
|
53
|
+
});
|
|
54
|
+
}
|