cloud-pc-templates 1.2.2 → 1.3.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 CHANGED
@@ -114,6 +114,36 @@ $ npx cloud-pc-templates ai login loginMode ollamalocal
114
114
  - Runs proxy on port 3005
115
115
  - Provides detailed status output
116
116
 
117
+ ##### Hugging Face Login
118
+
119
+ Connect to Hugging Face services:
120
+ ```bash
121
+ npx cloud-pc-templates ai login loginMode huggingface
122
+ ```
123
+
124
+ **What it does:**
125
+ 1. Prompts you to enter your Hugging Face API Key (masked input with asterisks)
126
+ 2. Downloads the Hugging Face proxy script from GitHub
127
+ 3. Runs the proxy on port 3006 with your API key
128
+ 4. Validates the proxy health endpoint
129
+ 5. Displays "Logged in" confirmation
130
+
131
+ **Example:**
132
+ ```bash
133
+ $ npx cloud-pc-templates ai login loginMode huggingface
134
+ Enter Hugging Face API Key: ****************************
135
+ ✓ Logged in
136
+ - Endpoint checked: http://localhost:3006/health
137
+ ```
138
+
139
+ **Features:**
140
+ - Masked input for API key (shows `*` instead of actual characters)
141
+ - Supports pasting long API keys
142
+ - Backspace support for corrections
143
+ - Runs proxy on port 3006
144
+ - Real-time proxy output logging for debugging
145
+ - Get your API key from: https://huggingface.co/settings/tokens
146
+
117
147
  ### Command Discovery
118
148
 
119
149
  The CLI features intelligent command discovery. If you don't provide all required arguments, it shows available options:
@@ -146,6 +176,7 @@ cloud-pc-templates/
146
176
  ├── handlers/
147
177
  │ ├── ollamacloud.js # Ollama Cloud login functionality
148
178
  │ ├── ollamalocal.js # Ollama Local login functionality
179
+ │ ├── huggingface.js # Hugging Face login functionality
149
180
  │ └── launch.js # Website launcher
150
181
  ├── package.json # Project metadata and bin configuration
151
182
  └── README.md # This file
@@ -170,6 +201,12 @@ cloud-pc-templates/
170
201
  - `checkProxyHealth()`: Health check for the offline proxy
171
202
  - `checkAndLoginOllamaLocal()`: Main login orchestrator with warning system
172
203
 
204
+ #### handlers/huggingface.js
205
+ - `promptForApiKey()`: Interactive masked API key input
206
+ - `checkHealthEndpoint()`: Health check for proxy server
207
+ - `downloadAndRunProxy()`: Downloads and executes proxy script with API key
208
+ - `checkAndLoginHuggingFace()`: Main login orchestrator
209
+
173
210
  #### handlers/launch.js
174
211
  - `openBrowser()`: Cross-platform browser launcher
175
212
  - `launchWebsite()`: Opens cloud-pc-templates.com
@@ -288,10 +325,17 @@ When entering your API key:
288
325
  - Start Ollama with: `ollama serve`
289
326
  - Check if Ollama is running on port 11434:
290
327
  ```bash
291
- curl http://localhost:11434/api/health
328
+ curl http://localhost:11434/api/tags
292
329
  ```
293
330
  - Ensure port 3005 is not in use by another application
294
331
 
332
+ ### Hugging Face login fails
333
+ - Check that you have a valid Hugging Face API key
334
+ - Get your API key from: https://huggingface.co/settings/tokens
335
+ - Make sure your API key has the necessary permissions
336
+ - Ensure port 3006 is not in use by another application
337
+ - Check your internet connection for accessing Hugging Face services
338
+
295
339
  ### Browser won't open with `launch`
296
340
  - Ensure you have a default browser configured
297
341
  - On Linux, make sure `xdg-open` is installed: `sudo apt-get install xdg-utils`
