openaihub 1.1.4 → 1.1.6

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
@@ -1,27 +1,27 @@
1
- # OpenAI Hub npm package
2
-
3
- Install globally:
4
-
5
- ```bash
6
- npm install -g openaihub
7
- ```
8
-
9
- Current support: Windows x64.
10
-
11
- Runtime location after install:
12
-
13
- ```text
14
- %USERPROFILE%/.openaihub/npm-runtime
15
- ```
16
-
17
- Then run:
18
-
19
- ```bash
20
- openaihub
21
- ```
22
-
23
- Or:
24
-
25
- ```bash
26
- OAH
27
- ```
1
+ # OpenAI Hub npm package
2
+
3
+ Install globally:
4
+
5
+ ```bash
6
+ npm install -g openaihub
7
+ ```
8
+
9
+ Current support: Windows x64.
10
+
11
+ Runtime location after install:
12
+
13
+ ```text
14
+ %USERPROFILE%/.openaihub/npm-runtime
15
+ ```
16
+
17
+ Then run:
18
+
19
+ ```bash
20
+ openaihub
21
+ ```
22
+
23
+ Or:
24
+
25
+ ```bash
26
+ OAH
27
+ ```
package/bin/OAH.js CHANGED
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env node
2
-
3
- require('../lib/run').main();
1
+ #!/usr/bin/env node
2
+
3
+ require('../lib/run').main();
package/bin/openaihub.js CHANGED
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env node
2
-
3
- require('../lib/run').main();
1
+ #!/usr/bin/env node
2
+
3
+ require('../lib/run').main();
package/lib/config.js CHANGED
@@ -1,43 +1,43 @@
1
- 'use strict';
2
-
3
- const os = require('node:os');
4
- const path = require('node:path');
5
-
6
- const packageRoot = path.resolve(__dirname, '..');
7
- const runtimeRoot = path.join(os.homedir(), '.openaihub', 'npm-runtime');
8
- const bundledRuntimeRoot = path.join(packageRoot, 'runtime');
9
-
10
- const packageInfo = require(path.join(packageRoot, 'package.json'));
11
-
12
- function getPlatformConfig() {
13
- const platform = process.platform;
14
- const arch = process.arch;
15
-
16
- if (platform === 'win32' && arch === 'x64') {
17
- return {
18
- assetName: 'openaihub-windows.zip',
19
- assetDownloadUrl: `https://github.com/gugezhanghao132-eng/openaihub/releases/download/${getTagName()}/openaihub-windows.zip`,
20
- executableRelativePath: path.join('openaihub.exe'),
21
- extractKind: 'zip',
22
- runtimeKey: 'win32-x64'
23
- };
24
- }
25
-
26
- throw new Error(`OpenAI Hub npm package does not support ${platform}-${arch} yet.`);
27
- }
28
-
29
- function getTagName() {
30
- return `v${packageInfo.version}`;
31
- }
32
-
33
- module.exports = {
34
- owner: 'gugezhanghao132-eng',
35
- repo: 'openaihub',
36
- packageName: packageInfo.name,
37
- packageVersion: packageInfo.version,
38
- packageRoot,
39
- bundledRuntimeRoot,
40
- runtimeRoot,
41
- getTagName,
42
- getPlatformConfig
43
- };
1
+ 'use strict';
2
+
3
+ const os = require('node:os');
4
+ const path = require('node:path');
5
+
6
+ const packageRoot = path.resolve(__dirname, '..');
7
+ const runtimeRoot = path.join(os.homedir(), '.openaihub', 'npm-runtime');
8
+ const bundledRuntimeRoot = path.join(packageRoot, 'runtime');
9
+
10
+ const packageInfo = require(path.join(packageRoot, 'package.json'));
11
+
12
+ function getPlatformConfig() {
13
+ const platform = process.platform;
14
+ const arch = process.arch;
15
+
16
+ if (platform === 'win32' && arch === 'x64') {
17
+ return {
18
+ assetName: 'openaihub-windows.zip',
19
+ assetDownloadUrl: `https://github.com/gugezhanghao132-eng/openaihub/releases/download/${getTagName()}/openaihub-windows.zip`,
20
+ executableRelativePath: path.join('openaihub.exe'),
21
+ extractKind: 'zip',
22
+ runtimeKey: 'win32-x64'
23
+ };
24
+ }
25
+
26
+ throw new Error(`OpenAI Hub npm package does not support ${platform}-${arch} yet.`);
27
+ }
28
+
29
+ function getTagName() {
30
+ return `v${packageInfo.version}`;
31
+ }
32
+
33
+ module.exports = {
34
+ owner: 'gugezhanghao132-eng',
35
+ repo: 'openaihub',
36
+ packageName: packageInfo.name,
37
+ packageVersion: packageInfo.version,
38
+ packageRoot,
39
+ bundledRuntimeRoot,
40
+ runtimeRoot,
41
+ getTagName,
42
+ getPlatformConfig
43
+ };
package/lib/install.js CHANGED
@@ -1,245 +1,245 @@
1
- 'use strict';
2
-
3
- const fs = require('node:fs');
4
- const fsp = require('node:fs/promises');
5
- const https = require('node:https');
6
- const os = require('node:os');
7
- const path = require('node:path');
8
- const { spawn } = require('node:child_process');
9
-
10
- const {
11
- bundledRuntimeRoot,
12
- packageVersion,
13
- runtimeRoot,
14
- getPlatformConfig,
15
- } = require('./config');
16
-
17
- function log(message) {
18
- process.stdout.write(`[OpenAI Hub] ${message}\n`);
19
- }
20
-
21
- function downloadFile(url, targetPath, redirectsRemaining = 5) {
22
- return new Promise((resolve, reject) => {
23
- const requestUrl = (currentUrl, redirectsLeft) => {
24
- const req = https.get(currentUrl, {
25
- headers: {
26
- 'User-Agent': 'OpenAIHub-npm-installer'
27
- }
28
- }, (res) => {
29
- if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
30
- if (redirectsLeft <= 0) {
31
- reject(new Error(`Too many redirects while downloading ${url}`));
32
- res.resume();
33
- return;
34
- }
35
- res.resume();
36
- requestUrl(res.headers.location, redirectsLeft - 1);
37
- return;
38
- }
39
-
40
- if (res.statusCode !== 200) {
41
- reject(new Error(`Download failed: ${res.statusCode} ${currentUrl}`));
42
- res.resume();
43
- return;
44
- }
45
-
46
- const file = fs.createWriteStream(targetPath);
47
- res.pipe(file);
48
- file.on('finish', () => {
49
- file.close(resolve);
50
- });
51
- file.on('error', (error) => {
52
- file.close(() => fs.rmSync(targetPath, { force: true }));
53
- reject(error);
54
- });
55
- });
56
-
57
- req.setTimeout(30000, () => {
58
- req.destroy(new Error(`Download timed out: ${currentUrl}`));
59
- });
60
- req.on('error', reject);
61
- };
62
-
63
- requestUrl(url, redirectsRemaining);
64
- });
65
- }
66
-
67
- function runCommand(command, args) {
68
- return new Promise((resolve, reject) => {
69
- const child = spawn(command, args, {
70
- stdio: 'inherit',
71
- windowsHide: true
72
- });
73
-
74
- child.on('error', reject);
75
- child.on('exit', (code) => {
76
- if (code === 0) {
77
- resolve();
78
- return;
79
- }
80
- reject(new Error(`${command} exited with code ${code}`));
81
- });
82
- });
83
- }
84
-
85
- async function withRetry(action, attempts, label) {
86
- let lastError = null;
87
- for (let attempt = 1; attempt <= attempts; attempt += 1) {
88
- try {
89
- return await action();
90
- } catch (error) {
91
- lastError = error;
92
- if (attempt < attempts) {
93
- log(`${label} failed, retrying (${attempt}/${attempts - 1})...`);
94
- await new Promise((resolve) => setTimeout(resolve, 1500));
95
- }
96
- }
97
- }
98
- throw lastError;
99
- }
100
-
101
- async function acquireLock(lockPath, timeoutMs = 60000) {
102
- const startedAt = Date.now();
103
- while (true) {
104
- try {
105
- return await fsp.open(lockPath, 'wx');
106
- } catch (error) {
107
- if (error && error.code === 'EEXIST') {
108
- if (Date.now() - startedAt >= timeoutMs) {
109
- throw new Error(`Timed out waiting for install lock: ${lockPath}`);
110
- }
111
- await new Promise((resolve) => setTimeout(resolve, 500));
112
- continue;
113
- }
114
- throw error;
115
- }
116
- }
117
- }
118
-
119
- async function removePathWithRetry(targetPath, attempts = 5, delayMs = 400) {
120
- for (let attempt = 1; attempt <= attempts; attempt += 1) {
121
- try {
122
- await fsp.rm(targetPath, { recursive: true, force: true });
123
- return;
124
- } catch (error) {
125
- if (!error || !['EBUSY', 'EPERM', 'ENOTEMPTY'].includes(error.code) || attempt === attempts) {
126
- throw error;
127
- }
128
- await new Promise((resolve) => setTimeout(resolve, delayMs * attempt));
129
- }
130
- }
131
- }
132
-
133
- async function extractArchive(archivePath, extractRoot, extractKind) {
134
- if (extractKind === 'zip' && process.platform === 'win32') {
135
- await runCommand('powershell.exe', [
136
- '-NoProfile',
137
- '-ExecutionPolicy',
138
- 'Bypass',
139
- '-Command',
140
- `Expand-Archive -Path '${archivePath.replace(/'/g, "''")}' -DestinationPath '${extractRoot.replace(/'/g, "''")}' -Force`
141
- ]);
142
- return;
143
- }
144
-
145
- throw new Error(`Unsupported archive extraction for ${process.platform}: ${extractKind}`);
146
- }
147
-
148
- function findExecutable(extractRoot, executableName) {
149
- const stack = [extractRoot];
150
- while (stack.length > 0) {
151
- const current = stack.pop();
152
- const entries = fs.readdirSync(current, { withFileTypes: true });
153
- for (const entry of entries) {
154
- const fullPath = path.join(current, entry.name);
155
- if (entry.isDirectory()) {
156
- stack.push(fullPath);
157
- continue;
158
- }
159
- if (entry.isFile() && entry.name.toLowerCase() === executableName.toLowerCase()) {
160
- return path.dirname(fullPath);
161
- }
162
- }
163
- }
164
- return null;
165
- }
166
-
167
- async function ensureInstalled(options = {}) {
168
- const { quiet = false, force = false } = options;
169
- const platformConfig = getPlatformConfig();
170
- const runtimeBaseDir = path.join(runtimeRoot, platformConfig.runtimeKey);
171
- const runtimeDir = path.join(runtimeBaseDir, packageVersion);
172
- const executablePath = path.join(runtimeDir, platformConfig.executableRelativePath);
173
- const bundledArchivePath = path.join(bundledRuntimeRoot, platformConfig.assetName);
174
- const versionMarkerPath = path.join(runtimeDir, 'version.txt');
175
-
176
- if (!force && fs.existsSync(executablePath) && fs.existsSync(versionMarkerPath)) {
177
- const installedVersion = fs.readFileSync(versionMarkerPath, 'utf8').trim();
178
- if (installedVersion === packageVersion) {
179
- return { executablePath, runtimeDir, downloaded: false };
180
- }
181
- }
182
-
183
- const tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), 'openaihub-npm-'));
184
- const archivePath = path.join(tempRoot, platformConfig.assetName);
185
- const extractRoot = path.join(tempRoot, 'extract');
186
- const stageRoot = path.join(tempRoot, 'stage');
187
- const lockPath = path.join(runtimeRoot, `${platformConfig.runtimeKey}.lock`);
188
- let lockHandle = null;
189
-
190
- try {
191
- await fsp.mkdir(runtimeRoot, { recursive: true });
192
- lockHandle = await acquireLock(lockPath);
193
-
194
- if (!quiet) {
195
- log(`Preparing OpenAI Hub ${packageVersion} for ${platformConfig.runtimeKey}...`);
196
- }
197
-
198
- await fsp.mkdir(extractRoot, { recursive: true });
199
- await fsp.mkdir(stageRoot, { recursive: true });
200
-
201
- if (fs.existsSync(bundledArchivePath)) {
202
- if (!quiet) {
203
- log(`Using bundled runtime archive ${platformConfig.assetName}...`);
204
- }
205
- await fsp.copyFile(bundledArchivePath, archivePath);
206
- } else {
207
- if (!quiet) {
208
- log(`Downloading ${platformConfig.assetName}...`);
209
- }
210
- await withRetry(() => downloadFile(platformConfig.assetDownloadUrl, archivePath), 3, 'Runtime download');
211
- }
212
-
213
- if (!quiet) {
214
- log('Extracting runtime...');
215
- }
216
- await extractArchive(archivePath, extractRoot, platformConfig.extractKind);
217
-
218
- const extractedRuntimeRoot = findExecutable(extractRoot, path.basename(platformConfig.executableRelativePath));
219
- if (!extractedRuntimeRoot) {
220
- throw new Error(`Executable ${platformConfig.executableRelativePath} was not found in downloaded asset.`);
221
- }
222
-
223
- await fsp.cp(extractedRuntimeRoot, stageRoot, { recursive: true, force: true });
224
- await fsp.writeFile(path.join(stageRoot, 'version.txt'), `${packageVersion}\n`, 'utf8');
225
- await removePathWithRetry(runtimeDir);
226
- await fsp.mkdir(runtimeBaseDir, { recursive: true });
227
- await fsp.rename(stageRoot, runtimeDir);
228
-
229
- if (!quiet) {
230
- log('Runtime ready.');
231
- }
232
-
233
- return { executablePath, runtimeDir, downloaded: true };
234
- } finally {
235
- if (lockHandle) {
236
- await lockHandle.close();
237
- }
238
- await fsp.rm(lockPath, { force: true });
239
- await fsp.rm(tempRoot, { recursive: true, force: true });
240
- }
241
- }
242
-
243
- module.exports = {
244
- ensureInstalled
245
- };
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs');
4
+ const fsp = require('node:fs/promises');
5
+ const https = require('node:https');
6
+ const os = require('node:os');
7
+ const path = require('node:path');
8
+ const { spawn } = require('node:child_process');
9
+
10
+ const {
11
+ bundledRuntimeRoot,
12
+ packageVersion,
13
+ runtimeRoot,
14
+ getPlatformConfig,
15
+ } = require('./config');
16
+
17
+ function log(message) {
18
+ process.stdout.write(`[OpenAI Hub] ${message}\n`);
19
+ }
20
+
21
+ function downloadFile(url, targetPath, redirectsRemaining = 5) {
22
+ return new Promise((resolve, reject) => {
23
+ const requestUrl = (currentUrl, redirectsLeft) => {
24
+ const req = https.get(currentUrl, {
25
+ headers: {
26
+ 'User-Agent': 'OpenAIHub-npm-installer'
27
+ }
28
+ }, (res) => {
29
+ if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
30
+ if (redirectsLeft <= 0) {
31
+ reject(new Error(`Too many redirects while downloading ${url}`));
32
+ res.resume();
33
+ return;
34
+ }
35
+ res.resume();
36
+ requestUrl(res.headers.location, redirectsLeft - 1);
37
+ return;
38
+ }
39
+
40
+ if (res.statusCode !== 200) {
41
+ reject(new Error(`Download failed: ${res.statusCode} ${currentUrl}`));
42
+ res.resume();
43
+ return;
44
+ }
45
+
46
+ const file = fs.createWriteStream(targetPath);
47
+ res.pipe(file);
48
+ file.on('finish', () => {
49
+ file.close(resolve);
50
+ });
51
+ file.on('error', (error) => {
52
+ file.close(() => fs.rmSync(targetPath, { force: true }));
53
+ reject(error);
54
+ });
55
+ });
56
+
57
+ req.setTimeout(30000, () => {
58
+ req.destroy(new Error(`Download timed out: ${currentUrl}`));
59
+ });
60
+ req.on('error', reject);
61
+ };
62
+
63
+ requestUrl(url, redirectsRemaining);
64
+ });
65
+ }
66
+
67
+ function runCommand(command, args) {
68
+ return new Promise((resolve, reject) => {
69
+ const child = spawn(command, args, {
70
+ stdio: 'inherit',
71
+ windowsHide: true
72
+ });
73
+
74
+ child.on('error', reject);
75
+ child.on('exit', (code) => {
76
+ if (code === 0) {
77
+ resolve();
78
+ return;
79
+ }
80
+ reject(new Error(`${command} exited with code ${code}`));
81
+ });
82
+ });
83
+ }
84
+
85
+ async function withRetry(action, attempts, label) {
86
+ let lastError = null;
87
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
88
+ try {
89
+ return await action();
90
+ } catch (error) {
91
+ lastError = error;
92
+ if (attempt < attempts) {
93
+ log(`${label} failed, retrying (${attempt}/${attempts - 1})...`);
94
+ await new Promise((resolve) => setTimeout(resolve, 1500));
95
+ }
96
+ }
97
+ }
98
+ throw lastError;
99
+ }
100
+
101
+ async function acquireLock(lockPath, timeoutMs = 60000) {
102
+ const startedAt = Date.now();
103
+ while (true) {
104
+ try {
105
+ return await fsp.open(lockPath, 'wx');
106
+ } catch (error) {
107
+ if (error && error.code === 'EEXIST') {
108
+ if (Date.now() - startedAt >= timeoutMs) {
109
+ throw new Error(`Timed out waiting for install lock: ${lockPath}`);
110
+ }
111
+ await new Promise((resolve) => setTimeout(resolve, 500));
112
+ continue;
113
+ }
114
+ throw error;
115
+ }
116
+ }
117
+ }
118
+
119
+ async function removePathWithRetry(targetPath, attempts = 5, delayMs = 400) {
120
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
121
+ try {
122
+ await fsp.rm(targetPath, { recursive: true, force: true });
123
+ return;
124
+ } catch (error) {
125
+ if (!error || !['EBUSY', 'EPERM', 'ENOTEMPTY'].includes(error.code) || attempt === attempts) {
126
+ throw error;
127
+ }
128
+ await new Promise((resolve) => setTimeout(resolve, delayMs * attempt));
129
+ }
130
+ }
131
+ }
132
+
133
+ async function extractArchive(archivePath, extractRoot, extractKind) {
134
+ if (extractKind === 'zip' && process.platform === 'win32') {
135
+ await runCommand('powershell.exe', [
136
+ '-NoProfile',
137
+ '-ExecutionPolicy',
138
+ 'Bypass',
139
+ '-Command',
140
+ `Expand-Archive -Path '${archivePath.replace(/'/g, "''")}' -DestinationPath '${extractRoot.replace(/'/g, "''")}' -Force`
141
+ ]);
142
+ return;
143
+ }
144
+
145
+ throw new Error(`Unsupported archive extraction for ${process.platform}: ${extractKind}`);
146
+ }
147
+
148
+ function findExecutable(extractRoot, executableName) {
149
+ const stack = [extractRoot];
150
+ while (stack.length > 0) {
151
+ const current = stack.pop();
152
+ const entries = fs.readdirSync(current, { withFileTypes: true });
153
+ for (const entry of entries) {
154
+ const fullPath = path.join(current, entry.name);
155
+ if (entry.isDirectory()) {
156
+ stack.push(fullPath);
157
+ continue;
158
+ }
159
+ if (entry.isFile() && entry.name.toLowerCase() === executableName.toLowerCase()) {
160
+ return path.dirname(fullPath);
161
+ }
162
+ }
163
+ }
164
+ return null;
165
+ }
166
+
167
+ async function ensureInstalled(options = {}) {
168
+ const { quiet = false, force = false } = options;
169
+ const platformConfig = getPlatformConfig();
170
+ const runtimeBaseDir = path.join(runtimeRoot, platformConfig.runtimeKey);
171
+ const runtimeDir = path.join(runtimeBaseDir, packageVersion);
172
+ const executablePath = path.join(runtimeDir, platformConfig.executableRelativePath);
173
+ const bundledArchivePath = path.join(bundledRuntimeRoot, platformConfig.assetName);
174
+ const versionMarkerPath = path.join(runtimeDir, 'version.txt');
175
+
176
+ if (!force && fs.existsSync(executablePath) && fs.existsSync(versionMarkerPath)) {
177
+ const installedVersion = fs.readFileSync(versionMarkerPath, 'utf8').trim();
178
+ if (installedVersion === packageVersion) {
179
+ return { executablePath, runtimeDir, downloaded: false };
180
+ }
181
+ }
182
+
183
+ const tempRoot = await fsp.mkdtemp(path.join(os.tmpdir(), 'openaihub-npm-'));
184
+ const archivePath = path.join(tempRoot, platformConfig.assetName);
185
+ const extractRoot = path.join(tempRoot, 'extract');
186
+ const stageRoot = path.join(tempRoot, 'stage');
187
+ const lockPath = path.join(runtimeRoot, `${platformConfig.runtimeKey}.lock`);
188
+ let lockHandle = null;
189
+
190
+ try {
191
+ await fsp.mkdir(runtimeRoot, { recursive: true });
192
+ lockHandle = await acquireLock(lockPath);
193
+
194
+ if (!quiet) {
195
+ log(`Preparing OpenAI Hub ${packageVersion} for ${platformConfig.runtimeKey}...`);
196
+ }
197
+
198
+ await fsp.mkdir(extractRoot, { recursive: true });
199
+ await fsp.mkdir(stageRoot, { recursive: true });
200
+
201
+ if (fs.existsSync(bundledArchivePath)) {
202
+ if (!quiet) {
203
+ log(`Using bundled runtime archive ${platformConfig.assetName}...`);
204
+ }
205
+ await fsp.copyFile(bundledArchivePath, archivePath);
206
+ } else {
207
+ if (!quiet) {
208
+ log(`Downloading ${platformConfig.assetName}...`);
209
+ }
210
+ await withRetry(() => downloadFile(platformConfig.assetDownloadUrl, archivePath), 3, 'Runtime download');
211
+ }
212
+
213
+ if (!quiet) {
214
+ log('Extracting runtime...');
215
+ }
216
+ await extractArchive(archivePath, extractRoot, platformConfig.extractKind);
217
+
218
+ const extractedRuntimeRoot = findExecutable(extractRoot, path.basename(platformConfig.executableRelativePath));
219
+ if (!extractedRuntimeRoot) {
220
+ throw new Error(`Executable ${platformConfig.executableRelativePath} was not found in downloaded asset.`);
221
+ }
222
+
223
+ await fsp.cp(extractedRuntimeRoot, stageRoot, { recursive: true, force: true });
224
+ await fsp.writeFile(path.join(stageRoot, 'version.txt'), `${packageVersion}\n`, 'utf8');
225
+ await removePathWithRetry(runtimeDir);
226
+ await fsp.mkdir(runtimeBaseDir, { recursive: true });
227
+ await fsp.rename(stageRoot, runtimeDir);
228
+
229
+ if (!quiet) {
230
+ log('Runtime ready.');
231
+ }
232
+
233
+ return { executablePath, runtimeDir, downloaded: true };
234
+ } finally {
235
+ if (lockHandle) {
236
+ await lockHandle.close();
237
+ }
238
+ await fsp.rm(lockPath, { force: true });
239
+ await fsp.rm(tempRoot, { recursive: true, force: true });
240
+ }
241
+ }
242
+
243
+ module.exports = {
244
+ ensureInstalled
245
+ };
package/lib/run.js CHANGED
@@ -1,35 +1,35 @@
1
- 'use strict';
2
-
3
- const { spawn } = require('node:child_process');
4
-
5
- const { ensureInstalled } = require('./install');
6
-
7
- async function main() {
8
- try {
9
- const { executablePath } = await ensureInstalled({ quiet: true });
10
- const child = spawn(executablePath, process.argv.slice(2), {
11
- stdio: 'inherit',
12
- windowsHide: false
13
- });
14
-
15
- child.on('exit', (code, signal) => {
16
- if (signal) {
17
- process.kill(process.pid, signal);
18
- return;
19
- }
20
- process.exit(code === null ? 1 : code);
21
- });
22
-
23
- child.on('error', (error) => {
24
- process.stderr.write(`[OpenAI Hub] Failed to launch runtime: ${error.message}\n`);
25
- process.exit(1);
26
- });
27
- } catch (error) {
28
- process.stderr.write(`[OpenAI Hub] ${error.message}\n`);
29
- process.exit(1);
30
- }
31
- }
32
-
33
- module.exports = {
34
- main
35
- };
1
+ 'use strict';
2
+
3
+ const { spawn } = require('node:child_process');
4
+
5
+ const { ensureInstalled } = require('./install');
6
+
7
+ async function main() {
8
+ try {
9
+ const { executablePath } = await ensureInstalled({ quiet: true });
10
+ const child = spawn(executablePath, process.argv.slice(2), {
11
+ stdio: 'inherit',
12
+ windowsHide: false
13
+ });
14
+
15
+ child.on('exit', (code, signal) => {
16
+ if (signal) {
17
+ process.kill(process.pid, signal);
18
+ return;
19
+ }
20
+ process.exit(code === null ? 1 : code);
21
+ });
22
+
23
+ child.on('error', (error) => {
24
+ process.stderr.write(`[OpenAI Hub] Failed to launch runtime: ${error.message}\n`);
25
+ process.exit(1);
26
+ });
27
+ } catch (error) {
28
+ process.stderr.write(`[OpenAI Hub] ${error.message}\n`);
29
+ process.exit(1);
30
+ }
31
+ }
32
+
33
+ module.exports = {
34
+ main
35
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openaihub",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "description": "OpenAI Hub CLI installer and launcher",
5
5
  "license": "MIT",
6
6
  "os": [
Binary file
@@ -1,9 +1,9 @@
1
- 'use strict';
2
-
3
- const { ensureInstalled } = require('../lib/install');
4
-
5
- ensureInstalled()
6
- .catch((error) => {
7
- process.stderr.write(`[OpenAI Hub] postinstall warning: ${error.message}\n`);
8
- process.stderr.write('[OpenAI Hub] The runtime will be downloaded automatically on first launch.\n');
9
- });
1
+ 'use strict';
2
+
3
+ const { ensureInstalled } = require('../lib/install');
4
+
5
+ ensureInstalled()
6
+ .catch((error) => {
7
+ process.stderr.write(`[OpenAI Hub] postinstall warning: ${error.message}\n`);
8
+ process.stderr.write('[OpenAI Hub] The runtime will be downloaded automatically on first launch.\n');
9
+ });