github-issue-tower-defence-management 1.141.0 → 1.142.1

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +6 -6
  3. package/bin/adapter/entry-points/console/dashboardComposeService.js +23 -4
  4. package/bin/adapter/entry-points/console/dashboardComposeService.js.map +1 -1
  5. package/bin/adapter/entry-points/handlers/tokenStatusWriter.js +1 -0
  6. package/bin/adapter/entry-points/handlers/tokenStatusWriter.js.map +1 -1
  7. package/bin/adapter/repositories/FileSystemSubAgentLivenessResolver.js +3 -3
  8. package/bin/adapter/repositories/FileSystemSubAgentLivenessResolver.js.map +1 -1
  9. package/bin/adapter/repositories/TranscriptOwnerCallStatusProvider.js +23 -9
  10. package/bin/adapter/repositories/TranscriptOwnerCallStatusProvider.js.map +1 -1
  11. package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js +46 -6
  12. package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js.map +1 -1
  13. package/bin/domain/usecases/dashboard/GenerateTokenStatusUseCase.js +16 -1
  14. package/bin/domain/usecases/dashboard/GenerateTokenStatusUseCase.js.map +1 -1
  15. package/package.json +2 -2
  16. package/src/adapter/entry-points/console/dashboardComposeService.test.ts +82 -0
  17. package/src/adapter/entry-points/console/dashboardComposeService.ts +38 -4
  18. package/src/adapter/entry-points/handlers/tokenStatusWriter.test.ts +6 -0
  19. package/src/adapter/entry-points/handlers/tokenStatusWriter.ts +4 -0
  20. package/src/adapter/repositories/FileSystemSubAgentLivenessResolver.test.ts +94 -0
  21. package/src/adapter/repositories/FileSystemSubAgentLivenessResolver.ts +3 -3
  22. package/src/adapter/repositories/TranscriptOwnerCallStatusProvider.test.ts +368 -1
  23. package/src/adapter/repositories/TranscriptOwnerCallStatusProvider.ts +28 -10
  24. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +31 -0
  25. package/src/domain/usecases/dashboard/ComposeDashboardUseCase.test.ts +177 -1
  26. package/src/domain/usecases/dashboard/ComposeDashboardUseCase.ts +67 -6
  27. package/src/domain/usecases/dashboard/GenerateTokenStatusUseCase.test.ts +73 -0
  28. package/src/domain/usecases/dashboard/GenerateTokenStatusUseCase.ts +23 -0
  29. package/types/adapter/entry-points/console/dashboardComposeService.d.ts.map +1 -1
  30. package/types/adapter/entry-points/handlers/tokenStatusWriter.d.ts +2 -1
  31. package/types/adapter/entry-points/handlers/tokenStatusWriter.d.ts.map +1 -1
  32. package/types/adapter/repositories/TranscriptOwnerCallStatusProvider.d.ts +2 -1
  33. package/types/adapter/repositories/TranscriptOwnerCallStatusProvider.d.ts.map +1 -1
  34. package/types/domain/usecases/dashboard/ComposeDashboardUseCase.d.ts +6 -1
  35. package/types/domain/usecases/dashboard/ComposeDashboardUseCase.d.ts.map +1 -1
  36. package/types/domain/usecases/dashboard/GenerateTokenStatusUseCase.d.ts +6 -0
  37. package/types/domain/usecases/dashboard/GenerateTokenStatusUseCase.d.ts.map +1 -1
@@ -1,5 +1,9 @@
1
1
  import { DashboardRow } from './GenerateDashboardRowUseCase';
2
- import { TokenStatus, TokenStatusColor } from './GenerateTokenStatusUseCase';
2
+ import {
3
+ SevenDayWindowAggregate,
4
+ TokenStatus,
5
+ TokenStatusColor,
6
+ } from './GenerateTokenStatusUseCase';
3
7
 
4
8
  export const PROJECT_ROW_WIDTH_BUDGET = 32;
5
9
 
