cloud-pc-templates 1.0.2 → 1.1.1
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/handlers/ollamacloud.js +152 -0
- package/index.js +10 -6
- package/package.json +1 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
const http = require('http');
|
|
2
|
+
const https = require('https');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { spawn } = require('child_process');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
|
|
8
|
+
// Function to get masked API key input
|
|
9
|
+
function promptForApiKey() {
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
process.stdout.write('Enter API Key: ');
|
|
12
|
+
|
|
13
|
+
const stdin = process.stdin;
|
|
14
|
+
|
|
15
|
+
// Handle both TTY and non-TTY environments
|
|
16
|
+
if (stdin.isTTY) {
|
|
17
|
+
stdin.setRawMode(true);
|
|
18
|
+
}
|
|
19
|
+
stdin.resume();
|
|
20
|
+
|
|
21
|
+
let apiKey = '';
|
|
22
|
+
|
|
23
|
+
stdin.on('data', (buffer) => {
|
|
24
|
+
const chunk = buffer.toString();
|
|
25
|
+
|
|
26
|
+
// Process each character in the chunk (handles pasted text)
|
|
27
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
28
|
+
const char = chunk[i];
|
|
29
|
+
|
|
30
|
+
if (char === '\n' || char === '\r' || char === '\u0004') {
|
|
31
|
+
// Enter or EOF
|
|
32
|
+
if (stdin.isTTY) {
|
|
33
|
+
stdin.setRawMode(false);
|
|
34
|
+
}
|
|
35
|
+
stdin.pause();
|
|
36
|
+
stdin.removeAllListeners('data');
|
|
37
|
+
console.log('');
|
|
38
|
+
resolve(apiKey);
|
|
39
|
+
return;
|
|
40
|
+
} else if (char === '\u0003') {
|
|
41
|
+
// Ctrl+C
|
|
42
|
+
if (stdin.isTTY) {
|
|
43
|
+
stdin.setRawMode(false);
|
|
44
|
+
}
|
|
45
|
+
process.exit();
|
|
46
|
+
} else if (char === '\x7f' || char === '\b') {
|
|
47
|
+
// Backspace
|
|
48
|
+
if (apiKey.length > 0) {
|
|
49
|
+
apiKey = apiKey.slice(0, -1);
|
|
50
|
+
process.stdout.write('\x1b[D\x1b[K');
|
|
51
|
+
}
|
|
52
|
+
} else if (char >= '\x20' && char <= '\x7e') {
|
|
53
|
+
// Printable character
|
|
54
|
+
apiKey += char;
|
|
55
|
+
process.stdout.write('*');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Function to check health endpoint
|
|
63
|
+
function checkHealthEndpoint(endpoint) {
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
const url = new URL(endpoint);
|
|
66
|
+
const protocol = url.protocol === 'https:' ? https : http;
|
|
67
|
+
|
|
68
|
+
const request = protocol.request(url, { method: 'GET' }, (res) => {
|
|
69
|
+
resolve(res.statusCode === 200);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
request.on('error', () => {
|
|
73
|
+
resolve(false);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
request.end();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Function to download and run the proxy
|
|
81
|
+
async function downloadAndRunProxy(endpoint) {
|
|
82
|
+
const url = 'https://raw.githubusercontent.com/devashish234073/cloud-pc-templates-marketplace/refs/heads/main/JS-PROXIES/ollama-proxy.js';
|
|
83
|
+
const tempFile = path.join(os.tmpdir(), 'ollama-proxy.js');
|
|
84
|
+
|
|
85
|
+
// Download the file
|
|
86
|
+
await new Promise((resolve, reject) => {
|
|
87
|
+
const file = fs.createWriteStream(tempFile);
|
|
88
|
+
https.get(url, (res) => {
|
|
89
|
+
res.pipe(file);
|
|
90
|
+
file.on('finish', () => {
|
|
91
|
+
file.close();
|
|
92
|
+
resolve();
|
|
93
|
+
});
|
|
94
|
+
}).on('error', reject);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Get API key from user
|
|
98
|
+
const apiKey = await promptForApiKey();
|
|
99
|
+
|
|
100
|
+
// Run the proxy with API key passed as environment variable
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
const env = Object.assign({}, process.env, { API_KEY: apiKey });
|
|
103
|
+
const child = spawn('node', [tempFile], { env });
|
|
104
|
+
|
|
105
|
+
child.on('close', (code) => {
|
|
106
|
+
if (code === 0) {
|
|
107
|
+
// Wait a bit for the server to start, then validate
|
|
108
|
+
setTimeout(async () => {
|
|
109
|
+
const isHealthy = await checkHealthEndpoint(endpoint);
|
|
110
|
+
if (isHealthy) {
|
|
111
|
+
console.log('✓ Logged in');
|
|
112
|
+
console.log(` - Endpoint checked: ${endpoint}`);
|
|
113
|
+
} else {
|
|
114
|
+
console.log('✓ Proxy started');
|
|
115
|
+
console.log(` - Endpoint: ${endpoint}`);
|
|
116
|
+
}
|
|
117
|
+
resolve();
|
|
118
|
+
}, 1000);
|
|
119
|
+
} else {
|
|
120
|
+
reject(new Error('Proxy process failed'));
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
child.on('error', reject);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Function to check and login to Ollama Cloud
|
|
129
|
+
async function checkAndLoginOllamaCloud() {
|
|
130
|
+
const endpoint = 'http://localhost:3004/health';
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const isHealthy = await checkHealthEndpoint(endpoint);
|
|
134
|
+
if (isHealthy) {
|
|
135
|
+
console.log('✓ Already logged in');
|
|
136
|
+
console.log(` - Endpoint checked: ${endpoint}`);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Not healthy, download and run proxy
|
|
141
|
+
await downloadAndRunProxy(endpoint);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
console.error('Error during login:', error.message);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
module.exports = {
|
|
148
|
+
checkAndLoginOllamaCloud,
|
|
149
|
+
checkHealthEndpoint,
|
|
150
|
+
downloadAndRunProxy,
|
|
151
|
+
promptForApiKey
|
|
152
|
+
};
|
package/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
const { checkAndLoginOllamaCloud } = require('./handlers/ollamacloud');
|
|
4
|
+
|
|
3
5
|
// Command tree structure
|
|
4
6
|
const commandTree = {
|
|
5
7
|
help: {
|
|
@@ -53,12 +55,11 @@ function aiDefault() {
|
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
// AI Login function
|
|
56
|
-
function aiLogin(mode) {
|
|
57
|
-
console.log(`✓ AI Login initialized with mode: ${mode}`);
|
|
58
|
+
async function aiLogin(mode) {
|
|
58
59
|
if (mode === 'ollamacloud') {
|
|
59
|
-
|
|
60
|
-
console.log(' - Initializing cloud connection...');
|
|
60
|
+
await checkAndLoginOllamaCloud();
|
|
61
61
|
} else if (mode === 'ollamalocal') {
|
|
62
|
+
console.log(`✓ AI Login initialized with mode: ${mode}`);
|
|
62
63
|
console.log(' - Connecting to Ollama Local...');
|
|
63
64
|
console.log(' - Initializing local connection...');
|
|
64
65
|
}
|
|
@@ -107,8 +108,11 @@ function traverseCommandTree(args, startNode, startPath = []) {
|
|
|
107
108
|
if (currentNode.subcommands) {
|
|
108
109
|
showAvailableOptions(currentNode, path);
|
|
109
110
|
} else if (currentNode.handler) {
|
|
110
|
-
// Execute the handler if available
|
|
111
|
-
currentNode.handler();
|
|
111
|
+
// Execute the handler if available (could be async)
|
|
112
|
+
const result = currentNode.handler();
|
|
113
|
+
if (result instanceof Promise) {
|
|
114
|
+
result.catch(err => console.error('Error:', err.message));
|
|
115
|
+
}
|
|
112
116
|
} else {
|
|
113
117
|
console.log('Command complete but no action defined');
|
|
114
118
|
}
|