@makerbi/remodex 1.3.9 → 1.3.10
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/remodex.js +0 -0
- package/package.json +2 -2
- package/src/bridge.js +62 -13
- package/src/package-version-status.js +1 -1
package/bin/remodex.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@makerbi/remodex",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.10",
|
|
4
4
|
"description": "Local bridge between Codex and the Remodex mobile app. Run `remodex up` to start.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"remodex": "
|
|
7
|
+
"remodex": "bin/remodex.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
package/src/bridge.js
CHANGED
|
@@ -55,6 +55,9 @@ const RELAY_WATCHDOG_PING_INTERVAL_MS = 10_000;
|
|
|
55
55
|
const RELAY_WATCHDOG_STALE_AFTER_MS = 70_000;
|
|
56
56
|
const BRIDGE_STATUS_HEARTBEAT_INTERVAL_MS = 5_000;
|
|
57
57
|
const STALE_RELAY_STATUS_MESSAGE = "Relay heartbeat stalled; reconnect pending.";
|
|
58
|
+
const CLOSE_CODE_INVALID_RELAY_REQUEST = 4000;
|
|
59
|
+
const CLOSE_CODE_REPLACED_BY_NEW_MAC = 4001;
|
|
60
|
+
const CLOSE_CODE_MAC_UNAUTHORIZED = 4005;
|
|
58
61
|
const RELAY_HISTORY_IMAGE_REFERENCE_URL = "remodex://history-image-elided";
|
|
59
62
|
const RELAY_THREAD_PAYLOAD_SOFT_LIMIT_BYTES = 4 * 1024 * 1024;
|
|
60
63
|
const RELAY_HISTORY_TEXT_TAIL_LIMIT_CHARS = 24_000;
|
|
@@ -146,6 +149,7 @@ function startBridge({
|
|
|
146
149
|
let lastRelayActivityAt = 0;
|
|
147
150
|
let lastPublishedBridgeStatus = null;
|
|
148
151
|
let lastConnectionStatus = null;
|
|
152
|
+
let lastConnectionError = "";
|
|
149
153
|
let codexLaunchState = config.codexEndpoint ? "connected" : "starting";
|
|
150
154
|
let codexHandshakeState = config.codexEndpoint ? "warm" : "cold";
|
|
151
155
|
const forwardedInitializeRequestIds = new Set();
|
|
@@ -322,35 +326,42 @@ function startBridge({
|
|
|
322
326
|
}
|
|
323
327
|
|
|
324
328
|
// Keeps npm start output compact by emitting only high-signal connection states.
|
|
325
|
-
function logConnectionStatus(status) {
|
|
326
|
-
if (lastConnectionStatus === status) {
|
|
329
|
+
function logConnectionStatus(status, lastError = "") {
|
|
330
|
+
if (lastConnectionStatus === status && lastConnectionError === lastError) {
|
|
327
331
|
return;
|
|
328
332
|
}
|
|
329
333
|
|
|
330
334
|
lastConnectionStatus = status;
|
|
335
|
+
lastConnectionError = lastError;
|
|
331
336
|
publishBridgeStatus({
|
|
332
337
|
state: "running",
|
|
333
338
|
connectionStatus: status,
|
|
334
339
|
pid: process.pid,
|
|
335
|
-
lastError
|
|
340
|
+
lastError,
|
|
336
341
|
});
|
|
337
342
|
console.log(`[remodex] ${status}`);
|
|
343
|
+
if (lastError) {
|
|
344
|
+
console.error(`[remodex] ${lastError}`);
|
|
345
|
+
}
|
|
338
346
|
}
|
|
339
347
|
|
|
340
348
|
// Retries the relay socket while preserving the active Codex process and session id.
|
|
341
|
-
function scheduleRelayReconnect(closeCode) {
|
|
349
|
+
function scheduleRelayReconnect(closeCode, closeReason = "") {
|
|
342
350
|
if (isShuttingDown) {
|
|
343
351
|
return;
|
|
344
352
|
}
|
|
345
353
|
|
|
346
|
-
if (closeCode
|
|
347
|
-
|
|
354
|
+
if (isTerminalRelayCloseCode(closeCode)) {
|
|
355
|
+
const lastError = buildRelayCloseStatusError(closeCode, closeReason);
|
|
356
|
+
logConnectionStatus("disconnected", lastError);
|
|
348
357
|
shutdown(codex, () => socket, () => {
|
|
349
358
|
isShuttingDown = true;
|
|
350
359
|
bridgeWakeAssertion.stop();
|
|
351
360
|
clearReconnectTimer();
|
|
352
361
|
clearRelayWatchdog();
|
|
353
362
|
clearBridgeStatusHeartbeat();
|
|
363
|
+
}, {
|
|
364
|
+
exitCode: closeCode === CLOSE_CODE_MAC_UNAUTHORIZED ? 1 : 0,
|
|
354
365
|
});
|
|
355
366
|
return;
|
|
356
367
|
}
|
|
@@ -421,18 +432,19 @@ function startBridge({
|
|
|
421
432
|
markRelayActivity();
|
|
422
433
|
});
|
|
423
434
|
|
|
424
|
-
nextSocket.on("close", (code) => {
|
|
435
|
+
nextSocket.on("close", (code, reason) => {
|
|
436
|
+
const closeReason = normalizeWebSocketCloseReason(reason);
|
|
425
437
|
if (socket === nextSocket) {
|
|
426
438
|
clearRelayWatchdog();
|
|
427
439
|
}
|
|
428
|
-
logConnectionStatus("disconnected");
|
|
440
|
+
logConnectionStatus("disconnected", buildRelayCloseStatusError(code, closeReason));
|
|
429
441
|
if (socket === nextSocket) {
|
|
430
442
|
socket = null;
|
|
431
443
|
}
|
|
432
444
|
stopContextUsageWatcher();
|
|
433
445
|
rolloutLiveMirror?.stopAll();
|
|
434
446
|
desktopRefresher.handleTransportReset();
|
|
435
|
-
scheduleRelayReconnect(code);
|
|
447
|
+
scheduleRelayReconnect(code, closeReason);
|
|
436
448
|
});
|
|
437
449
|
|
|
438
450
|
nextSocket.on("error", () => {
|
|
@@ -473,12 +485,13 @@ function startBridge({
|
|
|
473
485
|
codex.onClose(() => {
|
|
474
486
|
clearRelayWatchdog();
|
|
475
487
|
clearBridgeStatusHeartbeat();
|
|
476
|
-
|
|
488
|
+
const lastError = lastConnectionError || "";
|
|
489
|
+
logConnectionStatus("disconnected", lastError);
|
|
477
490
|
publishBridgeStatus({
|
|
478
491
|
state: "stopped",
|
|
479
492
|
connectionStatus: "disconnected",
|
|
480
493
|
pid: process.pid,
|
|
481
|
-
lastError
|
|
494
|
+
lastError,
|
|
482
495
|
});
|
|
483
496
|
isShuttingDown = true;
|
|
484
497
|
bridgeWakeAssertion.stop();
|
|
@@ -1281,7 +1294,7 @@ function buildMacRegistration(deviceState, pairingSession) {
|
|
|
1281
1294
|
};
|
|
1282
1295
|
}
|
|
1283
1296
|
|
|
1284
|
-
function shutdown(codex, getSocket, beforeExit = () => {}) {
|
|
1297
|
+
function shutdown(codex, getSocket, beforeExit = () => {}, { exitCode = 0 } = {}) {
|
|
1285
1298
|
beforeExit();
|
|
1286
1299
|
|
|
1287
1300
|
const socket = getSocket();
|
|
@@ -1291,7 +1304,41 @@ function shutdown(codex, getSocket, beforeExit = () => {}) {
|
|
|
1291
1304
|
|
|
1292
1305
|
codex.shutdown();
|
|
1293
1306
|
|
|
1294
|
-
setTimeout(() => process.exit(
|
|
1307
|
+
setTimeout(() => process.exit(exitCode), 100);
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
function isTerminalRelayCloseCode(closeCode) {
|
|
1311
|
+
return closeCode === CLOSE_CODE_INVALID_RELAY_REQUEST
|
|
1312
|
+
|| closeCode === CLOSE_CODE_REPLACED_BY_NEW_MAC
|
|
1313
|
+
|| closeCode === CLOSE_CODE_MAC_UNAUTHORIZED;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
function normalizeWebSocketCloseReason(reason) {
|
|
1317
|
+
if (typeof reason === "string") {
|
|
1318
|
+
return reason.trim();
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
if (Buffer.isBuffer(reason)) {
|
|
1322
|
+
return reason.toString("utf8").trim();
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
return "";
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
function buildRelayCloseStatusError(closeCode, closeReason = "") {
|
|
1329
|
+
if (!Number.isInteger(closeCode) || closeCode === 1000 || closeCode === 1005) {
|
|
1330
|
+
return "";
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
const normalizedReason = normalizeNonEmptyString(closeReason);
|
|
1334
|
+
if (closeCode === CLOSE_CODE_MAC_UNAUTHORIZED) {
|
|
1335
|
+
return normalizedReason
|
|
1336
|
+
|| "Relay authorization failed. Set REMODEX_RELAY_ACCESS_TOKEN or use a relay that does not require a Mac access token.";
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
return normalizedReason
|
|
1340
|
+
? `Relay closed the connection (${closeCode}): ${normalizedReason}`
|
|
1341
|
+
: `Relay closed the connection (${closeCode}).`;
|
|
1295
1342
|
}
|
|
1296
1343
|
|
|
1297
1344
|
function extractBridgeMessageContext(rawMessage) {
|
|
@@ -2103,10 +2150,12 @@ function persistBridgePreferences(
|
|
|
2103
2150
|
|
|
2104
2151
|
module.exports = {
|
|
2105
2152
|
buildHeartbeatBridgeStatus,
|
|
2153
|
+
buildRelayCloseStatusError,
|
|
2106
2154
|
buildRelayAccessTokenHeaders,
|
|
2107
2155
|
buildRelayUserAgentHeader,
|
|
2108
2156
|
createMacOSBridgeWakeAssertion,
|
|
2109
2157
|
hasRelayConnectionGoneStale,
|
|
2158
|
+
isTerminalRelayCloseCode,
|
|
2110
2159
|
persistBridgePreferences,
|
|
2111
2160
|
sanitizeLiveGeneratedImageMessageForRelay,
|
|
2112
2161
|
sanitizeThreadHistoryImagesForRelay,
|
|
@@ -10,7 +10,7 @@ const { version: installedVersion = "" } = require("../package.json");
|
|
|
10
10
|
const DEFAULT_CACHE_TTL_MS = 30 * 60 * 1000;
|
|
11
11
|
const DEFAULT_EMPTY_CACHE_RETRY_MS = 60 * 1000;
|
|
12
12
|
const DEFAULT_INITIAL_FETCH_WAIT_MS = 250;
|
|
13
|
-
const REMODEX_REGISTRY_URL = "https://registry.npmjs.org/
|
|
13
|
+
const REMODEX_REGISTRY_URL = "https://registry.npmjs.org/@makerbi%2fremodex/latest";
|
|
14
14
|
|
|
15
15
|
function createBridgePackageVersionStatusReader({
|
|
16
16
|
cacheTtlMs = DEFAULT_CACHE_TTL_MS,
|