github-issue-tower-defence-management 1.134.0 → 1.135.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 (51) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +5 -4
  3. package/bin/adapter/entry-points/cli/index.js +11 -1
  4. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  5. package/bin/adapter/entry-points/cli/projectConfig.js +21 -0
  6. package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
  7. package/bin/adapter/entry-points/console/dashboardComposeService.js +18 -0
  8. package/bin/adapter/entry-points/console/dashboardComposeService.js.map +1 -1
  9. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +81 -54
  10. package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
  11. package/bin/adapter/entry-points/handlers/machineStatusWriter.js +6 -0
  12. package/bin/adapter/entry-points/handlers/machineStatusWriter.js.map +1 -1
  13. package/bin/adapter/repositories/ProcHostMetricsRepository.js +4 -0
  14. package/bin/adapter/repositories/ProcHostMetricsRepository.js.map +1 -1
  15. package/bin/adapter/repositories/TranscriptSessionSubAgentActivityRepository.js +59 -2
  16. package/bin/adapter/repositories/TranscriptSessionSubAgentActivityRepository.js.map +1 -1
  17. package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js +26 -4
  18. package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js.map +1 -1
  19. package/package.json +1 -1
  20. package/src/adapter/entry-points/cli/index.test.ts +42 -1
  21. package/src/adapter/entry-points/cli/index.ts +20 -1
  22. package/src/adapter/entry-points/cli/projectConfig.test.ts +75 -0
  23. package/src/adapter/entry-points/cli/projectConfig.ts +31 -0
  24. package/src/adapter/entry-points/console/dashboardComposeService.test.ts +32 -0
  25. package/src/adapter/entry-points/console/dashboardComposeService.ts +20 -0
  26. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.test.ts +66 -0
  27. package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +7 -1
  28. package/src/adapter/entry-points/handlers/machineStatusWriter.test.ts +61 -0
  29. package/src/adapter/entry-points/handlers/machineStatusWriter.ts +17 -0
  30. package/src/adapter/repositories/ProcHostMetricsRepository.test.ts +25 -0
  31. package/src/adapter/repositories/ProcHostMetricsRepository.ts +5 -0
  32. package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.test.ts +196 -0
  33. package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.ts +62 -0
  34. package/src/adapter/repositories/issue/ApiV3CheerioRestIssueRepository.test.ts +26 -3
  35. package/src/domain/usecases/dashboard/ComposeDashboardUseCase.test.ts +55 -0
  36. package/src/domain/usecases/dashboard/ComposeDashboardUseCase.ts +34 -5
  37. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  38. package/types/adapter/entry-points/cli/projectConfig.d.ts +5 -0
  39. package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
  40. package/types/adapter/entry-points/console/dashboardComposeService.d.ts.map +1 -1
  41. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts +1 -1
  42. package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
  43. package/types/adapter/entry-points/handlers/machineStatusWriter.d.ts +7 -0
  44. package/types/adapter/entry-points/handlers/machineStatusWriter.d.ts.map +1 -1
  45. package/types/adapter/repositories/ProcHostMetricsRepository.d.ts +1 -0
  46. package/types/adapter/repositories/ProcHostMetricsRepository.d.ts.map +1 -1
  47. package/types/adapter/repositories/TranscriptSessionSubAgentActivityRepository.d.ts +1 -0
  48. package/types/adapter/repositories/TranscriptSessionSubAgentActivityRepository.d.ts.map +1 -1
  49. package/types/domain/usecases/dashboard/ComposeDashboardUseCase.d.ts +6 -1
  50. package/types/domain/usecases/dashboard/ComposeDashboardUseCase.d.ts.map +1 -1
  51. package/types/index.d.ts +1 -1
