github-issue-tower-defence-management 1.156.2 → 1.156.4

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 (56) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +3 -3
  3. package/bin/adapter/entry-points/cli/projectConfig.js +2 -0
  4. package/bin/adapter/entry-points/cli/projectConfig.js.map +1 -1
  5. package/bin/adapter/entry-points/handlers/rotationOrderFileWriter.js +2 -5
  6. package/bin/adapter/entry-points/handlers/rotationOrderFileWriter.js.map +1 -1
  7. package/bin/adapter/proxy/RateLimitCache.js +2 -5
  8. package/bin/adapter/proxy/RateLimitCache.js.map +1 -1
  9. package/bin/adapter/repositories/FileHandoverStateRepository.js +2 -5
  10. package/bin/adapter/repositories/FileHandoverStateRepository.js.map +1 -1
  11. package/bin/adapter/repositories/FileSystemKevReportWatermarkRepository.js +5 -7
  12. package/bin/adapter/repositories/FileSystemKevReportWatermarkRepository.js.map +1 -1
  13. package/bin/adapter/repositories/FileSystemSessionDegenerationCooldownStateRepository.js +5 -7
  14. package/bin/adapter/repositories/FileSystemSessionDegenerationCooldownStateRepository.js.map +1 -1
  15. package/bin/adapter/repositories/FileSystemSilentSessionCandidateStateRepository.js +5 -7
  16. package/bin/adapter/repositories/FileSystemSilentSessionCandidateStateRepository.js.map +1 -1
  17. package/bin/adapter/repositories/FileSystemSilentSessionHubTaskStatusCacheRepository.js +5 -7
  18. package/bin/adapter/repositories/FileSystemSilentSessionHubTaskStatusCacheRepository.js.map +1 -1
  19. package/bin/adapter/repositories/FileSystemSubAgentLivenessResolver.js +1 -19
  20. package/bin/adapter/repositories/FileSystemSubAgentLivenessResolver.js.map +1 -1
  21. package/bin/adapter/repositories/localStorageCacheDirectory.js +5 -3
  22. package/bin/adapter/repositories/localStorageCacheDirectory.js.map +1 -1
  23. package/package.json +2 -2
  24. package/src/adapter/entry-points/cli/projectConfig.test.ts +33 -0
  25. package/src/adapter/entry-points/cli/projectConfig.ts +5 -0
  26. package/src/adapter/entry-points/handlers/rotationOrderFileWriter.ts +3 -5
  27. package/src/adapter/proxy/RateLimitCache.ts +3 -5
  28. package/src/adapter/repositories/FileHandoverStateRepository.ts +4 -7
  29. package/src/adapter/repositories/FileSystemKevReportWatermarkRepository.test.ts +32 -1
  30. package/src/adapter/repositories/FileSystemKevReportWatermarkRepository.ts +4 -6
  31. package/src/adapter/repositories/FileSystemSessionDegenerationCooldownStateRepository.test.ts +37 -1
  32. package/src/adapter/repositories/FileSystemSessionDegenerationCooldownStateRepository.ts +4 -6
  33. package/src/adapter/repositories/FileSystemSilentSessionCandidateStateRepository.test.ts +34 -0
  34. package/src/adapter/repositories/FileSystemSilentSessionCandidateStateRepository.ts +4 -6
  35. package/src/adapter/repositories/FileSystemSilentSessionHubTaskStatusCacheRepository.test.ts +34 -0
  36. package/src/adapter/repositories/FileSystemSilentSessionHubTaskStatusCacheRepository.ts +4 -6
  37. package/src/adapter/repositories/FileSystemSubAgentLivenessResolver.test.ts +12 -4
  38. package/src/adapter/repositories/FileSystemSubAgentLivenessResolver.ts +1 -21
  39. package/src/adapter/repositories/localStorageCacheDirectory.test.ts +27 -0
  40. package/src/adapter/repositories/localStorageCacheDirectory.ts +5 -2
  41. package/types/adapter/entry-points/cli/projectConfig.d.ts.map +1 -1
  42. package/types/adapter/entry-points/handlers/rotationOrderFileWriter.d.ts.map +1 -1
  43. package/types/adapter/proxy/RateLimitCache.d.ts.map +1 -1
  44. package/types/adapter/repositories/FileHandoverStateRepository.d.ts.map +1 -1
  45. package/types/adapter/repositories/FileSystemKevReportWatermarkRepository.d.ts +1 -0
  46. package/types/adapter/repositories/FileSystemKevReportWatermarkRepository.d.ts.map +1 -1
  47. package/types/adapter/repositories/FileSystemSessionDegenerationCooldownStateRepository.d.ts +1 -0
  48. package/types/adapter/repositories/FileSystemSessionDegenerationCooldownStateRepository.d.ts.map +1 -1
  49. package/types/adapter/repositories/FileSystemSilentSessionCandidateStateRepository.d.ts +1 -0
  50. package/types/adapter/repositories/FileSystemSilentSessionCandidateStateRepository.d.ts.map +1 -1
  51. package/types/adapter/repositories/FileSystemSilentSessionHubTaskStatusCacheRepository.d.ts +1 -0
  52. package/types/adapter/repositories/FileSystemSilentSessionHubTaskStatusCacheRepository.d.ts.map +1 -1
  53. package/types/adapter/repositories/FileSystemSubAgentLivenessResolver.d.ts +0 -1
  54. package/types/adapter/repositories/FileSystemSubAgentLivenessResolver.d.ts.map +1 -1
  55. package/types/adapter/repositories/localStorageCacheDirectory.d.ts +1 -0
  56. package/types/adapter/repositories/localStorageCacheDirectory.d.ts.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "github-issue-tower-defence-management",
