@rallycry/conveyor-agent 6.0.5 → 6.0.6

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.
@@ -960,6 +960,7 @@ var RECONNECT_BASE_MS = 1e3;
960
960
  var RECONNECT_MAX_MS = 3e4;
961
961
  var TunnelClient = class _TunnelClient {
962
962
  static STABLE_MS = 3e4;
963
+ static MAX_RECONNECT_ATTEMPTS = 10;
963
964
  apiUrl;
964
965
  token;
965
966
  localPort;
@@ -968,6 +969,7 @@ var TunnelClient = class _TunnelClient {
968
969
  reconnectAttempts = 0;
969
970
  reconnectTimer = null;
970
971
  connectedAt = 0;
972
+ loggedNoWebSocket = false;
971
973
  constructor(apiUrl, token, localPort) {
972
974
  this.apiUrl = apiUrl;
973
975
  this.token = token;
@@ -975,6 +977,13 @@ var TunnelClient = class _TunnelClient {
975
977
  }
976
978
  connect() {
977
979
  if (this.stopped) return;
980
+ if (typeof WebSocket === "undefined") {
981
+ if (!this.loggedNoWebSocket) {
982
+ logger2.warn("WebSocket not available in this environment, tunnel disabled");
983
+ this.loggedNoWebSocket = true;
984
+ }
985
+ return;
986
+ }
978
987
  const wsUrl = this.apiUrl.replace(/^http/, "ws").replace(/\/$/, "");
979
988
  const url = `${wsUrl}/api/tunnel?token=${encodeURIComponent(this.token)}`;
980
989
  try {
@@ -990,7 +999,8 @@ var TunnelClient = class _TunnelClient {
990
999
  logger2.info("Tunnel connected", { port: this.localPort });
991
1000
  });
992
1001
  this.ws.addEventListener("close", (event) => {
993
- logger2.info("Tunnel disconnected", { code: event.code, reason: event.reason });
1002
+ const closeEvent = event;
1003
+ logger2.info("Tunnel disconnected", { code: closeEvent.code, reason: closeEvent.reason });
994
1004
  this.scheduleReconnect();
995
1005
  });
996
1006
  this.ws.addEventListener("error", (event) => {
@@ -998,7 +1008,8 @@ var TunnelClient = class _TunnelClient {
998
1008
  logger2.warn("Tunnel error", { error: msg });
999
1009
  });
1000
1010
  this.ws.addEventListener("message", (event) => {
1001
- this.handleMessage(event.data);
1011
+ const messageEvent = event;
1012
+ this.handleMessage(messageEvent.data);
1002
1013
  });
1003
1014
  }
1004
1015
  disconnect() {
@@ -1014,12 +1025,18 @@ var TunnelClient = class _TunnelClient {
1014
1025
  }
1015
1026
  scheduleReconnect() {
1016
1027
  if (this.stopped) return;
1017
- if (Date.now() - this.connectedAt >= _TunnelClient.STABLE_MS) {
1028
+ if (this.connectedAt > 0 && Date.now() - this.connectedAt >= _TunnelClient.STABLE_MS) {
1018
1029
  this.reconnectAttempts = 0;
1019
1030
  }
1031
+ if (this.reconnectAttempts >= _TunnelClient.MAX_RECONNECT_ATTEMPTS) {
1032
+ logger2.warn("Tunnel gave up after max reconnect attempts", {
1033
+ attempts: this.reconnectAttempts
1034
+ });
1035
+ return;
1036
+ }
1020
1037
  const delay = Math.min(RECONNECT_BASE_MS * 2 ** this.reconnectAttempts, RECONNECT_MAX_MS);
1021
1038
  this.reconnectAttempts++;
1022
- logger2.info("Tunnel reconnecting", { delay, attempt: this.reconnectAttempts });
1039
+ logger2.debug("Tunnel reconnecting", { delay, attempt: this.reconnectAttempts });
1023
1040
  this.reconnectTimer = setTimeout(() => this.connect(), delay);
1024
1041
  }
1025
1042
  // ---------------------------------------------------------------------------
@@ -1141,7 +1158,8 @@ var TunnelClient = class _TunnelClient {
1141
1158
  this.send(JSON.stringify({ type: "ws-open", id }));
1142
1159
  });
1143
1160
  localWs.addEventListener("message", (event) => {
1144
- const data = typeof event.data === "string" ? event.data : String(event.data);
1161
+ const messageEvent = event;
1162
+ const data = typeof messageEvent.data === "string" ? messageEvent.data : String(messageEvent.data);
1145
1163
  this.send(JSON.stringify({ type: "ws-data", id, data }));
1146
1164
  });
1147
1165
  localWs.addEventListener("close", () => {
@@ -1228,10 +1246,6 @@ async function processAssistantEvent(event, host, turnToolCalls) {
1228
1246
  if (turnTextParts.length > 0) {
1229
1247
  host.connection.postChatMessage(turnTextParts.join("\n\n"));
1230
1248
  }
1231
- if (turnToolCalls.length > 0) {
1232
- host.connection.sendEvent({ type: "turn_end", toolCalls: [...turnToolCalls] });
1233
- turnToolCalls.length = 0;
1234
- }
1235
1249
  }
1236
1250
  var API_ERROR_PATTERN = /API Error: [45]\d\d/;
1237
1251
  var IMAGE_ERROR_PATTERN = /Could not process image/i;
@@ -1473,6 +1487,17 @@ var API_ERROR_PATTERN2 = /API Error: [45]\d\d/;
1473
1487
  function stopTypingIfNeeded(host, isTyping) {
1474
1488
  if (isTyping) host.connection.sendTypingStop();
1475
1489
  }
1490
+ function flushPendingToolCalls(host, turnToolCalls) {
1491
+ if (turnToolCalls.length === 0) return;
1492
+ for (let i = 0; i < turnToolCalls.length; i++) {
1493
+ if (i < host.pendingToolOutputs.length) {
1494
+ turnToolCalls[i].output = host.pendingToolOutputs[i];
1495
+ }
1496
+ }
1497
+ host.connection.sendEvent({ type: "turn_end", toolCalls: [...turnToolCalls] });
1498
+ turnToolCalls.length = 0;
1499
+ host.pendingToolOutputs.length = 0;
1500
+ }
1476
1501
  async function processSystemCase(event, host, context, state) {
1477
1502
  if (event.subtype === "init") {
1478
1503
  const stored = await handleSystemEvent(event, host, context, state.sessionIdStored);
@@ -1509,6 +1534,7 @@ async function processResultCase(event, host, context, startTime, state) {
1509
1534
  );
1510
1535
  if (info.stoppedTyping) state.isTyping = false;
1511
1536
  state.retriable = info.retriable;
1537
+ if (!info.retriable) state.sawApiError = false;
1512
1538
  state.resultSummary = info.resultSummary;
1513
1539
  if (info.staleSession) state.staleSession = true;
1514
1540
  if (info.authError) state.authError = true;
@@ -1531,6 +1557,7 @@ async function processEvents(events, context, host) {
1531
1557
  };
1532
1558
  for await (const event of events) {
1533
1559
  if (host.isStopped()) break;
1560
+ flushPendingToolCalls(host, state.turnToolCalls);
1534
1561
  const now = Date.now();
1535
1562
  if (now - lastStatusEmit >= STATUS_REEMIT_INTERVAL_MS) {
1536
1563
  host.connection.emitStatus("running");
@@ -1560,6 +1587,7 @@ async function processEvents(events, context, host) {
1560
1587
  break;
1561
1588
  }
1562
1589
  }
1590
+ flushPendingToolCalls(host, state.turnToolCalls);
1563
1591
  stopTypingIfNeeded(host, state.isTyping);
1564
1592
  return {
1565
1593
  retriable: state.retriable || state.sawApiError,
@@ -4569,6 +4597,7 @@ function buildHooks(host) {
4569
4597
  output,
4570
4598
  isError: false
4571
4599
  });
4600
+ host.pendingToolOutputs.push(output);
4572
4601
  }
4573
4602
  return await Promise.resolve({ continue: true });
4574
4603
  }
@@ -4930,7 +4959,6 @@ var CostTracker = class {
4930
4959
 
4931
4960
  // src/runner/plan-sync.ts
4932
4961
  import { readdirSync, statSync, readFileSync } from "fs";
4933
- import { homedir } from "os";
4934
4962
  import { join as join3 } from "path";
4935
4963
  var PlanSync = class {
4936
4964
  planFileSnapshot = /* @__PURE__ */ new Map();
@@ -4945,7 +4973,7 @@ var PlanSync = class {
4945
4973
  this.workspaceDir = workspaceDir;
4946
4974
  }
4947
4975
  getPlanDirs() {
4948
- return [join3(homedir(), ".claude", "plans"), join3(this.workspaceDir, ".claude", "plans")];
4976
+ return [join3(this.workspaceDir, ".claude", "plans")];
4949
4977
  }
4950
4978
  snapshotPlanFiles() {
4951
4979
  this.planFileSnapshot.clear();
@@ -5300,6 +5328,7 @@ function buildQueryHost(deps) {
5300
5328
  },
5301
5329
  sessionIds: deps.sessionIds,
5302
5330
  activeQuery: null,
5331
+ pendingToolOutputs: [],
5303
5332
  isStopped: deps.isStopped,
5304
5333
  createInputStream: deps.createInputStream,
5305
5334
  snapshotPlanFiles: () => deps.planSync.snapshotPlanFiles(),
@@ -7308,4 +7337,4 @@ export {
7308
7337
  ProjectRunner,
7309
7338
  FileCache
7310
7339
  };
7311
- //# sourceMappingURL=chunk-PLSKXQTB.js.map
7340
+ //# sourceMappingURL=chunk-RHRQJO5E.js.map