github-issue-tower-defence-management 1.105.0 → 1.107.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.
- package/CHANGELOG.md +14 -0
- package/README.md +5 -0
- package/bin/adapter/entry-points/cli/index.js +18 -1
- package/bin/adapter/entry-points/cli/index.js.map +1 -1
- package/bin/adapter/entry-points/console/dashboardComposeService.js +178 -0
- package/bin/adapter/entry-points/console/dashboardComposeService.js.map +1 -0
- package/bin/adapter/entry-points/console/webServer.js +29 -7
- package/bin/adapter/entry-points/console/webServer.js.map +1 -1
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js +13 -0
- package/bin/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.js.map +1 -1
- package/bin/adapter/entry-points/handlers/staleTmuxSessionCleaner.js +18 -0
- package/bin/adapter/entry-points/handlers/staleTmuxSessionCleaner.js.map +1 -0
- package/bin/adapter/repositories/NodeTmuxSessionRepository.js +22 -0
- package/bin/adapter/repositories/NodeTmuxSessionRepository.js.map +1 -1
- package/bin/domain/entities/LiveTmuxSession.js +3 -0
- package/bin/domain/entities/LiveTmuxSession.js.map +1 -0
- package/bin/domain/usecases/StaleTmuxSessionKillUseCase.js +58 -0
- package/bin/domain/usecases/StaleTmuxSessionKillUseCase.js.map +1 -0
- package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js +161 -0
- package/bin/domain/usecases/dashboard/ComposeDashboardUseCase.js.map +1 -0
- package/package.json +1 -1
- package/src/adapter/entry-points/cli/index.ts +36 -2
- package/src/adapter/entry-points/console/dashboardComposeService.test.ts +443 -0
- package/src/adapter/entry-points/console/dashboardComposeService.ts +200 -0
- package/src/adapter/entry-points/console/ui/e2e/consoleTestHarness.ts +2 -0
- package/src/adapter/entry-points/console/webServer.test.ts +255 -54
- package/src/adapter/entry-points/console/webServer.ts +43 -10
- package/src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts +17 -0
- package/src/adapter/entry-points/handlers/staleTmuxSessionCleaner.test.ts +170 -0
- package/src/adapter/entry-points/handlers/staleTmuxSessionCleaner.ts +40 -0
- package/src/adapter/repositories/NodeTmuxSessionRepository.test.ts +81 -0
- package/src/adapter/repositories/NodeTmuxSessionRepository.ts +35 -0
- package/src/domain/entities/LiveTmuxSession.ts +4 -0
- package/src/domain/usecases/StaleTmuxSessionKillUseCase.test.ts +286 -0
- package/src/domain/usecases/StaleTmuxSessionKillUseCase.ts +102 -0
- package/src/domain/usecases/adapter-interfaces/TmuxSessionRepository.ts +4 -0
- package/src/domain/usecases/dashboard/ComposeDashboardUseCase.test.ts +405 -0
- package/src/domain/usecases/dashboard/ComposeDashboardUseCase.ts +220 -0
- package/src/domain/usecases/intmux/InTmuxByHumanSessionReconcileUseCase.test.ts +6 -0
- package/types/adapter/entry-points/cli/index.d.ts.map +1 -1
- package/types/adapter/entry-points/console/dashboardComposeService.d.ts +9 -0
- package/types/adapter/entry-points/console/dashboardComposeService.d.ts.map +1 -0
- package/types/adapter/entry-points/console/webServer.d.ts +4 -0
- package/types/adapter/entry-points/console/webServer.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.d.ts.map +1 -1
- package/types/adapter/entry-points/handlers/staleTmuxSessionCleaner.d.ts +12 -0
- package/types/adapter/entry-points/handlers/staleTmuxSessionCleaner.d.ts.map +1 -0
- package/types/adapter/repositories/NodeTmuxSessionRepository.d.ts +3 -0
- package/types/adapter/repositories/NodeTmuxSessionRepository.d.ts.map +1 -1
- package/types/domain/entities/LiveTmuxSession.d.ts +5 -0
- package/types/domain/entities/LiveTmuxSession.d.ts.map +1 -0
- package/types/domain/usecases/StaleTmuxSessionKillUseCase.d.ts +19 -0
- package/types/domain/usecases/StaleTmuxSessionKillUseCase.d.ts.map +1 -0
- package/types/domain/usecases/adapter-interfaces/TmuxSessionRepository.d.ts +3 -0
- package/types/domain/usecases/adapter-interfaces/TmuxSessionRepository.d.ts.map +1 -1
- package/types/domain/usecases/dashboard/ComposeDashboardUseCase.d.ts +28 -0
- package/types/domain/usecases/dashboard/ComposeDashboardUseCase.d.ts.map +1 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { DashboardRow } from './GenerateDashboardRowUseCase';
|
|
2
|
+
import { TokenStatus, TokenStatusColor } from './GenerateTokenStatusUseCase';
|
|
3
|
+
|
|
4
|
+
export const PROJECT_ROW_WIDTH_BUDGET = 32;
|
|
5
|
+
|
|
6
|
+
export type ComposeDashboardProject = {
|
|
7
|
+
code: string;
|
|
8
|
+
row: DashboardRow | null;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type ComposeDashboardMachineStatus = {
|
|
12
|
+
memPct: number | null;
|
|
13
|
+
cpuPct: number | null;
|
|
14
|
+
load: [number, number, number] | null;
|
|
15
|
+
cycleMinutes: number | null;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type ComposeDashboardInput = {
|
|
19
|
+
projects: ComposeDashboardProject[];
|
|
20
|
+
machineStatus: ComposeDashboardMachineStatus | null;
|
|
21
|
+
tokens: TokenStatus[];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type ProjectColumn = {
|
|
25
|
+
header: string;
|
|
26
|
+
key: keyof DashboardRow;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const PROJECT_COLUMNS: ProjectColumn[] = [
|
|
30
|
+
{ header: 'unr', key: 'unread' },
|
|
31
|
+
{ header: 'tdo', key: 'todo' },
|
|
32
|
+
{ header: 'aqc', key: 'qc' },
|
|
33
|
+
{ header: 'fal', key: 'fail' },
|
|
34
|
+
{ header: 'prp', key: 'pr' },
|
|
35
|
+
{ header: 'aws', key: 'ws' },
|
|
36
|
+
{ header: 'dep', key: 'dep' },
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const PROJECT_COLUMN_WIDTH = 3;
|
|
40
|
+
|
|
41
|
+
const SEVERITY_BLANK = ' ';
|
|
42
|
+
|
|
43
|
+
const TOKEN_COLOR_DOT: Record<TokenStatusColor, string> = {
|
|
44
|
+
G: '🟢',
|
|
45
|
+
Y: '🟡',
|
|
46
|
+
K: '⚪',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const padEnd = (value: string, width: number, fill: string): string => {
|
|
50
|
+
let result = value;
|
|
51
|
+
while (result.length < width) {
|
|
52
|
+
result = result + fill;
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const padStart = (value: string, width: number): string => {
|
|
58
|
+
let result = value;
|
|
59
|
+
while (result.length < width) {
|
|
60
|
+
result = ' ' + result;
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const padStartZero = (value: string, width: number): string => {
|
|
66
|
+
let result = value;
|
|
67
|
+
while (result.length < width) {
|
|
68
|
+
result = '0' + result;
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const roundHalfToEven = (value: number): number => {
|
|
74
|
+
const floor = Math.floor(value);
|
|
75
|
+
const difference = value - floor;
|
|
76
|
+
if (difference < 0.5) {
|
|
77
|
+
return floor;
|
|
78
|
+
}
|
|
79
|
+
if (difference > 0.5) {
|
|
80
|
+
return floor + 1;
|
|
81
|
+
}
|
|
82
|
+
return floor % 2 === 0 ? floor : floor + 1;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const formatResetCountdown = (totalSeconds: number): string => {
|
|
86
|
+
if (totalSeconds < 0) {
|
|
87
|
+
return '0d00h00';
|
|
88
|
+
}
|
|
89
|
+
const whole = Math.trunc(totalSeconds);
|
|
90
|
+
const days = Math.trunc(whole / 86400);
|
|
91
|
+
const afterDays = whole % 86400;
|
|
92
|
+
const hours = Math.trunc(afterDays / 3600);
|
|
93
|
+
const minutes = Math.trunc((afterDays % 3600) / 60);
|
|
94
|
+
return `${days}d${padStartZero(String(hours), 2)}h${padStartZero(
|
|
95
|
+
String(minutes),
|
|
96
|
+
2,
|
|
97
|
+
)}`;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const formatMachineStatusLine = (
|
|
101
|
+
machineStatus: ComposeDashboardMachineStatus | null,
|
|
102
|
+
): string => {
|
|
103
|
+
const memText =
|
|
104
|
+
machineStatus !== null && machineStatus.memPct !== null
|
|
105
|
+
? `${machineStatus.memPct}%`
|
|
106
|
+
: '?%';
|
|
107
|
+
const cpuText =
|
|
108
|
+
machineStatus !== null && machineStatus.cpuPct !== null
|
|
109
|
+
? `${machineStatus.cpuPct}%`
|
|
110
|
+
: '?%';
|
|
111
|
+
const load = machineStatus !== null ? machineStatus.load : null;
|
|
112
|
+
const oneMinute = load === null ? '?' : String(roundHalfToEven(load[0]));
|
|
113
|
+
const fiveMinute = load === null ? '?' : String(roundHalfToEven(load[1]));
|
|
114
|
+
const fifteenMinute = load === null ? '?' : String(roundHalfToEven(load[2]));
|
|
115
|
+
const cycle =
|
|
116
|
+
machineStatus !== null && machineStatus.cycleMinutes !== null
|
|
117
|
+
? `cy${machineStatus.cycleMinutes}`
|
|
118
|
+
: 'cy-';
|
|
119
|
+
return `M${memText} C${cpuText} LA ${oneMinute} ${fiveMinute} ${fifteenMinute} ${cycle}`;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const capThreeDigits = (value: number): string =>
|
|
123
|
+
value > 999 ? '999' : String(value);
|
|
124
|
+
|
|
125
|
+
export const formatProjectHeaderLine = (): string => {
|
|
126
|
+
const head = padEnd('pj', 4, ' ');
|
|
127
|
+
const columns = PROJECT_COLUMNS.map(
|
|
128
|
+
(column) => ' ' + padStart(column.header, PROJECT_COLUMN_WIDTH),
|
|
129
|
+
).join('');
|
|
130
|
+
return head + columns;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const severityDot = (row: DashboardRow): string => {
|
|
134
|
+
if (row.blocker >= 2) {
|
|
135
|
+
return '🔴';
|
|
136
|
+
}
|
|
137
|
+
if (row.blocker === 1) {
|
|
138
|
+
return '🟣';
|
|
139
|
+
}
|
|
140
|
+
if (row.unread >= 10 || row.qc >= 15 || row.fail >= 5) {
|
|
141
|
+
return '🟠';
|
|
142
|
+
}
|
|
143
|
+
if (row.unread >= 5 || row.qc >= 10 || row.fail >= 3) {
|
|
144
|
+
return '🟡';
|
|
145
|
+
}
|
|
146
|
+
return '🟢';
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export const formatProjectRowLine = (
|
|
150
|
+
project: ComposeDashboardProject,
|
|
151
|
+
): string => {
|
|
152
|
+
const mark = project.row === null ? SEVERITY_BLANK : severityDot(project.row);
|
|
153
|
+
const cells = PROJECT_COLUMNS.map((column) => {
|
|
154
|
+
const cell =
|
|
155
|
+
project.row === null ? '--' : capThreeDigits(project.row[column.key]);
|
|
156
|
+
return ' ' + padStart(cell, PROJECT_COLUMN_WIDTH);
|
|
157
|
+
}).join('');
|
|
158
|
+
return mark + padEnd(project.code, 2, ' ') + cells;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const formatUtilization = (percent: number | null): string =>
|
|
162
|
+
padStart(percent === null ? '?' : `${percent}%`, 4);
|
|
163
|
+
|
|
164
|
+
const formatReset = (resetSeconds: number | null): string =>
|
|
165
|
+
resetSeconds === null ? '?' : formatResetCountdown(resetSeconds);
|
|
166
|
+
|
|
167
|
+
const tokenSortKey = (token: TokenStatus): [number, number] =>
|
|
168
|
+
token.sevenDayResetSeconds === null
|
|
169
|
+
? [1, 0]
|
|
170
|
+
: [0, token.sevenDayResetSeconds];
|
|
171
|
+
|
|
172
|
+
const sortTokens = (tokens: TokenStatus[]): TokenStatus[] =>
|
|
173
|
+
tokens
|
|
174
|
+
.map((token, index) => ({ token, index }))
|
|
175
|
+
.sort((left, right) => {
|
|
176
|
+
const leftKey = tokenSortKey(left.token);
|
|
177
|
+
const rightKey = tokenSortKey(right.token);
|
|
178
|
+
if (leftKey[0] !== rightKey[0]) {
|
|
179
|
+
return leftKey[0] - rightKey[0];
|
|
180
|
+
}
|
|
181
|
+
if (leftKey[1] !== rightKey[1]) {
|
|
182
|
+
return leftKey[1] - rightKey[1];
|
|
183
|
+
}
|
|
184
|
+
return left.index - right.index;
|
|
185
|
+
})
|
|
186
|
+
.map((entry) => entry.token);
|
|
187
|
+
|
|
188
|
+
export const formatTokenRowLine = (token: TokenStatus): string => {
|
|
189
|
+
const dot = TOKEN_COLOR_DOT[token.color];
|
|
190
|
+
const name = padEnd(token.name, 4, '_');
|
|
191
|
+
const fiveHourUtilization = formatUtilization(
|
|
192
|
+
token.fiveHourUtilizationPercent,
|
|
193
|
+
);
|
|
194
|
+
const fiveHourReset = formatReset(token.fiveHourResetSeconds);
|
|
195
|
+
const sevenDayUtilization = formatUtilization(
|
|
196
|
+
token.sevenDayUtilizationPercent,
|
|
197
|
+
);
|
|
198
|
+
const sevenDayReset = formatReset(token.sevenDayResetSeconds);
|
|
199
|
+
const prep = String(token.prep);
|
|
200
|
+
const hum = String(token.hum);
|
|
201
|
+
return `${dot}${name} ${fiveHourUtilization} ${fiveHourReset} ${sevenDayUtilization} ${sevenDayReset} ${prep} ${hum}`;
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const wrapLine = (line: string): string =>
|
|
205
|
+
`<tt>${line.replace(/ /g, ' ')}</tt><br>`;
|
|
206
|
+
|
|
207
|
+
export class ComposeDashboardUseCase {
|
|
208
|
+
run = (input: ComposeDashboardInput): string => {
|
|
209
|
+
const statsLine = formatMachineStatusLine(input.machineStatus);
|
|
210
|
+
const projectLines = [
|
|
211
|
+
formatProjectHeaderLine(),
|
|
212
|
+
...input.projects.map((project) => formatProjectRowLine(project)),
|
|
213
|
+
];
|
|
214
|
+
const tokenLines = sortTokens(input.tokens).map((token) =>
|
|
215
|
+
formatTokenRowLine(token),
|
|
216
|
+
);
|
|
217
|
+
const lines = [statsLine, ...projectLines, '', ...tokenLines];
|
|
218
|
+
return lines.map((line) => wrapLine(line)).join('\n') + '\n';
|
|
219
|
+
};
|
|
220
|
+
}
|
|
@@ -60,10 +60,16 @@ const createFakeTmuxSessionRepository = (state: {
|
|
|
60
60
|
return {
|
|
61
61
|
launches,
|
|
62
62
|
listLiveSessionNames: async () => state.liveSessionNames,
|
|
63
|
+
listLiveSessionsWithActivity: async () =>
|
|
64
|
+
state.liveSessionNames.map((sessionName) => ({
|
|
65
|
+
sessionName,
|
|
66
|
+
activityEpochSeconds: 0,
|
|
67
|
+
})),
|
|
63
68
|
listInteractiveProcessCommandLines: async () => state.processCommandLines,
|
|
64
69
|
launchDetachedSession: async (sessionName, launcherCommand, issueUrl) => {
|
|
65
70
|
launches.push({ sessionName, launcherCommand, issueUrl });
|
|
66
71
|
},
|
|
72
|
+
killSession: async () => undefined,
|
|
67
73
|
};
|
|
68
74
|
};
|
|
69
75
|
|
|
@@ -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;
|
|
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;AA+HzB,eAAO,MAAM,OAAO,SAAgB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ComposeDashboardInput } from '../../../domain/usecases/dashboard/ComposeDashboardUseCase';
|
|
2
|
+
export type DashboardComposeOptions = {
|
|
3
|
+
dashboardDataDir: string;
|
|
4
|
+
projectCodes: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare const buildComposeDashboardInput: (options: DashboardComposeOptions) => ComposeDashboardInput;
|
|
7
|
+
export declare const dashboardComposeFilesPresent: (options: DashboardComposeOptions) => boolean;
|
|
8
|
+
export declare const composeDashboardText: (options: DashboardComposeOptions) => string;
|
|
9
|
+
//# sourceMappingURL=dashboardComposeService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboardComposeService.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/dashboardComposeService.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,qBAAqB,EAItB,MAAM,4DAA4D,CAAC;AAOpE,MAAM,MAAM,uBAAuB,GAAG;IACpC,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AA2IF,eAAO,MAAM,0BAA0B,GACrC,SAAS,uBAAuB,KAC/B,qBAYF,CAAC;AAUF,eAAO,MAAM,4BAA4B,GACvC,SAAS,uBAAuB,KAC/B,OAYF,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,uBAAuB,KAC/B,MACqE,CAAC"}
|
|
@@ -4,6 +4,7 @@ import { IssueTitleStateCache } from './consoleReadApi';
|
|
|
4
4
|
import { ConsoleProjectResolver } from './consoleOperationApi';
|
|
5
5
|
import { ImageFetcher } from './consoleImageProxy';
|
|
6
6
|
export declare const DEFAULT_WEB_PORT = 9981;
|
|
7
|
+
export declare const DEFAULT_DASHBOARD_PROJECT_CODES: string[];
|
|
7
8
|
export declare const CONSOLE_TOKEN_HEADER = "x-pv-token";
|
|
8
9
|
export declare const hasDotSegment: (requestPath: string) => boolean;
|
|
9
10
|
export declare const requiresToken: (requestPath: string) => boolean;
|
|
@@ -16,6 +17,8 @@ export type WebServerOptions = {
|
|
|
16
17
|
consoleDataOutputDir: string | null;
|
|
17
18
|
inTmuxDataDir: string | null;
|
|
18
19
|
dashboardDir: string | null;
|
|
20
|
+
dashboardDataDir: string | null;
|
|
21
|
+
dashboardProjectCodes: string[];
|
|
19
22
|
githubToken?: string | null;
|
|
20
23
|
imageFetcher?: ImageFetcher | null;
|
|
21
24
|
issueRepository?: IssueRepository | null;
|
|
@@ -26,6 +29,7 @@ export declare const DASHBOARD_REQUEST_PATH = "/tdpm.txt";
|
|
|
26
29
|
export declare const IMAGE_PROXY_REQUEST_PATH = "/api/img";
|
|
27
30
|
export declare const resolveDashboardFilePath: (dashboardDir: string, requestPath: string) => string | null;
|
|
28
31
|
export declare const resolveFlatInTmuxFilePath: (inTmuxDataDir: string, requestPath: string) => string | null;
|
|
32
|
+
export declare const resolveDashboardContent: (options: WebServerOptions, requestPath: string) => Buffer | null;
|
|
29
33
|
export declare const handleWebRequest: (options: WebServerOptions, request: http.IncomingMessage, response: http.ServerResponse) => Promise<void>;
|
|
30
34
|
export declare const createWebServer: (options: WebServerOptions) => http.Server;
|
|
31
35
|
export type StartWebServerOptions = WebServerOptions & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webServer.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/webServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAC;AAM9F,OAAO,EACL,oBAAoB,EAOrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,sBAAsB,EAMvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAqB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"webServer.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/console/webServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAC;AAM9F,OAAO,EACL,oBAAoB,EAOrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAEL,sBAAsB,EAMvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAqB,MAAM,qBAAqB,CAAC;AAMtE,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAErC,eAAO,MAAM,+BAA+B,UAA2B,CAAC;AAExE,eAAO,MAAM,oBAAoB,eAAe,CAAC;AAmCjD,eAAO,MAAM,aAAa,GAAI,aAAa,MAAM,KAAG,OAGiB,CAAC;AAEtE,eAAO,MAAM,aAAa,GAAI,aAAa,MAAM,KAAG,OAGrB,CAAC;AAIhC,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,KAAG,OAmBvD,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,eAAe,MAAM,EACrB,eAAe,MAAM,GAAG,IAAI,KAC3B,OAAoE,CAAC;AAExE,eAAO,MAAM,oBAAoB,GAC/B,YAAY,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,EACpC,aAAa,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,KACzC,MAAM,GAAG,IAQX,CAAC;AAuCF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACnC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IACzC,cAAc,CAAC,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC/C,oBAAoB,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;CACpD,CAAC;AAMF,eAAO,MAAM,sBAAsB,cAAc,CAAC;AAElD,eAAO,MAAM,wBAAwB,aAAa,CAAC;AAInD,eAAO,MAAM,wBAAwB,GACnC,cAAc,MAAM,EACpB,aAAa,MAAM,KAClB,MAAM,GAAG,IAWX,CAAC;AAEF,eAAO,MAAM,yBAAyB,GACpC,eAAe,MAAM,EACrB,aAAa,MAAM,KAClB,MAAM,GAAG,IAeX,CAAC;AA0UF,eAAO,MAAM,uBAAuB,GAClC,SAAS,gBAAgB,EACzB,aAAa,MAAM,KAClB,MAAM,GAAG,IAeX,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,SAAS,gBAAgB,EACzB,SAAS,IAAI,CAAC,eAAe,EAC7B,UAAU,IAAI,CAAC,cAAc,KAC5B,OAAO,CAAC,IAAI,CAwEd,CAAC;AAcF,eAAO,MAAM,eAAe,GAAI,SAAS,gBAAgB,KAAG,IAAI,CAAC,MAM7D,CAAC;AAEL,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,GAAG;IACrD,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,SAAS,qBAAqB,KAC7B,OAAO,CAAC,IAAI,CAAC,MAAM,CAQlB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"HandleScheduledEventUseCaseHandler.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/HandleScheduledEventUseCaseHandler.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAgC3D,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,CAwcP;CACH"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Project } from '../../../domain/entities/Project';
|
|
2
|
+
import { LocalCommandRunner } from '../../../domain/usecases/adapter-interfaces/LocalCommandRunner';
|
|
3
|
+
import { IssueRepository } from '../../../domain/usecases/adapter-interfaces/IssueRepository';
|
|
4
|
+
export type CleanStaleTmuxSessionsParams = {
|
|
5
|
+
project: Project;
|
|
6
|
+
allowCacheMinutes: number;
|
|
7
|
+
issueRepository: Pick<IssueRepository, 'getAllOpened'>;
|
|
8
|
+
localCommandRunner: LocalCommandRunner;
|
|
9
|
+
now: Date;
|
|
10
|
+
};
|
|
11
|
+
export declare const cleanStaleTmuxSessions: (params: CleanStaleTmuxSessionsParams) => Promise<void>;
|
|
12
|
+
//# sourceMappingURL=staleTmuxSessionCleaner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staleTmuxSessionCleaner.d.ts","sourceRoot":"","sources":["../../../../src/adapter/entry-points/handlers/staleTmuxSessionCleaner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gEAAgE,CAAC;AACpG,OAAO,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAC;AAQ9F,MAAM,MAAM,4BAA4B,GAAG;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;IACvD,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,QAAQ,4BAA4B,KACnC,OAAO,CAAC,IAAI,CAmBd,CAAC"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { LocalCommandRunner } from '../../domain/usecases/adapter-interfaces/LocalCommandRunner';
|
|
2
2
|
import { TmuxSessionRepository } from '../../domain/usecases/adapter-interfaces/TmuxSessionRepository';
|
|
3
|
+
import { LiveTmuxSession } from '../../domain/entities/LiveTmuxSession';
|
|
3
4
|
export declare class NodeTmuxSessionRepository implements TmuxSessionRepository {
|
|
4
5
|
private readonly localCommandRunner;
|
|
5
6
|
constructor(localCommandRunner: LocalCommandRunner);
|
|
6
7
|
listLiveSessionNames: () => Promise<string[]>;
|
|
8
|
+
listLiveSessionsWithActivity: () => Promise<LiveTmuxSession[]>;
|
|
7
9
|
listInteractiveProcessCommandLines: () => Promise<string[]>;
|
|
8
10
|
launchDetachedSession: (sessionName: string, launcherCommand: string, issueUrl: string) => Promise<void>;
|
|
11
|
+
killSession: (sessionName: string) => Promise<void>;
|
|
9
12
|
}
|
|
10
13
|
//# sourceMappingURL=NodeTmuxSessionRepository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeTmuxSessionRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/NodeTmuxSessionRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6DAA6D,CAAC;AACjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gEAAgE,CAAC;
|
|
1
|
+
{"version":3,"file":"NodeTmuxSessionRepository.d.ts","sourceRoot":"","sources":["../../../src/adapter/repositories/NodeTmuxSessionRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,6DAA6D,CAAC;AACjG,OAAO,EAAE,qBAAqB,EAAE,MAAM,gEAAgE,CAAC;AACvG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAExE,qBAAa,yBAA0B,YAAW,qBAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,kBAAkB;IAEnE,oBAAoB,QAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAYhD;IAEF,4BAA4B,QAAa,OAAO,CAAC,eAAe,EAAE,CAAC,CAkBjE;IAEF,kCAAkC,QAAa,OAAO,CAAC,MAAM,EAAE,CAAC,CAY9D;IAEF,qBAAqB,GACnB,aAAa,MAAM,EACnB,iBAAiB,MAAM,EACvB,UAAU,MAAM,KACf,OAAO,CAAC,IAAI,CAAC,CAcd;IAEF,WAAW,GAAU,aAAa,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAYtD;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LiveTmuxSession.d.ts","sourceRoot":"","sources":["../../../src/domain/entities/LiveTmuxSession.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Project } from '../entities/Project';
|
|
2
|
+
import { IssueRepository } from './adapter-interfaces/IssueRepository';
|
|
3
|
+
import { TmuxSessionRepository } from './adapter-interfaces/TmuxSessionRepository';
|
|
4
|
+
export declare const DEFAULT_EXCLUDED_STATUS = "In Tmux by human";
|
|
5
|
+
export declare const DEFAULT_IDLE_THRESHOLD_SECONDS: number;
|
|
6
|
+
export declare class StaleTmuxSessionKillUseCase {
|
|
7
|
+
private readonly issueRepository;
|
|
8
|
+
private readonly tmuxSessionRepository;
|
|
9
|
+
constructor(issueRepository: Pick<IssueRepository, 'getAllOpened'>, tmuxSessionRepository: Pick<TmuxSessionRepository, 'listLiveSessionsWithActivity' | 'killSession'>);
|
|
10
|
+
run: (params: {
|
|
11
|
+
project: Project;
|
|
12
|
+
allowCacheMinutes: number;
|
|
13
|
+
excludedStatus: string;
|
|
14
|
+
idleThresholdSeconds: number;
|
|
15
|
+
now: Date;
|
|
16
|
+
}) => Promise<void>;
|
|
17
|
+
private evaluateKillReason;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=StaleTmuxSessionKillUseCase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StaleTmuxSessionKillUseCase.d.ts","sourceRoot":"","sources":["../../../src/domain/usecases/StaleTmuxSessionKillUseCase.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AAGnF,eAAO,MAAM,uBAAuB,qBAAsB,CAAC;AAC3D,eAAO,MAAM,8BAA8B,QAAe,CAAC;AAO3D,qBAAa,2BAA2B;IAEpC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBADrB,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,cAAc,CAAC,EACtD,qBAAqB,EAAE,IAAI,CAC1C,qBAAqB,EACrB,8BAA8B,GAAG,aAAa,CAC/C;IAGH,GAAG,GAAU,QAAQ;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,cAAc,EAAE,MAAM,CAAC;QACvB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,GAAG,EAAE,IAAI,CAAC;KACX,KAAG,OAAO,CAAC,IAAI,CAAC,CA0Cf;IAEF,OAAO,CAAC,kBAAkB,CAyBxB;CACH"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { LiveTmuxSession } from '../../entities/LiveTmuxSession';
|
|
1
2
|
export interface TmuxSessionRepository {
|
|
2
3
|
listLiveSessionNames: () => Promise<string[]>;
|
|
4
|
+
listLiveSessionsWithActivity: () => Promise<LiveTmuxSession[]>;
|
|
3
5
|
listInteractiveProcessCommandLines: () => Promise<string[]>;
|
|
4
6
|
launchDetachedSession: (sessionName: string, launcherCommand: string, issueUrl: string) => Promise<void>;
|
|
7
|
+
killSession: (sessionName: string) => Promise<void>;
|
|
5
8
|
}
|
|
6
9
|
//# sourceMappingURL=TmuxSessionRepository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TmuxSessionRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/TmuxSessionRepository.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,oBAAoB,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9C,kCAAkC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5D,qBAAqB,EAAE,CACrB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"TmuxSessionRepository.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/adapter-interfaces/TmuxSessionRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE,MAAM,WAAW,qBAAqB;IACpC,oBAAoB,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9C,4BAA4B,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC/D,kCAAkC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5D,qBAAqB,EAAE,CACrB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { DashboardRow } from './GenerateDashboardRowUseCase';
|
|
2
|
+
import { TokenStatus } from './GenerateTokenStatusUseCase';
|
|
3
|
+
export declare const PROJECT_ROW_WIDTH_BUDGET = 32;
|
|
4
|
+
export type ComposeDashboardProject = {
|
|
5
|
+
code: string;
|
|
6
|
+
row: DashboardRow | null;
|
|
7
|
+
};
|
|
8
|
+
export type ComposeDashboardMachineStatus = {
|
|
9
|
+
memPct: number | null;
|
|
10
|
+
cpuPct: number | null;
|
|
11
|
+
load: [number, number, number] | null;
|
|
12
|
+
cycleMinutes: number | null;
|
|
13
|
+
};
|
|
14
|
+
export type ComposeDashboardInput = {
|
|
15
|
+
projects: ComposeDashboardProject[];
|
|
16
|
+
machineStatus: ComposeDashboardMachineStatus | null;
|
|
17
|
+
tokens: TokenStatus[];
|
|
18
|
+
};
|
|
19
|
+
export declare const roundHalfToEven: (value: number) => number;
|
|
20
|
+
export declare const formatResetCountdown: (totalSeconds: number) => string;
|
|
21
|
+
export declare const formatMachineStatusLine: (machineStatus: ComposeDashboardMachineStatus | null) => string;
|
|
22
|
+
export declare const formatProjectHeaderLine: () => string;
|
|
23
|
+
export declare const formatProjectRowLine: (project: ComposeDashboardProject) => string;
|
|
24
|
+
export declare const formatTokenRowLine: (token: TokenStatus) => string;
|
|
25
|
+
export declare class ComposeDashboardUseCase {
|
|
26
|
+
run: (input: ComposeDashboardInput) => string;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=ComposeDashboardUseCase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComposeDashboardUseCase.d.ts","sourceRoot":"","sources":["../../../../src/domain/usecases/dashboard/ComposeDashboardUseCase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAoB,MAAM,8BAA8B,CAAC;AAE7E,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,YAAY,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACtC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,uBAAuB,EAAE,CAAC;IACpC,aAAa,EAAE,6BAA6B,GAAG,IAAI,CAAC;IACpD,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC;AAmDF,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,KAAG,MAU/C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,cAAc,MAAM,KAAG,MAa3D,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAClC,eAAe,6BAA6B,GAAG,IAAI,KAClD,MAkBF,CAAC;AAKF,eAAO,MAAM,uBAAuB,QAAO,MAM1C,CAAC;AAkBF,eAAO,MAAM,oBAAoB,GAC/B,SAAS,uBAAuB,KAC/B,MAQF,CAAC;AA6BF,eAAO,MAAM,kBAAkB,GAAI,OAAO,WAAW,KAAG,MAcvD,CAAC;AAKF,qBAAa,uBAAuB;IAClC,GAAG,GAAI,OAAO,qBAAqB,KAAG,MAAM,CAW1C;CACH"}
|