3
- "version": "1.156.2",
3
+ "version": "1.156.4",
4
4
  "description": "",
5
5
  "main": "bin/index.js",
6
6
  "scripts": {
@@ -75,7 +75,7 @@
75
75
  "@storybook/react-vite": "^10.5.3",
76
76
  "@tailwindcss/vite": "^4.3.3",
77
77
  "@testing-library/react": "16.3.2",
78
- "@types/better-sqlite3": "7.6.13",
78
+ "@types/better-sqlite3": "9.6.0",
79
79
  "@types/jest": "^30.0.0",
80
80
  "@types/node": "^26.1.1",
81
81
  "@types/react": "^19.2.17",
@@ -78,6 +78,39 @@ describe('mergeConfigs disks', () => {
78
78
  });
79
79
  });
80
80
 
81
+ describe('parseProjectReadmeConfig labelsNotRequiringPullRequest', () => {
82
+ const makeReadme = (yaml: string) =>
83
+ `<details>\n<summary>config</summary>\n${yaml}\n</details>`;
84
+
85
+ it('returns labelsNotRequiringPullRequest from the README config section', () => {
86
+ const readme = makeReadme(
87
+ 'labelsNotRequiringPullRequest:\n - chore\n - accounting\n',
88
+ );
89
+ const result = parseProjectReadmeConfig(readme);
90
+ expect(result.labelsNotRequiringPullRequest).toEqual([
91
+ 'chore',
92
+ 'accounting',
93
+ ]);
94
+ });
95
+
96
+ it('does not emit a warning for labelsNotRequiringPullRequest', () => {
97
+ const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
98
+ const readme = makeReadme('labelsNotRequiringPullRequest:\n - chore\n');
99
+ parseProjectReadmeConfig(readme, 'https://example.com/project');
100
+ expect(warnSpy).not.toHaveBeenCalledWith(
101
+ expect.stringContaining('labelsNotRequiringPullRequest'),
102
+ );
103
+ warnSpy.mockRestore();
104
+ });
105
+
106
+ it('yields undefined labelsNotRequiringPullRequest when the key is absent', () => {
107
+ const readme = makeReadme('defaultAgentName: impl\n');
108
+ expect(
109
+ parseProjectReadmeConfig(readme).labelsNotRequiringPullRequest,
110
+ ).toBeUndefined();
111
+ });
112
+ });
113
+
81
114
  describe('parseProjectReadmeConfig labelsAsLlmAgentName', () => {
82
115
  const makeReadme = (yaml: string) =>
83
116
  `<details>\n<summary>config</summary>\n${yaml}\n</details>`;
@@ -130,6 +130,7 @@ const knownProjectReadmeConfigKeys = [
130
130
  'awLogDirectoryPath',
131
131
  'awLogStaleThresholdMinutes',
132
132
  'labelsAsLlmAgentName',
133
+ 'labelsNotRequiringPullRequest',
133
134
  'changeTargetPathAliases',
134
135
  ] as const;
135
136
 
@@ -272,6 +273,10 @@ export const parseProjectReadmeConfig = (
272
273
  'awLogStaleThresholdMinutes',
273
274
  ),
274
275
  labelsAsLlmAgentName: getStringArrayValue(parsed, 'labelsAsLlmAgentName'),
276
+ labelsNotRequiringPullRequest: getStringArrayValue(
277
+ parsed,
278
+ 'labelsNotRequiringPullRequest',
279
+ ),
275
280
  changeTargetPathAliases: getStringRecordValue(
276
281
  parsed,
277
282
  'changeTargetPathAliases',
@@ -1,12 +1,10 @@
1
1
  import fs from 'fs';
2
- import * as os from 'os';
3
2
  import * as path from 'path';
4
3
  import type { RotationOrderEntry } from '../../../domain/usecases/StartPreparationUseCase';
4
+ import { tdpmCacheDirectory } from '../../repositories/localStorageCacheDirectory';
5
5
 
6
- const rotationOrderFilePath = (): string => {
7
- const base = process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), '.cache');
8
- return path.join(base, 'tdpm', 'rotation-order.json');
9
- };
6
+ const rotationOrderFilePath = (): string =>
7
+ path.join(tdpmCacheDirectory(), 'rotation-order.json');
10
8
 
11
9
  export const writeRotationOrderFile = (
12
10
  rotationOrder: RotationOrderEntry[],
@@ -1,7 +1,7 @@
1
1
  import * as crypto from 'crypto';
2
2
  import * as fs from 'fs';
3
- import * as os from 'os';
4
3
  import * as path from 'path';
4
+ import { tdpmCacheDirectory } from '../repositories/localStorageCacheDirectory';
5
5
 
6
6
  export interface ModelWeeklyLimit {
7
7
  rejected: boolean;
@@ -44,10 +44,8 @@ const SEVEN_DAY_STATUS_HEADER = 'anthropic-ratelimit-unified-7d-status';
44
44
 
45
45
  const SEVEN_DAY_RESET_HEADER = 'anthropic-ratelimit-unified-7d-reset';
46
46
 
47
- export const cacheDir = (): string => {
48
- const base = process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), '.cache');
49
- return path.join(base, 'tdpm', 'ratelimit');
50
- };
47
+ export const cacheDir = (): string =>
48
+ path.join(tdpmCacheDirectory(), 'ratelimit');
51
49
 
52
50
  export const hashToken = (token: string): string =>
53
51
  crypto.createHash(HASH_ALGORITHM).update(token).digest('hex');
@@ -1,20 +1,17 @@
1
1
  import * as fs from 'fs';
2
- import * as os from 'os';
3
2
  import * as path from 'path';
4
3
  import {
5
4
  TokenExhaustionHandoverState,
6
5
  TokenExhaustionHandoverStateEntry,
7
6
  } from '../../domain/entities/TokenExhaustionHandoverState';
8
7
  import { TokenExhaustionHandoverStateRepository } from '../../domain/usecases/adapter-interfaces/TokenExhaustionHandoverStateRepository';
8
+ import { tdpmCacheDirectory } from './localStorageCacheDirectory';
9
9
 
10
- export const defaultHandoverStateFilePath = (): string => {
11
- const base = process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), '.cache');
12
- return path.join(
13
- base,
14
- 'tdpm',
10
+ export const defaultHandoverStateFilePath = (): string =>
11
+ path.join(
12
+ tdpmCacheDirectory(),
15
13
  'token-exhaustion-handover-state-tdpm-native.json',
16
14
  );
17
- };
18
15
 
