@coclaw/openclaw-coclaw 0.20.1 → 0.20.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coclaw/openclaw-coclaw",
3
- "version": "0.20.1",
3
+ "version": "0.20.2",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "description": "OpenClaw CoClaw channel plugin for remote chat",
@@ -43,6 +43,13 @@ const HEALTH_POLL_INTERVAL_MS = 3_000;
43
43
  // 及插件 bootstrap,合计 30~60s 常见;5 分钟给足余量
44
44
  const HEALTH_TOTAL_TIMEOUT_MS = 5 * 60 * 1000;
45
45
 
46
+ // 单调时钟(毫秒,整数)。轮询超时只关心"流逝",必须避开 Date.now() 的墙钟
47
+ // 跳变(NTP 同步、host suspend/resume、WSL2 vmtime sync)—— 这些跳变会让
48
+ // loop 误以为已经超时而提前退出
49
+ function monoNowMs() {
50
+ return Number(process.hrtime.bigint() / 1_000_000n);
51
+ }
52
+
46
53
  /**
47
54
  * 执行命令并返回 stdout;错误对象附带 stderr 以便诊断
48
55
  * @param {string} cmd
@@ -149,12 +156,12 @@ export async function pollUpgradeHealth(toVersion, opts) {
149
156
  const totalTimeout = opts?.totalTimeoutMs ?? HEALTH_TOTAL_TIMEOUT_MS;
150
157
  /* c8 ignore next -- ?? fallback */
151
158
  const pollInterval = opts?.pollIntervalMs ?? HEALTH_POLL_INTERVAL_MS;
152
- const start = Date.now();
159
+ const start = monoNowMs();
153
160
  let attempts = 0;
154
161
  let lastReason = '';
155
162
  let lastVersion = '';
156
163
 
157
- while (Date.now() - start < totalTimeout) {
164
+ while (monoNowMs() - start < totalTimeout) {
158
165
  attempts += 1;
159
166
  const result = await callUpgradeHealthOnce(opts);
160
167
  if (result.ok) {
@@ -164,7 +171,7 @@ export async function pollUpgradeHealth(toVersion, opts) {
164
171
  ok: true,
165
172
  version: result.version,
166
173
  attempts,
167
- elapsedMs: Date.now() - start,
174
+ elapsedMs: monoNowMs() - start,
168
175
  };
169
176
  }
170
177
  lastVersion = result.version;
@@ -174,14 +181,14 @@ export async function pollUpgradeHealth(toVersion, opts) {
174
181
  lastReason = result.reason;
175
182
  }
176
183
  // 剩余时间不足以再等一个 interval 就直接退出,避免最后一次毫无意义的 sleep
177
- if (Date.now() - start + pollInterval >= totalTimeout) break;
184
+ if (monoNowMs() - start + pollInterval >= totalTimeout) break;
178
185
  await sleep(pollInterval);
179
186
  }
180
187
 
181
188
  return {
182
189
  ok: false,
183
190
  attempts,
184
- elapsedMs: Date.now() - start,
191
+ elapsedMs: monoNowMs() - start,
185
192
  lastReason,
186
193
  lastVersion,
187
194
  };