github-issue-tower-defence-management 1.94.4 → 1.96.0

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 (47) hide show
  1. package/.github/workflows/console-ui.yml +17 -0
  2. package/CHANGELOG.md +14 -0
  3. package/README.md +11 -0
  4. package/bin/adapter/entry-points/cli/index.js +21 -0
  5. package/bin/adapter/entry-points/cli/index.js.map +1 -1
  6. package/bin/adapter/entry-points/console/ui-dist/assets/index-B3F4E8LD.js +101 -0
  7. package/bin/adapter/entry-points/console/ui-dist/index.html +1 -1
  8. package/bin/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.js +77 -0
  9. package/bin/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.js.map +1 -0
  10. package/bin/adapter/repositories/ProcClaudeLiveSessionRepository.js +139 -0
  11. package/bin/adapter/repositories/ProcClaudeLiveSessionRepository.js.map +1 -0
  12. package/bin/domain/usecases/LiveSessionOauthTokenSelectUseCase.js +59 -0
  13. package/bin/domain/usecases/LiveSessionOauthTokenSelectUseCase.js.map +1 -0
  14. package/bin/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.js +3 -0
  15. package/bin/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.js.map +1 -0
  16. package/package.json +4 -1
  17. package/src/adapter/entry-points/cli/index.ts +38 -0
  18. package/src/adapter/entry-points/console/ui/biome.json +7 -1
  19. package/src/adapter/entry-points/console/ui/e2e/consoleScenario.spec.ts +93 -0
  20. package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +380 -0
  21. package/src/adapter/entry-points/console/ui/e2e/playwright.config.ts +30 -0
  22. package/src/adapter/entry-points/console/ui/e2e/tsconfig.json +18 -0
  23. package/src/adapter/entry-points/console/ui/src/features/console/components/layout/ConsoleTabList.stories.tsx +14 -0
  24. package/src/adapter/entry-points/console/ui/src/features/console/logic/tabAdvance.test.ts +48 -0
  25. package/src/adapter/entry-points/console/ui/src/features/console/logic/tabAdvance.ts +19 -0
  26. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.test.tsx +39 -6
  27. package/src/adapter/entry-points/console/ui/src/features/console/pages/ConsolePage.tsx +31 -4
  28. package/src/adapter/entry-points/console/ui-dist/assets/index-B3F4E8LD.js +101 -0
  29. package/src/adapter/entry-points/console/ui-dist/index.html +1 -1
  30. package/src/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.test.ts +268 -0
  31. package/src/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.ts +116 -0
  32. package/src/adapter/repositories/ProcClaudeLiveSessionRepository.test.ts +146 -0
  33. package/src/adapter/repositories/ProcClaudeLiveSessionRepository.ts +119 -0
  34. package/src/domain/usecases/LiveSessionOauthTokenSelectUseCase.test.ts +147 -0
  35. package/src/domain/usecases/LiveSessionOauthTokenSelectUseCase.ts +100 -0
  36. package/src/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.ts +8 -0
  37. package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
  38. package/types/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.d.ts +20 -0
  39. package/types/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.d.ts.map +1 -0
  40. package/types/adapter/repositories/ProcClaudeLiveSessionRepository.d.ts +11 -0
  41. package/types/adapter/repositories/ProcClaudeLiveSessionRepository.d.ts.map +1 -0
  42. package/types/domain/usecases/LiveSessionOauthTokenSelectUseCase.d.ts +23 -0
  43. package/types/domain/usecases/LiveSessionOauthTokenSelectUseCase.d.ts.map +1 -0
  44. package/types/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.d.ts +8 -0
  45. package/types/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.d.ts.map +1 -0
  46. package/bin/adapter/entry-points/console/ui-dist/assets/index-fKvnL036.js +0 -101
  47. package/src/adapter/entry-points/console/ui-dist/assets/index-fKvnL036.js +0 -101