19
16
  const isRecord = (value: unknown): value is Record<string, unknown> =>
20
17
  value !== null && typeof value === 'object' && !Array.isArray(value);
@@ -1,7 +1,10 @@
1
1
  import * as fs from 'fs';
2
2
  import * as os from 'os';
3
3
  import * as path from 'path';
4
- import { FileSystemKevReportWatermarkRepository } from './FileSystemKevReportWatermarkRepository';
4
+ import {
5
+ defaultKevReportWatermarkFilePath,
6
+ FileSystemKevReportWatermarkRepository,
7
+ } from './FileSystemKevReportWatermarkRepository';
5
8
 
6
9
  describe('FileSystemKevReportWatermarkRepository', () => {
7
10
  let temporaryDirectory: string;
@@ -251,3 +254,31 @@ describe('FileSystemKevReportWatermarkRepository', () => {
251
254
  ).toBe(true);
252
255
  });
253
256
  });
257
+
258
+ describe('defaultKevReportWatermarkFilePath', () => {
259
+ const originalXdgCacheHome = process.env.XDG_CACHE_HOME;
260
+
261
+ afterEach(() => {
262
+ if (originalXdgCacheHome === undefined) {
263
+ delete process.env.XDG_CACHE_HOME;
264
+ } else {
265
+ process.env.XDG_CACHE_HOME = originalXdgCacheHome;
266
+ }
267
+ });
268
+
269
+ it('places the watermark file at tdpm/kev-report-watermark.json below XDG_CACHE_HOME when set', () => {
270
+ process.env.XDG_CACHE_HOME = '/custom/cache';
271
+
272
+ expect(defaultKevReportWatermarkFilePath()).toBe(
273
+ '/custom/cache/tdpm/kev-report-watermark.json',
274
+ );
275
+ });
276
+
277
+ it('places the watermark file at tdpm/kev-report-watermark.json below the home cache directory when XDG_CACHE_HOME is absent', () => {
278
+ delete process.env.XDG_CACHE_HOME;
279
+
280
+ expect(defaultKevReportWatermarkFilePath()).toBe(
281
+ path.join(os.homedir(), '.cache', 'tdpm', 'kev-report-watermark.json'),
282
+ );
283
+ });
284
+ });
@@ -1,11 +1,11 @@
1
1
  import * as fs from 'fs';
2
- import * as os from 'os';
3
2
  import * as path from 'path';
4
3
  import { KevReportWatermark } from '../../domain/entities/KevReportWatermark';
5
4
  import {
6
5
  KevReportWatermarkLoadResult,
7
6
  KevReportWatermarkRepository,
8
7
  } from '../../domain/usecases/adapter-interfaces/KevReportWatermarkRepository';
8
+ import { tdpmCacheDirectory } from './localStorageCacheDirectory';
9
9
 
10
10
  const isRecord = (value: unknown): value is Record<string, unknown> =>
11
11
  typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -29,14 +29,12 @@ const isCalendarYmd = (value: string): boolean => {
29
29
  );
30
30
  };
31
31
 
32
- const defaultStateFilePath = (): string => {
33
- const base = process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), '.cache');
34
- return path.join(base, 'tdpm', 'kev-report-watermark.json');
35
- };
32
+ export const defaultKevReportWatermarkFilePath = (): string =>
33
+ path.join(tdpmCacheDirectory(), 'kev-report-watermark.json');
36
34
 
