chatroom-cli 1.53.1 → 1.53.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/dist/index.js CHANGED
@@ -79715,9 +79715,11 @@ var init_featureFlags = __esm(() => {
79715
79715
  });
79716
79716
 
79717
79717
  // ../../services/backend/config/reliability.ts
79718
- var DAEMON_HEARTBEAT_INTERVAL_MS = 30000, AGENT_REQUEST_DEADLINE_MS = 120000, OBSERVATION_TTL_MS = 60000, OBSERVED_FULL_PUSH_INTERVAL_MS, OBSERVED_SAFETY_POLL_MS = 30000;
79718
+ var DAEMON_HEARTBEAT_INTERVAL_MS = 30000, AGENT_REQUEST_DEADLINE_MS = 120000, OBSERVATION_TTL_MS = 60000, OBSERVED_FULL_PUSH_INTERVAL_MS, OBSERVED_SAFETY_POLL_MS = 30000, WORKSPACE_RECENCY_WINDOW_MS, WORKSPACE_LIST_RECONCILE_MS;
79719
79719
  var init_reliability = __esm(() => {
79720
79720
  OBSERVED_FULL_PUSH_INTERVAL_MS = 5 * 60000;
79721
+ WORKSPACE_RECENCY_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
79722
+ WORKSPACE_LIST_RECONCILE_MS = 60 * 60 * 1000;
79721
79723
  });
79722
79724
 
79723
79725
  // src/commands/machine/daemon-start/capabilities-snapshot.ts
@@ -79987,34 +79989,30 @@ var init_command_discovery = __esm(() => {
79987
79989
  });
79988
79990
 
79989
79991
  // src/commands/machine/daemon-start/workspace-cache.ts
