tingly-box 0.2601.51400 → 0.2601.71440-preview
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/bin.js +91 -49
- package/package.json +3 -2
package/bin.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { execFileSync } from "child_process";
|
|
4
|
-
import { chmodSync, createWriteStream, existsSync, fsyncSync, mkdirSync } from "fs";
|
|
5
|
-
import { tmpdir } from "os";
|
|
4
|
+
import { chmodSync, createWriteStream, existsSync, fsyncSync, mkdirSync, statSync } from "fs";
|
|
6
5
|
import { join } from "path";
|
|
7
6
|
import { Readable } from "stream";
|
|
8
7
|
import { ProxyAgent } from "undici";
|
|
8
|
+
import unzipper from "unzipper";
|
|
9
9
|
|
|
10
10
|
// Configuration for binary downloads
|
|
11
11
|
const BASE_URL = "https://github.com/tingly-dev/tingly-box/releases/download/";
|
|
@@ -15,7 +15,7 @@ const LATEST_RELEASE_API_URL = "https://github.com/tingly-dev/tingly-box/release
|
|
|
15
15
|
|
|
16
16
|
// Default branch to use when not specified via transport version
|
|
17
17
|
// This will be replaced during the NPX build process
|
|
18
|
-
const BINARY_RELEASE_BRANCH = 'v0.2601.
|
|
18
|
+
const BINARY_RELEASE_BRANCH = 'v0.2601.071440-preview';
|
|
19
19
|
|
|
20
20
|
// Create proxy agent from environment variables (HTTP_PROXY, HTTPS_PROXY)
|
|
21
21
|
// Only create ProxyAgent if proxy is configured, otherwise use undefined (direct connection)
|
|
@@ -73,6 +73,13 @@ function validateTransportVersion(version) {
|
|
|
73
73
|
|
|
74
74
|
const { version: VERSION, remainingArgs } = parseTransportVersion();
|
|
75
75
|
|
|
76
|
+
// Default parameters to use when no arguments are provided
|
|
77
|
+
const DEFAULT_ARGS = [
|
|
78
|
+
// Add your default parameters here, e.g.:
|
|
79
|
+
"start",
|
|
80
|
+
"--daemon",
|
|
81
|
+
];
|
|
82
|
+
|
|
76
83
|
async function getPlatformArchAndBinary() {
|
|
77
84
|
const platform = process.platform;
|
|
78
85
|
const arch = process.arch;
|
|
@@ -192,62 +199,94 @@ async function downloadAndExtractZip(url, extractDir, binaryName) {
|
|
|
192
199
|
process.exit(1);
|
|
193
200
|
}
|
|
194
201
|
|
|
195
|
-
// Create a temporary file for the ZIP
|
|
196
|
-
const zipPath = join(tmpdir(), `tingly-box-${Date.now()}.zip`);
|
|
197
|
-
const fileStream = createWriteStream(zipPath, { flags: "w" });
|
|
198
|
-
|
|
199
202
|
const contentLength = res.headers.get("content-length");
|
|
200
203
|
const totalSize = contentLength ? parseInt(contentLength, 10) : null;
|
|
201
204
|
let downloadedSize = 0;
|
|
202
205
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
+
// Convert the fetch response body to a Node.js readable stream
|
|
207
|
+
const nodeStream = Readable.fromWeb(res.body);
|
|
208
|
+
|
|
209
|
+
// Collect the entire ZIP into a buffer
|
|
210
|
+
const chunks = [];
|
|
211
|
+
for await (const chunk of nodeStream) {
|
|
212
|
+
chunks.push(chunk);
|
|
213
|
+
downloadedSize += chunk.length;
|
|
214
|
+
if (totalSize) {
|
|
215
|
+
const progress = ((downloadedSize / totalSize) * 100).toFixed(1);
|
|
216
|
+
process.stdout.write(`\r⏱️ Downloading: ${progress}% (${formatBytes(downloadedSize)}/${formatBytes(totalSize)})`);
|
|
217
|
+
} else {
|
|
218
|
+
process.stdout.write(`\r⏱️ Downloaded: ${formatBytes(downloadedSize)}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const zipBuffer = Buffer.concat(chunks);
|
|
206
222
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
const progress = ((downloadedSize / totalSize) * 100).toFixed(1);
|
|
211
|
-
process.stdout.write(`\r⏱️ Downloading ZIP: ${progress}% (${formatBytes(downloadedSize)}/${formatBytes(totalSize)})`);
|
|
212
|
-
} else {
|
|
213
|
-
process.stdout.write(`\r⏱️ Downloaded: ${formatBytes(downloadedSize)}`);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
223
|
+
// Extract ZIP from buffer using unzipper
|
|
224
|
+
try {
|
|
225
|
+
console.log(`\n📦 Extracting ZIP to ${extractDir}...`);
|
|
216
226
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
nodeStream.on("error", reject);
|
|
224
|
-
} catch (error) {
|
|
225
|
-
reject(error);
|
|
227
|
+
const directory = await unzipper.Open.buffer(zipBuffer);
|
|
228
|
+
|
|
229
|
+
// Debug: List all entries in the ZIP
|
|
230
|
+
console.log(`📋 ZIP contents (${directory.files.length} entries):`);
|
|
231
|
+
for (const file of directory.files) {
|
|
232
|
+
console.log(` ${file.type}: ${file.path} (permissions: ${file.unixPermissions?.toString(8)})`);
|
|
226
233
|
}
|
|
227
|
-
});
|
|
228
234
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
235
|
+
// Extract all files to the target directory
|
|
236
|
+
for (const file of directory.files) {
|
|
237
|
+
// Skip directory entries and __MACOSX metadata
|
|
238
|
+
if (file.type === 'Directory' || file.path.startsWith('__MACOSX/') || file.path.includes('.DS_Store')) {
|
|
239
|
+
console.log(`⏭️ Skipping: ${file.path} (type: ${file.type})`);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const filePath = join(extractDir, file.path);
|
|
244
|
+
// Get parent directory of the file in the ZIP
|
|
245
|
+
const pathParts = file.path.split('/');
|
|
246
|
+
pathParts.pop(); // Remove the filename
|
|
247
|
+
const fileDir = pathParts.length > 0 ? join(extractDir, ...pathParts) : extractDir;
|
|
248
|
+
|
|
249
|
+
console.log(`📄 Extracting: ${file.path} -> ${filePath}`);
|
|
250
|
+
|
|
251
|
+
// Ensure parent directory exists
|
|
252
|
+
if (fileDir !== extractDir && !existsSync(fileDir)) {
|
|
253
|
+
mkdirSync(fileDir, { recursive: true });
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Remove existing directory if it exists (this was created incorrectly before)
|
|
257
|
+
if (existsSync(filePath) && statSync(filePath).isDirectory()) {
|
|
258
|
+
console.log(`🧹 Removing incorrect directory: ${filePath}`);
|
|
259
|
+
// Can't easily remove a directory in Node without fs.rm (Node 14.14+)
|
|
260
|
+
// Skip and let user clean up manually
|
|
261
|
+
console.log(`⚠️ Please manually remove: rm -rf "${filePath}"`);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Extract file
|
|
266
|
+
const content = await file.buffer();
|
|
267
|
+
const fileStream = createWriteStream(filePath);
|
|
268
|
+
await new Promise((resolve, reject) => {
|
|
269
|
+
fileStream.write(content, (err) => {
|
|
270
|
+
if (err) reject(err);
|
|
271
|
+
else {
|
|
272
|
+
fileStream.end();
|
|
273
|
+
resolve();
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
// Set file permissions after writing
|
|
278
|
+
if (process.platform !== "win32") {
|
|
279
|
+
// Use ZIP permissions if available, otherwise default to 0o755 (executable)
|
|
280
|
+
const permissions = file.unixPermissions && file.unixPermissions > 0 ? file.unixPermissions : 0o755;
|
|
281
|
+
chmodSync(filePath, permissions);
|
|
282
|
+
}
|
|
243
283
|
}
|
|
244
|
-
}
|
|
245
284
|
|
|
246
|
-
|
|
247
|
-
try {
|
|
248
|
-
execFileSync("rm", ["-f", zipPath]);
|
|
285
|
+
console.log(`✅ Extracted ZIP to ${extractDir}`);
|
|
249
286
|
} catch (error) {
|
|
250
|
-
|
|
287
|
+
console.error(`\n❌ Failed to extract ZIP: ${error.message}`);
|
|
288
|
+
console.error(`Stack: ${error.stack}`);
|
|
289
|
+
process.exit(1);
|
|
251
290
|
}
|
|
252
291
|
}
|
|
253
292
|
|
|
@@ -341,7 +380,10 @@ function formatBytes(bytes) {
|
|
|
341
380
|
console.log(`🔍 Executing binary: ${binaryPath}`);
|
|
342
381
|
|
|
343
382
|
try {
|
|
344
|
-
|
|
383
|
+
// Use default args if no arguments provided
|
|
384
|
+
const argsToUse = remainingArgs.length > 0 ? remainingArgs : DEFAULT_ARGS;
|
|
385
|
+
|
|
386
|
+
execFileSync(binaryPath, argsToUse, {
|
|
345
387
|
stdio: "inherit",
|
|
346
388
|
encoding: 'utf8'
|
|
347
389
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tingly-box",
|
|
3
|
-
"version": "0.2601.
|
|
3
|
+
"version": "0.2601.71440-preview",
|
|
4
4
|
"description": "High-performance AI gateway CLI - connect to multiple AI providers through a single API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"type": "module",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"undici": "^7.0.0"
|
|
32
|
+
"undici": "^7.0.0",
|
|
33
|
+
"unzipper": "^0.12.3"
|
|
33
34
|
}
|
|
34
35
|
}
|