37
35
  export class FileSystemKevReportWatermarkRepository implements KevReportWatermarkRepository {
38
36
  constructor(
39
- private readonly stateFilePath: string = defaultStateFilePath(),
37
+ private readonly stateFilePath: string = defaultKevReportWatermarkFilePath(),
40
38
  ) {}
41
39
 
42
40
  load = async (): Promise<KevReportWatermarkLoadResult> => {
@@ -1,7 +1,10 @@
1
1
  import * as fs from 'fs';
2
2
  import * as os from 'os';
3
3
  import * as path from 'path';
4
- import { FileSystemSessionDegenerationCooldownStateRepository } from './FileSystemSessionDegenerationCooldownStateRepository';
4
+ import {
5
+ defaultSessionDegenerationCooldownStateFilePath,
6
+ FileSystemSessionDegenerationCooldownStateRepository,
7
+ } from './FileSystemSessionDegenerationCooldownStateRepository';
5
8
 
6
9
  describe('FileSystemSessionDegenerationCooldownStateRepository', () => {
7
10
  let temporaryDirectory: string;
@@ -83,3 +86,36 @@ describe('FileSystemSessionDegenerationCooldownStateRepository', () => {
83
86
  expect(reloaded.has('fresh-session')).toBe(true);
84
87
  });
85
88
  });
89
+
90
+ describe('defaultSessionDegenerationCooldownStateFilePath', () => {
91
+ const originalXdgCacheHome = process.env.XDG_CACHE_HOME;
92
+
93
+ afterEach(() => {
94
+ if (originalXdgCacheHome === undefined) {
95
+ delete process.env.XDG_CACHE_HOME;
96
+ } else {
97
+ process.env.XDG_CACHE_HOME = originalXdgCacheHome;
98
+ }
99
+ });
100
+
101
+ it('places the state file at tdpm/output-degeneration-cooldown.json below XDG_CACHE_HOME when set', () => {
102
+ process.env.XDG_CACHE_HOME = '/custom/cache';
103
+
104
+ expect(defaultSessionDegenerationCooldownStateFilePath()).toBe(
105
+ '/custom/cache/tdpm/output-degeneration-cooldown.json',
106
+ );
107
+ });
108
+
109
+ it('places the state file at tdpm/output-degeneration-cooldown.json below the home cache directory when XDG_CACHE_HOME is absent', () => {
110
+ delete process.env.XDG_CACHE_HOME;
111
+
112
+ expect(defaultSessionDegenerationCooldownStateFilePath()).toBe(
113
+ path.join(
114
+ os.homedir(),
115
+ '.cache',
116
+ 'tdpm',
117
+ 'output-degeneration-cooldown.json',
118
+ ),
119
+ );
120
+ });
121
+ });
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'fs';
2
- import * as os from 'os';
3
2
  import * as path from 'path';
4
3
  import { SessionDegenerationCooldownStateRepository } from '../../domain/usecases/adapter-interfaces/SessionDegenerationCooldownStateRepository';
4
+ import { tdpmCacheDirectory } from './localStorageCacheDirectory';
5
5
 
6
6
  type StoredResetEntry = {
7
7
  sessionName: string;
@@ -13,14 +13,12 @@ const isRecord = (value: unknown): value is Record<string, unknown> =>
13
13
 
14
14
  export const DEFAULT_RESET_RETENTION_WINDOW_SECONDS = 60 * 60;
15
15
 
16
- const defaultStateFilePath = (): string => {
17
- const base = process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), '.cache');
18
- return path.join(base, 'tdpm', 'output-degeneration-cooldown.json');
19
- };
16
+ export const defaultSessionDegenerationCooldownStateFilePath = (): string =>
17
+ path.join(tdpmCacheDirectory(), 'output-degeneration-cooldown.json');
20
18
 
21
19
  export class FileSystemSessionDegenerationCooldownStateRepository implements SessionDegenerationCooldownStateRepository {
22
20
  constructor(
23
- private readonly stateFilePath: string = defaultStateFilePath(),
21
+ private readonly stateFilePath: string = defaultSessionDegenerationCooldownStateFilePath(),
24
22
  private readonly retentionWindowSeconds: number = DEFAULT_RESET_RETENTION_WINDOW_SECONDS,
25
23
  ) {}
26
24
 
@@ -3,6 +3,7 @@ import * as os from 'os';
3
3
  import * as path from 'path';
4
4
  import {
5
5
  DEFAULT_STATE_RETENTION_WINDOW_SECONDS,
6
+ defaultSilentSessionCandidateStateFilePath,
6
7
  FileSystemSilentSessionCandidateStateRepository,
7
8
  } from './FileSystemSilentSessionCandidateStateRepository';
8
9
 
@@ -251,3 +252,36 @@ describe('FileSystemSilentSessionCandidateStateRepository', () => {
251
252
  });
252
253
  });
253
254
  });
255
+
256
+ describe('defaultSilentSessionCandidateStateFilePath', () => {
257
+ const originalXdgCacheHome = process.env.XDG_CACHE_HOME;
258
+
259
+ afterEach(() => {
260
+ if (originalXdgCacheHome === undefined) {
261
+ delete process.env.XDG_CACHE_HOME;
262
+ } else {
263
+ process.env.XDG_CACHE_HOME = originalXdgCacheHome;
264
+ }
265
+ });
266
+
267
+ it('places the state file at tdpm/silent-session-candidates.json below XDG_CACHE_HOME when set', () => {
268
+ process.env.XDG_CACHE_HOME = '/custom/cache';
269
+
270
+ expect(defaultSilentSessionCandidateStateFilePath()).toBe(
271
+ '/custom/cache/tdpm/silent-session-candidates.json',
272
+ );
273
+ });
274
+
275
+ it('places the state file at tdpm/silent-session-candidates.json below the home cache directory when XDG_CACHE_HOME is absent', () => {
276
+ delete process.env.XDG_CACHE_HOME;
277
+
278
+ expect(defaultSilentSessionCandidateStateFilePath()).toBe(
279
+ path.join(
280
+ os.homedir(),
281
+ '.cache',
282
+ 'tdpm',
283
+ 'silent-session-candidates.json',
284
+ ),
285
+ );
286
+ });
287
+ });
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'fs';
2
- import * as os from 'os';
3
2
  import * as path from 'path';
