lunel-cli 0.1.95 → 0.1.97

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/dist/index.js CHANGED
@@ -2754,6 +2754,7 @@ async function processMessage(message) {
2754
2754
  };
2755
2755
  }
2756
2756
  }
2757
+ let currentReattachGeneration = null;
2757
2758
  function normalizeGatewayUrl(input) {
2758
2759
  const raw = input.trim();
2759
2760
  if (!raw) {
@@ -2853,6 +2854,47 @@ async function getAssignedProxyUrl(password) {
2853
2854
  }
2854
2855
  return normalizeGatewayUrl(payload.proxyUrl);
2855
2856
  }
2857
+ async function claimReattach(password) {
2858
+ const response = await fetch(new URL("/v2/reattach/claim", MANAGER_URL), {
2859
+ method: "POST",
2860
+ headers: { "Content-Type": "application/json" },
2861
+ body: JSON.stringify({
2862
+ password,
2863
+ role: "cli",
2864
+ }),
2865
+ });
2866
+ if (!response.ok) {
2867
+ let message = `Failed to claim reattach from manager: ${response.status}`;
2868
+ try {
2869
+ const payload = await response.json();
2870
+ if (payload.error) {
2871
+ message = payload.error;
2872
+ }
2873
+ else if (payload.reason) {
2874
+ message = payload.reason;
2875
+ }
2876
+ }
2877
+ catch {
2878
+ // ignore parse failures and use the fallback message
2879
+ }
2880
+ throw new Error(message);
2881
+ }
2882
+ const payload = await response.json();
2883
+ if (typeof payload.proxyUrl !== "string" || !payload.proxyUrl) {
2884
+ throw new Error("Manager returned invalid reattach proxy assignment");
2885
+ }
2886
+ if (typeof payload.generation !== "number" || !Number.isFinite(payload.generation) || payload.generation < 1) {
2887
+ throw new Error("Manager returned invalid reattach generation");
2888
+ }
2889
+ if (typeof payload.expiresAt !== "number" || !Number.isFinite(payload.expiresAt)) {
2890
+ throw new Error("Manager returned invalid reattach expiry");
2891
+ }
2892
+ return {
2893
+ proxyUrl: normalizeGatewayUrl(payload.proxyUrl),
2894
+ generation: payload.generation,
2895
+ expiresAt: payload.expiresAt,
2896
+ };
2897
+ }
2856
2898
  async function revokePassword(password, reason = "revoked by cli --new") {
2857
2899
  const response = await fetch(new URL("/v2/revoke", MANAGER_URL), {
2858
2900
  method: "POST",
@@ -2924,6 +2966,7 @@ async function connectWebSocketV2() {
2924
2966
  gatewayUrl,
2925
2967
  password: currentSessionPassword,
2926
2968
  sessionSecret: currentSessionPassword,
2969
+ generation: currentReattachGeneration,
2927
2970
  role: "cli",
2928
2971
  debugLog: DEBUG_MODE ? debugLog : undefined,
2929
2972
  handlers: {
@@ -2998,7 +3041,9 @@ async function handleConnectionDrop(reason) {
2998
3041
  const base = Math.min(250 * 2 ** (attempt - 1), 30_000);
2999
3042
  const delayMs = Math.round(base * (0.8 + Math.random() * 0.4));
3000
3043
  try {
3001
- currentPrimaryGateway = await getAssignedProxyUrl(currentSessionPassword);
3044
+ const reattach = await claimReattach(currentSessionPassword);
3045
+ currentPrimaryGateway = reattach.proxyUrl;
3046
+ currentReattachGeneration = reattach.generation;
3002
3047
  await connectWebSocketV2();
3003
3048
  debugLog(`[reconnect] connected via ${activeGatewayUrl}`);
3004
3049
  return;
@@ -3069,7 +3114,15 @@ async function main() {
3069
3114
  }
3070
3115
  currentSessionCode = sessionCodeToUse;
3071
3116
  currentSessionPassword = sessionPasswordToUse;
3072
- currentPrimaryGateway = await getAssignedProxyUrl(sessionPasswordToUse);
3117
+ if (usedSavedSession) {
3118
+ const reattach = await claimReattach(sessionPasswordToUse);
3119
+ currentPrimaryGateway = reattach.proxyUrl;
3120
+ currentReattachGeneration = reattach.generation;
3121
+ }
3122
+ else {
3123
+ currentPrimaryGateway = await getAssignedProxyUrl(sessionPasswordToUse);
3124
+ currentReattachGeneration = null;
3125
+ }
3073
3126
  activeGatewayUrl = currentPrimaryGateway;
3074
3127
  await connectWebSocketV2();
3075
3128
  }
@@ -74,4 +74,4 @@ export declare function decodeV2BinaryFrame(data: Uint8Array): {
74
74
  type: number;
75
75
  payload: Uint8Array;
76
76
  } | null;
77
- export declare function buildSessionV2WsUrl(gatewayUrl: string, role: "cli" | "app", password: string): string;
77
+ export declare function buildSessionV2WsUrl(gatewayUrl: string, role: "cli" | "app", password: string, generation?: number | null): string;
@@ -66,11 +66,14 @@ export function decodeV2BinaryFrame(data) {
66
66
  payload: data.subarray(3),
67
67
  };
68
68
  }
69
- export function buildSessionV2WsUrl(gatewayUrl, role, password) {
69
+ export function buildSessionV2WsUrl(gatewayUrl, role, password, generation) {
70
70
  const wsBase = gatewayUrl.replace(/^https:/, "wss:");
71
71
  if (!wsBase.startsWith("wss://")) {
72
72
  throw new Error("Gateway URL must use https://");
73
73
  }
74
74
  const query = new URLSearchParams({ password });
75
+ if (typeof generation === "number" && Number.isFinite(generation) && generation > 0) {
76
+ query.set("generation", String(generation));
77
+ }
75
78
  return `${wsBase}/v2/ws/${role}?${query.toString()}`;
76
79
  }
@@ -10,6 +10,7 @@ export interface V2TransportOptions {
10
10
  gatewayUrl: string;
11
11
  password: string;
12
12
  sessionSecret: string;
13
+ generation?: number | null;
13
14
  role: "cli" | "app";
14
15
  handlers: V2TransportHandlers;
15
16
  debugLog?: (message: string, ...args: unknown[]) => void;
@@ -44,7 +44,7 @@ export class V2SessionTransport {
44
44
  this.secureReadyResolve = resolve;
45
45
  this.secureReadyReject = reject;
46
46
  });
47
- const wsUrl = buildSessionV2WsUrl(this.options.gatewayUrl, this.options.role, this.options.password);
47
+ const wsUrl = buildSessionV2WsUrl(this.options.gatewayUrl, this.options.role, this.options.password, this.options.generation);
48
48
  await new Promise((resolve, reject) => {
49
49
  const ws = new WebSocket(wsUrl);
50
50
  let opened = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lunel-cli",
3
- "version": "0.1.95",
3
+ "version": "0.1.97",
4
4
  "author": [
5
5
  {
6
6
  "name": "Soham Bharambe",