@@ -0,0 +1,147 @@
1
+ import { ClaudeLiveSession } from './adapter-interfaces/ClaudeLiveSessionRepository';
2
+ import { LiveSessionOauthTokenSelectUseCase } from './LiveSessionOauthTokenSelectUseCase';
3
+ import {
4
+ OauthTokenCandidate,
5
+ OauthTokenWindowSnapshot,
6
+ } from './OauthTokenSelectUseCase';
7
+
8
+ const NOW = 1_000_000;
9
+ const HOUR = 3600;
10
+ const DAY = 86400;
11
+
12
+ const snapshot = (
13
+ overrides: Partial<OauthTokenWindowSnapshot>,
14
+ ): OauthTokenWindowSnapshot => ({
15
+ fiveHourUtilization: 0,
16
+ fiveHourReset: NOW + HOUR,
17
+ sevenDayUtilization: 0,
18
+ sevenDayReset: NOW + DAY,
19
+ ...overrides,
20
+ });
21
+
22
+ const candidate = (
23
+ name: string,
24
+ snapshotValue: OauthTokenWindowSnapshot | null,
25
+ ): OauthTokenCandidate => ({
26
+ name,
27
+ token: `fake-token-${name}`,
28
+ snapshot: snapshotValue,
29
+ });
30
+
31
+ const session = (name: string, sessionId: string): ClaudeLiveSession => ({
32
+ token: `fake-token-${name}`,
33
+ sessionId,
34
+ });
35
+
36
+ describe('LiveSessionOauthTokenSelectUseCase', () => {
37
+ const useCase = new LiveSessionOauthTokenSelectUseCase();
38
+
39
+ it('prefers the eligible token with zero live sessions', () => {
40
+ const result = useCase.run(
41
+ [candidate('busy', snapshot({})), candidate('idle', snapshot({}))],
42
+ [session('busy', 'session-a')],
43
+ NOW,
44
+ );
45
+
46
+ expect(result.selected?.name).toBe('idle');
47
+ expect(result.selected?.token).toBe('fake-token-idle');
48
+ const idle = result.metrics.find((m) => m.name === 'idle');
49
+ expect(idle?.liveSessionCount).toBe(0);
50
+ });
51
+
52
+ it('breaks an occupancy tie by the soonest 7d reset', () => {
53
+ const result = useCase.run(
54
+ [
55
+ candidate('far', snapshot({ sevenDayReset: NOW + 6 * DAY })),
56
+ candidate('soon', snapshot({ sevenDayReset: NOW + 2 * DAY })),
57
+ ],
58
+ [session('far', 'session-a'), session('soon', 'session-b')],
59
+ NOW,
60
+ );
61
+
62
+ expect(result.selected?.name).toBe('soon');
63
+ });
64
+
65
+ it('prefers fewer live sessions over a sooner 7d reset', () => {
66
+ const result = useCase.run(
67
+ [
68
+ candidate('soonButBusy', snapshot({ sevenDayReset: NOW + 2 * DAY })),
69
+ candidate('farButIdle', snapshot({ sevenDayReset: NOW + 6 * DAY })),
70
+ ],
71
+ [
72
+ session('soonButBusy', 'session-a'),
73
+ session('soonButBusy', 'session-b'),
74
+ ],
75
+ NOW,
76
+ );
77
+
78
+ expect(result.selected?.name).toBe('farButIdle');
79
+ });
80
+
81
+ it('excludes a rate-limit-ineligible token even when it has no live sessions', () => {
82
+ const result = useCase.run(
83
+ [
84
+ candidate('idleButBlocked', snapshot({ fiveHourUtilization: 0.9 })),
85
+ candidate('busyButFree', snapshot({})),
86
+ ],
87
+ [session('busyButFree', 'session-a')],
88
+ NOW,
89
+ );
90
+
91
+ expect(result.selected?.name).toBe('busyButFree');
92
+ const blocked = result.metrics.find((m) => m.name === 'idleButBlocked');
93
+ expect(blocked?.eligible).toBe(false);
94
+ expect(blocked?.liveSessionCount).toBe(0);
95
+ });
96
+
97
+ it('counts distinct session ids and dedupes child processes sharing one session', () => {
98
+ const result = useCase.run(
99
+ [
100
+ candidate('oneSession', snapshot({ sevenDayReset: NOW + 2 * DAY })),
101
+ candidate('twoSessions', snapshot({ sevenDayReset: NOW + 6 * DAY })),
102
+ ],
103
+ [
104
+ session('oneSession', 'session-a'),
105
+ session('oneSession', 'session-a'),
106
+ session('oneSession', 'session-a'),
107
+ session('twoSessions', 'session-b'),
108
+ session('twoSessions', 'session-c'),
109
+ ],
110
+ NOW,
111
+ );
112
+
113
+ expect(result.selected?.name).toBe('oneSession');
114
+ const oneSession = result.metrics.find((m) => m.name === 'oneSession');
115
+ const twoSessions = result.metrics.find((m) => m.name === 'twoSessions');
116
+ expect(oneSession?.liveSessionCount).toBe(1);
117
+ expect(twoSessions?.liveSessionCount).toBe(2);
118
+ });
119
+
120
+ it('returns null selection when no token passes the rate-limit filter', () => {
121
+ const result = useCase.run(
122
+ [candidate('blocked', snapshot({ fiveHourUtilization: 0.9 }))],
123
+ [],
124
+ NOW,
125
+ );
126
+
127
+ expect(result.selected).toBeNull();
128
+ });
129
+
130
+ it('returns null selection for an empty candidate list', () => {
131
+ const result = useCase.run([], [], NOW);
132
+
133
+ expect(result.selected).toBeNull();
134
+ expect(result.metrics).toEqual([]);
135
+ });
136
+
137
+ it('reports a zero live session count for tokens with no matching process', () => {
138
+ const result = useCase.run(
139
+ [candidate('lonely', snapshot({}))],
140
+ [session('other', 'session-x')],
141
+ NOW,
142
+ );
143
+
144
+ const lonely = result.metrics.find((m) => m.name === 'lonely');
145
+ expect(lonely?.liveSessionCount).toBe(0);
146
+ });
147
+ });
@@ -0,0 +1,100 @@
1
+ import { ClaudeLiveSession } from './adapter-interfaces/ClaudeLiveSessionRepository';
2
+ import {
3
+ OauthTokenCandidate,
4
+ OauthTokenSelectUseCase,
5
+ } from './OauthTokenSelectUseCase';
6
+
7
+ export type LiveSessionOauthTokenCandidateMetrics = {
8
+ name: string;
9
+ fiveHourFreeRatio: number;
10
+ sevenDayFreeRatio: number;
11
+ sevenDayEndEpoch: number;
12
+ liveSessionCount: number;
13
+ eligible: boolean;
14
+ exclusionReason: string | null;
15
+ };
16
+
17
+ export type LiveSessionOauthTokenSelectResult = {
18
+ selected: OauthTokenCandidate | null;
19
+ metrics: LiveSessionOauthTokenCandidateMetrics[];
20
+ };
21
+
22
+ export class LiveSessionOauthTokenSelectUseCase {
23
+ constructor(
24
+ private readonly rateLimitSelectUseCase: OauthTokenSelectUseCase = new OauthTokenSelectUseCase(),
25
+ ) {}
26
+
27
+ run = (
28
+ candidates: OauthTokenCandidate[],
29
+ liveSessions: ClaudeLiveSession[],
30
+ nowEpochSeconds: number,
31
+ ): LiveSessionOauthTokenSelectResult => {
32
+ const rateLimitResult = this.rateLimitSelectUseCase.run(
33
+ candidates,
34
+ nowEpochSeconds,
35
+ );
36
+ const liveSessionCountByToken = this.liveSessionCountByToken(liveSessions);
37
+
38
+ const evaluated = candidates.map((candidate, index) => {
39
+ const rateLimitMetric = rateLimitResult.metrics[index];
40
+ const liveSessionCount =
41
+ liveSessionCountByToken.get(candidate.token) ?? 0;
42
+ return {
43
+ candidate,
44
+ metric: {
45
+ name: rateLimitMetric.name,
46
+ fiveHourFreeRatio: rateLimitMetric.fiveHourFreeRatio,
47
+ sevenDayFreeRatio: rateLimitMetric.sevenDayFreeRatio,
48
+ sevenDayEndEpoch: rateLimitMetric.sevenDayEndEpoch,
49
+ liveSessionCount,
50
+ eligible: rateLimitMetric.eligible,
51
+ exclusionReason: rateLimitMetric.exclusionReason,
52
+ },
53
+ };
54
+ });
55
+
56
+ const metrics = evaluated.map((entry) => entry.metric);
57
+ const eligible = evaluated.filter((entry) => entry.metric.eligible);
58
+
59
+ if (eligible.length === 0) {
60
+ return { selected: null, metrics };
61
+ }
62
+
63
+ const best = eligible.reduce((bestEntry, currentEntry) =>
64
+ this.preferred(currentEntry.metric, bestEntry.metric)
65
+ ? currentEntry
66
+ : bestEntry,
67
+ );
68
+
69
+ return { selected: best.candidate, metrics };
70
+ };
71
+
72
+ private preferred = (
73
+ candidateMetric: LiveSessionOauthTokenCandidateMetrics,
74
+ incumbentMetric: LiveSessionOauthTokenCandidateMetrics,
75
+ ): boolean => {
76
+ if (candidateMetric.liveSessionCount !== incumbentMetric.liveSessionCount) {
77
+ return (
78
+ candidateMetric.liveSessionCount < incumbentMetric.liveSessionCount
79
+ );
80
+ }
81
+ return candidateMetric.sevenDayEndEpoch < incumbentMetric.sevenDayEndEpoch;
82
+ };
83
+
84
+ private liveSessionCountByToken = (
85
+ liveSessions: ClaudeLiveSession[],
86
+ ): Map<string, number> => {
87
+ const sessionIdsByToken = new Map<string, Set<string>>();
88
+ for (const liveSession of liveSessions) {
89
+ const sessionIds =
90
+ sessionIdsByToken.get(liveSession.token) ?? new Set<string>();
91
+ sessionIds.add(liveSession.sessionId);
92
+ sessionIdsByToken.set(liveSession.token, sessionIds);
93
+ }
94
+ const countByToken = new Map<string, number>();
95
+ for (const [token, sessionIds] of sessionIdsByToken.entries()) {
96
+ countByToken.set(token, sessionIds.size);
97
+ }
98
+ return countByToken;
99
+ };
100
+ }
@@ -0,0 +1,8 @@
1
+ export type ClaudeLiveSession = {
2
+ token: string;
3
+ sessionId: string;
4
+ };
5
+
6
+ export interface ClaudeLiveSessionRepository {
7
+ listLiveSessions: () => ClaudeLiveSession[];
8
+ }
@@ -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;AAkGzB,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;AAwGzB,eAAO,MAAM,OAAO,SAAgB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { ClaudeLiveSessionRepository } from '../../../domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository';
2
+ import { LiveSessionOauthTokenSelectUseCase } from '../../../domain/usecases/LiveSessionOauthTokenSelectUseCase';
3
+ export type LiveSessionOauthTokenSelectHandlerInput = {
4
+ tokenListJsonPath: string | null;
5
+ cacheDirectory: string | null;
6
+ nowEpochSeconds: number;
7
+ };
8
+ export type LiveSessionOauthTokenSelectHandlerOutput = {
9
+ selectedToken: string | null;
10
+ selectedName: string | null;
11
+ diagnostics: string[];
12
+ };
13
+ export declare class LiveSessionOauthTokenSelectHandler {
14
+ private readonly useCase;
15
+ private readonly liveSessionRepository;
16
+ constructor(useCase?: LiveSessionOauthTokenSelectUseCase, liveSessionRepository?: ClaudeLiveSessionRepository);
17
+ handle: (input: LiveSessionOauthTokenSelectHandlerInput) => LiveSessionOauthTokenSelectHandlerOutput;
18
+ private formatDiagnostics;
19
+ }
20
+ //# sourceMappingURL=LiveSessionOauthTokenSelectHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveSessionOauthTokenSelectHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/LiveSessionOauthTokenSelectHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,yEAAyE,CAAC;AACtH,OAAO,EAEL,kCAAkC,EACnC,MAAM,6DAA6D,CAAC;AAUrE,MAAM,MAAM,uCAAuC,GAAG;IACpD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,wCAAwC,GAAG;IACrD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAEF,qBAAa,kCAAkC;IAE3C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBADrB,OAAO,GAAE,kCAA6E,EACtF,qBAAqB,GAAE,2BAAmE;IAG7G,MAAM,GACJ,OAAO,uCAAuC,KAC7C,wCAAwC,CAuDzC;IAEF,OAAO,CAAC,iBAAiB,CAuBvB;CACH"}
@@ -0,0 +1,11 @@
1
+ import { ClaudeLiveSession, ClaudeLiveSessionRepository } from '../../domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository';
2
+ export declare class ProcClaudeLiveSessionRepository implements ClaudeLiveSessionRepository {
3
+ private readonly procDirectory;
4
+ constructor(procDirectory?: string);
5
+ listLiveSessions: () => ClaudeLiveSession[];
6
+ private listProcessIdDirectories;
7
+ private readLiveSession;
8
+ private isClaudeProcess;
9
+ private readEnviron;
10
+ }
11
+ //# sourceMappingURL=ProcClaudeLiveSessionRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProcClaudeLiveSessionRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/ProcClaudeLiveSessionRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EACjB,2BAA2B,EAC5B,MAAM,sEAAsE,CAAC;AAiB9E,qBAAa,+BAAgC,YAAW,2BAA2B;IAE/E,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,GAAE,MAA+B;IAGjE,gBAAgB,QAAO,iBAAiB,EAAE,CASxC;IAEF,OAAO,CAAC,wBAAwB,CAQ9B;IAEF,OAAO,CAAC,eAAe,CAqBrB;IAEF,OAAO,CAAC,eAAe,CAgBrB;IAEF,OAAO,CAAC,WAAW,CA4BjB;CACH"}
@@ -0,0 +1,23 @@
1
+ import { ClaudeLiveSession } from './adapter-interfaces/ClaudeLiveSessionRepository';
2
+ import { OauthTokenCandidate, OauthTokenSelectUseCase } from './OauthTokenSelectUseCase';
3
+ export type LiveSessionOauthTokenCandidateMetrics = {
4
+ name: string;
5
+ fiveHourFreeRatio: number;
6
+ sevenDayFreeRatio: number;
7
+ sevenDayEndEpoch: number;
8
+ liveSessionCount: number;
9
+ eligible: boolean;
10
+ exclusionReason: string | null;
11
+ };
12
+ export type LiveSessionOauthTokenSelectResult = {
13
+ selected: OauthTokenCandidate | null;
14
+ metrics: LiveSessionOauthTokenCandidateMetrics[];
15
+ };
16
+ export declare class LiveSessionOauthTokenSelectUseCase {
17
+ private readonly rateLimitSelectUseCase;
18
+ constructor(rateLimitSelectUseCase?: OauthTokenSelectUseCase);
19
+ run: (candidates: OauthTokenCandidate[], liveSessions: ClaudeLiveSession[], nowEpochSeconds: number) => LiveSessionOauthTokenSelectResult;
20
+ private preferred;
21
+ private liveSessionCountByToken;
22
+ }
23
+ //# sourceMappingURL=LiveSessionOauthTokenSelectUseCase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveSessionOauthTokenSelectUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/LiveSessionOauthTokenSelectUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kDAAkD,CAAC;AACrF,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,qCAAqC,GAAG;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAAG;IAC9C,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,OAAO,EAAE,qCAAqC,EAAE,CAAC;CAClD,CAAC;AAEF,qBAAa,kCAAkC;IAE3C,OAAO,CAAC,QAAQ,CAAC,sBAAsB;gBAAtB,sBAAsB,GAAE,uBAAuD;IAGlG,GAAG,GACD,YAAY,mBAAmB,EAAE,EACjC,cAAc,iBAAiB,EAAE,EACjC,iBAAiB,MAAM,KACtB,iCAAiC,CAuClC;IAEF,OAAO,CAAC,SAAS,CAUf;IAEF,OAAO,CAAC,uBAAuB,CAe7B;CACH"}
@@ -0,0 +1,8 @@
1
+ export type ClaudeLiveSession = {
2
+ token: string;
3
+ sessionId: string;
4
+ };
5
+ export interface ClaudeLiveSessionRepository {
6
+ listLiveSessions: () => ClaudeLiveSession[];
7
+ }
8
+ //# sourceMappingURL=ClaudeLiveSessionRepository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudeLiveSessionRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/ClaudeLiveSessionRepository.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,2BAA2B;IAC1C,gBAAgB,EAAE,MAAM,iBAAiB,EAAE,CAAC;CAC7C"}