@@ -26,6 +30,7 @@ export type ComposeDashboardInput = {
26
30
  projects: ComposeDashboardProject[];
27
31
  machineStatus: ComposeDashboardMachineStatus | null;
28
32
  tokens: TokenStatus[];
33
+ sevenDayWindowAggregate?: SevenDayWindowAggregate | null;
29
34
  };
30
35
 
31
36
  type ProjectColumn = {
@@ -45,7 +50,17 @@ const PROJECT_COLUMNS: ProjectColumn[] = [
45
50
 
46
51
  const PROJECT_COLUMN_WIDTH = 3;
47
52
 
48
- const SEVERITY_BLANK = ' ';
53
+ export const STATUS_DOT_DISPLAY_WIDTH = 2;
54
+
55
+ const SEVERITY_BLANK = ' '.repeat(STATUS_DOT_DISPLAY_WIDTH);
56
+
57
+ const TOKEN_NAME_WIDTH = 4;
58
+
59
+ export const TOKEN_UTILIZATION_WIDTH = 4;
60
+
61
+ const TOKEN_RESET_WIDTH = 7;
62
+
63
+ const TOKEN_SEGMENT_SEPARATOR = ' ';
49
64
 
50
65
  const TOKEN_COLOR_DOT: Record<TokenStatusColor, string> = {
51
66
  G: '🟢',
@@ -196,7 +211,7 @@ export const formatProjectRowLine = (
196
211
  };
197
212
 
198
213
  const formatUtilization = (percent: number | null): string =>
199
- padStart(percent === null ? '?' : `${percent}%`, 4);
214
+ padStart(percent === null ? '?' : `${percent}%`, TOKEN_UTILIZATION_WIDTH);
200
215
 
201
216
  const formatReset = (resetSeconds: number | null): string =>
202
217
  resetSeconds === null ? '?' : formatResetCountdown(resetSeconds);
@@ -222,9 +237,39 @@ const sortTokens = (tokens: TokenStatus[]): TokenStatus[] =>
222
237
  })
223
238
  .map((entry) => entry.token);
224
239
 
240
+ const joinTokenRowSegments = (segments: string[]): string =>
241
+ segments.join(TOKEN_SEGMENT_SEPARATOR);
242
+
243
+ export const SEVEN_DAY_UTILIZATION_COLUMN_START =
244
+ STATUS_DOT_DISPLAY_WIDTH +
245
+ TOKEN_NAME_WIDTH +
246
+ TOKEN_SEGMENT_SEPARATOR.length +
247
+ TOKEN_UTILIZATION_WIDTH +
248
+ TOKEN_SEGMENT_SEPARATOR.length +
249
+ TOKEN_RESET_WIDTH +
250
+ TOKEN_SEGMENT_SEPARATOR.length;
251
+
252
+ export const formatSevenDayWindowAggregateLine = (
253
+ aggregate: SevenDayWindowAggregate | null,
254
+ ): string | null => {
255
+ if (aggregate === null) {
256
+ return null;
257
+ }
258
+ const usedPercent = roundHalfToEven(aggregate.usedPercent);
259
+ const includedCountSuffix =
260
+ aggregate.includedTokenCount === aggregate.totalTokenCount
261
+ ? ''
262
+ : ` (${aggregate.includedTokenCount})`;
263
+ return (
264
+ padEnd('', SEVEN_DAY_UTILIZATION_COLUMN_START, ' ') +
265
+ formatUtilization(usedPercent) +
266
+ includedCountSuffix
267
+ );
268
+ };
269
+
225
270
  export const formatTokenRowLine = (token: TokenStatus): string => {
226
271
  const dot = TOKEN_COLOR_DOT[token.color];
227
- const name = padEnd(token.name, 4, '_');
272
+ const name = padEnd(token.name, TOKEN_NAME_WIDTH, '_');
228
273
  const fiveHourUtilization = formatUtilization(
229
274
  token.fiveHourUtilizationPercent,
230
275
  );
@@ -235,7 +280,15 @@ export const formatTokenRowLine = (token: TokenStatus): string => {
235
280
  const sevenDayReset = formatReset(token.sevenDayResetSeconds);
236
281
  const prep = String(token.prep);
237
282
  const hum = String(token.hum);
238
- return `${dot}${name} ${fiveHourUtilization} ${fiveHourReset} ${sevenDayUtilization} ${sevenDayReset} ${prep} ${hum}`;
283
+ return joinTokenRowSegments([
284
+ `${dot}${name}`,
285
+ fiveHourUtilization,
286
+ fiveHourReset,
287
+ sevenDayUtilization,
288
+ sevenDayReset,
289
+ prep,
290
+ hum,
291
+ ]);
239
292
  };
240
293
 
241
294
  const wrapLine = (line: string): string =>
@@ -251,7 +304,15 @@ export class ComposeDashboardUseCase {
251
304
  const tokenLines = sortTokens(input.tokens).map((token) =>
252
305
  formatTokenRowLine(token),
253
306
  );
254
- const lines = [...statsLines, ...projectLines, '', ...tokenLines];
307
+ const aggregateLine = formatSevenDayWindowAggregateLine(
308
+ input.sevenDayWindowAggregate ?? null,
309
+ );
310
+ const lines = [
311
+ ...statsLines,
312
+ ...projectLines,
313
+ aggregateLine === null ? '' : aggregateLine,
314
+ ...tokenLines,
315
+ ];
255
316
  return lines.map((line) => wrapLine(line)).join('\n') + '\n';
256
317
  };
257
318
  }
@@ -2,6 +2,8 @@ import {
2
2
  GenerateTokenStatusUseCase,
3
3
  TokenRateLimitDecision,
4
4
  TokenRateLimitSnapshot,
5
+ TokenStatus,
6
+ computeSevenDayWindowAggregate,
5
7
  judgeTokenColor,
6
8
  } from './GenerateTokenStatusUseCase';
7
9
 
@@ -207,3 +209,74 @@ describe('GenerateTokenStatusUseCase', () => {
207
209
  expect(result[0].color).toBe('G');
208
210
  });
209
211
  });
