openzca 0.1.56 → 0.1.57

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.
Files changed (2) hide show
  1. package/dist/cli.js +286 -60
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -3291,6 +3291,125 @@ function inferReplyMessageThreadId(params) {
3291
3291
  return void 0;
3292
3292
  }
3293
3293
 
3294
+ // src/lib/adaptive-batch.ts
3295
+ var RETRYABLE_LOOKUP_ERROR_PATTERNS = [
3296
+ /retry limit/i,
3297
+ /\brate limit/i,
3298
+ /\btoo many requests?\b/i,
3299
+ /\btimeout\b/i,
3300
+ /\btimed out\b/i,
3301
+ /\betimedout\b/i,
3302
+ /\beconnreset\b/i,
3303
+ /\besockettimedout\b/i,
3304
+ /\bsocket hang up\b/i,
3305
+ /\btemporar(?:y|ily)\b/i
3306
+ ];
3307
+ var SPLITTABLE_LOOKUP_ERROR_PATTERNS = [
3308
+ /\binvalid param(?:eter)?s?\b/i,
3309
+ /\binvalid request\b/i,
3310
+ /\bbad request\b/i,
3311
+ /tham so khong hop le/i,
3312
+ /tham số không hợp lệ/i
3313
+ ];
3314
+ function sleep2(ms) {
3315
+ return new Promise((resolve) => {
3316
+ setTimeout(resolve, ms);
3317
+ });
3318
+ }
3319
+ function chunkKeys(keys, size) {
3320
+ const chunkSize = Math.max(1, Math.trunc(size) || 1);
3321
+ const chunks = [];
3322
+ for (let index = 0; index < keys.length; index += chunkSize) {
3323
+ chunks.push(keys.slice(index, index + chunkSize));
3324
+ }
3325
+ return chunks;
3326
+ }
3327
+ function toErrorText(error) {
3328
+ return error instanceof Error ? error.message : String(error);
3329
+ }
3330
+ function isRetryableLookupError(error) {
3331
+ const message = toErrorText(error);
3332
+ return RETRYABLE_LOOKUP_ERROR_PATTERNS.some((pattern) => pattern.test(message));
3333
+ }
3334
+ function isSplittableLookupError(error) {
3335
+ const message = toErrorText(error);
3336
+ return SPLITTABLE_LOOKUP_ERROR_PATTERNS.some((pattern) => pattern.test(message));
3337
+ }
3338
+ async function runAdaptiveBatch(keys, options) {
3339
+ const maxRetries = Math.max(0, options.maxRetries ?? 2);
3340
+ const initialDelayMs = Math.max(0, options.retryDelayMs ?? 400);
3341
+ const backoffMultiplier = Math.max(1, options.backoffMultiplier ?? 2);
3342
+ const shouldRetry = options.shouldRetry ?? isRetryableLookupError;
3343
+ const shouldSplit = options.shouldSplit ?? isSplittableLookupError;
3344
+ let attempt = 0;
3345
+ let delayMs = initialDelayMs;
3346
+ while (true) {
3347
+ try {
3348
+ return await options.fetchBatch(keys) ?? {};
3349
+ } catch (error) {
3350
+ if (keys.length > 1 && shouldSplit(error)) {
3351
+ throw error;
3352
+ }
3353
+ attempt += 1;
3354
+ if (attempt > maxRetries || !shouldRetry(error)) {
3355
+ throw error;
3356
+ }
3357
+ await options.onRetry?.({
3358
+ keys: [...keys],
3359
+ attempt,
3360
+ maxRetries,
3361
+ delayMs,
3362
+ error
3363
+ });
3364
+ if (delayMs > 0) {
3365
+ await sleep2(delayMs);
3366
+ }
3367
+ delayMs = Math.max(delayMs * backoffMultiplier, delayMs + 1);
3368
+ }
3369
+ }
3370
+ }
3371
+ async function fetchAdaptiveObjectBatches(keys, options) {
3372
+ const uniqueKeys = Array.from(new Set(keys.map((value) => value.trim()).filter(Boolean)));
3373
+ const pending = chunkKeys(uniqueKeys, options.initialBatchSize ?? 5);
3374
+ const values = /* @__PURE__ */ new Map();
3375
+ const errors = [];
3376
+ const shouldRetry = options.shouldRetry ?? isRetryableLookupError;
3377
+ const shouldSplit = options.shouldSplit ?? isSplittableLookupError;
3378
+ const continueOnItemError = options.continueOnItemError ?? true;
3379
+ const batchDelayMs = Math.max(0, options.batchDelayMs ?? 75);
3380
+ while (pending.length > 0) {
3381
+ const batch = pending.shift();
3382
+ if (!batch || batch.length === 0) {
3383
+ continue;
3384
+ }
3385
+ try {
3386
+ const result = await runAdaptiveBatch(batch, options);
3387
+ for (const key of batch) {
3388
+ const value = result[key];
3389
+ if (value !== void 0) {
3390
+ values.set(key, value);
3391
+ }
3392
+ }
3393
+ } catch (error) {
3394
+ if (batch.length > 1 && (shouldSplit(error) || shouldRetry(error))) {
3395
+ pending.unshift(...chunkKeys(batch, Math.ceil(batch.length / 2)));
3396
+ continue;
3397
+ }
3398
+ if (!continueOnItemError || batch.length > 1) {
3399
+ throw error;
3400
+ }
3401
+ const itemError = { key: batch[0], error };
3402
+ errors.push(itemError);
3403
+ await options.onItemError?.(itemError);
3404
+ continue;
3405
+ }
3406
+ if (batchDelayMs > 0 && pending.length > 0) {
3407
+ await sleep2(batchDelayMs);
3408
+ }
3409
+ }
3410
+ return { values, errors };
3411
+ }
3412
+
3294
3413
  // src/cli.ts