@@ -0,0 +1,169 @@
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
+ const PROXY_PORT = 3003;
9
+
10
+ // Function to get masked API key input
11
+ function promptForApiKey() {
12
+ return new Promise((resolve) => {
13
+ process.stdout.write('Enter Hugging Face API Key: ');
14
+
15
+ const stdin = process.stdin;
16
+
17
+ // Handle both TTY and non-TTY environments
18
+ if (stdin.isTTY) {
19
+ stdin.setRawMode(true);
20
+ }
21
+ stdin.resume();
22
+
23
+ let apiKey = '';
24
+
25
+ stdin.on('data', (buffer) => {
26
+ const chunk = buffer.toString();
27
+
28
+ // Process each character in the chunk (handles pasted text)
29
+ for (let i = 0; i < chunk.length; i++) {
30
+ const char = chunk[i];
31
+
32
+ if (char === '\n' || char === '\r' || char === '\u0004') {
33
+ // Enter or EOF
34
+ if (stdin.isTTY) {
35
+ stdin.setRawMode(false);
36
+ }
37
+ stdin.pause();
38
+ stdin.removeAllListeners('data');
39
+ console.log('');
40
+ resolve(apiKey);
41
+ return;
42
+ } else if (char === '\u0003') {
43
+ // Ctrl+C
44
+ if (stdin.isTTY) {
45
+ stdin.setRawMode(false);
46
+ }
47
+ process.exit();
48
+ } else if (char === '\x7f' || char === '\b') {
49
+ // Backspace
50
+ if (apiKey.length > 0) {
51
+ apiKey = apiKey.slice(0, -1);
52
+ process.stdout.write('\x1b[D\x1b[K');
53
+ }
54
+ } else if (char >= '\x20' && char <= '\x7e') {
55
+ // Printable character
56
+ apiKey += char;
57
+ process.stdout.write('*');
58
+ }
59
+ }
60
+ });
61
+ });
62
+ }
63
+
64
+ // Function to check health endpoint
65
+ function checkHealthEndpoint(endpoint) {
66
+ return new Promise((resolve) => {
67
+ const url = new URL(endpoint);
68
+ const protocol = url.protocol === 'https:' ? https : http;
69
+
70
+ const request = protocol.request(url, { method: 'GET' }, (res) => {
71
+ resolve(res.statusCode === 200);
72
+ });
73
+
74
+ request.on('error', () => {
75
+ resolve(false);
76
+ });
77
+
78
+ request.end();
79
+ });
80
+ }
81
+
82
+ // Function to download and run the proxy
83
+ async function downloadAndRunProxy(endpoint) {
84
+ const url = 'https://raw.githubusercontent.com/devashish234073/cloud-pc-templates-marketplace/refs/heads/main/JS-PROXIES/hf-proxy.js';
85
+ const tempFile = path.join(os.tmpdir(), 'hf-proxy.js');
86
+
87
+ // Download the file
88
+ await new Promise((resolve, reject) => {
89
+ const file = fs.createWriteStream(tempFile);
90
+ https.get(url, (res) => {
91
+ res.pipe(file);
92
+ file.on('finish', () => {
93
+ file.close();
94
+ resolve();
95
+ });
96
+ }).on('error', reject);
97
+ });
98
+
99
+ // Get API key from user
100
+ const apiKey = await promptForApiKey();
101
+
102
+ // Run the proxy with API key passed as command-line argument
103
+ return new Promise((resolve, reject) => {
104
+ const child = spawn('node', [tempFile, apiKey]);
105
+
106
+ let serverReady = false;
107
+
108
+ // Capture stdout to detect when server is ready
109
+ child.stdout.on('data', (data) => {
110
+ const output = data.toString();
111
+ console.log(output);
112
+
113
+ // Check if server indicates it's ready
114
+ if (output.includes('listening') || output.includes('started') || output.includes('running')) {
115
+ serverReady = true;
116
+ }
117
+ });
118
+
119
+ // Capture stderr for error messages
120
+ child.stderr.on('data', (data) => {
121
+ console.error(data.toString());
122
+ });
123
+
124
+ // Wait a bit for server to start, then validate
125
+ setTimeout(async () => {
126
+ try {
127
+ const isHealthy = await checkHealthEndpoint(endpoint);
128
+ if (isHealthy) {
129
+ console.log('✓ Logged in');
130
+ console.log(` - Endpoint checked: ${endpoint}`);
131
+ } else {
132
+ console.log('✓ Proxy started');
133
+ console.log(` - Endpoint: ${endpoint}`);
134
+ }
135
+ resolve();
136
+ } catch (error) {
137
+ reject(error);
138
+ }
139
+ }, 2000);
140
+
141
+ child.on('error', reject);
142
+ });
143
+ }
144
+
145
+ // Function to check and login to Hugging Face
146
+ async function checkAndLoginHuggingFace() {
147
+ const endpoint = `http://localhost:${PROXY_PORT}/health`;
148
+
149
+ try {
150
+ const isHealthy = await checkHealthEndpoint(endpoint);
151
+ if (isHealthy) {
152
+ console.log('✓ Already logged in');
153
+ console.log(` - Endpoint checked: ${endpoint}`);
154
+ return;
155
+ }
156
+
157
+ // Not healthy, download and run proxy
158
+ await downloadAndRunProxy(endpoint);
159
+ } catch (error) {
160
+ console.error('Error during login:', error.message);
161
+ }
162
+ }
163
+
164
+ module.exports = {
165
+ checkAndLoginHuggingFace,
166
+ checkHealthEndpoint,
167
+ downloadAndRunProxy,
168
+ promptForApiKey
169
+ };
@@ -15,7 +15,7 @@ function checkOllamaHealth() {
15
15
  {
16
16
  hostname: 'localhost',
17
17
  port: OLLAMA_PORT,
18
- path: '/api/health',
18
+ path: '/api/tags',
19
19
  method: 'GET'
20
20
  },
21
21
  (res) => {
package/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  const { checkAndLoginOllamaCloud } = require('./handlers/ollamacloud');
4
4
  const { checkAndLoginOllamaLocal } = require('./handlers/ollamalocal');
5
+ const { checkAndLoginHuggingFace } = require('./handlers/huggingface');
5
6
  const { launchWebsite } = require('./handlers/launch');
6
7
 
7
8
  // Command tree structure
@@ -27,6 +28,10 @@ const commandTree = {
27
28
  ollamalocal: {
28
29
  description: 'Connect to Ollama Local',
29
30
  handler: () => aiLogin('ollamalocal')
31
+ },
32
+ huggingface: {
33
+ description: 'Connect to Hugging Face',
34
+ handler: () => aiLogin('huggingface')
30
35
  }
31
36
  }
32
37
  }
@@ -54,6 +59,7 @@ function help() {
54
59
  console.log('AI Commands:');
55
60
  console.log(' npx cloud-pc-templates ai login loginMode ollamacloud');
56
61
  console.log(' npx cloud-pc-templates ai login loginMode ollamalocal');
62
+ console.log(' npx cloud-pc-templates ai login loginMode huggingface');
57
63
  }
58
64
 
59
65
  // Default AI function
@@ -67,6 +73,8 @@ async function aiLogin(mode) {
67
73
  await checkAndLoginOllamaCloud();
68
74
  } else if (mode === 'ollamalocal') {
69
75
  await checkAndLoginOllamaLocal();
76
+ } else if (mode === 'huggingface') {
77
+ await checkAndLoginHuggingFace();
70
78
  }
71
79
  }
72
80
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloud-pc-templates",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {