instar 1.3.381 → 1.3.383

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.
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAQ3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiG7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA6JtD,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAs4BD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,GAC/F,IAAI,CAyUN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAutTtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAQ3D,OAAO,EAAE,eAAe,EAAiC,MAAM,iCAAiC,CAAC;AAuBjG,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiG7D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA6JtD,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;2DACuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAs4BD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,eAAe,EACzB,cAAc,EAAE,cAAc,EAC9B,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,CAAC,EAAE,WAAW,EACzB,WAAW,CAAC,EAAE,WAAW,EACzB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EAGvE,UAAU,CAAC,EAAE,MAAM,OAAO,8BAA8B,EAAE,WAAW,GAAG,IAAI,EAK5E,qBAAqB,CAAC,EAAE,MAAM,OAAO,gCAAgC,EAAE,kBAAkB,GAAG,IAAI,GAC/F,IAAI,CAyUN;AA2lBD,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAqtTtE;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD5E"}
@@ -3271,6 +3271,10 @@ export async function startServer(options) {
3271
3271
  });
3272
3272
  console.log(pc.green(` Quota tracking enabled (${quotaFile})`));
3273
3273
  }
3274
+ // NOTE (A1): the account switcher + quota collector pipeline are set up
3275
+ // below, AFTER the scheduler exists, but OUTSIDE the Telegram-polling block
3276
+ // (see the "Account switcher + quota collector pipeline" section) so the
3277
+ // collector runs regardless of who owns Telegram polling.
3274
3278
  // Set up opt-in telemetry heartbeat.
3275
3279
  // ALWAYS construct, even when disabled — fixes the chicken-and-egg deadlock
3276
3280
  // where POST /telemetry/enable returned 503 because the subsystem was only
