@neta-art/cohub-cli 8.0.1 → 8.1.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.
@@ -41,7 +41,6 @@ export async function runRuntime(config, onState, externalSignal, onDiagnostic)
41
41
  pid: process.pid, harnesses: config.harnesses, background: config.background,
42
42
  state: "starting", harnessConnected: false, workspaceConnected: false,
43
43
  diagnosticsPath: diagnostics.directory,
44
- nativeSync: true,
45
44
  };
46
45
  let hasBeenReady = false;
47
46
  const update = (patch) => {
@@ -221,29 +220,81 @@ export async function runRuntime(config, onState, externalSignal, onDiagnostic)
221
220
  }
222
221
  };
223
222
  bridgeTask = runBridge();
224
- closeNativeDaemon = await serveNativeDaemon({ runtimeRoot: store.root, handle: async (request) => ({
225
- store: await captureNativeSession(request),
226
- }) });
223
+ // Native reconciliation is event-driven: captures and channel reconnects wake it, while failures
224
+ // get bounded exponential retries so idle Runtimes do not scan every few seconds.
225
+ let nativeWakePending = true;
226
+ let nativeWake = null;
227
+ let nativeRetryTimer;
228
+ let nativeRetryDelay = 1000;
229
+ const wakeNativeSync = () => {
230
+ nativeWakePending = true;
231
+ if (nativeRetryTimer) {
232
+ clearTimeout(nativeRetryTimer);
233
+ nativeRetryTimer = undefined;
234
+ }
235
+ nativeWake?.();
236
+ nativeWake = null;
237
+ };
238
+ const waitForNativeWake = async () => {
239
+ if (nativeWakePending) {
240
+ nativeWakePending = false;
241
+ return;
242
+ }
243
+ await new Promise((resolve) => {
244
+ const finish = () => {
245
+ signal.removeEventListener("abort", finish);
246
+ if (nativeWake === finish)
247
+ nativeWake = null;
248
+ resolve();
249
+ };
250
+ nativeWake = finish;
251
+ signal.addEventListener("abort", finish, { once: true });
252
+ if (signal.aborted)
253
+ finish();
254
+ });
255
+ nativeWakePending = false;
256
+ };
227
257
  nativeSyncTask = (async () => {
228
258
  const report = (error) => diagnostics.log("warn", "native.sync_pending", { error: serializeDiagnosticError(error) });
229
259
  while (!signal.aborted) {
260
+ await waitForNativeWake();
261
+ if (signal.aborted)
262
+ break;
263
+ if (!nativeSend)
264
+ continue;
265
+ let failed = false;
230
266
  try {
231
- if (nativeSend)
232
- await flushNativeSessions(config.spaceId, config.identity, signal, report, nativeWebSocketTransport(config.spaceId, config.identity, nativeSend));
267
+ failed = await flushNativeSessions(config.spaceId, config.identity, signal, report, nativeWebSocketTransport(config.spaceId, config.identity, nativeSend));
233
268
  }
234
269
  catch (error) {
235
- if (!signal.aborted)
270
+ if (!signal.aborted) {
236
271
  report(error);
272
+ failed = true;
273
+ }
274
+ }
275
+ if (failed && !signal.aborted) {
276
+ nativeRetryTimer = setTimeout(() => { nativeRetryTimer = undefined; wakeNativeSync(); }, nativeRetryDelay);
277
+ nativeRetryDelay = Math.min(30_000, nativeRetryDelay * 2);
278
+ }
279
+ else if (!failed) {
280
+ nativeRetryDelay = 1000;
237
281
  }
238
- await delay(5000, undefined, { signal }).catch(() => undefined);
239
282
  }
283
+ if (nativeRetryTimer)
284
+ clearTimeout(nativeRetryTimer);
240
285
  })();
286
+ closeNativeDaemon = await serveNativeDaemon({ runtimeRoot: store.root, handle: async (request) => {
287
+ const result = { store: await captureNativeSession(request) };
288
+ if (result.store)
289
+ wakeNativeSync();
290
+ return result;
291
+ } });
241
292
  await serveRuntime({
242
293
  spaceId: config.spaceId, cwd: config.root, url: url.toString(), capabilities,
243
294
  harnesses: config.executables, runtimeId: status.runtimeId, diagnostics, token, signal, store,
244
295
  onReady: () => update({ harnessConnected: true }),
245
296
  onDisconnected: () => { nativeSend = null; update({ harnessConnected: false }); },
246
- onNativeChannel: (send) => { nativeSend = send; },
297
+ onNativeChannel: (send) => { nativeSend = send; wakeNativeSync(); },
247
298
  });
248
299
  }
249
300
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub-cli",
3
- "version": "8.0.1",
3
+ "version": "8.1.1",
4
4
  "description": "CLI for Cohub — spaces, sessions, and agent collaboration.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -22,7 +22,7 @@
22
22
  "commander": "^15.0.0",
23
23
  "pixi.js": "^8.20.1",
24
24
  "sharp": "^0.35.4",
25
- "@neta-art/cohub": "8.21.0"
25
+ "@neta-art/cohub": "8.21.1"
26
26
  },
27
27
  "publishConfig": {
28
28
  "access": "public"