212
+
213
+ describe('computeSevenDayWindowAggregate', () => {
214
+ const tokenStatus = (
215
+ sevenDayUtilizationPercent: number | null,
216
+ name: string,
217
+ ): TokenStatus => ({
218
+ name,
219
+ fiveHourUtilizationPercent: null,
220
+ fiveHourResetSeconds: null,
221
+ sevenDayUtilizationPercent,
222
+ sevenDayResetSeconds: null,
223
+ color: 'G',
224
+ prep: 0,
225
+ hum: 0,
226
+ });
227
+
228
+ it('averages the seven day utilization of every token when all values are present', () => {
229
+ expect(
230
+ computeSevenDayWindowAggregate([
231
+ tokenStatus(60, 'alice'),
232
+ tokenStatus(64, 'bob'),
233
+ tokenStatus(65, 'carol'),
234
+ ]),
235
+ ).toEqual({
236
+ usedPercent: 63,
237
+ includedTokenCount: 3,
238
+ totalTokenCount: 3,
239
+ });
240
+ });
241
+
242
+ it('excludes tokens without a value from both numerator and denominator', () => {
243
+ expect(
244
+ computeSevenDayWindowAggregate([
245
+ tokenStatus(80, 'alice'),
246
+ tokenStatus(null, 'bob'),
247
+ tokenStatus(40, 'carol'),
248
+ tokenStatus(null, 'dave'),
249
+ ]),
250
+ ).toEqual({
251
+ usedPercent: 60,
252
+ includedTokenCount: 2,
253
+ totalTokenCount: 4,
254
+ });
255
+ });
256
+
257
+ it('keeps the fractional mean so the presentation layer decides the rounding', () => {
258
+ expect(
259
+ computeSevenDayWindowAggregate([
260
+ tokenStatus(63, 'alice'),
261
+ tokenStatus(64, 'bob'),
262
+ ]),
263
+ ).toEqual({
264
+ usedPercent: 63.5,
265
+ includedTokenCount: 2,
266
+ totalTokenCount: 2,
267
+ });
268
+ });
269
+
270
+ it('returns null when no token has a seven day utilization value', () => {
271
+ expect(
272
+ computeSevenDayWindowAggregate([
273
+ tokenStatus(null, 'alice'),
274
+ tokenStatus(null, 'bob'),
275
+ ]),
276
+ ).toBeNull();
277
+ });
278
+
279
+ it('returns null when there is no token at all', () => {
280
+ expect(computeSevenDayWindowAggregate([])).toBeNull();
281
+ });
282
+ });
@@ -37,6 +37,12 @@ export type TokenStatus = {
37
37
  hum: number;
38
38
  };