@@ -1,5 +1,6 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
+ import { DiskConfig } from '../cli/projectConfig';
3
4
  import {
4
5
  ProcHostMetricsRepository,
5
6
  cycleMinutesFromFetchTimestamps,
@@ -8,14 +9,21 @@ import {
8
9
  export type MachineStatusWriterParams = {
9
10
  dashboardDataDir: string | null | undefined;
10
11
  allIssuesCacheDir: string | null | undefined;
12
+ disks?: DiskConfig[] | null;
11
13
  hostMetricsRepository?: ProcHostMetricsRepository;
12
14
  now?: Date;
13
15
  };
14
16
 
17
+ export type MachineStatusDisk = {
18
+ title: string;
19
+ pct: number;
20
+ };
21
+
15
22
  export type MachineStatusFile = {
16
23
  memPct: number;
17
24
  cpuPct: number;
18
25
  diskPct: number;
26
+ disks?: MachineStatusDisk[];
19
27
  load: [number, number, number];
20
28
  cycleMinutes: number | null;
21
29
  lastFetchedAt: string | null;
@@ -68,6 +76,14 @@ export const writeMachineStatus = async (
68
76
  const diskPct = hostMetricsRepository.readDiskUsedPercent();
69
77
  const load = hostMetricsRepository.readLoadAverages();
70
78
 
79
+ const configuredDisks = params.disks ?? [];
80
+ const disks: MachineStatusDisk[] = configuredDisks.map((disk) => ({
81
+ title: disk.title,
82
+ pct: hostMetricsRepository.readDiskUsedPercentForMountpoint(
83
+ disk.mountpoint,
84
+ ),
85
+ }));
86
+
71
87
  const machineStatusPath = path.join(dashboardDataDir, 'machine-status.json');
72
88
  const previousLastFetchedAt =
73
89
  readLastFetchedAtFromJsonFile(machineStatusPath);
@@ -83,6 +99,7 @@ export const writeMachineStatus = async (
83
99
  memPct,
84
100
  cpuPct,
85
101
  diskPct,
102
+ ...(disks.length > 0 ? { disks } : {}),
86
103
  load: [load.oneMinute, load.fiveMinute, load.fifteenMinute],
87
104
  cycleMinutes,
88
105
  lastFetchedAt: currentLastFetchedAt,
@@ -167,6 +167,31 @@ describe('ProcHostMetricsRepository', () => {
167
167
  expect(repository.readDiskUsedPercent()).toBe(90);
168
168
  });
169
169
 
170
+ it('reads the df-style disk used percent for a given mountpoint', () => {
171
+ const blocksByMountpoint: Record<string, DiskBlocks> = {
172
+ '/': { blocks: 1100, bfree: 200, bavail: 100 },
173
+ '/mountpoint-a': { blocks: 1000, bfree: 700, bavail: 700 },
174
+ };
175
+ const requestedMountpoints: string[] = [];
176
+ const repository = new ProcHostMetricsRepository(
177
+ procDirectory,
178
+ async () => {},
179
+ (mountpoint) => {
180
+ requestedMountpoints.push(mountpoint);
181
+ const blocks = blocksByMountpoint[mountpoint];
182
+ if (!blocks) {
183
+ throw new Error(`unexpected mountpoint ${mountpoint}`);
184
+ }
185
+ return blocks;
186
+ },
187
+ );
188
+ expect(repository.readDiskUsedPercentForMountpoint('/mountpoint-a')).toBe(
189
+ 30,
190
+ );
191
+ expect(repository.readDiskUsedPercentForMountpoint('/')).toBe(90);
192
+ expect(requestedMountpoints).toEqual(['/mountpoint-a', '/']);
193
+ });
194
+
170
195
  it('samples /proc/stat twice and computes the busy percent', async () => {
171
196
  const statPath = path.join(procDirectory, 'stat');
172
197
  let sampleIndex = 0;
@@ -173,4 +173,9 @@ export class ProcHostMetricsRepository {
173
173
  const { blocks, bfree, bavail } = this.readDiskBlocks(this.rootPath);
174
174
  return parseDiskUsedPercent(blocks, bfree, bavail);
175
175
  };
176
+
177
+ readDiskUsedPercentForMountpoint = (mountpoint: string): number => {
178
+ const { blocks, bfree, bavail } = this.readDiskBlocks(mountpoint);
179
+ return parseDiskUsedPercent(blocks, bfree, bavail);
180
+ };
176
181
  }
@@ -1044,4 +1044,200 @@ describe('TranscriptSessionSubAgentActivityRepository', () => {
1044
1044
  expect(result.get(sessionName)?.[0]?.waitingOnExternalProcess).toBe(true);
1045
1045
  });
1046
1046
  });
1047
+
1048
+ const writeMainTranscript = (sessionName: string, lines: object[]): void => {
1049
+ const filePath = mainTranscriptPathFor(sessionName);
1050
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
1051
+ fs.writeFileSync(
1052
+ filePath,
1053
+ lines.map((line) => JSON.stringify(line)).join('\n'),
1054
+ 'utf8',
1055
+ );
1056
+ };
1057
+
1058
+ const killedNotificationEntry = (
1059
+ agentId: string,
1060
+ timestamp: string,
1061
+ ): object => ({
1062
+ type: 'queue-operation',
1063
+ operation: 'enqueue',
1064
+ timestamp,
1065
+ content: `<task-notification>\n<task-id>${agentId}</task-id>\n<status>killed</status>\n</task-notification>`,
1066
+ });
1067
+
1068
+ const failedNotificationEntry = (
1069
+ agentId: string,
1070
+ timestamp: string,
1071
+ ): object => ({
1072
+ type: 'queue-operation',
1073
+ operation: 'enqueue',
1074
+ timestamp,
1075
+ content: `<task-notification>\n<task-id>${agentId}</task-id>\n<status>failed</status>\n</task-notification>`,
1076
+ });
1077
+
1078
+ const completedNotificationEntry = (
1079
+ agentId: string,
1080
+ timestamp: string,
1081
+ ): object => ({
1082
+ type: 'queue-operation',
1083
+ operation: 'enqueue',
1084
+ timestamp,
1085
+ content: `<task-notification>\n<task-id>${agentId}</task-id>\n<status>completed</status>\n</task-notification>`,
1086
+ });
1087
+
1088
+ it('excludes a sub-agent killed via TaskStop when the parent transcript records a killed notification for its id', async () => {
1089
+ const sessionName = 'https_//github_com/owner/repo/issues/9';
1090
+ const killedAgentId = 'aaabbbbcccc00001';
1091
+ writeAgentTranscript(
1092
+ sessionName,
1093
+ killedAgentId,
1094
+ pendingToolUseEntries('2026-06-27T11:00:00.000Z'),
1095
+ nowEpochSeconds - 300,
1096
+ );
1097
+ writeMainTranscript(sessionName, [
1098
+ killedNotificationEntry(killedAgentId, '2026-06-27T11:55:00.000Z'),
1099
+ ]);
1100
+ const repository = new TranscriptSessionSubAgentActivityRepository(
1101
+ createResolver(),
1102
+ emptyProcessLister(),
1103
+ now,
1104
+ );
1105
+
1106
+ const result = await repository.listSubAgentActivitiesBySessionName(
1107
+ [sessionName],
1108
+ transcriptMapFor([sessionName]),
1109
+ );
1110
+
1111
+ expect(result.size).toBe(0);
1112
+ });
1113
+
1114
+ it('excludes a sub-agent whose process crashed when the parent transcript records a failed notification for its id', async () => {
1115
+ const sessionName = 'https_//github_com/owner/repo/issues/9';
1116
+ const failedAgentId = 'aaabbbbcccc00002';
1117
+ writeAgentTranscript(
1118
+ sessionName,
1119
+ failedAgentId,
1120
+ pendingToolUseEntries('2026-06-27T11:00:00.000Z'),
1121
+ nowEpochSeconds - 300,
1122
+ );
1123
+ writeMainTranscript(sessionName, [
1124
+ failedNotificationEntry(failedAgentId, '2026-06-27T11:55:00.000Z'),
1125
+ ]);
1126
+ const repository = new TranscriptSessionSubAgentActivityRepository(
1127
+ createResolver(),
1128
+ emptyProcessLister(),
1129
+ now,
1130
+ );
1131
+
1132
+ const result = await repository.listSubAgentActivitiesBySessionName(
1133
+ [sessionName],
1134
+ transcriptMapFor([sessionName]),
1135
+ );
1136
+
1137
+ expect(result.size).toBe(0);
1138
+ });
1139
+
1140
+ it('does not exclude a sub-agent whose parent transcript records only a completed notification for its id', async () => {
1141
+ const sessionName = 'https_//github_com/owner/repo/issues/9';
1142
+ const startTimestamp = '2026-06-27T11:45:00.000Z';
1143
+ const completedAgentId = 'aaabbbbcccc00003';
1144
+ writeAgentTranscript(
1145
+ sessionName,
1146
+ completedAgentId,
1147
+ pendingToolUseEntries(startTimestamp),
1148
+ nowEpochSeconds - 120,
1149
+ );
1150
+ writeMainTranscript(sessionName, [
1151
+ completedNotificationEntry(completedAgentId, '2026-06-27T11:58:00.000Z'),
1152
+ ]);
1153
+ const repository = new TranscriptSessionSubAgentActivityRepository(
1154
+ createResolver(),
1155
+ emptyProcessLister(),
1156
+ now,
1157
+ );
1158
+
1159
+ const result = await repository.listSubAgentActivitiesBySessionName(
1160
+ [sessionName],
1161
+ transcriptMapFor([sessionName]),
1162
+ );
1163
+
1164
+ expect(result.get(sessionName)).toEqual([
1165
+ {
1166
+ label: `agent-${completedAgentId}`,
1167
+ silentSeconds: 120,
1168
+ runningSeconds: 900,
1169
+ waitingOnExternalProcess: false,
1170
+ },
1171
+ ]);
1172
+ });
1173
+
1174
+ it('excludes a killed sub-agent but reports a still-active sibling in the same session', async () => {
1175
+ const sessionName = 'https_//github_com/owner/repo/issues/9';
1176
+ const killedAgentId = 'aaabbbbcccc00004';
1177
+ const aliveAgentId = 'aaabbbbcccc00005';
1178
+ writeAgentTranscript(
1179
+ sessionName,
1180
+ killedAgentId,
1181
+ pendingToolUseEntries('2026-06-27T11:00:00.000Z'),
1182
+ nowEpochSeconds - 600,
1183
+ );
1184
+ writeAgentTranscript(
1185
+ sessionName,
1186
+ aliveAgentId,
1187
+ runningEntries('2026-06-27T11:45:00.000Z'),
1188
+ nowEpochSeconds - 120,
1189
+ );
1190
+ writeMainTranscript(sessionName, [
1191
+ killedNotificationEntry(killedAgentId, '2026-06-27T11:55:00.000Z'),
1192
+ ]);
1193
+ const repository = new TranscriptSessionSubAgentActivityRepository(
1194
+ createResolver(),
1195
+ emptyProcessLister(),
1196
+ now,
1197
+ );
1198
+
1199
+ const result = await repository.listSubAgentActivitiesBySessionName(
1200
+ [sessionName],
1201
+ transcriptMapFor([sessionName]),
1202
+ );
1203
+
1204
+ expect(result.get(sessionName)).toEqual([
1205
+ {
1206
+ label: `agent-${aliveAgentId}`,
1207
+ silentSeconds: 120,
1208
+ runningSeconds: 900,
1209
+ waitingOnExternalProcess: false,
1210
+ },
1211
+ ]);
1212
+ });
1213
+
1214
+ it('reports a sub-agent even when the parent transcript path does not exist', async () => {
1215
+ const sessionName = 'https_//github_com/owner/repo/issues/9';
1216
+ const startTimestamp = '2026-06-27T11:45:00.000Z';
1217
+ writeAgentTranscript(
1218
+ sessionName,
1219
+ 'aabb1122cc3344ee',
1220
+ runningEntries(startTimestamp),
1221
+ nowEpochSeconds - 120,
1222
+ );
1223
+ const repository = new TranscriptSessionSubAgentActivityRepository(
1224
+ createResolver(),
1225
+ emptyProcessLister(),
1226
+ now,
1227
+ );
1228
+
1229
+ const result = await repository.listSubAgentActivitiesBySessionName(
1230
+ [sessionName],
1231
+ transcriptMapFor([sessionName]),
1232
+ );
1233
+
1234
+ expect(result.get(sessionName)).toEqual([
1235
+ {
1236
+ label: 'agent-aabb1122cc3344ee',
1237
+ silentSeconds: 120,
1238
+ runningSeconds: 900,
1239
+ waitingOnExternalProcess: false,
1240
+ },
1241
+ ]);
1242
+ });
1047
1243
  });
@@ -190,6 +190,45 @@ const parseTranscript = (content: string): ParsedTranscript => {
190
190
 
191
191
  const clampToZero = (value: number): number => (value > 0 ? value : 0);
192
192
 
193
+ const parseKilledOrFailedAgentIds = (content: string): Set<string> => {
194
+ const result = new Set<string>();
195
+ for (const line of content.split('\n')) {
196
+ const trimmed = line.trim();
197
+ if (trimmed.length === 0) {
198
+ continue;
199
+ }
200
+ let parsed: unknown;
201
+ try {
202
+ parsed = JSON.parse(trimmed);
203
+ } catch {
204
+ continue;
205
+ }
206
+ if (!isRecord(parsed)) {
207
+ continue;
208
+ }
209
+ if (readString(parsed, 'type') !== 'queue-operation') {
210
+ continue;
211
+ }
212
+ if (readString(parsed, 'operation') !== 'enqueue') {
213
+ continue;
214
+ }
215
+ const notifContent = readString(parsed, 'content');
216
+ if (notifContent === null) {
217
+ continue;
218
+ }
219
+ const taskIdMatch = notifContent.match(/<task-id>(a[0-9a-f]+)<\/task-id>/);
220
+ const statusMatch = notifContent.match(/<status>([^<]+)<\/status>/);
221
+ if (!taskIdMatch || !statusMatch) {
222
+ continue;
223
+ }
224
+ const status = statusMatch[1];
225
+ if (status === 'killed' || status === 'failed') {
226
+ result.add(taskIdMatch[1]);
227
+ }
228
+ }
229
+ return result;
230
+ };
231
+
193
232
  export class TranscriptSessionSubAgentActivityRepository implements SessionSubAgentActivityRepository {
194
233
  constructor(
195
234
  private readonly directoryResolver: SubAgentTranscriptDirectoryResolver,
@@ -223,9 +262,12 @@ export class TranscriptSessionSubAgentActivityRepository implements SessionSubAg
223
262
  if (directory === null) {
224
263
  continue;
225
264
  }
265
+ const killedOrFailedAgentIds =
266
+ this.loadKilledOrFailedAgentIds(mainTranscriptPath);
226
267
  const activities = await this.collectActivities(
227
268
  directory,
228
269
  nowEpochSeconds,
270
+ killedOrFailedAgentIds,
229
271
  loadNormalizedProcessCommandLines,
230
272
  );
231
273
  if (activities.length > 0) {
@@ -235,9 +277,25 @@ export class TranscriptSessionSubAgentActivityRepository implements SessionSubAg
235
277
  return result;
236
278
  };
237
279
 
280
+ private loadKilledOrFailedAgentIds = (
281
+ mainTranscriptPath: string | null,
282
+ ): Set<string> => {
283
+ if (mainTranscriptPath === null) {
284
+ return new Set();
285
+ }
286
+ let content: string;
287
+ try {
288
+ content = fs.readFileSync(mainTranscriptPath, 'utf8');
289
+ } catch {
290
+ return new Set();
291
+ }
292
+ return parseKilledOrFailedAgentIds(content);
293
+ };
294
+
238
295
  private collectActivities = async (
239
296
  directory: string,
240
297
  nowEpochSeconds: number,
298
+ killedOrFailedAgentIds: Set<string>,
241
299
  loadNormalizedProcessCommandLines: () => Promise<string[]>,
242
300
  ): Promise<SubAgentActivity[]> => {
243
301
  let entries: fs.Dirent[];
@@ -252,6 +310,10 @@ export class TranscriptSessionSubAgentActivityRepository implements SessionSubAg
252
310
  if (!fileName.startsWith('agent-') || !fileName.endsWith('.jsonl')) {
253
311
  continue;
254
312
  }
313
+ const agentId = fileName.slice('agent-'.length, -'.jsonl'.length);
314
+ if (killedOrFailedAgentIds.has(agentId)) {
315
+ continue;
316
+ }
255
317
  const filePath = path.join(directory, fileName);
256
318
  const activity = await this.toActivity(
257
319
  filePath,
@@ -2107,7 +2107,7 @@ describe('ApiV3CheerioRestIssueRepository', () => {
2107
2107
  fetchSpy: FetchSpy,
2108
2108
  predicate: (url: string, body: string) => boolean,
2109
2109
  ): number =>
2110
- fetchSpy.mock.calls.filter(([input, init]) =>
2110
+ fetchSpy.mock.calls.filter(([input, init]: Parameters<typeof fetch>) =>
2111
2111
  predicate(requestUrlOf(input), requestBodyOf(init)),
2112
2112
  ).length;
2113
2113
 
@@ -2287,6 +2287,28 @@ describe('ApiV3CheerioRestIssueRepository', () => {
2287
2287
  expect(result?.isCiStateSuccess).toBe(true);
2288
2288
  expect(result?.isPassedAllCiJob).toBe(true);
2289
2289
  });
2290
+
2291
+ it('returns isCiStateSuccess true when check run conclusions are neutral or skipped', async () => {
2292
+ mockFetchRoutes({
2293
+ slimPullRequest: () => buildSlimPullRequestResponse(),
2294
+ checkRuns: () => ({
2295
+ total_count: 2,
2296
+ check_runs: [
2297
+ { id: 100, name: 'lint', conclusion: 'neutral' },
2298
+ { id: 200, name: 'docs', conclusion: 'skipped' },
2299
+ ],
2300
+ }),
2301
+ });
2302
+
2303
+ const { repository } = createApiV3CheerioRestIssueRepository();
2304
+ const result = await repository.getOpenPullRequest(
2305
+ 'https://github.com/HiromiShikata/test-repository/pull/31',
2306
+ );
2307
+
2308
+ expect(result).not.toBeNull();
2309
+ expect(result?.isCiStateSuccess).toBe(true);
2310
+ expect(result?.isPassedAllCiJob).toBe(true);
2311
+ });
2290
2312
  });
2291
2313
 
2292
2314
  describe('getOpenPullRequest required check resolution via REST', () => {
@@ -2625,13 +2647,14 @@ describe('ApiV3CheerioRestIssueRepository', () => {
2625
2647
  ),
2626
2648
  ).toBe(2);
2627
2649
  const secondSlimCall = fetchSpy.mock.calls
2628
- .map(([input, init]) =>
2650
+ .map(([input, init]): GraphqlRequestBody | null =>
2629
2651
  requestUrlOf(input) === 'https://api.github.com/graphql'
2630
2652
  ? parseGraphqlRequestBody(init)
2631
2653
  : null,
2632
2654
  )
2633
2655
  .filter(
2634
- (body) => body !== null && body.query.includes('headRefOid'),
2656
+ (body): body is GraphqlRequestBody =>
2657
+ body !== null && body.query.includes('headRefOid'),
2635
2658
  )[1];
2636
2659
  expect(secondSlimCall?.variables.reviewThreadsAfter).toBe('cursor-1');
2637
2660
  });
@@ -120,6 +120,61 @@ describe('formatMachineStatusLines', () => {
120
120
  ).toEqual(['M55% C62% D?% cy13', 'LA 16 23 40']);
121
121
  });
122
122
 
123
+ it('renders each configured partition as title and percent on a disk line', () => {
124
+ expect(
125
+ formatMachineStatusLines({
126
+ memPct: 55,
127
+ cpuPct: 62,
128
+ diskPct: 89,
129
+ disks: [
130
+ { title: 'D', pct: 89 },
131
+ { title: 'S', pct: 41 },
132
+ ],
133
+ load: [16, 23, 40],
134
+ cycleMinutes: 13,
135
+ }),
136
+ ).toEqual(['M55% C62% cy13', 'D89% S41%', 'LA 16 23 40']);
137
+ });
138
+
139
+ it('wraps partitions onto a second disk line when they exceed the width budget', () => {
140
+ const lines = formatMachineStatusLines({
141
+ memPct: 55,
142
+ cpuPct: 62,
143
+ diskPct: 89,
144
+ disks: [
145
+ { title: 'D', pct: 100 },
146
+ { title: 'S', pct: 100 },
147
+ { title: 'A', pct: 100 },
148
+ { title: 'B', pct: 100 },
149
+ { title: 'C', pct: 100 },
150
+ { title: 'E', pct: 100 },
151
+ { title: 'F', pct: 100 },
152
+ ],
153
+ load: [16, 23, 40],
154
+ cycleMinutes: 13,
155
+ });
156
+ expect(lines[0]).toBe('M55% C62% cy13');
157
+ expect(lines[lines.length - 1]).toBe('LA 16 23 40');
158
+ expect(lines.length).toBeGreaterThan(3);
159
+ for (const line of lines) {
160
+ expect(codePointLength(line)).toBeLessThanOrEqual(
161
+ PROJECT_ROW_WIDTH_BUDGET,
162
+ );
163
+ }
164
+ });
165
+
166
+ it('renders the single disk percent when no disks list is present', () => {
167
+ expect(
168
+ formatMachineStatusLines({
169
+ memPct: 55,
170
+ cpuPct: 62,
171
+ diskPct: 89,
172
+ load: [16, 23, 40],
173
+ cycleMinutes: 13,
174
+ }),
175
+ ).toEqual(['M55% C62% D89% cy13', 'LA 16 23 40']);
176
+ });
177
+
123
178
  it('keeps both lines within the 32 character width budget at worst case', () => {
124
179
  const lines = formatMachineStatusLines({
125
180
  memPct: 100,
@@ -8,10 +8,16 @@ export type ComposeDashboardProject = {
8
8
  row: DashboardRow | null;
9
9
  };
10
10
 
11
+ export type ComposeDashboardDisk = {
12
+ title: string;
13
+ pct: number;
14
+ };
15
+
11
16
  export type ComposeDashboardMachineStatus = {
12
17
  memPct: number | null;
13
18
  cpuPct: number | null;
14
19
  diskPct: number | null;
20
+ disks?: ComposeDashboardDisk[] | null;
15
21
  load: [number, number, number] | null;
16
22
  cycleMinutes: number | null;
17
23
  };
@@ -98,9 +104,27 @@ export const formatResetCountdown = (totalSeconds: number): string => {
98
104
  )}`;
99
105
  };
100
106
 
107
+ const packTokensWithinBudget = (tokens: string[]): string[] => {
108
+ const lines: string[] = [];
109
+ let current = '';
110
+ for (const token of tokens) {
111
+ const candidate = current === '' ? token : `${current} ${token}`;
112
+ if (current !== '' && candidate.length > PROJECT_ROW_WIDTH_BUDGET) {
113
+ lines.push(current);
114
+ current = token;
115
+ } else {
116
+ current = candidate;
117
+ }
118
+ }
119
+ if (current !== '') {
120
+ lines.push(current);
121
+ }
122
+ return lines;
123
+ };
124
+
101
125
  export const formatMachineStatusLines = (
102
126
  machineStatus: ComposeDashboardMachineStatus | null,
103
- ): [string, string] => {
127
+ ): string[] => {
104
128
  const memText =
105
129
  machineStatus !== null && machineStatus.memPct !== null
106
130
  ? `${machineStatus.memPct}%`
@@ -121,10 +145,15 @@ export const formatMachineStatusLines = (
121
145
  machineStatus !== null && machineStatus.cycleMinutes !== null
122
146
  ? `cy${machineStatus.cycleMinutes}`
123
147
  : 'cy-';
124
- return [
125
- `M${memText} C${cpuText} D${diskText} ${cycle}`,
126
- `LA ${oneMinute} ${fiveMinute} ${fifteenMinute}`,
127
- ];
148
+ const loadLine = `LA ${oneMinute} ${fiveMinute} ${fifteenMinute}`;
149
+ const disks =
150
+ machineStatus !== null && machineStatus.disks ? machineStatus.disks : null;
151
+ if (disks !== null && disks.length > 0) {
152
+ const diskTokens = disks.map((disk) => `${disk.title}${disk.pct}%`);
153
+ const diskLines = packTokensWithinBudget(diskTokens);
154
+ return [`M${memText} C${cpuText} ${cycle}`, ...diskLines, loadLine];
155
+ }
156
+ return [`M${memText} C${cpuText} D${diskText} ${cycle}`, loadLine];
128
157
  };
129
158
 
130
159
  const capThreeDigits = (value: number): string =>
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAqIzB,eAAO,MAAM,OAAO,SAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EACL,UAAU,EACV,cAAc,EACd,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAgJzB,eAAO,MAAM,OAAO,SAAgB,CAAC"}
@@ -21,6 +21,11 @@ export type ConfigFile = {
21
21
  changeTargetPathAliases?: Record<string, string>;
22
22
  consoleAccessToken?: string;
23
23
  consoleProjects?: Record<string, string>;
24
+ disks?: DiskConfig[];
25
+ };
26
+ export type DiskConfig = {
27
+ title: string;
28
+ mountpoint: string;
24
29
  };
25
30
  export declare const isRecord: (value: unknown) => value is Record<string, unknown>;
26
31
  export declare const loadConfigFile: (configFilePath: string) => ConfigFile;
@@ -1 +1 @@
1
- {"version":3,"file":"projectConfig.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/projectConfig.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C,CAAC;AAsDF,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CACH,CAAC;AAqBvE,eAAO,MAAM,cAAc,GAAI,gBAAgB,MAAM,KAAG,UA8DvD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,QAAQ,MAAM,EACd,aAAa,MAAM,KAClB,UAuEF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,YAAY,UAAU,EACtB,cAAc,UAAU,EACxB,iBAAiB,UAAU,KAC1B,UA2ED,CAAC;AAkBH,eAAO,MAAM,kBAAkB,GAC7B,YAAY,MAAM,EAClB,OAAO,MAAM,KACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAoDvB,CAAC"}
1
+ {"version":3,"file":"projectConfig.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/cli/projectConfig.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8BAA8B,CAAC,EAAE,MAAM,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAsDF,eAAO,MAAM,QAAQ,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CACH,CAAC;AA4CvE,eAAO,MAAM,cAAc,GAAI,gBAAgB,MAAM,KAAG,UA+DvD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,QAAQ,MAAM,EACd,aAAa,MAAM,KAClB,UAuEF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,YAAY,UAAU,EACtB,cAAc,UAAU,EACxB,iBAAiB,UAAU,KAC1B,UA4ED,CAAC;AAkBH,eAAO,MAAM,kBAAkB,GAC7B,YAAY,MAAM,EAClB,OAAO,MAAM,KACZ,OAAO,CAAC,MAAM,GAAG,IAAI,CAoDvB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"dashboardComposeService.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/dashboardComposeService.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,qBAAqB,EAItB,MAAM,4DAA4D,CAAC;AAQpE,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AA8IF,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;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,7 +1,7 @@
1
1
  import { Issue } from '../../../domain/entities/Issue';
2
2
  import { Project } from '../../../domain/entities/Project';
3
3
  export declare class HandleScheduledEventUseCaseHandler {
4
- handle: (configFilePath: string, _verbose: boolean) => Promise<{
4
+ handle: (configFilePath: string, _verbose: boolean, inTmuxProjectOrderOverride?: string[] | null) => Promise<{
5
5
  project: Project;
6
6
  issues: Issue[];
7
7
  cacheUsed: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAiD3D,qBAAa,kCAAkC;IAC7C,MAAM,GACJ,gBAAgB,MAAM,EACtB,UAAU,OAAO,KAChB,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,eAAe,EAAE,IAAI,EAAE,CAAC;KACzB,GAAG,IAAI,CAAC,CAklBP;CACH"}
1
+ {"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAiD3D,qBAAa,kCAAkC;IAC7C,MAAM,GACJ,gBAAgB,MAAM,EACtB,UAAU,OAAO,EACjB,6BAA4B,MAAM,EAAE,GAAG,IAAW,KACjD,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,KAAK,EAAE,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,eAAe,EAAE,IAAI,EAAE,CAAC;KACzB,GAAG,IAAI,CAAC,CAulBP;CACH"}
@@ -1,14 +1,21 @@
1
+ import { DiskConfig } from '../cli/projectConfig';
1
2
  import { ProcHostMetricsRepository } from '../../repositories/ProcHostMetricsRepository';
2
3
  export type MachineStatusWriterParams = {
3
4
  dashboardDataDir: string | null | undefined;
4
5
  allIssuesCacheDir: string | null | undefined;
6
+ disks?: DiskConfig[] | null;
5
7
  hostMetricsRepository?: ProcHostMetricsRepository;
6
8
  now?: Date;
7
9
  };
10
+ export type MachineStatusDisk = {
11
+ title: string;
12
+ pct: number;
13
+ };
8
14
  export type MachineStatusFile = {
9
15
  memPct: number;
10
16
  cpuPct: number;
11
17
  diskPct: number;
18
+ disks?: MachineStatusDisk[];
12
19
  load: [number, number, number];
13
20
  cycleMinutes: number | null;
14
21
  lastFetchedAt: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"machineStatusWriter.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/machineStatusWriter.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,yBAAyB,EAE1B,MAAM,8CAA8C,CAAC;AAEtD,MAAM,MAAM,yBAAyB,GAAG;IACtC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,qBAAqB,CAAC,EAAE,yBAAyB,CAAC;IAClD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAgCF,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,yBAAyB,KAChC,OAAO,CAAC,IAAI,CAoCd,CAAC"}
1
+ {"version":3,"file":"machineStatusWriter.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/machineStatusWriter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EACL,yBAAyB,EAE1B,MAAM,8CAA8C,CAAC;AAEtD,MAAM,MAAM,yBAAyB,GAAG;IACtC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,KAAK,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAC5B,qBAAqB,CAAC,EAAE,yBAAyB,CAAC;IAClD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC5B,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAgCF,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,yBAAyB,KAChC,OAAO,CAAC,IAAI,CA6Cd,CAAC"}
@@ -28,5 +28,6 @@ export declare class ProcHostMetricsRepository {
28
28
  readCpuUsedPercent: () => Promise<number>;
29
29
  readLoadAverages: () => LoadAverages;
30
30
  readDiskUsedPercent: () => number;
31
+ readDiskUsedPercentForMountpoint: (mountpoint: string) => number;
31
32
  }
32
33
  //# sourceMappingURL=ProcHostMetricsRepository.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProcHostMetricsRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/ProcHostMetricsRepository.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAMF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,aAAa,MAAM,KAAG,MA2B5D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,KAAG,SAiBjD,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,OAAO,SAAS,EAChB,QAAQ,SAAS,KAChB,MAQF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,OAAO,MAAM,EACb,QAAQ,MAAM,KACb,MAOF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,YAavD,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAC1C,sBAAsB,MAAM,GAAG,IAAI,EACnC,qBAAqB,MAAM,GAAG,IAAI,KACjC,MAAM,GAAG,IAUX,CAAC;AAEF,qBAAa,yBAAyB;IAElC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAMtB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAU/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAjBR,aAAa,GAAE,MAA+B,EAC9C,KAAK,GAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAK1D,EACa,cAAc,GAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,UAStD,EACgB,QAAQ,GAAE,MAA0B;IAGvD,qBAAqB,QAAO,MAAM,CAG9B;IAEJ,kBAAkB,QAAa,OAAO,CAAC,MAAM,CAAC,CAS5C;IAEF,gBAAgB,QAAO,YAAY,CAG/B;IAEJ,mBAAmB,QAAO,MAAM,CAG9B;CACH"}
1
+ {"version":3,"file":"ProcHostMetricsRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/ProcHostMetricsRepository.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAMF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,aAAa,MAAM,KAAG,MA2B5D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,KAAG,SAiBjD,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,OAAO,SAAS,EAChB,QAAQ,SAAS,KAChB,MAQF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,OAAO,MAAM,EACb,QAAQ,MAAM,KACb,MAOF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,YAavD,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAC1C,sBAAsB,MAAM,GAAG,IAAI,EACnC,qBAAqB,MAAM,GAAG,IAAI,KACjC,MAAM,GAAG,IAUX,CAAC;AAEF,qBAAa,yBAAyB;IAElC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAMtB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAU/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAjBR,aAAa,GAAE,MAA+B,EAC9C,KAAK,GAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAK1D,EACa,cAAc,GAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,UAStD,EACgB,QAAQ,GAAE,MAA0B;IAGvD,qBAAqB,QAAO,MAAM,CAG9B;IAEJ,kBAAkB,QAAa,OAAO,CAAC,MAAM,CAAC,CAS5C;IAEF,gBAAgB,QAAO,YAAY,CAG/B;IAEJ,mBAAmB,QAAO,MAAM,CAG9B;IAEF,gCAAgC,GAAI,YAAY,MAAM,KAAG,MAAM,CAG7D;CACH"}