3295
3414
  var require3 = createRequire2(import.meta.url);
3296
3415
  var { version: PKG_VERSION } = require3("../package.json");
@@ -3532,6 +3651,44 @@ function retrySendMethod(operation, command, metaBuilder) {
3532
3651
  }
3533
3652
  });
3534
3653
  }
3654
+ var LOOKUP_BATCH_SIZE = 5;
3655
+ var LOOKUP_RETRY_COUNT = 2;
3656
+ var LOOKUP_RETRY_DELAY_MS = 400;
3657
+ var LOOKUP_BATCH_DELAY_MS = 75;
3658
+ async function fetchGroupInfoRecords(api, groupIds) {
3659
+ const { values } = await fetchAdaptiveObjectBatches(groupIds, {
3660
+ fetchBatch: async (keys) => {
3661
+ const response = await api.getGroupInfo(keys);
3662
+ return response.gridInfoMap ?? {};
3663
+ },
3664
+ initialBatchSize: LOOKUP_BATCH_SIZE,
3665
+ maxRetries: LOOKUP_RETRY_COUNT,
3666
+ retryDelayMs: LOOKUP_RETRY_DELAY_MS,
3667
+ batchDelayMs: LOOKUP_BATCH_DELAY_MS
3668
+ });
3669
+ return values;
3670
+ }
3671
+ async function fetchGroupInfoRecord(api, groupId) {
3672
+ const groups = await fetchGroupInfoRecords(api, [groupId]);
3673
+ const group2 = groups.get(groupId);
3674
+ if (!group2) {
3675
+ throw new Error(`Group not found: ${groupId}`);
3676
+ }
3677
+ return group2;
3678
+ }
3679
+ async function fetchGroupMemberProfiles(api, memberIds) {
3680
+ const { values } = await fetchAdaptiveObjectBatches(memberIds, {
3681
+ fetchBatch: async (keys) => {
3682
+ const response = await api.getGroupMembersInfo(keys);
3683
+ return response.profiles ?? {};
3684
+ },
3685
+ initialBatchSize: LOOKUP_BATCH_SIZE,
3686
+ maxRetries: LOOKUP_RETRY_COUNT,
3687
+ retryDelayMs: LOOKUP_RETRY_DELAY_MS,
3688
+ batchDelayMs: LOOKUP_BATCH_DELAY_MS
3689
+ });
3690
+ return values;
3691
+ }
3535
3692
  function isProcessAlive(pid) {
3536
3693
  if (!Number.isInteger(pid) || pid <= 0) return false;
3537
3694
  try {
@@ -3737,7 +3894,7 @@ async function startListenerIpcServer(api, profile, sessionId, command) {
3737
3894
  command
3738
3895
  );
3739
3896
  } catch (error) {
3740
- fail(parsed.requestId, toErrorText(error));
3897
+ fail(parsed.requestId, toErrorText2(error));
3741
3898
  writeDebugLine(
3742
3899
  "listen.ipc.upload.error",
3743
3900
  {
@@ -3746,7 +3903,7 @@ async function startListenerIpcServer(api, profile, sessionId, command) {
3746
3903
  requestId: parsed.requestId,
3747
3904
  threadId: parsed.threadId,
3748
3905
  threadType: parsed.threadType,
3749
- message: toErrorText(error)
3906
+ message: toErrorText2(error)
3750
3907
  },
3751
3908
  command
3752
3909
  );
@@ -3775,7 +3932,7 @@ async function startListenerIpcServer(api, profile, sessionId, command) {
3775
3932
  {
3776
3933
  profile,
3777
3934
  sessionId,
3778
- message: toErrorText(error)
3935
+ message: toErrorText2(error)
3779
3936
  },
3780
3937
  command
3781
3938
  );
@@ -3787,7 +3944,7 @@ async function startListenerIpcServer(api, profile, sessionId, command) {
3787
3944
  {
3788
3945
  profile,
3789
3946
  sessionId,
3790
- message: toErrorText(error)
3947
+ message: toErrorText2(error)
3791
3948
  },
3792
3949
  command
3793
3950
  );
@@ -3976,7 +4133,7 @@ async function resolveUploadThreadType(api, profile, threadId, groupFlag, comman
3976
4133
  {
3977
4134
  profile,
3978
4135
  threadId,
3979
- message: toErrorText(error)
4136
+ message: toErrorText2(error)
3980
4137
  },
3981
4138
  command
3982
4139
  );
@@ -4001,7 +4158,7 @@ async function resolveUploadThreadType(api, profile, threadId, groupFlag, comman
4001
4158
  {
4002
4159
  profile,
4003
4160
  threadId,
4004
- message: toErrorText(error)
4161
+ message: toErrorText2(error)
4005
4162
  },
4006
4163
  command
4007
4164
  );
@@ -4242,8 +4399,8 @@ async function persistOutgoingMessageBestEffort(params) {
4242
4399
  });
4243
4400
  }
4244
4401
  }