4
3
  import { SilentSessionCandidateStateRepository } from '../../domain/usecases/adapter-interfaces/SilentSessionCandidateStateRepository';
4
+ import { tdpmCacheDirectory } from './localStorageCacheDirectory';
5
5
 
6
6
  type StoredCandidateEntry = {
7
7
  sessionName: string;
@@ -13,10 +13,8 @@ const isRecord = (value: unknown): value is Record<string, unknown> =>
13
13
 
14
14
  export const DEFAULT_STATE_RETENTION_WINDOW_SECONDS = 60 * 60;
15
15
 
16
- const defaultStateFilePath = (): string => {
17
- const base = process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), '.cache');
18
- return path.join(base, 'tdpm', 'silent-session-candidates.json');
19
- };
16
+ export const defaultSilentSessionCandidateStateFilePath = (): string =>
17
+ path.join(tdpmCacheDirectory(), 'silent-session-candidates.json');
20
18
 
21
19
  // Persists only the candidate set used by the two-consecutive-cycle
22
20
  // debounce. The formerly persisted announced-running-sub-agent labels
@@ -28,7 +26,7 @@ const defaultStateFilePath = (): string => {
28
26
  // write.
29
27
  export class FileSystemSilentSessionCandidateStateRepository implements SilentSessionCandidateStateRepository {
30
28
  constructor(
31
- private readonly stateFilePath: string = defaultStateFilePath(),
29
+ private readonly stateFilePath: string = defaultSilentSessionCandidateStateFilePath(),
32
30
  private readonly retentionWindowSeconds: number = DEFAULT_STATE_RETENTION_WINDOW_SECONDS,
33
31
  ) {}
34
32
 
@@ -3,6 +3,7 @@ import * as os from 'os';
3
3
  import * as path from 'path';
4
4
  import {
5
5
  DEFAULT_HUB_TASK_STATUS_RETENTION_WINDOW_SECONDS,
6
+ defaultSilentSessionHubTaskStatusCacheFilePath,
6
7
  FileSystemSilentSessionHubTaskStatusCacheRepository,
7
8
  } from './FileSystemSilentSessionHubTaskStatusCacheRepository';
8
9
 
@@ -249,3 +250,36 @@ describe('FileSystemSilentSessionHubTaskStatusCacheRepository', () => {
249
250
  expect(DEFAULT_HUB_TASK_STATUS_RETENTION_WINDOW_SECONDS).toBe(60 * 60);
250
251
  });
251
252
  });
253
+
254
+ describe('defaultSilentSessionHubTaskStatusCacheFilePath', () => {
255
+ const originalXdgCacheHome = process.env.XDG_CACHE_HOME;
256
+
257
+ afterEach(() => {
258
+ if (originalXdgCacheHome === undefined) {
259
+ delete process.env.XDG_CACHE_HOME;
260
+ } else {
261
+ process.env.XDG_CACHE_HOME = originalXdgCacheHome;
262
+ }
263
+ });
264
+
265
+ it('places the state file at tdpm/silent-session-hub-task-status.json below XDG_CACHE_HOME when set', () => {
266
+ process.env.XDG_CACHE_HOME = '/custom/cache';
267
+
268
+ expect(defaultSilentSessionHubTaskStatusCacheFilePath()).toBe(
269
+ '/custom/cache/tdpm/silent-session-hub-task-status.json',
270
+ );
271
+ });
272
+
273
+ it('places the state file at tdpm/silent-session-hub-task-status.json below the home cache directory when XDG_CACHE_HOME is absent', () => {
274
+ delete process.env.XDG_CACHE_HOME;
275
+
276
+ expect(defaultSilentSessionHubTaskStatusCacheFilePath()).toBe(
277
+ path.join(
278
+ os.homedir(),
279
+ '.cache',
280
+ 'tdpm',
281
+ 'silent-session-hub-task-status.json',
282
+ ),
283
+ );
284
+ });
285
+ });
@@ -1,11 +1,11 @@
1
1
  import * as fs from 'fs';
2
- import * as os from 'os';
3
2
  import * as path from 'path';
4
3
  import { Issue } from '../../domain/entities/Issue';
5
4
  import {
6
5
  SilentSessionHubTaskStatusCacheEntry,
7
6
  SilentSessionHubTaskStatusCacheRepository,
8
7
  } from '../../domain/usecases/adapter-interfaces/SilentSessionHubTaskStatusCacheRepository';
8
+ import { tdpmCacheDirectory } from './localStorageCacheDirectory';
9
9
 
10
10
  const isRecord = (value: unknown): value is Record<string, unknown> =>
11
11
  typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -15,14 +15,12 @@ const isIssueState = (value: unknown): value is Issue['state'] =>
15
15
 
16
16
  export const DEFAULT_HUB_TASK_STATUS_RETENTION_WINDOW_SECONDS = 60 * 60;
17
17
 