39
39
 
40
+ export type SevenDayWindowAggregate = {
41
+ usedPercent: number;
42
+ includedTokenCount: number;
43
+ totalTokenCount: number;
44
+ };
45
+
40
46
  export type TokenStatusInput = {
41
47
  name: string;
42
48
  token: string;
@@ -86,6 +92,23 @@ export const judgeTokenColor = (
86
92
  return 'G';
87
93
  };
88
94
 
95
+ export const computeSevenDayWindowAggregate = (
96
+ tokens: TokenStatus[],
97
+ ): SevenDayWindowAggregate | null => {
98
+ const utilizations = tokens
99
+ .map((token) => token.sevenDayUtilizationPercent)
100
+ .filter((percent): percent is number => percent !== null);
101
+ if (utilizations.length === 0) {
102
+ return null;
103
+ }
104
+ const total = utilizations.reduce((sum, percent) => sum + percent, 0);
105
+ return {
106
+ usedPercent: total / utilizations.length,
107
+ includedTokenCount: utilizations.length,
108
+ totalTokenCount: tokens.length,
109
+ };
110
+ };
111
+
89
112
  export class GenerateTokenStatusUseCase {
90
113
  run = (input: GenerateTokenStatusInput): TokenStatus[] => {
91
114
  const { tokens, prepCountByToken, humCountByToken, nowEpochSeconds } =
@@ -1 +1 @@
1
- {"version":3,"file":"dashboardComposeService.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/dashboardComposeService.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,qBAAqB,EAItB,MAAM,4DAA4D,CAAC;AAQpE,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAiKF,eAAO,MAAM,0BAA0B,GACrC,SAAS,uBAAuB,KAC/B,qBAYF,CAAC;AAUF,eAAO,MAAM,4BAA4B,GACvC,SAAS,uBAAuB,KAC/B,OAYF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,uBAAuB,KAC/B,MACqE,CAAC"}
1
+ {"version":3,"file":"dashboardComposeService.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/dashboardComposeService.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,qBAAqB,EAItB,MAAM,4DAA4D,CAAC;AASpE,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAgMF,eAAO,MAAM,0BAA0B,GACrC,SAAS,uBAAuB,KAC/B,qBAcF,CAAC;AAUF,eAAO,MAAM,4BAA4B,GACvC,SAAS,uBAAuB,KAC/B,OAYF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,uBAAuB,KAC/B,MACqE,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { Issue } from '../../../domain/entities/Issue';
2
- import { TokenRateLimitSnapshot, TokenStatus } from '../../../domain/usecases/dashboard/GenerateTokenStatusUseCase';
2
+ import { SevenDayWindowAggregate, TokenRateLimitSnapshot, TokenStatus } from '../../../domain/usecases/dashboard/GenerateTokenStatusUseCase';
3
3
  import { ClaudeInteractiveSessionRepository } from '../../../domain/usecases/adapter-interfaces/ClaudeInteractiveSessionRepository';
4
4
  import { TakeOwnershipSpawnRepository } from '../../../domain/usecases/adapter-interfaces/TakeOwnershipSpawnRepository';
5
5
  import { RateLimitSnapshot } from '../../proxy/RateLimitCache';
@@ -15,6 +15,7 @@ export type TokenStatusWriterParams = {
15
15
  };
16
16
  export type TokenStatusFile = {
17
17
  tokens: TokenStatus[];
18
+ sevenDayWindowAggregate: SevenDayWindowAggregate | null;
18
19
  capturedAt: string;
19
20
  };
20
21
  export declare const toTokenRateLimitSnapshot: (snapshot: RateLimitSnapshot | null) => TokenRateLimitSnapshot | null;
@@ -1 +1 @@
1
- {"version":3,"file":"tokenStatusWriter.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/tokenStatusWriter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAE5D,OAAO,EAEL,sBAAsB,EACtB,WAAW,EAEZ,MAAM,+DAA+D,CAAC;AAGvE,OAAO,EAAE,kCAAkC,EAAE,MAAM,gFAAgF,CAAC;AACpI,OAAO,EAAE,4BAA4B,EAAE,MAAM,0EAA0E,CAAC;AACxH,OAAO,EAAE,iBAAiB,EAAiB,MAAM,4BAA4B,CAAC;AAU9E,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,iBAAiB,GAAG,IAAI,CAAC;IAC3D,4BAA4B,CAAC,EAAE,kCAAkC,CAAC;IAClE,eAAe,CAAC,EAAE,4BAA4B,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AA0EF,eAAO,MAAM,wBAAwB,GACnC,UAAU,iBAAiB,GAAG,IAAI,KACjC,sBAAsB,GAAG,IA0B3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,QAAQ,uBAAuB,KAAG,IA+GlE,CAAC"}
1
+ {"version":3,"file":"tokenStatusWriter.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/tokenStatusWriter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAE5D,OAAO,EAEL,uBAAuB,EACvB,sBAAsB,EACtB,WAAW,EAGZ,MAAM,+DAA+D,CAAC;AAGvE,OAAO,EAAE,kCAAkC,EAAE,MAAM,gFAAgF,CAAC;AACpI,OAAO,EAAE,4BAA4B,EAAE,MAAM,0EAA0E,CAAC;AACxH,OAAO,EAAE,iBAAiB,EAAiB,MAAM,4BAA4B,CAAC;AAU9E,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACnC,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,iBAAiB,GAAG,IAAI,CAAC;IAC3D,4BAA4B,CAAC,EAAE,kCAAkC,CAAC;IAClE,eAAe,CAAC,EAAE,4BAA4B,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,uBAAuB,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACxD,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AA0EF,eAAO,MAAM,wBAAwB,GACnC,UAAU,iBAAiB,GAAG,IAAI,KACjC,sBAAsB,GAAG,IA0B3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,QAAQ,uBAAuB,KAAG,IAgHlE,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { OwnerCallStatusProvider } from '../../domain/usecases/adapter-interfaces/OwnerCallStatusProvider';
2
+ export declare const ownerCallMarkerFamilyResolve: (marker: string) => string[];
2
3
  export declare class TranscriptOwnerCallStatusProvider implements OwnerCallStatusProvider {
3
- private readonly ownerCallMarker;
4
+ private readonly ownerCallMarkerFamily;
4
5
  constructor(ownerCallMarker: string | null);
5
6
  listUnansweredOwnerCallEpochSecondsBySessionName: (transcriptPathBySessionName: Map<string, string>) => Promise<Map<string, number>>;
6
7
  private findUnansweredOwnerCallEpochMs;
@@ -1 +1 @@
1
- {"version":3,"file":"TranscriptOwnerCallStatusProvider.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/TranscriptOwnerCallStatusProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kEAAkE,CAAC;AAyF3G,qBAAa,iCAAkC,YAAW,uBAAuB;IACnE,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAAf,eAAe,EAAE,MAAM,GAAG,IAAI;IAE3D,gDAAgD,GAC9C,6BAA6B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAsB7B;IAEF,OAAO,CAAC,8BAA8B,CAsDpC;CACH"}
1
+ {"version":3,"file":"TranscriptOwnerCallStatusProvider.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/TranscriptOwnerCallStatusProvider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kEAAkE,CAAC;AA6F3G,eAAO,MAAM,4BAA4B,GAAI,QAAQ,MAAM,KAAG,MAAM,EAMtD,CAAC;AAEf,qBAAa,iCAAkC,YAAW,uBAAuB;IAC/E,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAW;gBAErC,eAAe,EAAE,MAAM,GAAG,IAAI;IAO1C,gDAAgD,GAC9C,6BAA6B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqB7B;IAEF,OAAO,CAAC,8BAA8B,CAsDpC;CACH"}
@@ -1,5 +1,5 @@
1
1
  import { DashboardRow } from './GenerateDashboardRowUseCase';
2
- import { TokenStatus } from './GenerateTokenStatusUseCase';
2
+ import { SevenDayWindowAggregate, TokenStatus } from './GenerateTokenStatusUseCase';
3
3
  export declare const PROJECT_ROW_WIDTH_BUDGET = 32;
4
4
  export type ComposeDashboardProject = {
5
5
  code: string;
@@ -21,12 +21,17 @@ export type ComposeDashboardInput = {
21
21
  projects: ComposeDashboardProject[];
22
22
  machineStatus: ComposeDashboardMachineStatus | null;
23
23
  tokens: TokenStatus[];
24
+ sevenDayWindowAggregate?: SevenDayWindowAggregate | null;
24
25
  };
26
+ export declare const STATUS_DOT_DISPLAY_WIDTH = 2;
27
+ export declare const TOKEN_UTILIZATION_WIDTH = 4;
25
28
  export declare const roundHalfToEven: (value: number) => number;
26
29
  export declare const formatResetCountdown: (totalSeconds: number) => string;
27
30
  export declare const formatMachineStatusLines: (machineStatus: ComposeDashboardMachineStatus | null) => string[];
28
31
  export declare const formatProjectHeaderLine: () => string;
29
32
  export declare const formatProjectRowLine: (project: ComposeDashboardProject) => string;
33
+ export declare const SEVEN_DAY_UTILIZATION_COLUMN_START: number;
34
+ export declare const formatSevenDayWindowAggregateLine: (aggregate: SevenDayWindowAggregate | null) => string | null;
30
35
  export declare const formatTokenRowLine: (token: TokenStatus) => string;
31
36
  export declare class ComposeDashboardUseCase {
32
37
  run: (input: ComposeDashboardInput) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"ComposeDashboardUseCase.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/dashboard/ComposeDashboardUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAoB,MAAM,8BAA8B,CAAC;AAE7E,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,YAAY,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC;IACtC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACtC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,uBAAuB,EAAE,CAAC;IACpC,aAAa,EAAE,6BAA6B,GAAG,IAAI,CAAC;IACpD,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC;AAmDF,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,MAU/C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,KAAG,MAa3D,CAAC;AAoBF,eAAO,MAAM,wBAAwB,GACnC,eAAe,6BAA6B,GAAG,IAAI,KAClD,MAAM,EA8BR,CAAC;AAKF,eAAO,MAAM,uBAAuB,QAAO,MAM1C,CAAC;AAkBF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,uBAAuB,KAC/B,MAQF,CAAC;AA6BF,eAAO,MAAM,kBAAkB,GAAI,OAAO,WAAW,KAAG,MAcvD,CAAC;AAKF,qBAAa,uBAAuB;IAClC,GAAG,GAAI,OAAO,qBAAqB,KAAG,MAAM,CAW1C;CACH"}
1
+ {"version":3,"file":"ComposeDashboardUseCase.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/dashboard/ComposeDashboardUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EACL,uBAAuB,EACvB,WAAW,EAEZ,MAAM,8BAA8B,CAAC;AAEtC,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,YAAY,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC;IACtC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACtC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,uBAAuB,EAAE,CAAC;IACpC,aAAa,EAAE,6BAA6B,GAAG,IAAI,CAAC;IACpD,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,uBAAuB,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;CAC1D,CAAC;AAmBF,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAM1C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAoCzC,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,MAU/C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,KAAG,MAa3D,CAAC;AAoBF,eAAO,MAAM,wBAAwB,GACnC,eAAe,6BAA6B,GAAG,IAAI,KAClD,MAAM,EA8BR,CAAC;AAKF,eAAO,MAAM,uBAAuB,QAAO,MAM1C,CAAC;AAkBF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,uBAAuB,KAC/B,MAQF,CAAC;AAgCF,eAAO,MAAM,kCAAkC,QAOf,CAAC;AAEjC,eAAO,MAAM,iCAAiC,GAC5C,WAAW,uBAAuB,GAAG,IAAI,KACxC,MAAM,GAAG,IAcX,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,OAAO,WAAW,KAAG,MAsBvD,CAAC;AAKF,qBAAa,uBAAuB;IAClC,GAAG,GAAI,OAAO,qBAAqB,KAAG,MAAM,CAmB1C;CACH"}
@@ -33,6 +33,11 @@ export type TokenStatus = {
33
33
  prep: number;
34
34
  hum: number;
35
35
  };
36
+ export type SevenDayWindowAggregate = {
37
+ usedPercent: number;
38
+ includedTokenCount: number;
39
+ totalTokenCount: number;
40
+ };
36
41
  export type TokenStatusInput = {
37
42
  name: string;
38
43
  token: string;
@@ -45,6 +50,7 @@ export type GenerateTokenStatusInput = {
45
50
  nowEpochSeconds: number;
46
51
  };
47
52
  export declare const judgeTokenColor: (decision: TokenRateLimitDecision | null) => TokenStatusColor;
53
+ export declare const computeSevenDayWindowAggregate: (tokens: TokenStatus[]) => SevenDayWindowAggregate | null;
48
54
  export declare class GenerateTokenStatusUseCase {
49
55
  run: (input: GenerateTokenStatusInput) => TokenStatus[];
50
56
  private normalizeWindows;
@@ -1 +1 @@
1
- {"version":3,"file":"GenerateTokenStatusUseCase.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/dashboard/GenerateTokenStatusUseCase.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE/C,MAAM,MAAM,sBAAsB,GAAG;IACnC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;IAChC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;IAChC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,KAAK,EAAE,gBAAgB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,sBAAsB,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAKF,eAAO,MAAM,eAAe,GAC1B,UAAU,sBAAsB,GAAG,IAAI,KACtC,gBA6BF,CAAC;AAEF,qBAAa,0BAA0B;IACrC,GAAG,GAAI,OAAO,wBAAwB,KAAG,WAAW,EAAE,CAoBpD;IAEF,OAAO,CAAC,gBAAgB,CAyCtB;IAEF,OAAO,CAAC,UAAU,CAuChB;CACH"}
1
+ {"version":3,"file":"GenerateTokenStatusUseCase.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/dashboard/GenerateTokenStatusUseCase.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE/C,MAAM,MAAM,sBAAsB,GAAG;IACnC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;IAChC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sBAAsB,EAAE,OAAO,CAAC;IAChC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,KAAK,EAAE,gBAAgB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,sBAAsB,GAAG,IAAI,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAKF,eAAO,MAAM,eAAe,GAC1B,UAAU,sBAAsB,GAAG,IAAI,KACtC,gBA6BF,CAAC;AAEF,eAAO,MAAM,8BAA8B,GACzC,QAAQ,WAAW,EAAE,KACpB,uBAAuB,GAAG,IAa5B,CAAC;AAEF,qBAAa,0BAA0B;IACrC,GAAG,GAAI,OAAO,wBAAwB,KAAG,WAAW,EAAE,CAoBpD;IAEF,OAAO,CAAC,gBAAgB,CAyCtB;IAEF,OAAO,CAAC,UAAU,CAuChB;CACH"}