remodex-windows-fix 1.0.6 → 1.0.7

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
@@ -30,27 +30,74 @@ remodex-windows-fix
30
30
 
31
31
  ## Usage
32
32
 
33
- Start the bridge:
34
-
35
- ```bash
36
- remodex-windows-fix up
37
- ```
38
-
39
- Resume the last active thread:
33
+ Start the bridge:
34
+
35
+ ```bash
36
+ remodex-windows-fix up
37
+ ```
38
+
39
+ Reset the saved pairing state and force a brand new QR:
40
+
41
+ ```bash
42
+ remodex-windows-fix reset-pairing
43
+ ```
44
+
45
+ Resume the last active thread:
40
46
 
41
47
  ```bash
42
48
  remodex-windows-fix resume
43
49
  ```
44
50
 
45
- Watch rollout output:
46
-
47
- ```bash
48
- remodex-windows-fix watch [threadId]
49
- ```
50
-
51
- ## Windows Override
52
-
53
- If you want to force a specific Codex binary, set one of these environment variables before running `remodex up`:
51
+ Watch rollout output:
52
+
53
+ ```bash
54
+ remodex-windows-fix watch [threadId]
55
+ ```
56
+
57
+ Get a fresh QR on Windows without stale pairing state:
58
+
59
+ ```bat
60
+ run-clean-qr.bat
61
+ ```
62
+
63
+ This helper:
64
+
65
+ - stops any existing `remodex-windows-fix` bridge process
66
+ - runs `reset-pairing`
67
+ - starts a fresh bridge in a new PowerShell window
68
+ - waits for `C:\Users\%USERNAME%\.remodex\pairing-qr.png` and opens it automatically
69
+
70
+ It defaults to:
71
+
72
+ ```text
73
+ wss://remodex-relay.th07290828.workers.dev/relay
74
+ ```
75
+
76
+ You can also pass a custom relay URL:
77
+
78
+ ```bat
79
+ run-clean-qr.bat wss://YOUR-RELAY/relay
80
+ ```
81
+
82
+ ## Pairing Behavior
83
+
84
+ The bridge now keeps a stable saved relay session id, so you only need to scan the QR once per paired iPhone in normal use.
85
+
86
+ After the first QR pairing:
87
+
88
+ - you can stop and start `remodex-windows-fix up` again
89
+ - the same iPhone can reconnect with trusted reconnect
90
+ - you do not need a fresh QR unless you intentionally reset pairing
91
+
92
+ Use `remodex-windows-fix reset-pairing` when you want to:
93
+
94
+ - pair a different iPhone
95
+ - discard the saved trust/session state
96
+ - force a brand new QR bootstrap
97
+
98
+ ## Windows Override
99
+
100
+ If you want to force a specific Codex binary, set one of these environment variables before running `remodex up`:
54
101
 
55
102
  ```powershell
56
103
  $env:REMODEX_CODEX_BIN = "C:\Users\th072\AppData\Roaming\npm\codex.cmd"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remodex-windows-fix",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Local bridge between Codex and the Remodex mobile app with a Windows-safe Codex launcher.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -54,15 +54,22 @@ function resetBridgeDeviceState() {
54
54
  };
55
55
  }
56
56
 
57
- // Generates a fresh relay session for every bridge launch so QR pairing stays explicit per-run.
57
+ // Reuses the saved relay session so the paired iPhone can reconnect without rescanning.
58
58
  function resolveBridgeRelaySession(state) {
59
+ const persistedSessionId = normalizeNonEmptyString(state?.relaySessionId);
59
60
  return {
60
- deviceState: state,
61
- isPersistent: false,
62
- sessionId: randomUUID(),
61
+ deviceState: persistedSessionId
62
+ ? state
63
+ : rememberRelaySessionId(state, randomUUID(), { persist: true }),
64
+ isPersistent: true,
65
+ sessionId: persistedSessionId || readRelaySessionId(state),
63
66
  };
64
67
  }
65
68
 
69
+ function readRelaySessionId(state) {
70
+ return normalizeNonEmptyString(state?.relaySessionId);
71
+ }
72
+
66
73
  // Persists the trusted iPhone identity so reconnects can be authenticated during the current pairing flow.
67
74
  function rememberTrustedPhone(state, phoneDeviceId, phoneIdentityPublicKey, { persist = true } = {}) {
68
75
  const normalizedDeviceId = normalizeNonEmptyString(phoneDeviceId);
@@ -102,6 +109,7 @@ function createBridgeDeviceState() {
102
109
  macDeviceId: randomUUID(),
103
110
  macIdentityPublicKey: base64UrlToBase64(publicJwk.x),
104
111
  macIdentityPrivateKey: base64UrlToBase64(privateJwk.d),
112
+ relaySessionId: randomUUID(),
105
113
  trustedPhones: {},
106
114
  };
107
115
  }
@@ -310,6 +318,7 @@ function normalizeBridgeDeviceState(rawState) {
310
318
  const macDeviceId = normalizeNonEmptyString(rawState?.macDeviceId);
311
319
  const macIdentityPublicKey = normalizeNonEmptyString(rawState?.macIdentityPublicKey);
312
320
  const macIdentityPrivateKey = normalizeNonEmptyString(rawState?.macIdentityPrivateKey);
321
+ const relaySessionId = normalizeNonEmptyString(rawState?.relaySessionId) || randomUUID();
313
322
 
314
323
  if (!macDeviceId || !macIdentityPublicKey || !macIdentityPrivateKey) {
315
324
  throw new Error("Bridge device state is incomplete");
@@ -332,10 +341,27 @@ function normalizeBridgeDeviceState(rawState) {
332
341
  macDeviceId,
333
342
  macIdentityPublicKey,
334
343
  macIdentityPrivateKey,
344
+ relaySessionId,
335
345
  trustedPhones,
336
346
  };
337
347
  }
338
348
 
349
+ function rememberRelaySessionId(state, relaySessionId, { persist = true } = {}) {
350
+ const normalizedRelaySessionId = normalizeNonEmptyString(relaySessionId);
351
+ if (!normalizedRelaySessionId) {
352
+ return state;
353
+ }
354
+
355
+ const nextState = normalizeBridgeDeviceState({
356
+ ...state,
357
+ relaySessionId: normalizedRelaySessionId,
358
+ });
359
+ if (persist) {
360
+ writeBridgeDeviceState(nextState);
361
+ }
362
+ return nextState;
363
+ }
364
+
339
365
  function bridgeStatesEqual(left, right) {
340
366
  return JSON.stringify(left) === JSON.stringify(right);
341
367
  }
@@ -29,7 +29,7 @@ const HANDSHAKE_MODE_QR_BOOTSTRAP = "qr_bootstrap";
29
29
  const HANDSHAKE_MODE_TRUSTED_RECONNECT = "trusted_reconnect";
30
30
  const SECURE_SENDER_MAC = "mac";
31
31
  const SECURE_SENDER_IPHONE = "iphone";
32
- const MAX_PAIRING_AGE_MS = 5 * 60 * 1000;
32
+ const MAX_PAIRING_AGE_MS = 365 * 24 * 60 * 60 * 1000;
33
33
  const MAX_BRIDGE_OUTBOUND_MESSAGES = 500;
34
34
  const MAX_BRIDGE_OUTBOUND_BYTES = 10 * 1024 * 1024;
35
35