18
- const defaultStateFilePath = (): string => {
19
- const base = process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), '.cache');
20
- return path.join(base, 'tdpm', 'silent-session-hub-task-status.json');
21
- };
18
+ export const defaultSilentSessionHubTaskStatusCacheFilePath = (): string =>
19
+ path.join(tdpmCacheDirectory(), 'silent-session-hub-task-status.json');
22
20
 
23
21
  export class FileSystemSilentSessionHubTaskStatusCacheRepository implements SilentSessionHubTaskStatusCacheRepository {
24
22
  constructor(
25
- private readonly stateFilePath: string = defaultStateFilePath(),
23
+ private readonly stateFilePath: string = defaultSilentSessionHubTaskStatusCacheFilePath(),
26
24
  private readonly retentionWindowSeconds: number = DEFAULT_HUB_TASK_STATUS_RETENTION_WINDOW_SECONDS,
27
25
  ) {}
28
26
 
@@ -69,7 +69,7 @@ describe('FileSystemSubAgentLivenessResolver', () => {
69
69
  expect(result).toEqual(new Set());
70
70
  });
71
71
 
72
- it('returns an empty set when the runtime root exists and the session has no running file', async () => {
72
+ it('returns null when the runtime root exists and the session has no running file', async () => {
73
73
  const resolver = new FileSystemSubAgentLivenessResolver(runtimeRoot);
74
74
 
75
75
  const result = await resolver.resolveLiveSubAgentIds({
@@ -77,7 +77,7 @@ describe('FileSystemSubAgentLivenessResolver', () => {
77
77
  mainTranscriptPath,
78
78
  });
79
79
 
80
- expect(result).toEqual(new Set());
80
+ expect(result).toBeNull();
81
81
  });
82
82
 
83
83
  it('returns null when the configured runtime root directory does not exist', async () => {
@@ -192,7 +192,7 @@ describe('running-subagents record agent id contract with TranscriptSessionSubAg
192
192
  ]);
193
193
  });
194
194
 
195
- it('reports no sub-agent when the runtime root exists and the session has no running-subagents record', async () => {
195
+ it('detects a working sub-agent when the runtime root exists and the session has no running-subagents record', async () => {
196
196
  const subAgentsDirectory = path.join(
197
197
  transcriptRoot,
198
198
  cwdSlug,
@@ -224,6 +224,14 @@ describe('running-subagents record agent id contract with TranscriptSessionSubAg
224
224
  new Map([[sessionName, mainTranscriptPath]]),
225
225
  );
226
226
 
227
- expect(result.get(sessionName)).toBeUndefined();
227
+ expect(result.get(sessionName)).toEqual([
228
+ {
229
+ label: `agent-${liveAgentId}`,
230
+ silentSeconds: 0,
231
+ runningSeconds: 694800,
232
+ waitingOnExternalProcess: false,
233
+ finishedResultUnconsumed: false,
234
+ },
235
+ ]);
228
236
  });
229
237
  });
@@ -4,12 +4,6 @@ import { SubAgentLivenessResolver } from '../../domain/usecases/adapter-interfac
4
4
 
5
5
  const RUNNING_SUBAGENTS_FILE_NAME = 'running-subagents.txt';
6
6
 
7
- const isMissingFileError = (error: unknown): boolean =>
8
- typeof error === 'object' &&
9
- error !== null &&
10
- 'code' in error &&
11
- error.code === 'ENOENT';
12
-
13
7
  export class FileSystemSubAgentLivenessResolver implements SubAgentLivenessResolver {
14
8
  constructor(private readonly runtimeRootDirectory: string | null) {}
15
9
 
@@ -26,10 +20,7 @@ export class FileSystemSubAgentLivenessResolver implements SubAgentLivenessResol
26
20
  let content: string;
27
21
  try {
28
22
  content = fs.readFileSync(runningFilePath, 'utf8');
29
- } catch (error) {
30
- if (isMissingFileError(error) && this.hasReadableRuntimeRootDirectory()) {
31
- return new Set();
32
- }
23
+ } catch {
33
24
  return null;
34
25
  }
35
26
  const liveIds = new Set<string>();
@@ -42,17 +33,6 @@ export class FileSystemSubAgentLivenessResolver implements SubAgentLivenessResol
42
33
  return liveIds;
43
34
  };
44
35
 
45
- private hasReadableRuntimeRootDirectory = (): boolean => {
46
- if (this.runtimeRootDirectory === null) {
47
- return false;
48
- }
49
- try {
50
- return fs.statSync(this.runtimeRootDirectory).isDirectory();
51
- } catch {
52
- return false;
53
- }
54
- };
55
-
56
36
  private resolveRunningSubAgentsFilePath = (
57
37
  mainTranscriptPath: string | null,
58
38
  ): string | null => {
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import {
4
4
  localStorageCacheBaseDirectory,
5
5
  projectCacheDirectory,
6
+ tdpmCacheDirectory,
6
7
  } from './localStorageCacheDirectory';
7
8
 
8
9
  describe('localStorageCacheBaseDirectory', () => {
@@ -52,3 +53,29 @@ describe('projectCacheDirectory', () => {
52
53
  );
53
54
  });
54
55
  });
56
+
57
+ describe('tdpmCacheDirectory', () => {
58
+ const originalXdgCacheHome = process.env.XDG_CACHE_HOME;
59
+
60
+ afterEach(() => {
61
+ if (originalXdgCacheHome === undefined) {
62
+ delete process.env.XDG_CACHE_HOME;
63
+ } else {
64
+ process.env.XDG_CACHE_HOME = originalXdgCacheHome;
65
+ }
66
+ });
67
+
68
+ test('places the tdpm directory below XDG_CACHE_HOME when it is set', () => {
69
+ process.env.XDG_CACHE_HOME = '/var/tmp/xdg-cache-home-for-test';
70
+
71
+ expect(tdpmCacheDirectory()).toBe('/var/tmp/xdg-cache-home-for-test/tdpm');
72
+ });
73
+
74
+ test('places the tdpm directory below the home cache directory when XDG_CACHE_HOME is absent', () => {
75
+ delete process.env.XDG_CACHE_HOME;
76
+
77
+ expect(tdpmCacheDirectory()).toBe(
78
+ path.join(os.homedir(), '.cache', 'tdpm'),
79
+ );
80
+ });
81
+ });
@@ -1,10 +1,13 @@
1
1
  import os from 'node:os';
2
2
  import path from 'node:path';
3
3
 
4
- export const localStorageCacheBaseDirectory = (): string => {
4
+ export const tdpmCacheDirectory = (): string => {
5
5
  const base = process.env.XDG_CACHE_HOME ?? path.join(os.homedir(), '.cache');
6
- return path.join(base, 'tdpm', 'cache');
6
+ return path.join(base, 'tdpm');
7
7
  };
8
8
 
9
+ export const localStorageCacheBaseDirectory = (): string =>
10
+ path.join(tdpmCacheDirectory(), 'cache');
11
+
9
12
  export const projectCacheDirectory = (projectName: string): string =>
10
13
  path.join(localStorageCacheBaseDirectory(), projectName);
@@ -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,6BAA6B,CAAC,EAAE,MAAM,EAAE,CAAC;IACzC,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,wCAAwC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClE,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;AA6CvE,eAAO,MAAM,cAAc,GAAI,gBAAgB,MAAM,KAAG,UAuEvD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,QAAQ,MAAM,EACd,aAAa,MAAM,KAClB,UAwEF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,YAAY,UAAU,EACtB,cAAc,UAAU,EACxB,iBAAiB,UAAU,KAC1B,UAmFD,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,6BAA6B,CAAC,EAAE,MAAM,EAAE,CAAC;IACzC,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,wCAAwC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClE,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;AA8CvE,eAAO,MAAM,cAAc,GAAI,gBAAgB,MAAM,KAAG,UAuEvD,CAAC;AAEF,eAAO,MAAM,wBAAwB,GACnC,QAAQ,MAAM,EACd,aAAa,MAAM,KAClB,UA4EF,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,YAAY,UAAU,EACtB,cAAc,UAAU,EACxB,iBAAiB,UAAU,KAC1B,UAmFD,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":"rotationOrderFileWriter.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/rotationOrderFileWriter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kDAAkD,CAAC;AAO3F,eAAO,MAAM,sBAAsB,GACjC,eAAe,kBAAkB,EAAE,KAClC,IAOF,CAAC"}
1
+ {"version":3,"file":"rotationOrderFileWriter.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/rotationOrderFileWriter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kDAAkD,CAAC;AAM3F,eAAO,MAAM,sBAAsB,GACjC,eAAe,kBAAkB,EAAE,KAClC,IAOF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"RateLimitCache.d.ts","sourceRoot":"","sources":["../../../src/adapter/proxy/RateLimitCache.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,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,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,UAAU,OAAO,CAAC;AAE/B,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAIlD,eAAO,MAAM,uCAAuC,KAAK,CAAC;AAE1D,eAAO,MAAM,mCAAmC,MAAM,CAAC;AAEvD,eAAO,MAAM,oCAAoC,OAAO,CAAC;AAQzD,eAAO,MAAM,QAAQ,QAAO,MAG3B,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,MACqB,CAAC;AAEhE,eAAO,MAAM,iBAAiB,GAC5B,OAAO,MAAM,EACb,UAAS,MAAmB,KAC3B,MAAwD,CAAC;AAsD5D,eAAO,MAAM,cAAc,GACzB,OAAO,MAAM,EACb,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EACtD,aAAY,MAAM,GAAG,IAAW,KAC/B,IAoDF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,EACb,QAAQ,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,KACvC,IAkBF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,WAAW,MAAM,GAAG,IAAI,KAAG,OACL,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAUD,eAAO,MAAM,sBAAsB,GACjC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,KACrD,uBAWF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,EACb,mBAAmB,MAAM,GAAG,IAAI,EAChC,gBAAe,MAAM,GAAG,IAAW,KAClC,IAQF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,OAAO,MAAM,EACb,UAAS,MAAmB,KAC3B,IAYF,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,MAAM,MAAM,KACX,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA0BjC,CAAC;AAOF,eAAO,MAAM,+BAA+B,GAC1C,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC9B,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAmBjC,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,EACb,UAAS,MAAmB,KAC3B,iBAAiB,GAAG,IAuEtB,CAAC"}
1
+ {"version":3,"file":"RateLimitCache.d.ts","sourceRoot":"","sources":["../../../src/adapter/proxy/RateLimitCache.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,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,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,eAAO,MAAM,UAAU,OAAO,CAAC;AAE/B,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAIlD,eAAO,MAAM,uCAAuC,KAAK,CAAC;AAE1D,eAAO,MAAM,mCAAmC,MAAM,CAAC;AAEvD,eAAO,MAAM,oCAAoC,OAAO,CAAC;AAQzD,eAAO,MAAM,QAAQ,QAAO,MACkB,CAAC;AAE/C,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,MACqB,CAAC;AAEhE,eAAO,MAAM,iBAAiB,GAC5B,OAAO,MAAM,EACb,UAAS,MAAmB,KAC3B,MAAwD,CAAC;AAsD5D,eAAO,MAAM,cAAc,GACzB,OAAO,MAAM,EACb,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EACtD,aAAY,MAAM,GAAG,IAAW,KAC/B,IAoDF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,EACb,QAAQ,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,KACvC,IAkBF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,WAAW,MAAM,GAAG,IAAI,KAAG,OACL,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAUD,eAAO,MAAM,sBAAsB,GACjC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,KACrD,uBAWF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,MAAM,EACb,mBAAmB,MAAM,GAAG,IAAI,EAChC,gBAAe,MAAM,GAAG,IAAW,KAClC,IAQF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,OAAO,MAAM,EACb,UAAS,MAAmB,KAC3B,IAYF,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,MAAM,MAAM,KACX,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA0BjC,CAAC;AAOF,eAAO,MAAM,+BAA+B,GAC1C,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC9B,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAmBjC,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,EACb,UAAS,MAAmB,KAC3B,iBAAiB,GAAG,IAuEtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"FileHandoverStateRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/FileHandoverStateRepository.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,4BAA4B,EAE7B,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EAAE,sCAAsC,EAAE,MAAM,iFAAiF,CAAC;AAEzI,eAAO,MAAM,4BAA4B,QAAO,MAO/C,CAAC;AAKF,qBAAa,2BAA4B,YAAW,sCAAsC;IAEtF,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,GAAE,MAAuC;IAGpE,IAAI,QAAO,4BAA4B,CAcrC;IAEF,IAAI,GAAI,OAAO,4BAA4B,KAAG,IAAI,CAQhD;IAEF,OAAO,CAAC,YAAY,CAsBlB;CACH"}
1
+ {"version":3,"file":"FileHandoverStateRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/FileHandoverStateRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,4BAA4B,EAE7B,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EAAE,sCAAsC,EAAE,MAAM,iFAAiF,CAAC;AAGzI,eAAO,MAAM,4BAA4B,QAAO,MAI7C,CAAC;AAKJ,qBAAa,2BAA4B,YAAW,sCAAsC;IAEtF,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,GAAE,MAAuC;IAGpE,IAAI,QAAO,4BAA4B,CAcrC;IAEF,IAAI,GAAI,OAAO,4BAA4B,KAAG,IAAI,CAQhD;IAEF,OAAO,CAAC,YAAY,CAsBlB;CACH"}
@@ -1,5 +1,6 @@
1
1
  import { KevReportWatermark } from '../../domain/entities/KevReportWatermark';
2
2
  import { KevReportWatermarkLoadResult, KevReportWatermarkRepository } from '../../domain/usecases/adapter-interfaces/KevReportWatermarkRepository';
3
+ export declare const defaultKevReportWatermarkFilePath: () => string;
3
4
  export declare class FileSystemKevReportWatermarkRepository implements KevReportWatermarkRepository {
4
5
  private readonly stateFilePath;
5
6
  constructor(stateFilePath?: string);
@@ -1 +1 @@
1
- {"version":3,"file":"FileSystemKevReportWatermarkRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/FileSystemKevReportWatermarkRepository.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AA6B/E,qBAAa,sCAAuC,YAAW,4BAA4B;IAEvF,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,GAAE,MAA+B;IAGjE,IAAI,QAAa,OAAO,CAAC,4BAA4B,CAAC,CAiEpD;IAEF,IAAI,GAAU,WAAW,kBAAkB,KAAG,OAAO,CAAC,IAAI,CAAC,CAazD;IAEF,OAAO,CAAC,UAAU,CAKhB;CACH"}
1
+ {"version":3,"file":"FileSystemKevReportWatermarkRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/FileSystemKevReportWatermarkRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAC9E,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAyB/E,eAAO,MAAM,iCAAiC,QAAO,MACS,CAAC;AAE/D,qBAAa,sCAAuC,YAAW,4BAA4B;IAEvF,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,GAAE,MAA4C;IAG9E,IAAI,QAAa,OAAO,CAAC,4BAA4B,CAAC,CAiEpD;IAEF,IAAI,GAAU,WAAW,kBAAkB,KAAG,OAAO,CAAC,IAAI,CAAC,CAazD;IAEF,OAAO,CAAC,UAAU,CAKhB;CACH"}
@@ -1,5 +1,6 @@
1
1
  import { SessionDegenerationCooldownStateRepository } from '../../domain/usecases/adapter-interfaces/SessionDegenerationCooldownStateRepository';
2
2
  export declare const DEFAULT_RESET_RETENTION_WINDOW_SECONDS: number;
3
+ export declare const defaultSessionDegenerationCooldownStateFilePath: () => string;
3
4
  export declare class FileSystemSessionDegenerationCooldownStateRepository implements SessionDegenerationCooldownStateRepository {
4
5
  private readonly stateFilePath;
5
6
  private readonly retentionWindowSeconds;