feat: persistent token tracking with global stats aggregation

- Add restoreTokens() method to Session class for recovery after restart
- Add GlobalStats type for cumulative usage tracking across all sessions
- Accumulate tokens from deleted sessions into global stats
- Track lifetime session count with incrementSessionsCreated()
- Add /api/stats endpoint for global stats
- Include globalStats in /api/status response
- Frontend shows aggregate tokens + cost in header
- Fix respawn controller config to filter undefined values
- Add 7 new tests for global stats functionality (v0.1343)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
arkon
2026-01-25 07:26:49 +01:00
co-authored by Claude Opus 4.5
parent 0aca55b099
commit e56c8626e4
10 changed files with 322 additions and 19 deletions
+25
View File
@@ -248,6 +248,31 @@ describe('RespawnController', () => {
const config = controller.getConfig();
expect(config.idleTimeoutMs).toBe(originalTimeout);
});
it('should not override defaults with explicit undefined values in constructor', () => {
const configWithUndefined = {
idleTimeoutMs: 5000,
aiIdleCheckTimeoutMs: undefined,
aiIdleCheckModel: undefined,
} as Partial<RespawnConfig>;
const newController = new RespawnController(session as unknown as Session, configWithUndefined);
const config = newController.getConfig();
// Explicit undefined should not override defaults
expect(config.aiIdleCheckTimeoutMs).toBe(90000); // default value
expect(config.aiIdleCheckModel).toBe('claude-opus-4-5-20251101'); // default value
expect(config.idleTimeoutMs).toBe(5000); // explicit value should be preserved
newController.stop();
});
it('should not override existing config with explicit undefined in updateConfig', () => {
const originalTimeout = controller.getConfig().aiIdleCheckTimeoutMs;
controller.updateConfig({ aiIdleCheckTimeoutMs: undefined } as Partial<RespawnConfig>);
const config = controller.getConfig();
expect(config.aiIdleCheckTimeoutMs).toBe(originalTimeout);
});
});
describe('Status', () => {