79990
- function invalidateWorkspacesForMachineCache(ctx) {
79991
- delete ctx._workspacesCache;
79992
- }
79993
79992
  async function getWorkspacesForMachine(ctx) {
79994
- const extended = ctx;
79995
- const now = Date.now();
79996
- const cached4 = extended._workspacesCache;
79997
- if (cached4 && now - cached4.fetchedAt < CACHE_TTL_MS) {
79998
- return cached4.workspaces;
79993
+ const store = ctx.workspaceListStore;
79994
+ if (store && store.updatedAt > 0) {
79995
+ return store.workspaces;
79999
79996
  }
80000
79997
  try {
80001
- const workspaces = await ctx.deps.backend.query(api.workspaces.listWorkspacesForMachine, {
79998
+ const workspaces = await ctx.deps.backend.query(api.workspaces.listRecentlyObservedWorkspacesForMachine, {
80002
79999
  sessionId: ctx.sessionId,
80003
80000
  machineId: ctx.machineId
80004
80001
  });
80005
- extended._workspacesCache = { fetchedAt: now, workspaces };
80006
- return workspaces;
80002
+ const mapped = workspaces.map((ws) => ({ workingDir: ws.workingDir }));
80003
+ if (store) {
80004
+ store.workspaces = mapped;
80005
+ store.updatedAt = Date.now();
80006
+ }
80007
+ return mapped;
80007
80008
  } catch (err) {
80008
80009
  console.warn(`[${formatTimestamp()}] ⚠️ Failed to query workspaces: ${getErrorMessage(err)}`);
80009
80010
  return [];
80010
80011
  }
80011
80012
  }
80012
- var CACHE_TTL_MS;
80013
80013
  var init_workspace_cache = __esm(() => {
80014
- init_reliability();
80015
80014
  init_api3();
80016
80015
  init_convex_error();
80017
- CACHE_TTL_MS = DAEMON_HEARTBEAT_INTERVAL_MS;
80018
80016
  });
80019
80017
 
80020
80018
  // src/commands/machine/daemon-start/command-sync-heartbeat.ts
@@ -83159,7 +83157,45 @@ var init_output_store = __esm(() => {
83159
83157
  RUN_ID_RE = /^[a-z0-9]+$/i;
83160
83158
  });
83161
83159
 
83162
- // src/commands/machine/daemon-start/handlers/process/log-observer-sync.ts
83160
+ // src/commands/machine/daemon-start/handlers/process/log-observer-subscription.ts
83161
+ function setsEqual(a, b) {
83162
+ if (a.size !== b.size)
83163
+ return false;
83164
+ for (const id3 of a) {
83165
+ if (!b.has(id3))
83166
+ return false;
83167
+ }
83168
+ return true;
83169
+ }
83170
+ function formatRunIdShort(runId) {
83171
+ return runId.length > 8 ? `${runId.slice(0, 8)}…` : runId;
83172
+ }
83173
+ function logObserverSetChangeIfNeeded(runs) {
83174
+ const nextObserved = new Set;
83175
+ const nextPending = new Set;
83176
+ for (const run3 of runs) {
83177
+ nextObserved.add(run3._id);
83178
+ if (run3.pendingFullOutputSync) {
83179
+ nextPending.add(run3._id);
83180
+ }
83181
+ }
83182
+ if (setsEqual(observedRunIds, nextObserved) && setsEqual(pendingFullSyncRunIds, nextPending)) {
83183
+ return;
83184
+ }
83185
+ const runSummaries = [...nextObserved].map(formatRunIdShort).join(", ") || "none";
83186
+ console.log(`[${formatTimestamp()}] \uD83D\uDCDC Log observers updated: ${nextObserved.size} run(s) [${runSummaries}] pendingFull=${nextPending.size}`);
83187
+ }
83188
+ function applyObservedRuns(runs) {
83189
+ logObserverSetChangeIfNeeded(runs);
83190
+ observedRunIds.clear();
83191
+ pendingFullSyncRunIds.clear();
83192
+ for (const run3 of runs) {
83193
+ observedRunIds.add(run3._id);
83194
+ if (run3.pendingFullOutputSync) {
83195
+ pendingFullSyncRunIds.add(run3._id);
83196
+ }
83197
+ }
83198
+ }
83163
83199
  function isRunLogObserved(runId) {
83164
83200
  return observedRunIds.has(runId);
83165
83201
  }
@@ -83169,77 +83205,41 @@ function consumePendingFullSync(runId) {
83169
83205
  pendingFullSyncRunIds.delete(runId);
83170
83206
  return true;
83171
83207
  }
83172
- function startLogObserverPoll(ctx) {
83208
+ function startLogObserverSubscription(ctx, wsClient2) {
83209
+ const queryArgs = {
83210
+ sessionId: ctx.sessionId,
83211
+ machineId: ctx.machineId
83212
+ };
83173
83213
  let stopped = false;
83174
- let consecutiveIdlePolls = 0;
83175
- let pollInFlight = false;
83176
- let timeoutHandle = null;
83177
- const scheduleNext = (delayMs) => {
83214
+ const unsubscribe = wsClient2.onUpdate(api.daemon.commands.listRunsWithLogObservers, queryArgs, (runs) => {
83178
83215
  if (stopped)
83179
83216
  return;
83180
- if (timeoutHandle)
83181
- clearTimeout(timeoutHandle);
83182
- timeoutHandle = setTimeout(() => {
83183
- poll4();
83184
- }, delayMs);
83185
- timeoutHandle.unref?.();
83186
- };
83187
- const poll4 = async () => {
83188
- if (stopped || pollInFlight)
83189
- return;
83190
- const hasLocalObservers = observedRunIds.size > 0;
83191
- if (!hasLocalObservers && consecutiveIdlePolls >= IDLE_SKIP_AFTER_CONSECUTIVE) {
83192
- scheduleNext(IDLE_POLL_INTERVAL_MS);
83193
- return;
83194
- }
83195
- pollInFlight = true;
83196
- try {
83197
- const runs = await ctx.deps.backend.query(api.commands.listRunsWithLogObservers, {
83198
- sessionId: ctx.sessionId,
83199
- machineId: ctx.machineId
83200
- });
83201
- observedRunIds.clear();
83202
- pendingFullSyncRunIds.clear();
83203
- for (const run3 of runs) {
83204
- observedRunIds.add(run3._id);
83205
- if (run3.pendingFullOutputSync) {
83206
- pendingFullSyncRunIds.add(run3._id);
83207
- }
83208
- }
83209
- const isActive2 = runs.length > 0 || hasLocalObservers;
83210
- if (isActive2) {
83211
- consecutiveIdlePolls = 0;
83212
- scheduleNext(ACTIVE_POLL_INTERVAL_MS);
83213
- } else {
83214
- consecutiveIdlePolls++;
83215
- scheduleNext(consecutiveIdlePolls >= IDLE_SKIP_AFTER_CONSECUTIVE ? IDLE_POLL_INTERVAL_MS : ACTIVE_POLL_INTERVAL_MS);
83216
- }
83217
- } catch (err) {
83218
- console.warn(`[${formatTimestamp()}] ⚠️ Log-observer poll failed: ${getErrorMessage(err)}`);
83219
- scheduleNext(ACTIVE_POLL_INTERVAL_MS);
83220
- } finally {
83221
- pollInFlight = false;
83222
- }
83223
- };
83224
- poll4();
83217
+ applyObservedRuns(runs ?? []);
83218
+ }, (err) => {
83219
+ console.warn(`[${formatTimestamp()}] ⚠️ Log-observer subscription error: ${getErrorMessage(err)}`);
83220
+ });
83221
+ console.log(`[${formatTimestamp()}] \uD83D\uDCDC Log-observer subscription started`);
83225
83222
  return {
83226
83223
  stop: () => {
83227
83224
  stopped = true;
83228
- if (timeoutHandle)
83229
- clearTimeout(timeoutHandle);
83225
+ unsubscribe();
83230
83226
  observedRunIds.clear();
83231
83227
  pendingFullSyncRunIds.clear();
83228
+ console.log(`[${formatTimestamp()}] \uD83D\uDCDC Log-observer subscription stopped`);
83232
83229
  }
83233
83230
  };
83234
83231
  }
83235
- var observedRunIds, pendingFullSyncRunIds, ACTIVE_POLL_INTERVAL_MS, IDLE_POLL_INTERVAL_MS = 15000, IDLE_SKIP_AFTER_CONSECUTIVE = 3;
83236
- var init_log_observer_sync = __esm(() => {
83232
+ var observedRunIds, pendingFullSyncRunIds;
83233
+ var init_log_observer_subscription = __esm(() => {
83237
83234
  init_api3();
83238
83235
  init_convex_error();
83239
- init_state2();
83240
83236
  observedRunIds = new Set;
83241
83237
  pendingFullSyncRunIds = new Set;
83242
- ACTIVE_POLL_INTERVAL_MS = OUTPUT_FLUSH_INTERVAL_MS;
83238
+ });
83239
+
83240
+ // src/commands/machine/daemon-start/handlers/process/log-observer-sync.ts
83241
+ var init_log_observer_sync = __esm(() => {
83242
+ init_log_observer_subscription();
83243
83243
  });
83244
83244
 
83245
83245
  // src/commands/machine/daemon-start/handlers/process/spawner.ts
@@ -85246,6 +85246,62 @@ var init_observed_sync = __esm(() => {
85246
85246
  init_convex_error();
85247
85247
  });
85248
85248
 
85249
+ // src/commands/machine/daemon-start/workspace-list-subscription.ts
85250
+ function toSyncWorkspaces(workspaces) {
85251
+ return workspaces.map((ws) => ({ workingDir: ws.workingDir }));
85252
+ }
85253
+ function applyWorkspaceList(ctx, workspaces) {
85254
+ if (!ctx.workspaceListStore)
85255
+ return;
85256
+ ctx.workspaceListStore.workspaces = toSyncWorkspaces(workspaces);
85257
+ ctx.workspaceListStore.updatedAt = Date.now();
85258
+ }
85259
+ function startWorkspaceListSubscription(ctx, wsClient2) {
85260
+ ctx.workspaceListStore = { workspaces: [], updatedAt: 0 };
85261
+ const queryArgs = {
85262
+ sessionId: ctx.sessionId,
85263
+ machineId: ctx.machineId,
85264
+ recencyWindowMs: WORKSPACE_RECENCY_WINDOW_MS
85265
+ };
85266
+ let stopped = false;
85267
+ let reconcileInFlight = false;
85268
+ const unsubscribe = wsClient2.onUpdate(api.workspaces.listRecentlyObservedWorkspacesForMachine, queryArgs, (workspaces) => {
85269
+ if (stopped)
85270
+ return;
85271
+ applyWorkspaceList(ctx, workspaces ?? []);
85272
+ }, (err) => {
85273
+ console.warn(`[${formatTimestamp()}] ⚠️ Workspace-list subscription error: ${getErrorMessage(err)}`);
85274
+ });
85275
+ const reconcileTimer = setInterval(() => {
85276
+ if (stopped || reconcileInFlight)
85277
+ return;
85278
+ reconcileInFlight = true;
85279
+ ctx.deps.backend.query(api.workspaces.listRecentlyObservedWorkspacesForMachine, queryArgs).then((workspaces) => {
85280
+ if (!stopped)
85281
+ applyWorkspaceList(ctx, workspaces ?? []);
85282
+ }).catch((err) => {
85283
+ console.warn(`[${formatTimestamp()}] ⚠️ Workspace-list reconcile failed: ${getErrorMessage(err)}`);
85284
+ }).finally(() => {
85285
+ reconcileInFlight = false;
85286
+ });
85287
+ }, WORKSPACE_LIST_RECONCILE_MS);
85288
+ console.log(`[${formatTimestamp()}] \uD83D\uDCC2 Workspace-list subscription started`);
85289
+ return {
85290
+ stop: () => {
85291
+ stopped = true;
85292
+ unsubscribe();
85293
+ clearInterval(reconcileTimer);
85294
+ delete ctx.workspaceListStore;
85295
+ console.log(`[${formatTimestamp()}] \uD83D\uDCC2 Workspace-list subscription stopped`);
85296
+ }
85297
+ };
85298
+ }
85299
+ var init_workspace_list_subscription = __esm(() => {
85300
+ init_reliability();
85301
+ init_api3();
85302
+ init_convex_error();
85303
+ });
85304
+
85249
85305
  // src/infrastructure/git/git-writer.ts
85250
85306
  import { exec as exec5 } from "node:child_process";
85251
85307
  import { promisify as promisify5 } from "node:util";
@@ -85961,7 +86017,6 @@ async function startCommandLoop(ctx) {
85961
86017
  }).then(() => {
85962
86018
  heartbeatCount++;
85963
86019
  console.log(`[${formatTimestamp()}] \uD83D\uDC93 Daemon heartbeat #${heartbeatCount} OK`);
85964
- invalidateWorkspacesForMachineCache(ctx);
85965
86020
  if (!ctx.observedSyncEnabled) {
85966
86021
  pushGitState(ctx).catch((err) => {
85967
86022
  console.warn(`[${formatTimestamp()}] ⚠️ Git state push failed: ${getErrorMessage(err)}`);
@@ -85981,8 +86036,9 @@ async function startCommandLoop(ctx) {
85981
86036
  let gitSubscriptionHandle = null;
85982
86037
  let fileContentSubscriptionHandle = null;
85983
86038
  let fileTreeSubscriptionHandle = null;
86039
+ let workspaceListSubscriptionHandle = null;
85984
86040
  let observedSyncSubscriptionHandle = null;
85985
- let logObserverPollHandle = null;
86041
+ let logObserverSubscriptionHandle = null;
85986
86042
  let pendingPromptSubscriptionHandle = null;
85987
86043
  let pendingHarnessSessionSubscriptionHandle = null;
85988
86044
  let commandSubscriptionHandle = null;
@@ -86006,10 +86062,12 @@ async function startCommandLoop(ctx) {
86006
86062
  fileContentSubscriptionHandle.stop();
86007
86063
  if (fileTreeSubscriptionHandle)
86008
86064
  fileTreeSubscriptionHandle.stop();
86065
+ if (workspaceListSubscriptionHandle)
86066
+ workspaceListSubscriptionHandle.stop();
86009
86067
  if (observedSyncSubscriptionHandle)
86010
86068
  observedSyncSubscriptionHandle.stop();
86011
- if (logObserverPollHandle)
86012
- logObserverPollHandle.stop();
86069
+ if (logObserverSubscriptionHandle)
86070
+ logObserverSubscriptionHandle.stop();
86013
86071
  if (pendingPromptSubscriptionHandle)
86014
86072
  pendingPromptSubscriptionHandle.stop();
86015
86073
  if (pendingHarnessSessionSubscriptionHandle)
@@ -86035,10 +86093,11 @@ async function startCommandLoop(ctx) {
86035
86093
  gitSubscriptionHandle = startGitRequestSubscription(ctx, wsClient2);
86036
86094
  fileContentSubscriptionHandle = startFileContentSubscription(ctx, wsClient2);
86037
86095
  fileTreeSubscriptionHandle = startFileTreeSubscription(ctx, wsClient2);
86096
+ workspaceListSubscriptionHandle = startWorkspaceListSubscription(ctx, wsClient2);
86038
86097
  if (ctx.observedSyncEnabled) {
86039
86098
  observedSyncSubscriptionHandle = startObservedSyncSubscription(ctx, wsClient2);
86040
86099
  }
86041
- logObserverPollHandle = startLogObserverPoll(ctx);
86100
+ logObserverSubscriptionHandle = startLogObserverSubscription(ctx, wsClient2);
86042
86101
  if (featureFlags.directHarnessWorkers) {
86043
86102
  const sessionRepository = new ConvexSessionRepository({
86044
86103
  backend: ctx.deps.backend,
@@ -86128,8 +86187,8 @@ var init_command_loop = __esm(() => {
86128
86187
  init_manager();
86129
86188
  init_init2();
86130
86189
  init_log_observer_sync();
86131
- init_workspace_cache();
86132
86190
  init_observed_sync();
86191
+ init_workspace_list_subscription();
86133
86192
  init_api3();
86134
86193
  init_client2();
86135
86194
  init_local_actions();
@@ -87304,8 +87363,8 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
87304
87363
  if (!sessionId)
87305
87364
  return;
87306
87365
  const client4 = await getConvexClient2();
87307
- sendLifecycleHeartbeat2(client4, { sessionId, chatroomId, role, action: actionCommand.name() });
87366
+ sendLifecycleHeartbeat2(client4, { sessionId, chatroomId, role });
87308
87367
  });
87309
87368
  program2.parse();
87310
87369
 
87311
- //# debugId=D59205F0E7B31DAD64756E2164756E21
87370
+ //# debugId=C18F126578765BC664756E2164756E21