4245
- async function persistGroupMembersSnapshot(profile, groupId, api) {
4246
- const rows = await listGroupMemberRows(api, groupId);
4402
+ async function persistGroupMembersSnapshot(profile, groupId, api, groupInfo) {
4403
+ const rows = await listGroupMemberRows(api, groupId, groupInfo);
4247
4404
  const snapshotAtMs = Date.now();
4248
4405
  for (const row of rows) {
4249
4406
  await persistContact({
@@ -4448,7 +4605,15 @@ async function prepareDbGroupTarget(params) {
4448
4605
  isHidden: params.hiddenIds.has(params.groupId),
4449
4606
  rawJson: params.rawJson
4450
4607
  });
4451
- await persistGroupMembersSnapshot(params.profile, params.groupId, params.api);
4608
+ if (params.hydrateMembers === false) {
4609
+ return {};
4610
+ }
4611
+ try {
4612
+ await persistGroupMembersSnapshot(params.profile, params.groupId, params.api, params.group);
4613
+ return {};
4614
+ } catch (error) {
4615
+ return { memberSnapshotError: toErrorText2(error) };
4616
+ }
4452
4617
  }
4453
4618
  function resolveContactDisplayName(params) {
4454
4619
  return params.displayName?.trim() || params.zaloName?.trim() || params.fallbackTitle?.trim() || params.userId.trim() || void 0;
@@ -4550,18 +4715,17 @@ async function hydrateUnknownLiveGroup(params) {
4550
4715
  }
4551
4716
  }
4552
4717
  if (group2 || title) {
4553
- await persistThread({
4718
+ await prepareDbGroupTarget({
4554
4719
  profile: params.profile,
4555
- scopeThreadId: params.groupId,
4556
- rawThreadId: params.groupId,
4557
- threadType: "group",
4720
+ api: params.api,
4721
+ groupId: params.groupId,
4722
+ group: group2,
4558
4723
  title,
4559
- rawJson: group2 ? JSON.stringify(group2) : void 0
4724
+ rawJson: group2 ? JSON.stringify(group2) : void 0,
4725
+ pinnedIds: /* @__PURE__ */ new Set(),
4726
+ hiddenIds: /* @__PURE__ */ new Set(),
4727
+ hydrateMembers: Boolean(group2)
4560
4728
  });
4561
- try {
4562
- await persistGroupMembersSnapshot(params.profile, params.groupId, params.api);
4563
- } catch {
4564
- }
4565
4729
  return;
4566
4730
  }
4567
4731
  if (params.fallbackTitle?.trim()) {
@@ -4631,16 +4795,23 @@ async function syncDbGroupHistoryFull(params) {
4631
4795
  pagesRequested = result.pagesRequested;
4632
4796
  listenerImportedCount = await getStoredGroupMessageCount() - beforeCount;
4633
4797
  } catch (error) {
4634
- stopReason = `fallback_window:${toErrorText(error)}`;
4798
+ stopReason = `fallback_window:${toErrorText2(error)}`;
4635
4799
  completeness = "window";
4636
4800
  }
4637
4801
  const fallbackCount = 200;
4638
4802
  params.progress?.(`merging recent group API window (${fallbackCount} per group)`);
4639
4803
  const beforeApiCount = await getStoredGroupMessageCount();
4804
+ const topoffErrors = [];
4640
4805
  for (const groupId of params.targetGroupIds) {
4641
- const messages = await fetchRecentGroupMessagesViaApi(params.api, groupId, fallbackCount);
4642
- await persistMessages(messages);
4643
- params.progress?.(`group ${groupId}: fetched ${messages.length} message(s) from group history API`);
4806
+ try {
4807
+ const messages = await fetchRecentGroupMessagesViaApi(params.api, groupId, fallbackCount);
4808
+ await persistMessages(messages);
4809
+ params.progress?.(`group ${groupId}: fetched ${messages.length} message(s) from group history API`);
4810
+ } catch (error) {
4811
+ const message = toErrorText2(error);
4812
+ topoffErrors.push({ groupId, error: message });
4813
+ params.progress?.(`group ${groupId}: group history API skipped (${message})`);
4814
+ }
4644
4815
  }
4645
4816
  const afterCount = await getStoredGroupMessageCount();
4646
4817
  const apiAddedCount = afterCount - beforeApiCount;
@@ -4670,7 +4841,8 @@ async function syncDbGroupHistoryFull(params) {
4670
4841
  imported,
4671
4842
  completeness,
4672
4843
  stopReason,
4673
- pagesRequested
4844
+ pagesRequested,
4845
+ topoffErrors
4674
4846
  });
4675
4847
  }
4676
4848
  async function syncDbFriendDirectory(params) {
@@ -4807,25 +4979,70 @@ async function runDbSync(params) {
4807
4979
  });
4808
4980
  }
4809
4981
  if (params.mode === "all" || params.mode === "groups") {
4810
- const groups = await buildGroupsDetailed(api);
4982
+ const groups = await api.getAllGroups();
4983
+ const groupIds = Object.keys(groups.gridVerMap ?? {});
4811
4984
  const targetGroupIds = /* @__PURE__ */ new Set();
4812
4985
  const titleById = /* @__PURE__ */ new Map();
4813
- for (const group2 of groups) {
4814
- const record = group2;
4815
- const groupId = normalizeCachedId(record.groupId);
4816
- if (!groupId) continue;
4817
- const title = typeof record.name === "string" && record.name.trim() ? record.name.trim() : typeof record.groupName === "string" && record.groupName.trim() ? record.groupName.trim() : void 0;
4818
- targetGroupIds.add(groupId);
4819
- titleById.set(groupId, title);
4820
- await prepareDbGroupTarget({
4821
- profile,
4822
- api,
4823
- groupId,
4824
- title,
4825
- rawJson: JSON.stringify(group2),
4826
- pinnedIds,
4827
- hiddenIds
4828
- });
4986
+ params.progress?.(`syncing group directory for ${groupIds.length} group(s)`);
4987
+ for (const groupId of groupIds) {
4988
+ let group2;
4989
+ let title;
4990
+ try {
4991
+ try {
4992
+ group2 = await fetchGroupInfoRecord(api, groupId);
4993
+ title = extractGroupTitle(group2);
4994
+ } catch (error) {
4995
+ const message = toErrorText2(error);
4996
+ params.progress?.(`group ${groupId}: metadata unavailable (${message}), continuing`);
4997
+ summary.syncState.push({
4998
+ kind: "group",
4999
+ groupId,
5000
+ status: "warning",
5001
+ stage: "metadata",
5002
+ error: message
5003
+ });
5004
+ }
5005
+ const { memberSnapshotError } = await prepareDbGroupTarget({
5006
+ profile,
5007
+ api,
5008
+ groupId,
5009
+ group: group2,
5010
+ title,
5011
+ rawJson: group2 ? JSON.stringify(group2) : void 0,
5012
+ pinnedIds,
5013
+ hiddenIds,
5014
+ hydrateMembers: Boolean(group2)
5015
+ });
5016
+ if (memberSnapshotError) {
5017
+ params.progress?.(`group ${groupId}: member snapshot unavailable (${memberSnapshotError}), continuing`);
5018
+ summary.syncState.push({
5019
+ kind: "group",
5020
+ groupId,
5021
+ status: "warning",
5022
+ stage: "members",
5023
+ error: memberSnapshotError
5024
+ });
5025
+ }
5026
+ targetGroupIds.add(groupId);
5027
+ titleById.set(groupId, title);
5028
+ } catch (error) {
5029
+ const message = toErrorText2(error);
5030
+ params.progress?.(`group ${groupId}: skipped (${message})`);
5031
+ await setSyncState({
5032
+ profile,
5033
+ scopeThreadId: groupId,
5034
+ threadType: "group",
5035
+ status: "error",
5036
+ error: message
5037
+ });
5038
+ summary.syncState.push({
5039
+ kind: "group",
5040
+ groupId,
5041
+ status: "error",
5042
+ stage: "prepare",
5043
+ error: message
5044
+ });
5045
+ }
4829
5046
  }
4830
5047
  await syncDbGroupHistoryFull({
4831
5048
  profile,
@@ -4841,18 +5058,29 @@ async function runDbSync(params) {
4841
5058
  if (!params.groupId) {
4842
5059
  throw new Error("Missing group id for db sync group.");
4843
5060
  }
4844
- const groupInfo = await api.getGroupInfo(params.groupId);
4845
- const group2 = groupInfo.gridInfoMap[params.groupId];
4846
- const title = typeof group2?.name === "string" && group2.name.trim() ? group2.name.trim() : void 0;
4847
- await prepareDbGroupTarget({
5061
+ const group2 = await fetchGroupInfoRecord(api, params.groupId);
5062
+ const title = extractGroupTitle(group2);
5063
+ const { memberSnapshotError } = await prepareDbGroupTarget({
4848
5064
  profile,
4849
5065
  api,
4850
5066
  groupId: params.groupId,
5067
+ group: group2,
4851
5068
  title,
4852
5069
  rawJson: group2 ? JSON.stringify(group2) : void 0,
4853
5070
  pinnedIds,
4854
- hiddenIds
5071
+ hiddenIds,
5072
+ hydrateMembers: Boolean(group2)
4855
5073
  });
5074
+ if (memberSnapshotError) {
5075
+ params.progress?.(`group ${params.groupId}: member snapshot unavailable (${memberSnapshotError}), continuing`);
5076
+ summary.syncState.push({
5077
+ kind: "group",
5078
+ groupId: params.groupId,
5079
+ status: "warning",
5080
+ stage: "members",
5081
+ error: memberSnapshotError
5082
+ });
5083
+ }
4856
5084
  await syncDbGroupHistoryFull({
4857
5085
  profile,
4858
5086
  api,
@@ -4911,8 +5139,8 @@ async function buildGroupsDetailed(api) {
4911
5139
  const groups = await api.getAllGroups();
4912
5140
  const ids = Object.keys(groups.gridVerMap ?? {});
4913
5141
  if (ids.length === 0) return [];
4914
- const info = await api.getGroupInfo(ids);
4915
- return ids.map((id) => info.gridInfoMap?.[id]).filter((item) => Boolean(item));
5142
+ const info = await fetchGroupInfoRecords(api, ids);
5143
+ return ids.map((id) => info.get(id)).filter((item) => Boolean(item));
4916
5144
  }
4917
5145
  function normalizeGroupMemberId(value) {
4918
5146
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -4923,9 +5151,8 @@ function normalizeGroupMemberId(value) {
4923
5151
  if (!trimmed) return "";
4924
5152
  return trimmed.replace(/_\d+$/, "");
4925
5153
  }
4926
- async function listGroupMemberRows(api, groupId) {
4927
- const info = await api.getGroupInfo(groupId);
4928
- const groupInfo = info.gridInfoMap[groupId];
5154
+ async function listGroupMemberRows(api, groupId, preloadedGroupInfo) {
5155
+ const groupInfo = preloadedGroupInfo ?? await fetchGroupInfoRecord(api, groupId);
4929
5156
  if (!groupInfo) {
4930
5157
  throw new Error(`Group not found: ${groupId}`);
4931
5158
  }
@@ -4949,10 +5176,9 @@ async function listGroupMemberRows(api, groupId) {
4949
5176
  ...Array.from(currentMemberMap.keys())
4950
5177
  ])
4951
5178
  );
4952
- const profiles = ids.length > 0 ? await api.getGroupMembersInfo(ids) : { profiles: {} };
4953
- const rawProfileMap = profiles.profiles;
5179
+ const profileLookup = ids.length > 0 ? await fetchGroupMemberProfiles(api, ids) : /* @__PURE__ */ new Map();
4954
5180
  const profileMap = /* @__PURE__ */ new Map();
4955
- for (const [key, profile] of Object.entries(rawProfileMap)) {
5181
+ for (const [key, profile] of profileLookup.entries()) {
4956
5182
  if (!profile) continue;
4957
5183
  const normalizedKey = normalizeGroupMemberId(key);
4958
5184
  if (normalizedKey && !profileMap.has(normalizedKey)) {
@@ -5007,7 +5233,7 @@ function isListenerAlreadyStarted(error) {
5007
5233
  if (!(error instanceof Error)) return false;
5008
5234
  return /already started/i.test(error.message);
5009
5235
  }
5010
- function toErrorText(error) {
5236
+ function toErrorText2(error) {
5011
5237
  return error instanceof Error ? error.message : String(error);
5012
5238
  }
5013
5239
  var SHUTDOWN_CALLBACKS = /* @__PURE__ */ new Set();
@@ -5045,7 +5271,7 @@ async function runShutdownCallbacks(signal) {
5045
5271
  "process.signal.callback_error",
5046
5272
  {
5047
5273
  signal,
5048
- message: toErrorText(error)
5274
+ message: toErrorText2(error)
5049
5275
  },
5050
5276
  void 0
5051
5277
  );
@@ -5128,7 +5354,7 @@ async function withUploadListener(api, command, task) {
5128
5354
  writeDebugLine(
5129
5355
  "msg.upload.listener.error",
5130
5356
  {
5131
- message: toErrorText(error)
5357
+ message: toErrorText2(error)
5132
5358
  },
5133
5359
  command
5134
5360
  );
@@ -5170,7 +5396,7 @@ async function withUploadListener(api, command, task) {
5170
5396
  finish();
5171
5397
  };
5172
5398
  const onConnectError = (error) => {
5173
- finish(new Error(`Upload listener connection error: ${toErrorText(error)}`));
5399
+ finish(new Error(`Upload listener connection error: ${toErrorText2(error)}`));
5174
5400
  };
5175
5401
  const onConnectClosed = (code, reason) => {
5176
5402
  finish(
@@ -5808,7 +6034,7 @@ async function parseCredentialFile(filePath) {
5808
6034
  language: parsed.language
5809
6035
  };
5810
6036
  }
5811
- function sleep2(ms) {
6037
+ function sleep3(ms) {
5812
6038
  return new Promise((resolve) => {
5813
6039
  setTimeout(resolve, ms);
5814
6040
  });
@@ -5823,7 +6049,7 @@ async function waitForFileContent(filePath, timeoutMs) {
5823
6049
  }
5824
6050
  } catch {
5825
6051
  }
5826
- await sleep2(150);
6052
+ await sleep3(150);
5827
6053
  }
5828
6054
  throw new Error(`Timed out waiting for QR image file: ${filePath}`);
5829
6055
  }
@@ -9052,7 +9278,7 @@ ${replyContextText}` : replyContextText;
9052
9278
  code,
9053
9279
  reason: reason || void 0,
9054
9280
  delayMs: keepAliveRestartDelayMs,
9055
- message: toErrorText(error),
9281
+ message: toErrorText2(error),
9056
9282
  sessionId
9057
9283
  },
9058
9284
  command
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzca",
3
- "version": "0.1.56",
3
+ "version": "0.1.57",
4
4
  "description": "Open-source zca-compatible CLI to integrate Zalo with OpenClaw",
5
5
  "type": "module",
6
6
  "bin": {