@songsid/agend 2.1.6-beta.10 → 2.1.6-beta.11

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.
@@ -292,6 +292,8 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
292
292
  private eventLogPruneTimer;
293
293
  private logRotateTimer;
294
294
  private discordPresenceTimer;
295
+ private discordPresenceEagerTimer;
296
+ private discordPresenceEagerPending;
295
297
  private discordPresenceInFlight;
296
298
  private static readonly DISCORD_PRESENCE_REFRESH_MS;
297
299
  /** Days of event/activity history to keep. */
@@ -681,6 +683,12 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
681
683
  startAll(configPath: string): Promise<void>;
682
684
  /** Keep Discord profile activity aligned with the same cached usage source as /usage. */
683
685
  private startDiscordUsagePresence;
686
+ /**
687
+ * Request one prompt presence refresh after an instance/adapter comes online.
688
+ * Startup can bring several instances up together; a short coalescing window
689
+ * keeps that herd on the existing shared refresh path and one usage fetch.
690
+ */
691
+ private requestDiscordUsagePresenceRefresh;
684
692
  private refreshDiscordUsagePresence;
685
693
  /**
686
694
  * Delete inbox files older than retentionDays (by mtime). Cleans the shared
@@ -488,6 +488,8 @@ export class FleetManager {
488
488
  eventLogPruneTimer = null;
489
489
  logRotateTimer = null;
490
490
  discordPresenceTimer = null;
491
+ discordPresenceEagerTimer = null;
492
+ discordPresenceEagerPending = false;
491
493
  discordPresenceInFlight = null;
492
494
  static DISCORD_PRESENCE_REFRESH_MS = 15 * 60_000;
493
495
  /** Days of event/activity history to keep. */
@@ -1839,6 +1841,7 @@ export class FleetManager {
1839
1841
  catch { /* consumed or absent */ }
1840
1842
  // Auto-connect IPC — daemon.start() ensures socket is ready before resolving
1841
1843
  await this.connectIpcToInstance(name);
1844
+ this.requestDiscordUsagePresenceRefresh();
1842
1845
  }
1843
1846
  /** Recreate a daemon for a marker-only paused instance after an explicit wake/delivery. */
1844
1847
  async startPersistedPausedInstance(name) {
@@ -3058,12 +3061,37 @@ export class FleetManager {
3058
3061
  startDiscordUsagePresence() {
3059
3062
  if (this.discordPresenceTimer)
3060
3063
  clearInterval(this.discordPresenceTimer);
3064
+ if (this.discordPresenceEagerTimer) {
3065
+ clearTimeout(this.discordPresenceEagerTimer);
3066
+ this.discordPresenceEagerTimer = null;
3067
+ }
3068
+ this.discordPresenceEagerPending = false;
3061
3069
  void this.refreshDiscordUsagePresence();
3062
3070
  this.discordPresenceTimer = setInterval(() => {
3063
3071
  void this.refreshDiscordUsagePresence();
3064
3072
  }, FleetManager.DISCORD_PRESENCE_REFRESH_MS);
3065
3073
  this.discordPresenceTimer.unref?.();
3066
3074
  }
3075
+ /**
3076
+ * Request one prompt presence refresh after an instance/adapter comes online.
3077
+ * Startup can bring several instances up together; a short coalescing window
3078
+ * keeps that herd on the existing shared refresh path and one usage fetch.
3079
+ */
3080
+ requestDiscordUsagePresenceRefresh() {
3081
+ this.discordPresenceEagerPending = true;
3082
+ // During early fleet startup the interval is not installed yet; its first
3083
+ // refresh in startDiscordUsagePresence already covers all pending starts.
3084
+ if (!this.discordPresenceTimer || this.discordPresenceEagerTimer)
3085
+ return;
3086
+ this.discordPresenceEagerTimer = setTimeout(() => {
3087
+ this.discordPresenceEagerTimer = null;
3088
+ if (!this.discordPresenceEagerPending || !this.discordPresenceTimer)
3089
+ return;
3090
+ this.discordPresenceEagerPending = false;
3091
+ void this.refreshDiscordUsagePresence();
3092
+ }, 50);
3093
+ this.discordPresenceEagerTimer.unref?.();
3094
+ }
3067
3095
  refreshDiscordUsagePresence() {
3068
3096
  if (this.discordPresenceInFlight)
3069
3097
  return this.discordPresenceInFlight;
@@ -3706,7 +3734,7 @@ export class FleetManager {
3706
3734
  this.adapter.setChatId(String(fleet.channel.group_id));
3707
3735
  }
3708
3736
  if (this.discordPresenceTimer && this.adapter.type === "discord") {
3709
- void this.refreshDiscordUsagePresence();
3737
+ this.requestDiscordUsagePresenceRefresh();
3710
3738
  }
3711
3739
  this.startTopicCleanupPoller();
3712
3740
  // Prune stale external sessions every 5 minutes
@@ -4051,7 +4079,7 @@ export class FleetManager {
4051
4079
  adapter.setChatId(String(channelConfig.group_id));
4052
4080
  }
4053
4081
  if (this.discordPresenceTimer && adapter.type === "discord") {
4054
- void this.refreshDiscordUsagePresence();
4082
+ this.requestDiscordUsagePresenceRefresh();
4055
4083
  }
4056
4084
  this.logger.info({ adapterId, type: channelConfig.type }, "Additional adapter started");
4057
4085
  }
@@ -4296,7 +4324,7 @@ export class FleetManager {
4296
4324
  await adapter.reconnectGateway(previous?.lastError ?? "fleet adapter restart");
4297
4325
  this.adapterState.set(id, { status: "connected", retryCount: 0 });
4298
4326
  if (this.discordPresenceTimer && adapter.type === "discord") {
4299
- void this.refreshDiscordUsagePresence();
4327
+ this.requestDiscordUsagePresenceRefresh();
4300
4328
  }
4301
4329
  this.logger.info({ id }, "Adapter gateway rebuilt successfully");
4302
4330
  }
@@ -4324,7 +4352,7 @@ export class FleetManager {
4324
4352
  this.logger.info({ id, attempt }, "Adapter restarted successfully");
4325
4353
  this.adapterState.set(id, { status: "connected", retryCount: 0 });
4326
4354
  if (this.discordPresenceTimer && adapter.type === "discord") {
4327
- void this.refreshDiscordUsagePresence();
4355
+ this.requestDiscordUsagePresenceRefresh();
4328
4356
  }
4329
4357
  return;
4330
4358
  }
@@ -10987,6 +11015,11 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
10987
11015
  clearInterval(this.discordPresenceTimer);
10988
11016
  this.discordPresenceTimer = null;
10989
11017
  }
11018
+ if (this.discordPresenceEagerTimer) {
11019
+ clearTimeout(this.discordPresenceEagerTimer);
11020
+ this.discordPresenceEagerTimer = null;
11021
+ }
11022
+ this.discordPresenceEagerPending = false;
10990
11023
  // Cancel-button timers were never cleared here. The idle-check interval is not
10991
11024
  // unref'd, so it held the event loop open past shutdown and kept retrying
10992
11025
  // deletes against an adapter that was already gone.