workday-daemon 0.1.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/README.md +95 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +710 -0
- package/dist/cli.js.map +1 -0
- package/dist/collectors/git-client.d.ts +16 -0
- package/dist/collectors/git-client.js +58 -0
- package/dist/collectors/git-client.js.map +1 -0
- package/dist/collectors/git-tracker.d.ts +43 -0
- package/dist/collectors/git-tracker.js +168 -0
- package/dist/collectors/git-tracker.js.map +1 -0
- package/dist/collectors/reflog-parser.d.ts +30 -0
- package/dist/collectors/reflog-parser.js +71 -0
- package/dist/collectors/reflog-parser.js.map +1 -0
- package/dist/collectors/snapshot-parser.d.ts +34 -0
- package/dist/collectors/snapshot-parser.js +79 -0
- package/dist/collectors/snapshot-parser.js.map +1 -0
- package/dist/core/activity-evaluator.d.ts +33 -0
- package/dist/core/activity-evaluator.js +94 -0
- package/dist/core/activity-evaluator.js.map +1 -0
- package/dist/core/config.d.ts +18 -0
- package/dist/core/config.js +174 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/constants.d.ts +39 -0
- package/dist/core/constants.js +51 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/daily-log.d.ts +56 -0
- package/dist/core/daily-log.js +366 -0
- package/dist/core/daily-log.js.map +1 -0
- package/dist/core/session-tracker.d.ts +110 -0
- package/dist/core/session-tracker.js +460 -0
- package/dist/core/session-tracker.js.map +1 -0
- package/dist/core/status-renderer.d.ts +20 -0
- package/dist/core/status-renderer.js +178 -0
- package/dist/core/status-renderer.js.map +1 -0
- package/dist/core/types.d.ts +320 -0
- package/dist/core/types.js +52 -0
- package/dist/core/types.js.map +1 -0
- package/dist/daemon.d.ts +31 -0
- package/dist/daemon.js +266 -0
- package/dist/daemon.js.map +1 -0
- package/dist/http-server.d.ts +30 -0
- package/dist/http-server.js +342 -0
- package/dist/http-server.js.map +1 -0
- package/dist/push/jira-client.d.ts +5 -0
- package/dist/push/jira-client.js +84 -0
- package/dist/push/jira-client.js.map +1 -0
- package/dist/push/report-builder.d.ts +9 -0
- package/dist/push/report-builder.js +77 -0
- package/dist/push/report-builder.js.map +1 -0
- package/dist/push/tempo-client.d.ts +27 -0
- package/dist/push/tempo-client.js +92 -0
- package/dist/push/tempo-client.js.map +1 -0
- package/dist/push/tempo-pusher.d.ts +17 -0
- package/dist/push/tempo-pusher.js +317 -0
- package/dist/push/tempo-pusher.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
import { SessionState, ClosedBy, SignalType, PauseSource } from './types.js';
|
|
3
|
+
import { generateSessionId, createEmptyEvidence, createEmptyLog, writeDailyLog, addSignal, isBudgetExhausted, addManualAdjustment, setDayManualStart, resolveSessionTarget, computeManualMinutes, getRemainingBudgetMs, getOpenPause, } from './daily-log.js';
|
|
4
|
+
import { computeWorkingDate } from './config.js';
|
|
5
|
+
/**
|
|
6
|
+
* Manages session lifecycle within a DailyLog.
|
|
7
|
+
*
|
|
8
|
+
* Responsibilities:
|
|
9
|
+
* - Opens/closes/updates sessions based on PollResult from GitTracker
|
|
10
|
+
* - Handles task switches (close old → open new)
|
|
11
|
+
* - Handles day boundary (close all → start fresh)
|
|
12
|
+
* - Logs signals (diff_dynamics, commit, checkout)
|
|
13
|
+
* - Credits evidence counters to sessions
|
|
14
|
+
* - Supports crash recovery (resume open sessions from disk)
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* const tracker = new SessionTracker(config);
|
|
18
|
+
* // or with crash recovery:
|
|
19
|
+
* const tracker = new SessionTracker(config, existingLog);
|
|
20
|
+
*
|
|
21
|
+
* // each poll tick:
|
|
22
|
+
* for (const result of pollResults) {
|
|
23
|
+
* tracker.processPollResult(result);
|
|
24
|
+
* }
|
|
25
|
+
* tracker.flush();
|
|
26
|
+
*/
|
|
27
|
+
export class SessionTracker {
|
|
28
|
+
dailyLog;
|
|
29
|
+
config;
|
|
30
|
+
autoPauseDisabledSessions = new Set();
|
|
31
|
+
lastEvaluatorResult = null;
|
|
32
|
+
onSessionClosed = null;
|
|
33
|
+
constructor(config, initialLog) {
|
|
34
|
+
const today = computeWorkingDate(Date.now(), config.dayBoundaryHour, config.timezone);
|
|
35
|
+
this.config = config;
|
|
36
|
+
this.dailyLog = initialLog ?? createEmptyLog(today, config);
|
|
37
|
+
// Normalize old logs that lack new fields
|
|
38
|
+
if (this.dailyLog.dayStartedAt === undefined) {
|
|
39
|
+
this.dailyLog.dayStartedAt = null;
|
|
40
|
+
}
|
|
41
|
+
// Normalize old sessions that lack new fields
|
|
42
|
+
for (const session of this.dailyLog.sessions) {
|
|
43
|
+
if (!session.pauses)
|
|
44
|
+
session.pauses = [];
|
|
45
|
+
if (!session.manualAdjustments)
|
|
46
|
+
session.manualAdjustments = [];
|
|
47
|
+
if (session.activatedAt === undefined)
|
|
48
|
+
session.activatedAt = null;
|
|
49
|
+
if (session.evidence.linesAdded === undefined)
|
|
50
|
+
session.evidence.linesAdded = 0;
|
|
51
|
+
if (session.evidence.linesRemoved === undefined)
|
|
52
|
+
session.evidence.linesRemoved = 0;
|
|
53
|
+
if (session.evidence.filesChanged === undefined)
|
|
54
|
+
session.evidence.filesChanged = 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
getDailyLog() {
|
|
58
|
+
return this.dailyLog;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Process one poll tick for a single repo.
|
|
62
|
+
*
|
|
63
|
+
* Flow:
|
|
64
|
+
* 1. Credit reflog evidence to current open session (before any close)
|
|
65
|
+
* 2. Log signals (dynamics, commits, checkouts)
|
|
66
|
+
* 3. Handle session lifecycle (close/open/switch)
|
|
67
|
+
* 4. Update session tick (lastSeenAt, evidence, promote PENDING→ACTIVE)
|
|
68
|
+
*/
|
|
69
|
+
processPollResult(result) {
|
|
70
|
+
if (this.isBudgetExhausted())
|
|
71
|
+
return;
|
|
72
|
+
const now = new Date().toISOString();
|
|
73
|
+
const repoName = basename(result.repoPath);
|
|
74
|
+
let openSession = this.findOpenSession(repoName);
|
|
75
|
+
// Pause handling
|
|
76
|
+
if (openSession && this.hasOpenPause(openSession)) {
|
|
77
|
+
const pauseSource = this.getOpenPauseSource(openSession);
|
|
78
|
+
const hasActivity = result.delta.hasDynamics || result.newReflogEntries.some(e => e.type === 'commit');
|
|
79
|
+
if (pauseSource === PauseSource.Manual) {
|
|
80
|
+
if (hasActivity) {
|
|
81
|
+
// Auto-resume: developer forgot to resume, close pause and continue
|
|
82
|
+
this.closeOpenPause(openSession, now);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// Manual pause, no activity — full freeze
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Auto-pauses (IdleTimeout/Superseded) — fall through, normal processing
|
|
90
|
+
}
|
|
91
|
+
// 1. Credit reflog evidence to current open session before potential close
|
|
92
|
+
if (openSession && result.newReflogEntries.length > 0) {
|
|
93
|
+
this.creditReflogEvidence(openSession, result.newReflogEntries);
|
|
94
|
+
}
|
|
95
|
+
// 2. Log signals
|
|
96
|
+
this.logSignals(repoName, result);
|
|
97
|
+
// 3. Handle session lifecycle
|
|
98
|
+
if (result.task === null) {
|
|
99
|
+
// Not on developer's branch → close if open
|
|
100
|
+
if (openSession) {
|
|
101
|
+
this.closeSession(openSession, ClosedBy.CheckoutOtherTask, now);
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (openSession && openSession.task !== result.task) {
|
|
106
|
+
// Task changed → close old, will open new below
|
|
107
|
+
this.closeSession(openSession, ClosedBy.CheckoutOtherTask, now);
|
|
108
|
+
openSession = null;
|
|
109
|
+
}
|
|
110
|
+
if (!openSession) {
|
|
111
|
+
openSession = this.openSession(repoName, result.task, result.branch, now);
|
|
112
|
+
}
|
|
113
|
+
// 4. Update session with current tick data
|
|
114
|
+
this.updateSessionTick(openSession, result, now);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Close orphaned sessions from a previous daemon crash.
|
|
118
|
+
* Preserves saved lastSeenAt (last known poll time, at most ~30s before crash).
|
|
119
|
+
*/
|
|
120
|
+
closeCrashedSessions() {
|
|
121
|
+
let count = 0;
|
|
122
|
+
for (const session of this.dailyLog.sessions) {
|
|
123
|
+
if (!session.closedBy) {
|
|
124
|
+
this.closeOpenPause(session, session.lastSeenAt);
|
|
125
|
+
session.closedBy = ClosedBy.DaemonCrash;
|
|
126
|
+
count++;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return count;
|
|
130
|
+
}
|
|
131
|
+
/** Close all open sessions with given reason */
|
|
132
|
+
closeAllSessions(reason) {
|
|
133
|
+
const now = new Date().toISOString();
|
|
134
|
+
for (const session of this.dailyLog.sessions) {
|
|
135
|
+
if (!session.closedBy) {
|
|
136
|
+
this.closeSession(session, reason, now);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Handle day boundary: close all sessions, return completed log, start fresh.
|
|
142
|
+
* Caller should flush the returned log to disk.
|
|
143
|
+
*/
|
|
144
|
+
handleDayBoundary() {
|
|
145
|
+
this.closeAllSessions(ClosedBy.DayBoundary);
|
|
146
|
+
const completedLog = this.dailyLog;
|
|
147
|
+
const newDate = computeWorkingDate(Date.now(), this.config.dayBoundaryHour, this.config.timezone);
|
|
148
|
+
this.dailyLog = createEmptyLog(newDate, this.config);
|
|
149
|
+
this.autoPauseDisabledSessions.clear();
|
|
150
|
+
this.lastEvaluatorResult = null;
|
|
151
|
+
return completedLog;
|
|
152
|
+
}
|
|
153
|
+
/** Mark manual start of workday */
|
|
154
|
+
setManualStart(timestamp) {
|
|
155
|
+
this.dailyLog.manualStart = timestamp;
|
|
156
|
+
}
|
|
157
|
+
/** Set dayStartedAt (called by daemon on startup) */
|
|
158
|
+
setDayStartedAt(timestamp) {
|
|
159
|
+
if (!this.dailyLog.dayStartedAt) {
|
|
160
|
+
this.dailyLog.dayStartedAt = timestamp;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// ─── Budget ────────────────────────────────────────────────────────────
|
|
164
|
+
/** Check if budget is exhausted */
|
|
165
|
+
isBudgetExhausted() {
|
|
166
|
+
return isBudgetExhausted(this.dailyLog, this.config);
|
|
167
|
+
}
|
|
168
|
+
/** Close all open sessions with BudgetExhausted */
|
|
169
|
+
closeBudgetExhausted() {
|
|
170
|
+
this.closeAllSessions(ClosedBy.BudgetExhausted);
|
|
171
|
+
}
|
|
172
|
+
/** Add manual time adjustment to a session */
|
|
173
|
+
addAdjustment(target, minutes, reason) {
|
|
174
|
+
const session = resolveSessionTarget(this.dailyLog, target);
|
|
175
|
+
if (!session) {
|
|
176
|
+
return { ok: false, error: `Session not found: ${target}` };
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
addManualAdjustment(this.dailyLog, session.id, minutes, reason, this.config);
|
|
180
|
+
return { ok: true, sessionId: session.id };
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/** Set manual day start */
|
|
187
|
+
setManualDayStart(isoTimestamp) {
|
|
188
|
+
try {
|
|
189
|
+
setDayManualStart(this.dailyLog, isoTimestamp, this.config);
|
|
190
|
+
return { ok: true };
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/** Get remaining budget in ms */
|
|
197
|
+
getRemainingBudgetMs() {
|
|
198
|
+
return getRemainingBudgetMs(this.dailyLog, this.config);
|
|
199
|
+
}
|
|
200
|
+
/** Get manual minutes for a session */
|
|
201
|
+
getManualMinutes(session) {
|
|
202
|
+
return computeManualMinutes(session);
|
|
203
|
+
}
|
|
204
|
+
/** Write current daily log to disk (atomic) */
|
|
205
|
+
flush() {
|
|
206
|
+
writeDailyLog(this.dailyLog);
|
|
207
|
+
}
|
|
208
|
+
/** Get summary of open sessions (for status display) */
|
|
209
|
+
getOpenSessions() {
|
|
210
|
+
return this.dailyLog.sessions.filter(s => !s.closedBy);
|
|
211
|
+
}
|
|
212
|
+
// ─── Evaluator integration ────────────────────────────────────────────
|
|
213
|
+
/** Build TickInput[] for all open sessions (except manually paused) */
|
|
214
|
+
buildTickInputs(pollResults) {
|
|
215
|
+
const resultMap = new Map();
|
|
216
|
+
for (const r of pollResults) {
|
|
217
|
+
resultMap.set(basename(r.repoPath), r);
|
|
218
|
+
}
|
|
219
|
+
const ticks = [];
|
|
220
|
+
for (const session of this.dailyLog.sessions) {
|
|
221
|
+
if (session.closedBy)
|
|
222
|
+
continue;
|
|
223
|
+
// Manually paused sessions are frozen — don't send to evaluator
|
|
224
|
+
if (this.hasOpenPause(session) && this.getOpenPauseSource(session) === PauseSource.Manual) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const poll = resultMap.get(session.repo);
|
|
228
|
+
const signals = poll
|
|
229
|
+
? {
|
|
230
|
+
hasDynamics: poll.delta.hasDynamics,
|
|
231
|
+
hasCommit: poll.newReflogEntries.some(e => e.type === 'commit'),
|
|
232
|
+
deltaMagnitude: Math.abs(poll.delta.addedDelta) + Math.abs(poll.delta.removedDelta),
|
|
233
|
+
}
|
|
234
|
+
: { hasDynamics: false, hasCommit: false, deltaMagnitude: 0 };
|
|
235
|
+
ticks.push({
|
|
236
|
+
sessionId: session.id,
|
|
237
|
+
signals,
|
|
238
|
+
autoPauseDisabled: this.autoPauseDisabledSessions.has(session.id),
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
return ticks;
|
|
242
|
+
}
|
|
243
|
+
/** Apply evaluator results: auto-pause, auto-resume, Pending→Active promotion */
|
|
244
|
+
applyEvaluatorResult(result) {
|
|
245
|
+
this.lastEvaluatorResult = result;
|
|
246
|
+
const now = new Date().toISOString();
|
|
247
|
+
for (const session of this.dailyLog.sessions) {
|
|
248
|
+
if (session.closedBy)
|
|
249
|
+
continue;
|
|
250
|
+
const sessionScore = result.scores.get(session.id);
|
|
251
|
+
if (!sessionScore)
|
|
252
|
+
continue; // manually paused, not in evaluator
|
|
253
|
+
const isLeader = result.leaderId === session.id;
|
|
254
|
+
if (session.state === SessionState.Active) {
|
|
255
|
+
if (isLeader) {
|
|
256
|
+
// Leader — close any auto-pause
|
|
257
|
+
this.closeAutoPause(session, now);
|
|
258
|
+
}
|
|
259
|
+
else if (sessionScore.isIdleTimeout) {
|
|
260
|
+
// score == 0 → IdleTimeout (unless autopause disabled)
|
|
261
|
+
if (!this.autoPauseDisabledSessions.has(session.id)) {
|
|
262
|
+
this.applyAutoPause(session, PauseSource.IdleTimeout, now);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
// score > 0 but not leader → Superseded
|
|
267
|
+
this.applyAutoPause(session, PauseSource.Superseded, now);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
else if (session.state === SessionState.Pending) {
|
|
271
|
+
// Pending → Active: score > 0 AND is leader
|
|
272
|
+
if (sessionScore.score > 0 && isLeader) {
|
|
273
|
+
session.state = SessionState.Active;
|
|
274
|
+
session.activatedAt = now;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
getLastEvaluatorResult() {
|
|
280
|
+
return this.lastEvaluatorResult;
|
|
281
|
+
}
|
|
282
|
+
// ─── Autopause management ────────────────────────────────────────────
|
|
283
|
+
/** Toggle autopause for a specific repo or all repos. Returns affected repo names. */
|
|
284
|
+
setAutoPauseDisabled(disabled, repoName) {
|
|
285
|
+
const affected = [];
|
|
286
|
+
for (const session of this.dailyLog.sessions) {
|
|
287
|
+
if (session.closedBy)
|
|
288
|
+
continue;
|
|
289
|
+
if (repoName && session.repo !== repoName)
|
|
290
|
+
continue;
|
|
291
|
+
if (disabled) {
|
|
292
|
+
this.autoPauseDisabledSessions.add(session.id);
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
this.autoPauseDisabledSessions.delete(session.id);
|
|
296
|
+
}
|
|
297
|
+
affected.push(session.repo);
|
|
298
|
+
}
|
|
299
|
+
return affected;
|
|
300
|
+
}
|
|
301
|
+
isAutoPauseDisabled(sessionId) {
|
|
302
|
+
return this.autoPauseDisabledSessions.has(sessionId);
|
|
303
|
+
}
|
|
304
|
+
// ─── Pause / Resume ──────────────────────────────────────────────────
|
|
305
|
+
/** Pause all open sessions */
|
|
306
|
+
pauseAllSessions() {
|
|
307
|
+
const now = new Date().toISOString();
|
|
308
|
+
for (const session of this.dailyLog.sessions) {
|
|
309
|
+
if (!session.closedBy && !this.hasOpenPause(session)) {
|
|
310
|
+
session.pauses.push({ from: now, to: null, source: PauseSource.Manual });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
/** Pause a specific repo's open session. Returns true if a session was paused. */
|
|
315
|
+
pauseRepoSession(repoName) {
|
|
316
|
+
const session = this.findOpenSession(repoName);
|
|
317
|
+
if (!session || this.hasOpenPause(session))
|
|
318
|
+
return false;
|
|
319
|
+
const now = new Date().toISOString();
|
|
320
|
+
session.pauses.push({ from: now, to: null, source: PauseSource.Manual });
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
/** Resume all paused sessions */
|
|
324
|
+
resumeAllSessions() {
|
|
325
|
+
const now = new Date().toISOString();
|
|
326
|
+
for (const session of this.dailyLog.sessions) {
|
|
327
|
+
if (!session.closedBy) {
|
|
328
|
+
this.closeOpenPause(session, now);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/** Check if a session is currently paused */
|
|
333
|
+
hasOpenPause(session) {
|
|
334
|
+
return getOpenPause(session) !== null;
|
|
335
|
+
}
|
|
336
|
+
// ─── Private: session lifecycle ────────────────────────────────────────
|
|
337
|
+
findOpenSession(repo) {
|
|
338
|
+
return this.dailyLog.sessions.find(s => s.repo === repo && !s.closedBy) ?? null;
|
|
339
|
+
}
|
|
340
|
+
openSession(repo, task, branch, now) {
|
|
341
|
+
const session = {
|
|
342
|
+
id: generateSessionId(),
|
|
343
|
+
repo,
|
|
344
|
+
task,
|
|
345
|
+
branch,
|
|
346
|
+
state: SessionState.Pending,
|
|
347
|
+
startedAt: now,
|
|
348
|
+
activatedAt: null,
|
|
349
|
+
lastSeenAt: now,
|
|
350
|
+
closedBy: null,
|
|
351
|
+
evidence: createEmptyEvidence(),
|
|
352
|
+
pauses: [],
|
|
353
|
+
manualAdjustments: [],
|
|
354
|
+
};
|
|
355
|
+
this.dailyLog.sessions.push(session);
|
|
356
|
+
return session;
|
|
357
|
+
}
|
|
358
|
+
closeSession(session, reason, now) {
|
|
359
|
+
if (session.closedBy)
|
|
360
|
+
return; // already closed
|
|
361
|
+
// Close any open pause before closing the session
|
|
362
|
+
this.closeOpenPause(session, now);
|
|
363
|
+
session.closedBy = reason;
|
|
364
|
+
session.lastSeenAt = now;
|
|
365
|
+
// state stays as 'pending' or 'active' — preserved for reporting
|
|
366
|
+
this.autoPauseDisabledSessions.delete(session.id);
|
|
367
|
+
this.onSessionClosed?.(session.id);
|
|
368
|
+
}
|
|
369
|
+
closeOpenPause(session, now) {
|
|
370
|
+
const pause = getOpenPause(session);
|
|
371
|
+
if (pause) {
|
|
372
|
+
pause.to = now;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
getOpenPauseSource(session) {
|
|
376
|
+
return getOpenPause(session)?.source ?? null;
|
|
377
|
+
}
|
|
378
|
+
/** Apply auto-pause if not already paused with the same source */
|
|
379
|
+
applyAutoPause(session, source, now) {
|
|
380
|
+
const currentSource = this.getOpenPauseSource(session);
|
|
381
|
+
if (currentSource === PauseSource.Manual)
|
|
382
|
+
return; // Never override manual pause
|
|
383
|
+
if (currentSource === source)
|
|
384
|
+
return; // already paused with same source
|
|
385
|
+
if (currentSource !== null) {
|
|
386
|
+
// Close existing auto-pause before applying new one
|
|
387
|
+
this.closeOpenPause(session, now);
|
|
388
|
+
}
|
|
389
|
+
session.pauses.push({ from: now, to: null, source });
|
|
390
|
+
}
|
|
391
|
+
/** Close auto-pause (IdleTimeout or Superseded) if present */
|
|
392
|
+
closeAutoPause(session, now) {
|
|
393
|
+
const pause = getOpenPause(session);
|
|
394
|
+
if (pause && (pause.source === PauseSource.IdleTimeout || pause.source === PauseSource.Superseded)) {
|
|
395
|
+
pause.to = now;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
// ─── Private: tick update ──────────────────────────────────────────────
|
|
399
|
+
updateSessionTick(session, result, now) {
|
|
400
|
+
session.lastSeenAt = now;
|
|
401
|
+
// Accumulate line stats (positive deltas = new edits, negative = committed/reverted)
|
|
402
|
+
if (result.delta.addedDelta > 0) {
|
|
403
|
+
session.evidence.linesAdded += result.delta.addedDelta;
|
|
404
|
+
}
|
|
405
|
+
if (result.delta.removedDelta > 0) {
|
|
406
|
+
session.evidence.linesRemoved += result.delta.removedDelta;
|
|
407
|
+
}
|
|
408
|
+
// Track max concurrent files changed (high water mark)
|
|
409
|
+
if (result.snapshot.trackedFileCount > session.evidence.filesChanged) {
|
|
410
|
+
session.evidence.filesChanged = result.snapshot.trackedFileCount;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
creditReflogEvidence(session, entries) {
|
|
414
|
+
for (const entry of entries) {
|
|
415
|
+
if (entry.type === 'commit') {
|
|
416
|
+
session.evidence.commits++;
|
|
417
|
+
session.evidence.reflogEvents++;
|
|
418
|
+
}
|
|
419
|
+
else if (entry.type === 'checkout' || entry.type === 'reset') {
|
|
420
|
+
session.evidence.reflogEvents++;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
// ─── Private: signals ──────────────────────────────────────────────────
|
|
425
|
+
logSignals(repoName, result) {
|
|
426
|
+
const now = Date.now();
|
|
427
|
+
const dedup = this.config.session.signalDeduplicationSeconds;
|
|
428
|
+
if (result.delta.hasDynamics) {
|
|
429
|
+
addSignal(this.dailyLog, {
|
|
430
|
+
ts: now,
|
|
431
|
+
type: SignalType.DiffDynamics,
|
|
432
|
+
repo: repoName,
|
|
433
|
+
delta: {
|
|
434
|
+
added: result.delta.addedDelta,
|
|
435
|
+
removed: result.delta.removedDelta,
|
|
436
|
+
untracked: result.delta.untrackedDelta,
|
|
437
|
+
},
|
|
438
|
+
}, dedup);
|
|
439
|
+
}
|
|
440
|
+
for (const entry of result.newReflogEntries) {
|
|
441
|
+
if (entry.type === 'commit') {
|
|
442
|
+
addSignal(this.dailyLog, {
|
|
443
|
+
ts: entry.ts,
|
|
444
|
+
type: SignalType.Commit,
|
|
445
|
+
repo: repoName,
|
|
446
|
+
task: result.task,
|
|
447
|
+
}, dedup);
|
|
448
|
+
}
|
|
449
|
+
else if (entry.type === 'checkout') {
|
|
450
|
+
addSignal(this.dailyLog, {
|
|
451
|
+
ts: entry.ts,
|
|
452
|
+
type: SignalType.Checkout,
|
|
453
|
+
repo: repoName,
|
|
454
|
+
task: result.task,
|
|
455
|
+
}, dedup);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
//# sourceMappingURL=session-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-tracker.js","sourceRoot":"","sources":["../../src/core/session-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SessionTracker } from './session-tracker.js';
|
|
2
|
+
import type { AppConfig } from './types.js';
|
|
3
|
+
interface RenderContext {
|
|
4
|
+
readonly sessionTracker: SessionTracker;
|
|
5
|
+
readonly config: AppConfig;
|
|
6
|
+
currentDate: string;
|
|
7
|
+
readonly startedAt: number;
|
|
8
|
+
readonly timezone: string;
|
|
9
|
+
readonly pollSeconds: number;
|
|
10
|
+
readonly repos: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
export declare class StatusRenderer {
|
|
13
|
+
private readonly ctx;
|
|
14
|
+
private tickCount;
|
|
15
|
+
constructor(ctx: RenderContext);
|
|
16
|
+
updateDate(date: string): void;
|
|
17
|
+
renderError(message: string): void;
|
|
18
|
+
render(): void;
|
|
19
|
+
}
|
|
20
|
+
export {};
|