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.
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +63 -60
- package/dist/commands/server.js.map +1 -1
- package/dist/core/ConvergenceChecker.js +1 -1
- package/dist/core/ConvergenceChecker.js.map +1 -1
- package/dist/core/PostUpdateMigrator.js +1 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +20 -20
- package/src/templates/scripts/convergence-check.sh +4 -1
- package/upgrades/1.3.383.md +76 -0
- package/upgrades/side-effects/convergence-commitment-regex-boundaries.md +53 -0
- package/upgrades/side-effects/quota-collector-polling-independence.md +62 -0
|
@@ -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,
|
|
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"}
|
package/dist/commands/server.js
CHANGED
|
@@ -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
|
-
//
|
|
3729
|
-
|
|
3730
|
-
//
|
|
3731
|
-
|
|
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.
|