@@ -3489,6 +3493,61 @@ export async function startServer(options) {
3489
3493
  else if (config.scheduler.enabled && !coordinator.isAwake) {
3490
3494
  console.log(pc.yellow(' Scheduler skipped (standby mode)'));
3491
3495
  }
3496
+ // Account switcher + quota collector pipeline (live-matrix finding A1,
3497
+ // 2026-06-06). The collector that WRITES quota-state.json — and the
3498
+ // QuotaManager that drives its adaptive polling — were previously nested
3499
+ // inside the `!lifelineOwnsPolling` Telegram block, so on any agent whose
3500
+ // LIFELINE owns Telegram polling (the normal production topology) the
3501
+ // collector never started: quota-state.json was never written, the tracker
3502
+ // read an absent file, and quota-aware placement (#804) stayed permanently
3503
+ // fail-open — the exact EXO rate-limit-stall hazard it exists to prevent.
3504
+ // Collecting quota is independent of who polls Telegram, so it lives here
3505
+ // at top scope (after the scheduler exists so migration wiring is real),
3506
+ // gated only on quotaTracker. accountSwitcher is also consumed by
3507
+ // wireTelegramCallbacks in the polling block; constructing it here keeps it
3508
+ // in scope for both the polling and send-only paths.
3509
+ const accountSwitcher = new AccountSwitcher();
3510
+ if (quotaTracker) {
3511
+ const quotaNotifier = new QuotaNotifier(config.stateDir);
3512
+ const alertTopicId = state.get('agent-attention-topic') ?? null;
3513
+ quotaNotifier.configure(async (_topicId, text) => {
3514
+ const tier = text.includes('EXHAUSTED') || text.includes('critical') ? 'IMMEDIATE' : 'SUMMARY';
3515
+ notify(tier, 'quota', text);
3516
+ }, alertTopicId);
3517
+ let collector = null;
3518
+ let migrator = null;
3519
+ try {
3520
+ const { QuotaCollector } = await import('../monitoring/QuotaCollector.js');
3521
+ const { createDefaultProvider } = await import('../monitoring/CredentialProvider.js');
3522
+ if (resolvedFramework === 'claude-code') {
3523
+ const provider = createDefaultProvider();
3524
+ collector = new QuotaCollector(provider, quotaTracker);
3525
+ }
3526
+ else {
3527
+ console.log(pc.yellow(` QuotaCollector skipped for ${resolvedFramework} (no framework usage meter)`));
3528
+ }
3529
+ }
3530
+ catch (err) {
3531
+ console.log(pc.yellow(` QuotaCollector not available: ${err instanceof Error ? err.message : err}`));
3532
+ }
3533
+ try {
3534
+ const { SessionMigrator } = await import('../monitoring/SessionMigrator.js');
3535
+ migrator = new SessionMigrator({ stateDir: config.stateDir });
3536
+ }
3537
+ catch (err) {
3538
+ console.log(pc.yellow(` SessionMigrator not available: ${err instanceof Error ? err.message : err}`));
3539
+ }
3540
+ quotaManager = new QuotaManager({ stateDir: config.stateDir }, { tracker: quotaTracker, collector, switcher: accountSwitcher, migrator, notifier: quotaNotifier });
3541
+ quotaManager.setSessionManager(sessionManager);
3542
+ if (scheduler)
3543
+ quotaManager.setScheduler(scheduler);
3544
+ quotaManager.setNotificationSender(async (message) => {
3545
+ const tier = message.includes('❌') || message.includes('EXHAUSTED') ? 'IMMEDIATE' : 'SUMMARY';
3546
+ notify(tier, 'quota', message);
3547
+ });
3548
+ quotaManager.start();
3549
+ console.log(pc.green(' QuotaManager started (adaptive polling) — runs regardless of Telegram-polling ownership (A1)'));
3550
+ }
3492
3551
  // Start telemetry heartbeat (deferred to here so collector can be wired first)
3493
3552
  if (telemetryHeartbeat) {
3494
3553
  telemetryHeartbeat.start();
@@ -3725,66 +3784,10 @@ export async function startServer(options) {
3725
3784
  });
3726
3785
  notificationBatcher.start();
3727
3786
  console.log(pc.green(' Notification batcher enabled (SUMMARY: 30m, DIGEST: 2h)'));
3728
- // Set up account switcher (Keychain-based OAuth account swapping)
3729
- const accountSwitcher = new AccountSwitcher();
3730
- // Set up quota notifier (Telegram alerts on threshold crossings)
3731
- const quotaNotifier = new QuotaNotifier(config.stateDir);
3732
- const alertTopicId = state.get('agent-attention-topic') ?? null;
3733
- quotaNotifier.configure(async (_topicId, text) => {
3734
- // Quota exhaustion is IMMEDIATE; warnings are SUMMARY
3735
- const tier = text.includes('EXHAUSTED') || text.includes('critical') ? 'IMMEDIATE' : 'SUMMARY';
3736
- notify(tier, 'quota', text);
3737
- }, alertTopicId);
3738
- // Set up QuotaManager orchestration hub (Phase 4)
3739
- if (quotaTracker) {
3740
- // Try to set up the full collector-driven pipeline
3741
- let collector = null;
3742
- let migrator = null;
3743
- try {
3744
- const { QuotaCollector } = await import('../monitoring/QuotaCollector.js');
3745
- const { createDefaultProvider } = await import('../monitoring/CredentialProvider.js');
3746
- if (resolvedFramework === 'claude-code') {
3747
- const provider = createDefaultProvider();
3748
- collector = new QuotaCollector(provider, quotaTracker);
3749
- }
3750
- else {
3751
- console.log(pc.yellow(` QuotaCollector skipped for ${resolvedFramework} (no framework usage meter)`));
3752
- }
3753
- }
3754
- catch (err) {
3755
- console.log(pc.yellow(` QuotaCollector not available: ${err instanceof Error ? err.message : err}`));
3756
- }
3757
- try {
3758
- const { SessionMigrator } = await import('../monitoring/SessionMigrator.js');
3759
- migrator = new SessionMigrator({ stateDir: config.stateDir });
3760
- }
3761
- catch (err) {
3762
- console.log(pc.yellow(` SessionMigrator not available: ${err instanceof Error ? err.message : err}`));
3763
- }
3764
- quotaManager = new QuotaManager({ stateDir: config.stateDir }, {
3765
- tracker: quotaTracker,
3766
- collector,
3767
- switcher: accountSwitcher,
3768
- migrator,
3769
- notifier: quotaNotifier,
3770
- });
3771
- // Wire session manager and scheduler for migration support
3772
- quotaManager.setSessionManager(sessionManager);
3773
- if (scheduler) {
3774
- quotaManager.setScheduler(scheduler);
3775
- }
3776
- // Wire Telegram notifications
3777
- quotaManager.setNotificationSender(async (message) => {
3778
- const tier = message.includes('❌') || message.includes('EXHAUSTED') ? 'IMMEDIATE' : 'SUMMARY';
3779
- notify(tier, 'quota', message);
3780
- });
3781
- // Start adaptive polling (replaces the 10-min setInterval)
3782
- quotaManager.start();
3783
- console.log(pc.green(' QuotaManager started (adaptive polling, auto-migration)'));
3784
- }
3785
- else {
3786
- console.log(pc.yellow(' QuotaManager skipped (no quota tracker)'));
3787
- }
3787
+ // accountSwitcher + the QuotaManager/collector pipeline were hoisted OUT
3788
+ // of this Telegram-polling block to top scope (finding A1) so the quota
3789
+ // collector runs even when the lifeline owns Telegram polling. See the
3790
+ // "Account switcher + quota collector pipeline" section above.
3788
3791
  // Initialize persistent UserManager for user identity resolution (Gap 8)
3789
3792
  const userManager = new UserManager(config.stateDir, config.users);
3790
3793
  // Fix command dependencies — populated later when subsystems initialize.