claude-simple 0.2.31 → 0.2.33
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/edge-ctl.js +0 -1
- package/client.js +19 -7
- package/dist/{app.0.2.31.min.js → app.0.2.33.min.js} +142 -142
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/public/cache.js +41 -5
- package/public/chat.js +11 -2
- package/public/files.js +23 -1
- package/public/index.html +2 -2
- package/public/shell/session-nav.js +2 -0
- package/public/sw.js +3 -3
- package/src/agents/sessions.js +52 -2
- package/src/app.js +17 -7
- package/src/runtime/external-session-sync.js +2 -0
- package/src/runtime/http-transfer.js +76 -0
- /package/dist/{style.0.2.31.min.css → style.0.2.33.min.css} +0 -0
package/bin/edge-ctl.js
CHANGED
|
@@ -330,7 +330,6 @@ function cmdWinLogs(mode) {
|
|
|
330
330
|
|
|
331
331
|
function cmdStatus(backend) {
|
|
332
332
|
if (backend === 'win32') return cmdWinStatus();
|
|
333
|
-
if (backend === 'launchd') ensureRoot();
|
|
334
333
|
if (backend === 'launchd' || backend === 'launchd-user') {
|
|
335
334
|
const target = macTarget(backend);
|
|
336
335
|
const r = runRoot('launchctl', ['print', target.label]);
|
package/client.js
CHANGED
|
@@ -6,6 +6,9 @@ import { createPortWebSocketRelay } from './src/runtime/port-websocket.js';
|
|
|
6
6
|
import os from 'os';
|
|
7
7
|
import crypto from 'crypto';
|
|
8
8
|
import zlib from 'zlib';
|
|
9
|
+
import { promisify } from 'node:util';
|
|
10
|
+
import { createHTTPTransfer, TransferBudget, readLimitedBody } from './src/runtime/http-transfer.js';
|
|
11
|
+
const gzip = promisify(zlib.gzip);
|
|
9
12
|
import { promises as fs, watch as watchFs } from 'fs';
|
|
10
13
|
import path from 'path';
|
|
11
14
|
|
|
@@ -15,6 +18,8 @@ const MACHINE_TOKEN = process.env.MACHINE_TOKEN; // shared secret with gateway
|
|
|
15
18
|
const LOCAL_PORT = parseInt(process.env.LOCAL_PORT || '13000');
|
|
16
19
|
const SYNC_DIR = process.env.EDGE_SYNC_DIR || path.join(os.homedir(), '.claude-simple-edge');
|
|
17
20
|
const SYNC_FILE = path.join(SYNC_DIR, 'hub-stream-outbox.json');
|
|
21
|
+
const transferRate = Math.max(32 * 1024, Number(process.env.FILE_TRANSFER_BYTES_PER_SECOND) || 256 * 1024);
|
|
22
|
+
const transferHTTP = createHTTPTransfer({ gatewayURL: GATEWAY_URL, token: MACHINE_TOKEN, machineId: MACHINE_ID, budget: new TransferBudget(transferRate) });
|
|
18
23
|
const portWebSockets = createPortWebSocketRelay(sendControl, { allowRemote: process.env.PORT_PROXY_ALLOW_REMOTE === '1' });
|
|
19
24
|
|
|
20
25
|
if (!GATEWAY_URL) { console.error('GATEWAY_URL is required'); process.exit(1); }
|
|
@@ -360,12 +365,17 @@ function connect() {
|
|
|
360
365
|
if (reqBody != null && reqBody !== '' && String(msg.encoding || '').toLowerCase() === 'base64') {
|
|
361
366
|
reqBody = Buffer.from(reqBody, 'base64');
|
|
362
367
|
}
|
|
363
|
-
const
|
|
368
|
+
const options = {
|
|
364
369
|
method: msg.method,
|
|
365
370
|
headers: reqHeaders,
|
|
366
371
|
body: reqBody,
|
|
367
372
|
redirect: 'manual',
|
|
368
|
-
}
|
|
373
|
+
};
|
|
374
|
+
if (msg.transfer) {
|
|
375
|
+
await transferHTTP(msg, url, options, sanitizeProxyHeaders);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const res = await fetch(url, options);
|
|
369
379
|
const headers = sanitizeProxyHeaders(Object.fromEntries(res.headers.entries()));
|
|
370
380
|
const contentType = res.headers.get('content-type') || '';
|
|
371
381
|
const contentDisp = res.headers.get('content-disposition') || '';
|
|
@@ -398,7 +408,7 @@ function connect() {
|
|
|
398
408
|
|| (contentType !== '' && !/^(text\/|application\/(json|javascript|xml|problem\+json|x-www-form-urlencoded)|multipart\/)/i.test(contentType));
|
|
399
409
|
|
|
400
410
|
if (isBinary) {
|
|
401
|
-
const buf =
|
|
411
|
+
const buf = await readLimitedBody(res);
|
|
402
412
|
headers['content-length'] = String(buf.length);
|
|
403
413
|
sendControl({
|
|
404
414
|
type: 'http-res',
|
|
@@ -411,13 +421,13 @@ function connect() {
|
|
|
411
421
|
return;
|
|
412
422
|
}
|
|
413
423
|
|
|
414
|
-
const
|
|
415
|
-
const
|
|
424
|
+
const raw = await readLimitedBody(res);
|
|
425
|
+
const body = raw.toString('utf8');
|
|
416
426
|
// Large JSON (session history) is gzip+base64 on the control channel so
|
|
417
427
|
// Hub→phone does not wait on an uncompressed multi-MB WS frame.
|
|
418
428
|
if (raw.length >= 4096) {
|
|
419
429
|
try {
|
|
420
|
-
const zipped =
|
|
430
|
+
const zipped = await gzip(raw, { level: 4 });
|
|
421
431
|
if (zipped.length < raw.length * 0.95) {
|
|
422
432
|
sendControl({
|
|
423
433
|
type: 'http-res',
|
|
@@ -440,7 +450,9 @@ function connect() {
|
|
|
440
450
|
body,
|
|
441
451
|
});
|
|
442
452
|
} catch (e) {
|
|
443
|
-
sendControl(
|
|
453
|
+
sendControl(msg.transfer
|
|
454
|
+
? { type: 'http-error', reqId: msg.reqId, status: e.status || 502, message: e.message }
|
|
455
|
+
: { type: 'http-res', reqId: msg.reqId, status: e.status || 502, headers: {}, body: e.message });
|
|
444
456
|
}
|
|
445
457
|
return;
|
|
446
458
|
}
|