github-issue-tower-defence-management 1.110.1 → 1.111.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.
- package/CHANGELOG.md +14 -0
- package/README.md +10 -9
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +9 -21
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
- package/bin/adapter/entry-points/handlers/notifySilentTmuxSessions.js +10 -15
- package/bin/adapter/entry-points/handlers/notifySilentTmuxSessions.js.map +1 -1
- package/bin/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.js +104 -0
- package/bin/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.js.map +1 -0
- package/bin/adapter/repositories/FileSystemSessionOutputActivityRepository.js +55 -19
- package/bin/adapter/repositories/FileSystemSessionOutputActivityRepository.js.map +1 -1
- package/bin/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.js +75 -0
- package/bin/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.js.map +1 -0
- package/bin/adapter/repositories/NoUnansweredOwnerCallStatusProvider.js +1 -1
- package/bin/adapter/repositories/NoUnansweredOwnerCallStatusProvider.js.map +1 -1
- package/bin/adapter/repositories/ProcFsProcessEnvironReader.js +73 -0
- package/bin/adapter/repositories/ProcFsProcessEnvironReader.js.map +1 -0
- package/bin/adapter/repositories/TranscriptOwnerCallStatusProvider.js +8 -16
- package/bin/adapter/repositories/TranscriptOwnerCallStatusProvider.js.map +1 -1
- package/bin/adapter/repositories/TranscriptSessionSubAgentActivityRepository.js +2 -1
- package/bin/adapter/repositories/TranscriptSessionSubAgentActivityRepository.js.map +1 -1
- package/bin/domain/entities/InteractiveLiveSession.js +3 -0
- package/bin/domain/entities/InteractiveLiveSession.js.map +1 -0
- package/bin/domain/entities/LiveSessionProcessSnapshot.js +3 -0
- package/bin/domain/entities/LiveSessionProcessSnapshot.js.map +1 -0
- package/bin/domain/usecases/NotifySilentLiveSessionsUseCase.js +20 -33
- package/bin/domain/usecases/NotifySilentLiveSessionsUseCase.js.map +1 -1
- package/bin/domain/usecases/ResolveInteractiveLiveSessionsUseCase.js +89 -0
- package/bin/domain/usecases/ResolveInteractiveLiveSessionsUseCase.js.map +1 -0
- package/bin/domain/usecases/adapter-interfaces/InteractiveLiveSessionTranscriptResolver.js +3 -0
- package/bin/domain/usecases/adapter-interfaces/InteractiveLiveSessionTranscriptResolver.js.map +1 -0
- package/bin/domain/usecases/adapter-interfaces/LiveSessionProcessSnapshotProvider.js +3 -0
- package/bin/domain/usecases/adapter-interfaces/LiveSessionProcessSnapshotProvider.js.map +1 -0
- package/bin/domain/usecases/adapter-interfaces/ProcessEnvironReader.js +3 -0
- package/bin/domain/usecases/adapter-interfaces/ProcessEnvironReader.js.map +1 -0
- package/package.json +1 -1
- package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +5 -15
- package/src/adapter/entry-points/handlers/notifySilentTmuxSessions.test.ts +96 -204
- package/src/adapter/entry-points/handlers/notifySilentTmuxSessions.ts +19 -40
- package/src/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.test.ts +147 -0
- package/src/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.ts +75 -0
- package/src/adapter/repositories/FileSystemSessionOutputActivityRepository.test.ts +82 -44
- package/src/adapter/repositories/FileSystemSessionOutputActivityRepository.ts +62 -24
- package/src/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.test.ts +138 -0
- package/src/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.ts +93 -0
- package/src/adapter/repositories/NoUnansweredOwnerCallStatusProvider.test.ts +6 -4
- package/src/adapter/repositories/NoUnansweredOwnerCallStatusProvider.ts +1 -1
- package/src/adapter/repositories/ProcFsProcessEnvironReader.test.ts +60 -0
- package/src/adapter/repositories/ProcFsProcessEnvironReader.ts +38 -0
- package/src/adapter/repositories/TranscriptOwnerCallStatusProvider.test.ts +61 -81
- package/src/adapter/repositories/TranscriptOwnerCallStatusProvider.ts +8 -25
- package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.test.ts +29 -0
- package/src/adapter/repositories/TranscriptSessionSubAgentActivityRepository.ts +4 -1
- package/src/domain/entities/InteractiveLiveSession.ts +5 -0
- package/src/domain/entities/LiveSessionProcessSnapshot.ts +17 -0
- package/src/domain/usecases/NotifySilentLiveSessionsUseCase.test.ts +125 -349
- package/src/domain/usecases/NotifySilentLiveSessionsUseCase.ts +33 -55
- package/src/domain/usecases/ResolveInteractiveLiveSessionsUseCase.test.ts +220 -0
- package/src/domain/usecases/ResolveInteractiveLiveSessionsUseCase.ts +105 -0
- package/src/domain/usecases/adapter-interfaces/InteractiveLiveSessionTranscriptResolver.ts +7 -0
- package/src/domain/usecases/adapter-interfaces/LiveSessionProcessSnapshotProvider.ts +5 -0
- package/src/domain/usecases/adapter-interfaces/OwnerCallStatusProvider.ts +1 -1
- package/src/domain/usecases/adapter-interfaces/ProcessEnvironReader.ts +3 -0
- package/src/domain/usecases/adapter-interfaces/SessionOutputActivityRepository.ts +1 -1
- package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/notifySilentTmuxSessions.d.ts +3 -7
- package/types/adapter/entry-points/handlers/notifySilentTmuxSessions.d.ts.map +1 -1
- package/types/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.d.ts +18 -0
- package/types/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.d.ts.map +1 -0
- package/types/adapter/repositories/FileSystemSessionOutputActivityRepository.d.ts +9 -5
- package/types/adapter/repositories/FileSystemSessionOutputActivityRepository.d.ts.map +1 -1
- package/types/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.d.ts +21 -0
- package/types/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.d.ts.map +1 -0
- package/types/adapter/repositories/NoUnansweredOwnerCallStatusProvider.d.ts +1 -1
- package/types/adapter/repositories/NoUnansweredOwnerCallStatusProvider.d.ts.map +1 -1
- package/types/adapter/repositories/ProcFsProcessEnvironReader.d.ts +12 -0
- package/types/adapter/repositories/ProcFsProcessEnvironReader.d.ts.map +1 -0
- package/types/adapter/repositories/TranscriptOwnerCallStatusProvider.d.ts +2 -4
- package/types/adapter/repositories/TranscriptOwnerCallStatusProvider.d.ts.map +1 -1
- package/types/adapter/repositories/TranscriptSessionSubAgentActivityRepository.d.ts.map +1 -1
- package/types/domain/entities/InteractiveLiveSession.d.ts +6 -0
- package/types/domain/entities/InteractiveLiveSession.d.ts.map +1 -0
- package/types/domain/entities/LiveSessionProcessSnapshot.d.ts +16 -0
- package/types/domain/entities/LiveSessionProcessSnapshot.d.ts.map +1 -0
- package/types/domain/usecases/NotifySilentLiveSessionsUseCase.d.ts +6 -11
- package/types/domain/usecases/NotifySilentLiveSessionsUseCase.d.ts.map +1 -1
- package/types/domain/usecases/ResolveInteractiveLiveSessionsUseCase.d.ts +23 -0
- package/types/domain/usecases/ResolveInteractiveLiveSessionsUseCase.d.ts.map +1 -0
- package/types/domain/usecases/adapter-interfaces/InteractiveLiveSessionTranscriptResolver.d.ts +5 -0
- package/types/domain/usecases/adapter-interfaces/InteractiveLiveSessionTranscriptResolver.d.ts.map +1 -0
- package/types/domain/usecases/adapter-interfaces/LiveSessionProcessSnapshotProvider.d.ts +5 -0
- package/types/domain/usecases/adapter-interfaces/LiveSessionProcessSnapshotProvider.d.ts.map +1 -0
- package/types/domain/usecases/adapter-interfaces/OwnerCallStatusProvider.d.ts +1 -1
- package/types/domain/usecases/adapter-interfaces/OwnerCallStatusProvider.d.ts.map +1 -1
- package/types/domain/usecases/adapter-interfaces/ProcessEnvironReader.d.ts +4 -0
- package/types/domain/usecases/adapter-interfaces/ProcessEnvironReader.d.ts.map +1 -0
- package/types/domain/usecases/adapter-interfaces/SessionOutputActivityRepository.d.ts +1 -1
- package/types/domain/usecases/adapter-interfaces/SessionOutputActivityRepository.d.ts.map +1 -1
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import { Issue } from '../entities/Issue';
|
|
2
1
|
import { LiveSessionActivitySnapshot } from '../entities/LiveSessionActivitySnapshot';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { InteractiveLiveSession } from '../entities/InteractiveLiveSession';
|
|
3
|
+
import { LiveSessionProcessSnapshotProvider } from './adapter-interfaces/LiveSessionProcessSnapshotProvider';
|
|
4
|
+
import { InteractiveLiveSessionTranscriptResolver } from './adapter-interfaces/InteractiveLiveSessionTranscriptResolver';
|
|
6
5
|
import { OwnerCallStatusProvider } from './adapter-interfaces/OwnerCallStatusProvider';
|
|
7
6
|
import { SessionOutputActivityRepository } from './adapter-interfaces/SessionOutputActivityRepository';
|
|
8
7
|
import { SessionSubAgentActivityRepository } from './adapter-interfaces/SessionSubAgentActivityRepository';
|
|
9
8
|
import { SilentSessionMessageComposer } from './adapter-interfaces/SilentSessionMessageComposer';
|
|
10
9
|
import { SilentSessionNotificationRepository } from './adapter-interfaces/SilentSessionNotificationRepository';
|
|
11
10
|
import { Sleeper } from './adapter-interfaces/Sleeper';
|
|
12
|
-
import {
|
|
13
|
-
import { toTmuxSessionName } from './intmux/InTmuxByHumanSessionReconcileUseCase';
|
|
11
|
+
import { ResolveInteractiveLiveSessionsUseCase } from './ResolveInteractiveLiveSessionsUseCase';
|
|
14
12
|
|
|
15
|
-
export const DEFAULT_MONITORED_STATUS = IN_TMUX_STATUS_NAME;
|
|
16
13
|
export const DEFAULT_MAIN_SILENT_THRESHOLD_SECONDS = 10 * 60;
|
|
17
14
|
export const DEFAULT_SUBAGENT_SILENT_THRESHOLD_SECONDS = 5 * 60;
|
|
18
15
|
export const DEFAULT_SUBAGENT_RUNNING_THRESHOLD_SECONDS = 15 * 60;
|
|
@@ -25,12 +22,12 @@ type NotifyCandidate = {
|
|
|
25
22
|
};
|
|
26
23
|
|
|
27
24
|
export class NotifySilentLiveSessionsUseCase {
|
|
25
|
+
private readonly resolveInteractiveLiveSessions =
|
|
26
|
+
new ResolveInteractiveLiveSessionsUseCase();
|
|
27
|
+
|
|
28
28
|
constructor(
|
|
29
|
-
private readonly
|
|
30
|
-
private readonly
|
|
31
|
-
TmuxSessionRepository,
|
|
32
|
-
'listLiveSessionNames'
|
|
33
|
-
>,
|
|
29
|
+
private readonly liveSessionProcessSnapshotProvider: LiveSessionProcessSnapshotProvider,
|
|
30
|
+
private readonly interactiveLiveSessionTranscriptResolver: InteractiveLiveSessionTranscriptResolver,
|
|
34
31
|
private readonly sessionOutputActivityRepository: SessionOutputActivityRepository,
|
|
35
32
|
private readonly subAgentActivityRepository: SessionSubAgentActivityRepository,
|
|
36
33
|
private readonly ownerCallStatusProvider: OwnerCallStatusProvider,
|
|
@@ -40,9 +37,6 @@ export class NotifySilentLiveSessionsUseCase {
|
|
|
40
37
|
) {}
|
|
41
38
|
|
|
42
39
|
run = async (params: {
|
|
43
|
-
project: Project;
|
|
44
|
-
allowCacheMinutes: number;
|
|
45
|
-
monitoredStatus: string;
|
|
46
40
|
mainSilentThresholdSeconds: number;
|
|
47
41
|
subAgentSilentThresholdSeconds: number;
|
|
48
42
|
subAgentRunningThresholdSeconds: number;
|
|
@@ -50,29 +44,26 @@ export class NotifySilentLiveSessionsUseCase {
|
|
|
50
44
|
staggerSeconds: number;
|
|
51
45
|
now: Date;
|
|
52
46
|
}): Promise<void> => {
|
|
53
|
-
const
|
|
54
|
-
await this.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
openIssues,
|
|
62
|
-
liveSessionNames,
|
|
63
|
-
params.monitoredStatus,
|
|
64
|
-
);
|
|
47
|
+
const snapshot =
|
|
48
|
+
await this.liveSessionProcessSnapshotProvider.getSnapshot();
|
|
49
|
+
const interactiveSessions =
|
|
50
|
+
this.resolveInteractiveLiveSessions.resolve(snapshot);
|
|
51
|
+
const transcriptPathBySessionName =
|
|
52
|
+
this.interactiveLiveSessionTranscriptResolver.resolveTranscriptPaths(
|
|
53
|
+
interactiveSessions,
|
|
54
|
+
);
|
|
65
55
|
|
|
66
56
|
const snapshots = await this.collectSnapshots(
|
|
67
|
-
|
|
57
|
+
interactiveSessions,
|
|
58
|
+
transcriptPathBySessionName,
|
|
68
59
|
params.now,
|
|
69
60
|
);
|
|
70
61
|
|
|
71
62
|
const candidates: NotifyCandidate[] = [];
|
|
72
|
-
for (const
|
|
73
|
-
const message = this.composeMessage(
|
|
63
|
+
for (const sessionSnapshot of snapshots) {
|
|
64
|
+
const message = this.composeMessage(sessionSnapshot, params);
|
|
74
65
|
if (message !== null) {
|
|
75
|
-
candidates.push({ sessionName:
|
|
66
|
+
candidates.push({ sessionName: sessionSnapshot.sessionName, message });
|
|
76
67
|
}
|
|
77
68
|
}
|
|
78
69
|
candidates.sort((left, right) =>
|
|
@@ -84,7 +75,7 @@ export class NotifySilentLiveSessionsUseCase {
|
|
|
84
75
|
);
|
|
85
76
|
|
|
86
77
|
console.log(
|
|
87
|
-
`Silent live session notification: ${candidates.length} candidate(s) of ${
|
|
78
|
+
`Silent live session notification: ${candidates.length} candidate(s) of ${interactiveSessions.length} interactive session(s).`,
|
|
88
79
|
);
|
|
89
80
|
|
|
90
81
|
const nowEpochSeconds = Math.floor(params.now.getTime() / 1000);
|
|
@@ -122,12 +113,17 @@ export class NotifySilentLiveSessionsUseCase {
|
|
|
122
113
|
};
|
|
123
114
|
|
|
124
115
|
private collectSnapshots = async (
|
|
125
|
-
|
|
116
|
+
interactiveSessions: InteractiveLiveSession[],
|
|
117
|
+
transcriptPathBySessionName: Map<string, string>,
|
|
126
118
|
now: Date,
|
|
127
119
|
): Promise<LiveSessionActivitySnapshot[]> => {
|
|
120
|
+
const sessionNames = interactiveSessions.map(
|
|
121
|
+
(session) => session.sessionName,
|
|
122
|
+
);
|
|
123
|
+
|
|
128
124
|
const activities =
|
|
129
125
|
await this.sessionOutputActivityRepository.listSessionOutputActivities(
|
|
130
|
-
|
|
126
|
+
transcriptPathBySessionName,
|
|
131
127
|
);
|
|
132
128
|
const lastOutputBySessionName = new Map<string, number>();
|
|
133
129
|
for (const activity of activities) {
|
|
@@ -139,16 +135,16 @@ export class NotifySilentLiveSessionsUseCase {
|
|
|
139
135
|
|
|
140
136
|
const subAgentsBySessionName =
|
|
141
137
|
await this.subAgentActivityRepository.listSubAgentActivitiesBySessionName(
|
|
142
|
-
|
|
138
|
+
sessionNames,
|
|
143
139
|
);
|
|
144
140
|
|
|
145
141
|
const sessionNamesWithUnansweredOwnerCall =
|
|
146
142
|
await this.ownerCallStatusProvider.listSessionNamesWithUnansweredOwnerCall(
|
|
147
|
-
|
|
143
|
+
transcriptPathBySessionName,
|
|
148
144
|
);
|
|
149
145
|
|
|
150
146
|
const nowEpochSeconds = Math.floor(now.getTime() / 1000);
|
|
151
|
-
return
|
|
147
|
+
return sessionNames.map((sessionName) => {
|
|
152
148
|
const lastOutputEpochSeconds = lastOutputBySessionName.get(sessionName);
|
|
153
149
|
const mainSilentSeconds =
|
|
154
150
|
lastOutputEpochSeconds === undefined
|
|
@@ -202,22 +198,4 @@ export class NotifySilentLiveSessionsUseCase {
|
|
|
202
198
|
}
|
|
203
199
|
return sections.join('\n\n');
|
|
204
200
|
};
|
|
205
|
-
|
|
206
|
-
private selectMonitoredSessionNames = (
|
|
207
|
-
openIssues: Issue[],
|
|
208
|
-
liveSessionNames: Set<string>,
|
|
209
|
-
monitoredStatus: string,
|
|
210
|
-
): string[] => {
|
|
211
|
-
const monitoredSessionNames: string[] = [];
|
|
212
|
-
for (const issue of openIssues) {
|
|
213
|
-
if (issue.status !== monitoredStatus) {
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
const sessionName = toTmuxSessionName(issue.url);
|
|
217
|
-
if (liveSessionNames.has(sessionName)) {
|
|
218
|
-
monitoredSessionNames.push(sessionName);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return monitoredSessionNames;
|
|
222
|
-
};
|
|
223
201
|
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { ResolveInteractiveLiveSessionsUseCase } from './ResolveInteractiveLiveSessionsUseCase';
|
|
2
|
+
import { LiveSessionProcessSnapshot } from '../entities/LiveSessionProcessSnapshot';
|
|
3
|
+
|
|
4
|
+
describe('ResolveInteractiveLiveSessionsUseCase', () => {
|
|
5
|
+
const useCase = new ResolveInteractiveLiveSessionsUseCase();
|
|
6
|
+
|
|
7
|
+
it('resolves an issue-url-named session through its pane child process', () => {
|
|
8
|
+
const snapshot: LiveSessionProcessSnapshot = {
|
|
9
|
+
sessions: [
|
|
10
|
+
{
|
|
11
|
+
sessionName: 'https_//github_com/owner/repo/issues/9',
|
|
12
|
+
panePids: [100],
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
processes: [
|
|
16
|
+
{
|
|
17
|
+
pid: 100,
|
|
18
|
+
ppid: 1,
|
|
19
|
+
commandLine: 'tmux pane shell',
|
|
20
|
+
sessionId: null,
|
|
21
|
+
configDir: null,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
pid: 101,
|
|
25
|
+
ppid: 100,
|
|
26
|
+
commandLine: 'claude --model opus --resume abc',
|
|
27
|
+
sessionId: 'abc',
|
|
28
|
+
configDir: '/config/issues-9',
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const result = useCase.resolve(snapshot);
|
|
34
|
+
|
|
35
|
+
expect(result).toEqual([
|
|
36
|
+
{
|
|
37
|
+
sessionName: 'https_//github_com/owner/repo/issues/9',
|
|
38
|
+
sessionId: 'abc',
|
|
39
|
+
configDir: '/config/issues-9',
|
|
40
|
+
},
|
|
41
|
+
]);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('resolves a plain-named session such as workbench', () => {
|
|
45
|
+
const snapshot: LiveSessionProcessSnapshot = {
|
|
46
|
+
sessions: [{ sessionName: 'workbench', panePids: [200] }],
|
|
47
|
+
processes: [
|
|
48
|
+
{
|
|
49
|
+
pid: 200,
|
|
50
|
+
ppid: 1,
|
|
51
|
+
commandLine: 'shell',
|
|
52
|
+
sessionId: null,
|
|
53
|
+
configDir: null,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
pid: 201,
|
|
57
|
+
ppid: 200,
|
|
58
|
+
commandLine: 'claude --model opus --name workbench',
|
|
59
|
+
sessionId: 'wb-uuid',
|
|
60
|
+
configDir: '/config/workbench',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const result = useCase.resolve(snapshot);
|
|
66
|
+
|
|
67
|
+
expect(result).toEqual([
|
|
68
|
+
{
|
|
69
|
+
sessionName: 'workbench',
|
|
70
|
+
sessionId: 'wb-uuid',
|
|
71
|
+
configDir: '/config/workbench',
|
|
72
|
+
},
|
|
73
|
+
]);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('finds the interactive process several levels below the pane', () => {
|
|
77
|
+
const snapshot: LiveSessionProcessSnapshot = {
|
|
78
|
+
sessions: [{ sessionName: 'control-room', panePids: [300] }],
|
|
79
|
+
processes: [
|
|
80
|
+
{
|
|
81
|
+
pid: 300,
|
|
82
|
+
ppid: 1,
|
|
83
|
+
commandLine: 'shell',
|
|
84
|
+
sessionId: null,
|
|
85
|
+
configDir: null,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
pid: 301,
|
|
89
|
+
ppid: 300,
|
|
90
|
+
commandLine: 'node wrapper',
|
|
91
|
+
sessionId: null,
|
|
92
|
+
configDir: null,
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
pid: 302,
|
|
96
|
+
ppid: 301,
|
|
97
|
+
commandLine: 'claude --name control-room',
|
|
98
|
+
sessionId: 'cr-uuid',
|
|
99
|
+
configDir: '/config/control-room',
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const result = useCase.resolve(snapshot);
|
|
105
|
+
|
|
106
|
+
expect(result).toEqual([
|
|
107
|
+
{
|
|
108
|
+
sessionName: 'control-room',
|
|
109
|
+
sessionId: 'cr-uuid',
|
|
110
|
+
configDir: '/config/control-room',
|
|
111
|
+
},
|
|
112
|
+
]);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('excludes a session whose only claude process is an owner-handover spawn', () => {
|
|
116
|
+
const snapshot: LiveSessionProcessSnapshot = {
|
|
117
|
+
sessions: [{ sessionName: 'aw-host', panePids: [400] }],
|
|
118
|
+
processes: [
|
|
119
|
+
{
|
|
120
|
+
pid: 400,
|
|
121
|
+
ppid: 1,
|
|
122
|
+
commandLine: 'shell',
|
|
123
|
+
sessionId: null,
|
|
124
|
+
configDir: null,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
pid: 401,
|
|
128
|
+
ppid: 400,
|
|
129
|
+
commandLine:
|
|
130
|
+
'claude --verbose -p Take ownership of https://example.com/issues/1 and finish it',
|
|
131
|
+
sessionId: 'aw-uuid',
|
|
132
|
+
configDir: '/config/aw',
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const result = useCase.resolve(snapshot);
|
|
138
|
+
|
|
139
|
+
expect(result).toEqual([]);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('skips a session whose interactive process exposes no session id or config dir', () => {
|
|
143
|
+
const snapshot: LiveSessionProcessSnapshot = {
|
|
144
|
+
sessions: [{ sessionName: 'partial', panePids: [500] }],
|
|
145
|
+
processes: [
|
|
146
|
+
{
|
|
147
|
+
pid: 501,
|
|
148
|
+
ppid: 500,
|
|
149
|
+
commandLine: 'claude --model opus',
|
|
150
|
+
sessionId: null,
|
|
151
|
+
configDir: '/config/partial',
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const result = useCase.resolve(snapshot);
|
|
157
|
+
|
|
158
|
+
expect(result).toEqual([]);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('ignores non-claude descendants such as monitors', () => {
|
|
162
|
+
const snapshot: LiveSessionProcessSnapshot = {
|
|
163
|
+
sessions: [{ sessionName: 'monitored', panePids: [600] }],
|
|
164
|
+
processes: [
|
|
165
|
+
{
|
|
166
|
+
pid: 601,
|
|
167
|
+
ppid: 600,
|
|
168
|
+
commandLine: 'node monitor.js',
|
|
169
|
+
sessionId: 'mon-uuid',
|
|
170
|
+
configDir: '/config/monitor',
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const result = useCase.resolve(snapshot);
|
|
176
|
+
|
|
177
|
+
expect(result).toEqual([]);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('resolves multiple sessions and drops the ones without an interactive process', () => {
|
|
181
|
+
const snapshot: LiveSessionProcessSnapshot = {
|
|
182
|
+
sessions: [
|
|
183
|
+
{ sessionName: 'workbench', panePids: [700] },
|
|
184
|
+
{ sessionName: 'empty', panePids: [800] },
|
|
185
|
+
],
|
|
186
|
+
processes: [
|
|
187
|
+
{
|
|
188
|
+
pid: 701,
|
|
189
|
+
ppid: 700,
|
|
190
|
+
commandLine: 'claude --name workbench',
|
|
191
|
+
sessionId: 'wb-uuid',
|
|
192
|
+
configDir: '/config/workbench',
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
pid: 801,
|
|
196
|
+
ppid: 800,
|
|
197
|
+
commandLine: 'bash idle',
|
|
198
|
+
sessionId: null,
|
|
199
|
+
configDir: null,
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const result = useCase.resolve(snapshot);
|
|
205
|
+
|
|
206
|
+
expect(result).toEqual([
|
|
207
|
+
{
|
|
208
|
+
sessionName: 'workbench',
|
|
209
|
+
sessionId: 'wb-uuid',
|
|
210
|
+
configDir: '/config/workbench',
|
|
211
|
+
},
|
|
212
|
+
]);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('returns an empty list when there are no sessions', () => {
|
|
216
|
+
const result = useCase.resolve({ sessions: [], processes: [] });
|
|
217
|
+
|
|
218
|
+
expect(result).toEqual([]);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { InteractiveLiveSession } from '../entities/InteractiveLiveSession';
|
|
2
|
+
import {
|
|
3
|
+
LiveSessionProcessInfo,
|
|
4
|
+
LiveSessionProcessSnapshot,
|
|
5
|
+
} from '../entities/LiveSessionProcessSnapshot';
|
|
6
|
+
|
|
7
|
+
// Command-line substring that identifies an "owner-handover" agent spawn (for
|
|
8
|
+
// example a background implementation agent started with a prompt beginning
|
|
9
|
+
// "Take ownership of ..."). These spawns are not interactive owner sessions and
|
|
10
|
+
// MUST NOT be notified, so any process whose command line contains this marker
|
|
11
|
+
// is excluded even if it somehow appears under a monitored pane.
|
|
12
|
+
export const OWNER_HANDOVER_COMMAND_MARKER = 'Take ownership of';
|
|
13
|
+
|
|
14
|
+
// Command-name substring that identifies the interactive Claude Code process.
|
|
15
|
+
const INTERACTIVE_PROCESS_COMMAND_MARKER = 'claude';
|
|
16
|
+
|
|
17
|
+
const isInteractiveCandidate = (process: LiveSessionProcessInfo): boolean => {
|
|
18
|
+
if (process.commandLine.includes(OWNER_HANDOVER_COMMAND_MARKER)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (!process.commandLine.includes(INTERACTIVE_PROCESS_COMMAND_MARKER)) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return process.sessionId !== null && process.configDir !== null;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Selects the interactive Claude Code sessions that are eligible for the silent
|
|
29
|
+
* self-check notification, independently of session naming or any GitHub issue
|
|
30
|
+
* linkage.
|
|
31
|
+
*
|
|
32
|
+
* Selection works purely from a process snapshot: for each live tmux session,
|
|
33
|
+
* the descendants of its pane processes are walked, and the first descendant
|
|
34
|
+
* that looks like an interactive Claude Code process (command line contains
|
|
35
|
+
* `claude`, does not contain the owner-handover marker, and exposes both a
|
|
36
|
+
* session id and a config directory in its environment) is taken as the
|
|
37
|
+
* session's interactive process. Because the walk is anchored on tmux panes,
|
|
38
|
+
* background owner-handover spawns, the preparation daemon, and monitor
|
|
39
|
+
* processes — none of which run inside an interactive tmux pane — are naturally
|
|
40
|
+
* excluded; the explicit owner-handover marker check is an additional guard.
|
|
41
|
+
*/
|
|
42
|
+
export class ResolveInteractiveLiveSessionsUseCase {
|
|
43
|
+
resolve = (
|
|
44
|
+
snapshot: LiveSessionProcessSnapshot,
|
|
45
|
+
): InteractiveLiveSession[] => {
|
|
46
|
+
const processByPid = new Map<number, LiveSessionProcessInfo>();
|
|
47
|
+
const childrenByPpid = new Map<number, LiveSessionProcessInfo[]>();
|
|
48
|
+
for (const process of snapshot.processes) {
|
|
49
|
+
processByPid.set(process.pid, process);
|
|
50
|
+
const siblings = childrenByPpid.get(process.ppid) ?? [];
|
|
51
|
+
siblings.push(process);
|
|
52
|
+
childrenByPpid.set(process.ppid, siblings);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const sessions: InteractiveLiveSession[] = [];
|
|
56
|
+
for (const session of snapshot.sessions) {
|
|
57
|
+
const interactiveProcess = this.findInteractiveProcess(
|
|
58
|
+
session.panePids,
|
|
59
|
+
processByPid,
|
|
60
|
+
childrenByPpid,
|
|
61
|
+
);
|
|
62
|
+
if (
|
|
63
|
+
interactiveProcess === null ||
|
|
64
|
+
interactiveProcess.sessionId === null ||
|
|
65
|
+
interactiveProcess.configDir === null
|
|
66
|
+
) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
sessions.push({
|
|
70
|
+
sessionName: session.sessionName,
|
|
71
|
+
sessionId: interactiveProcess.sessionId,
|
|
72
|
+
configDir: interactiveProcess.configDir,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return sessions;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
private findInteractiveProcess = (
|
|
79
|
+
panePids: number[],
|
|
80
|
+
processByPid: Map<number, LiveSessionProcessInfo>,
|
|
81
|
+
childrenByPpid: Map<number, LiveSessionProcessInfo[]>,
|
|
82
|
+
): LiveSessionProcessInfo | null => {
|
|
83
|
+
const visited = new Set<number>();
|
|
84
|
+
const queue: number[] = [...panePids];
|
|
85
|
+
let head = 0;
|
|
86
|
+
while (head < queue.length) {
|
|
87
|
+
const pid = queue[head];
|
|
88
|
+
head += 1;
|
|
89
|
+
if (visited.has(pid)) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
visited.add(pid);
|
|
93
|
+
const process = processByPid.get(pid);
|
|
94
|
+
if (process !== undefined && isInteractiveCandidate(process)) {
|
|
95
|
+
return process;
|
|
96
|
+
}
|
|
97
|
+
for (const child of childrenByPpid.get(pid) ?? []) {
|
|
98
|
+
if (!visited.has(child.pid)) {
|
|
99
|
+
queue.push(child.pid);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -2,6 +2,6 @@ import { LiveSessionOutputActivity } from '../../entities/LiveSessionOutputActiv
|
|
|
2
2
|
|
|
3
3
|
export interface SessionOutputActivityRepository {
|
|
4
4
|
listSessionOutputActivities: (
|
|
5
|
-
|
|
5
|
+
transcriptPathBySessionName: Map<string, string>,
|
|
6
6
|
) => Promise<LiveSessionOutputActivity[]>;
|
|
7
7
|
}
|
|
@@ -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,
|
|
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,CAoiBP;CACH"}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import { Project } from '../../../domain/entities/Project';
|
|
2
1
|
import { LocalCommandRunner } from '../../../domain/usecases/adapter-interfaces/LocalCommandRunner';
|
|
3
|
-
import {
|
|
2
|
+
import { ProcessEnvironReader } from '../../../domain/usecases/adapter-interfaces/ProcessEnvironReader';
|
|
4
3
|
import { LocalStorageCacheRepository } from '../../repositories/LocalStorageCacheRepository';
|
|
5
4
|
import { SilentSessionMessageTemplates } from '../../repositories/ConfigurableSilentSessionMessageComposer';
|
|
6
5
|
export type NotifySilentTmuxSessionsParams = {
|
|
7
|
-
|
|
8
|
-
allowCacheMinutes: number;
|
|
9
|
-
issueRepository: Pick<IssueRepository, 'getAllOpened'>;
|
|
6
|
+
enabled: boolean;
|
|
10
7
|
localCommandRunner: LocalCommandRunner;
|
|
8
|
+
processEnvironReader?: ProcessEnvironReader;
|
|
11
9
|
cacheRepository: Pick<LocalStorageCacheRepository, 'getLatest' | 'set'>;
|
|
12
|
-
sessionOutputRootDirectory: string | null;
|
|
13
|
-
sessionTranscriptRootDirectory: string | null;
|
|
14
10
|
ownerCallMarker: string | null;
|
|
15
11
|
subAgentOutputRootDirectory: string | null;
|
|
16
12
|
subAgentProcessMatchPattern: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifySilentTmuxSessions.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/notifySilentTmuxSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"notifySilentTmuxSessions.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/notifySilentTmuxSessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gEAAgE,CAAC;AAGpG,OAAO,EAAE,oBAAoB,EAAE,MAAM,kEAAkE,CAAC;AAexG,OAAO,EAAE,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAQ7F,OAAO,EAEL,6BAA6B,EAC9B,MAAM,6DAA6D,CAAC;AAGrE,MAAM,MAAM,8BAA8B,GAAG;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,eAAe,EAAE,IAAI,CAAC,2BAA2B,EAAE,WAAW,GAAG,KAAK,CAAC,CAAC;IACxE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,2BAA2B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,2BAA2B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,+BAA+B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,0BAA0B,EAAE,MAAM,CAAC;IACnC,8BAA8B,EAAE,MAAM,CAAC;IACvC,+BAA+B,EAAE,MAAM,CAAC;IACxC,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,6BAA6B,CAAC;IAChD,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAoCF,eAAO,MAAM,wBAAwB,GACnC,QAAQ,8BAA8B,KACrC,OAAO,CAAC,IAAI,CA0Dd,CAAC;AAEF,eAAO,MAAM,0CAA0C;;;;;;CAM7C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { InteractiveLiveSession } from '../../domain/entities/InteractiveLiveSession';
|
|
2
|
+
import { InteractiveLiveSessionTranscriptResolver } from '../../domain/usecases/adapter-interfaces/InteractiveLiveSessionTranscriptResolver';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the real transcript path of an interactive Claude Code session from
|
|
5
|
+
* the session id and config directory taken from the session's process
|
|
6
|
+
* environment. The transcript lives at
|
|
7
|
+
* `<configDir>/projects/<cwd-slug>/<sessionId>.jsonl`; this resolver scans the
|
|
8
|
+
* `projects` subdirectories for a file named `<sessionId>.jsonl` and returns the
|
|
9
|
+
* most recently modified match. Because resolution is keyed on the process
|
|
10
|
+
* session id rather than on a session name or issue URL, a plain-named session
|
|
11
|
+
* (for example one named `workbench`) resolves just as well as an issue-url
|
|
12
|
+
* named one.
|
|
13
|
+
*/
|
|
14
|
+
export declare class FileSystemInteractiveLiveSessionTranscriptResolver implements InteractiveLiveSessionTranscriptResolver {
|
|
15
|
+
resolveTranscriptPaths: (sessions: InteractiveLiveSession[]) => Map<string, string>;
|
|
16
|
+
private resolveTranscriptPath;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=FileSystemInteractiveLiveSessionTranscriptResolver.d.ts.map
|
package/types/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileSystemInteractiveLiveSessionTranscriptResolver.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/FileSystemInteractiveLiveSessionTranscriptResolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAE,wCAAwC,EAAE,MAAM,mFAAmF,CAAC;AAW7I;;;;;;;;;;GAUG;AACH,qBAAa,kDAAmD,YAAW,wCAAwC;IACjH,sBAAsB,GACpB,UAAU,sBAAsB,EAAE,KACjC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CASpB;IAEF,OAAO,CAAC,qBAAqB,CAkC3B;CACH"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { LiveSessionOutputActivity } from '../../domain/entities/LiveSessionOutputActivity';
|
|
2
2
|
import { SessionOutputActivityRepository } from '../../domain/usecases/adapter-interfaces/SessionOutputActivityRepository';
|
|
3
|
+
/**
|
|
4
|
+
* Reads the last main-session output time for each live session from its
|
|
5
|
+
* already-resolved transcript path. Idle time is computed from the timestamp of
|
|
6
|
+
* the latest `assistant` entry rather than from the transcript file modification
|
|
7
|
+
* time, so a transcript touched only by tool results or owner replies still
|
|
8
|
+
* counts as silent.
|
|
9
|
+
*/
|
|
3
10
|
export declare class FileSystemSessionOutputActivityRepository implements SessionOutputActivityRepository {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
listSessionOutputActivities: (sessionNames: string[]) => Promise<LiveSessionOutputActivity[]>;
|
|
7
|
-
private readLastOutputEpochSeconds;
|
|
8
|
-
private toOutputFileName;
|
|
11
|
+
listSessionOutputActivities: (transcriptPathBySessionName: Map<string, string>) => Promise<LiveSessionOutputActivity[]>;
|
|
12
|
+
private readLastAssistantOutputEpochSeconds;
|
|
9
13
|
}
|
|
10
14
|
//# sourceMappingURL=FileSystemSessionOutputActivityRepository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSystemSessionOutputActivityRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/FileSystemSessionOutputActivityRepository.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FileSystemSessionOutputActivityRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/FileSystemSessionOutputActivityRepository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC5F,OAAO,EAAE,+BAA+B,EAAE,MAAM,0EAA0E,CAAC;AAqB3H;;;;;;GAMG;AACH,qBAAa,yCAA0C,YAAW,+BAA+B;IAC/F,2BAA2B,GACzB,6BAA6B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAC/C,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAUrC;IAEF,OAAO,CAAC,mCAAmC,CAuCzC;CACH"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { LocalCommandRunner } from '../../domain/usecases/adapter-interfaces/LocalCommandRunner';
|
|
2
|
+
import { LiveSessionProcessSnapshotProvider } from '../../domain/usecases/adapter-interfaces/LiveSessionProcessSnapshotProvider';
|
|
3
|
+
import { ProcessEnvironReader } from '../../domain/usecases/adapter-interfaces/ProcessEnvironReader';
|
|
4
|
+
import { LiveSessionProcessSnapshot } from '../../domain/entities/LiveSessionProcessSnapshot';
|
|
5
|
+
/**
|
|
6
|
+
* Builds a live-session process snapshot from the local host: it lists the live
|
|
7
|
+
* tmux sessions and each session's pane process ids, lists the full process
|
|
8
|
+
* tree with command lines, and reads each process environment to expose the
|
|
9
|
+
* Claude Code session id and config directory. The snapshot is consumed by a
|
|
10
|
+
* pure resolver, so all host access is contained in this adapter.
|
|
11
|
+
*/
|
|
12
|
+
export declare class LocalProcessLiveSessionProcessSnapshotProvider implements LiveSessionProcessSnapshotProvider {
|
|
13
|
+
private readonly localCommandRunner;
|
|
14
|
+
private readonly environReader;
|
|
15
|
+
constructor(localCommandRunner: LocalCommandRunner, environReader: ProcessEnvironReader);
|
|
16
|
+
getSnapshot: () => Promise<LiveSessionProcessSnapshot>;
|
|
17
|
+
private listSessionNames;
|
|
18
|
+
private listPanePids;
|
|
19
|
+
private listProcesses;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=LocalProcessLiveSessionProcessSnapshotProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalProcessLiveSessionProcessSnapshotProvider.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/LocalProcessLiveSessionProcessSnapshotProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6DAA6D,CAAC;AACjG,OAAO,EAAE,kCAAkC,EAAE,MAAM,6EAA6E,CAAC;AACjI,OAAO,EAAE,oBAAoB,EAAE,MAAM,+DAA+D,CAAC;AACrG,OAAO,EAGL,0BAA0B,EAC3B,MAAM,kDAAkD,CAAC;AAK1D;;;;;;GAMG;AACH,qBAAa,8CAA+C,YAAW,kCAAkC;IAErG,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa;gBADb,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,oBAAoB;IAGtD,WAAW,QAAa,OAAO,CAAC,0BAA0B,CAAC,CASzD;IAEF,OAAO,CAAC,gBAAgB,CAYtB;IAEF,OAAO,CAAC,YAAY,CAYlB;IAEF,OAAO,CAAC,aAAa,CA2BnB;CACH"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OwnerCallStatusProvider } from '../../domain/usecases/adapter-interfaces/OwnerCallStatusProvider';
|
|
2
2
|
export declare class NoUnansweredOwnerCallStatusProvider implements OwnerCallStatusProvider {
|
|
3
|
-
listSessionNamesWithUnansweredOwnerCall: (
|
|
3
|
+
listSessionNamesWithUnansweredOwnerCall: (_transcriptPathBySessionName: Map<string, string>) => Promise<Set<string>>;
|
|
4
4
|
}
|
|
5
5
|
//# sourceMappingURL=NoUnansweredOwnerCallStatusProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NoUnansweredOwnerCallStatusProvider.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/NoUnansweredOwnerCallStatusProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kEAAkE,CAAC;AAE3G,qBAAa,mCAAoC,YAAW,uBAAuB;IACjF,uCAAuC,GACrC,
|
|
1
|
+
{"version":3,"file":"NoUnansweredOwnerCallStatusProvider.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/NoUnansweredOwnerCallStatusProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kEAAkE,CAAC;AAE3G,qBAAa,mCAAoC,YAAW,uBAAuB;IACjF,uCAAuC,GACrC,8BAA8B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,KAChD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAErB;CACH"}
|