@ccpocket/bridge 1.79.0 → 1.80.1

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/websocket.js CHANGED
@@ -10,6 +10,7 @@ import { SdkProcess, listAvailableClaudeModels, } from "./sdk-process.js";
10
10
  import { codexErrorMessage, CodexRpcError, CodexProcess, } from "./codex-process.js";
11
11
  import { stopManagedCodexAppServers } from "./codex-transport.js";
12
12
  import { parseClientMessage, } from "./parser.js";
13
+ import { BRIDGE_PROTOCOL_MAX_VERSION, BRIDGE_PROTOCOL_MIN_VERSION, clientProtocolRange, negotiateProtocolVersion, } from "./protocol-version.js";
13
14
  import { getAllRecentSessions, getCodexSessionHistory, getSessionHistory, codexUserTurnUuid, codexThreadToSessionHistory, findSessionsByClaudeIds, extractMessageImages, getClaudeSessionName, getCodexSessionIndexMetadata, loadCodexSessionNames, renameClaudeSession, renameCodexSession, saveCodexSessionProfile, } from "./sessions-index.js";
14
15
  import { isSafeUploadFileName, UploadStoreError, } from "./upload-store.js";
15
16
  import { formatResumePerformanceLog, summarizeResumeHistory, } from "./resume-metrics.js";
@@ -564,6 +565,8 @@ export class BridgeWebSocketServer {
564
565
  deltaBatches = new Map();
565
566
  platform;
566
567
  clientSupportedServerMessages = new WeakMap();
568
+ clientProtocolVersions = new WeakMap();
569
+ rejectedProtocolClients = new WeakSet();
567
570
  pendingClaudeResumeInputs = new WeakMap();
568
571
  resumeOperations = new Map();
569
572
  constructor(options) {
@@ -1852,6 +1855,8 @@ export class BridgeWebSocketServer {
1852
1855
  const projects = this.projectHistory?.getProjects() ?? [];
1853
1856
  this.send(ws, { type: "project_history", projects });
1854
1857
  ws.on("message", (data) => {
1858
+ if (this.rejectedProtocolClients.has(ws))
1859
+ return;
1855
1860
  const raw = data.toString();
1856
1861
  const msg = parseClientMessage(raw);
1857
1862
  if (!msg) {
@@ -1865,6 +1870,18 @@ export class BridgeWebSocketServer {
1865
1870
  catch {
1866
1871
  /* ignore */
1867
1872
  }
1873
+ if (rawType === "client_capabilities") {
1874
+ this.rejectedProtocolClients.add(ws);
1875
+ this.send(ws, {
1876
+ type: "error",
1877
+ errorCode: "incompatible_protocol",
1878
+ message: "Client advertised a malformed protocol range.",
1879
+ protocolVersion: BRIDGE_PROTOCOL_MAX_VERSION,
1880
+ minimumProtocolVersion: BRIDGE_PROTOCOL_MIN_VERSION,
1881
+ });
1882
+ ws.close(4406, "Incompatible protocol version");
1883
+ return;
1884
+ }
1868
1885
  console.error("[ws] Unsupported message:", rawType ?? raw.slice(0, 200));
1869
1886
  this.send(ws, {
1870
1887
  type: "error",
@@ -1899,7 +1916,26 @@ export class BridgeWebSocketServer {
1899
1916
  void this.refreshClaudeModels();
1900
1917
  }
1901
1918
  async handleClientMessage(msg, ws) {
1919
+ if (this.rejectedProtocolClients.has(ws))
1920
+ return;
1902
1921
  if (msg.type === "client_capabilities") {
1922
+ const clientRange = clientProtocolRange(msg);
1923
+ const selectedProtocolVersion = negotiateProtocolVersion(clientRange);
1924
+ if (selectedProtocolVersion === null) {
1925
+ this.rejectedProtocolClients.add(ws);
1926
+ this.send(ws, {
1927
+ type: "error",
1928
+ errorCode: "incompatible_protocol",
1929
+ protocolVersion: BRIDGE_PROTOCOL_MAX_VERSION,
1930
+ minimumProtocolVersion: BRIDGE_PROTOCOL_MIN_VERSION,
1931
+ message: `Client protocol range ${clientRange.min}-${clientRange.max} `
1932
+ + `does not overlap Bridge protocol range `
1933
+ + `${BRIDGE_PROTOCOL_MIN_VERSION}-${BRIDGE_PROTOCOL_MAX_VERSION}.`,
1934
+ });
1935
+ ws.close(4406, "Incompatible protocol version");
1936
+ return;
1937
+ }
1938
+ this.clientProtocolVersions.set(ws, selectedProtocolVersion);
1903
1939
  this.clientSupportedServerMessages.set(ws, new Set(msg.supportedServerMessages ?? []));
1904
1940
  this.sendPromptHistoryStatus(ws);
1905
1941
  return;
@@ -6144,6 +6180,8 @@ export class BridgeWebSocketServer {
6144
6180
  defaultCodexProfile: this.defaultCodexProfile,
6145
6181
  codexAutoReviewDisabled: this.codexAutoReviewDisabled,
6146
6182
  bridgeVersion: getPackageVersion(),
6183
+ protocolVersion: BRIDGE_PROTOCOL_MAX_VERSION,
6184
+ minimumProtocolVersion: BRIDGE_PROTOCOL_MIN_VERSION,
6147
6185
  protocolCapabilities: [
6148
6186
  "project_request_correlation_v1",
6149
6187
  "session_context_v1",
@@ -6180,6 +6218,8 @@ export class BridgeWebSocketServer {
6180
6218
  defaultCodexProfile: this.defaultCodexProfile,
6181
6219
  codexAutoReviewDisabled: this.codexAutoReviewDisabled,
6182
6220
  bridgeVersion: getPackageVersion(),
6221
+ protocolVersion: BRIDGE_PROTOCOL_MAX_VERSION,
6222
+ minimumProtocolVersion: BRIDGE_PROTOCOL_MIN_VERSION,
6183
6223
  protocolCapabilities: [
6184
6224
  "project_request_correlation_v1",
6185
6225
  "session_context_v1",